Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modifying the AST #1006

Open
deakjahn opened this issue Sep 20, 2022 · 4 comments
Open

Modifying the AST #1006

deakjahn opened this issue Sep 20, 2022 · 4 comments

Comments

@deakjahn
Copy link

deakjahn commented Sep 20, 2022

Was the AST ever intended to be modified externally? I've just written an AST->PHP writer (yes, I'm aware of php-writer, it's very old and dated, I needed the full support up to the latest PHP 8.1). It's in TypeScript, actually, not JavaScript. I didn't yet have time to test it at all but I'm more than willing to share it as soon as it's reasonably error free.

However, this leads to the current question. I'd need to modify the AST so that I can export it in full or partly back to PHP. Was php-parser ever intended to support this scenario? The various AST classes don't seem to have constructors and there seems to be no easy way to build or modify an AST tree (except for assembling PHP strings and parsing them eval-style but that's not what would really be needed).

@deakjahn
Copy link
Author

deakjahn commented Sep 20, 2022

Addendum: I could actually create some nodes like this:

let newExpression: php.Bin = {
  kind: 'bin',
  left: node.left,
  right: node.right,
  type: '+',
  setTrailingComments: (docs: any) => { },
  destroy: () => { },
  includeToken: (parser: any) => { },
  loc: null,
  trailingComments: null,
  leadingComments: null,
};

but it just doesn't feel right. But I have to override those functions in the middle because the compiler doesn't accept a partial class, leaving out some fields.

@deakjahn
Copy link
Author

I finally came up with this solution and it works but adding real constructors would be very welcome down the line:

import * as php from "php-parser";

export function binary(left: php.Expression, right: php.Expression, operator: string): php.Bin {
  return {
    kind: 'bin',
    left: left,
    right: right,
    type: operator,
  } as php.Bin;
}

@czosel
Copy link
Collaborator

czosel commented Sep 25, 2022

Hi @deakjahn, thanks for bringing this up. As far as I can tell, a public API for this use-case has not been a focus yet. If I'm not mistaken, the functions in the src/ast directory are node constructors, though. The parser itself creates them like this: https://github.com/glayzzle/php-parser/blob/main/src/ast.js#L393 - you're looking for something typed though, right?

@deakjahn
Copy link
Author

deakjahn commented Sep 25, 2022

Yes, they look like constructors, but there's no way to pass them the required parameters. So, I need to create one for each and every one of the node types, of course.

The ATS->PHP writer is practically done, I listed the small problems I found along the route in the other issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants