Skip to content

[Feature] Direct AST-based format-preserving source-code transformation #538

@lisachenko

Description

@lisachenko

Current version of framework installs the PHP stream filter php_user_filter defined in the SourceTransformingLoader which creates a Data-Transfer-Object StreamMetaData, triggers the transformation process and returns the transformed code back from filter call:

$metadata = new StreamMetaData($this->stream, $this->data);
self::transformCode($metadata);
....
$bucket = stream_bucket_new($this->stream, $metadata->source);
stream_bucket_append($out, $bucket);

StreamMetaData uses goaop/parser-reflection and underlying nikic/parser-reflection library to parse source code into AST and tokens:

$this->syntaxTree = ReflectionEngine::parseFile($this->uri, $source);
$this->setTokenStreamFromRawTokens(...ReflectionEngine::getParser()->getTokens());

goaop/parser-reflection has implemented the format-preserving AST transformation and pretty-printing in goaop/parser-reflection#137 according to the https://github.com/nikic/PHP-Parser/blob/master/doc/component/Pretty_printing.markdown

ClassLoading and Transformer namespaces and classes inside should be refactored into traditional AST node walkers/transformers instead of token manipulation. And once AST will be transformed into $newStmts, PrettyPrinter will be used together with $oldStmts, $oldTokens to pretty-print transformed version of code back. It is important to ensure that line numbers in original source code and transformed should match, so if change is introduced in line - it should remain in that line. StreamMetadata->source should be removed, as new version will work around AST.

Code and tests should pass phpunit tests and phpstan analysis.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions