fkling / astexplorer

A web tool to explore the ASTs generated by various parsers.
https://astexplorer.net/
MIT License
6.13k stars 729 forks source link

Feature request: Tree of JavaScript scopes (eslint-scope) #510

Open ajvincent opened 4 years ago

ajvincent commented 4 years ago

https://github.com/eslint/eslint-scope

I'm thinking about using eslint-scope in one of my projects, but I need a visualization of its output to be sure that's what I'm looking for.

Can someone help me out, please?

fkling commented 4 years ago

This sounds interesting but I'm not sure how such a visualization would look like. What did you have in mind?

ajvincent commented 4 years ago

I think the tree root would be a global scope object, with child objects being child scopes and the variables in each scope (AST objects). var currentScope = scopeManager.acquire(ast); // global scope

fkling commented 4 years ago

Would you expect it to be rendered like we currently render the AST (like an object with properties), or something else?

ajvincent commented 4 years ago

As similarly as possible, yes. I'm really not expecting major changes in the appearance.

0xdevalias commented 1 year ago

Stumbled across this issue today and figured some of the following notes/references from some research i've been doing lately might be relevant/helpful here:

Of particular note are the demo's for escope and eslevels; and the forked escope demo that also seems to add support for eslint-scope:

While I wouldn't say that any of these tools represent an optimal UX for my personal needs/desires, they definitely take steps in the right direction!


Then to add my personal /2c to this as well, it would be nice to be able to view the scopes from any number of compatible tools/parsers. For example I am currently working with Babel's parser, and it seems to have built in scope handling, so it would be great to be able to visualise that.

Here's a link to some super hacky explorative code i've been playing with lately:

But within that we can see how the scopes can be viewed:

image

Which is output from this snippet of code:

// Source: https://replit.com/@0xdevalias/Rewriting-JavaScript-Variables-via-AST-Examples#babel_v1_3_clean.js

const debugLogScopeBindings = ({ path }) => {
  if (!DEBUG) return

  const debugLog = makeDebugLog(path);

  const scopeBindings = path.scope.bindings;
  const allBindings = path.scope.getAllBindings();

  const nameFromPath = getNameFromPath(path);

  console.group(`[DEBUG] Path (type=${path.type}, nameFromPath=${nameFromPath}, pathLocation=${path.getPathLocation()})`);

  console.group('Code');

  console.log(path.toString().slice(0, MAX_CODE_CONTEXT_LENGTH));

  console.groupEnd();

  console.group(`Scope Dump (uid=${path.scope.uid})`);

  path.scope.dump();

  console.groupEnd();

  console.group('Scope Bindings');

  console.table(
    Object.entries(scopeBindings).map(([bindingName, binding]) => {
      return {
        name: bindingName,
        kind: binding.kind,
        references: binding.references,
        scopeUid: binding.scope.uid,
        scopeType: binding.scope.path.type,
      }
    })
  );

  console.groupEnd();

  console.group('All Bindings');

  console.table(
    Object.entries(allBindings).map(([bindingName, binding]) => {
      return {
        name: bindingName,
        kind: binding.kind,
        references: binding.references,
        scopeUid: binding.scope.uid,
        scopeType: binding.scope.path.type,
      }
    })
  );

  console.groupEnd();

  // ..snip..

  console.groupEnd();
}