0

While working with Esprima JavaScript Parser, which generates an AST in JSON format from JS source code, I noticed that it would be handy if I could register the type of a node (string) and trigger events when this type of node is visited, such as:

ASTFramework.on("Identifier", function(evt){
  /*Some code here*/
});

By making some research, it seems that JSHint implements internally such functionality, but is not available from its API. Are there any suggestions on this?

EDIT: What I want to do, is to be able to register events in order to be fired when an AST node is visited. In simple words, a framework that triggers events in specific JSON node visiting would be sufficient for that case.

Nick Louloudakis
  • 5,856
  • 4
  • 41
  • 54

2 Answers2

1

The closest thing I found searching for AST node traversing was the tool estraverse, which gave me the ability to visit the nodes and check the type in order to make actions:

//Using require from Node.js here to add module.
var estraverse = require("estraverse");

//Rest of code....

estraverse.traverse(astTree, {
  enter: function (node) {
    if(node.type == "Identifier") {
      //Do something
    } else if(node.type == "Literal") {
      //Do something else, etc
    }
  }
});

Because estraverse visits all nodes (probably using DFS), it is pretty easy to specify which types are wanted to be considered for actions, even if they are deeply nested inside others.

Nick Louloudakis
  • 5,856
  • 4
  • 41
  • 54
  • Pretty classic: "walk the tree, check each node as it goes by". Registering a function for a particular node type can be accomplished by saving a pair in any associative container, and then running "walk the tree, consult the container for the node type and run the associated function" so your original request is relatively easy to implement. It will probably not perform as well as just checking for the specific node type unless you go out of your way to optimize the associative lookup. – Ira Baxter Jun 02 '16 at 10:47
1

You can use babel, which can transform JS (and fires events like you want).

I wrote a simple plugin that converts x[-1] to x[x.length -1], which could get you started.

Code looks like this:

visitor: {
  MemberExpression(path) {
    const node = path.node;

    /* obj[...] */
    if (t.isMemberExpression(node) && node.computed) {

      if (t.isUnaryExpression(node.property) && node.property.operator === "-") {

        if (t.isNumericLiteral(node.property.argument)) {
          ...
        }
      }
    }
  },
}

More info: Babel Plugin Handbook

Fabian Zeindl
  • 5,860
  • 8
  • 54
  • 78