How can I know when the scope changes within an abstract syntax tree?

116 views Asked by At

Can someone help me with figuring out how to know when the scope changing while traversing the ast tree? I am using the esprima parser and I know that babel does this but I want to create my own to understand how it works and help increase my knowledge with using asts.

So how would I go about to knowing the scopes of each node?


var global = "I am in the global scope";

function scopeOne() {
  var one = "I am in the scope created by `scopeOne()`";

  function scopeTwo() {
    var two = "I am in the scope created by `scopeTwo()`";
  }
}

1

There are 1 answers

0
coderaiser On BEST ANSWER

The base idea is to determine how many scopes is upper then current node. For this purpose we need to check:

  • is current node is Program, the upper most node in AST;
  • is current node is BlockStatements that is used by all kinds of functions and statements (like IfConditionStatement, loops etc);

Then we just increase counter of scopes, this way we can distinguish them in the similar to Babel way.

Here is how it can look like written in Putout, tool I'm working on:

export const traverse = () => {
    let uid = 0;
    return {
        'BlockStatement|Program'(path) {
            console.log('babel scope', path.scope.uid);
            console.log('our scope', ++uid);
        },
    }
};

For code like this:

var global = "I am in the global scope";

function scopeOne() {
  var one = "I am in the scope created by `scopeOne()`";

  function scopeTwo() {
    var two = "I am in the scope created by `scopeTwo()`";
  }
}

if (a > 3) {
    console.log('hello');
}

It outputs:

Scopes

Playground: https://putout.cloudcmd.io/#/gist/06b547b6cd6f132b5300dd9d4473177e/b2a193c5c7233c309c46222cbb9ea8a46bd99a92