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

How to turn ast into PHP code #969

Open
Yuri2 opened this issue Jul 4, 2022 · 5 comments
Open

How to turn ast into PHP code #969

Yuri2 opened this issue Jul 4, 2022 · 5 comments

Comments

@Yuri2
Copy link

Yuri2 commented Jul 4, 2022

const parser = new engine({
// some options :
parser: {
extractDoc: true,
php7: true,
},
ast: {
withPositions: true,
},
});

// Load a static file (Note: this file should exist on your computer)
const phpcode = fs.readFileSync("./1.php", {
encoding: "utf-8"
});

let ast=parser.parseCode(phpcode);


now:
How to turn ast into PHP code?

@dominic-p
Copy link

I'm new to this project, but I believe you will want to use something like php-writer for that.

@loilo
Copy link
Contributor

loilo commented May 8, 2023

Possibly helpful: It's not exactly turning an AST into code, but if you just want to make changes to some PHP code based on the php-parser AST, I just made a library for that. 🙂

@yaegassy
Copy link

yaegassy commented Jul 4, 2023

@loilo Hi, do you have a code example for traversing or visitors with php-parser?

@loilo
Copy link
Contributor

loilo commented Jul 4, 2023

@yaegassy Sure. You basically have to recursively check all properties of a node to find descendant nodes, where a node is defined by having a kind property.

Here's some code defining a walk function which you can feed a callback and an AST:

/**
 * Check whether a value resembles a php-parser AST node
 *
 * @param value The value to check
 */
function isNode(value) {
  return (
    typeof value === 'object' &&
    value !== null &&
    typeof value.kind === 'string'
  )
}

/**
 * Collect the child nodes of an AST node
 *
 * @param node The node to search for child nodes
 */
function collectChildNodes(node) {
  const childNodes = []

  // Walk all AST node properties, performing a recursive `walk`
  // on everything that looks like another AST node
  for (const key of Object.keys(node)) {
    const property = node[key]

    if (Array.isArray(property)) {
      // Step into arrays and walk their items
      for (const propertyElement of property) {
        if (isNode(propertyElement)) {
          childNodes.push(propertyElement)
        }
      }
    } else if (isNode(property)) {
      childNodes.push(property)
    }
  }

  return childNodes
}

/**
 * Walk an AST recursively
 *
 * @param callback  A function to invoke for every node
 * @param node      The tree to visit
 * @param parent    The parent of the (sub)tree node
 */
function walk(callback, node, parent = undefined) {
  const children = collectChildNodes(node)
  for (const child of children) {
    walk(callback, child, node)
  }
  callback(node, parent)
}

@yaegassy
Copy link

yaegassy commented Jul 4, 2023

@loilo Thanks, I will refer to it. 🙇

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

4 participants