Created
July 1, 2020 06:09
-
-
Save lukeed/f0d5e384ef0a5442670fcddde1b26d98 to your computer and use it in GitHub Desktop.
how to traverse an AST with astray and collect identifier sources + references
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as astray from 'astray'; | |
import { parse } from 'meriyah'; | |
const AST = parse(` | |
var intro = greeting(); | |
function greeting() { | |
return 'Hello world!'; | |
} | |
console.log('this is my intro:', intro); | |
console.log('it should match:', greeting()); | |
`); | |
const REFS = new Map; | |
astray.walk(AST, { | |
Identifier(node, state) { | |
let value = state.get(node.name) || { | |
source: null, | |
refs: [] | |
}; | |
let source = toParent(node); | |
if (source && source.type === 'MemberExpression') return; | |
if (source && /Declaration/.test(source.type)) value.source = source; | |
else value.refs.push(source || node); | |
state.set(node.name, value); | |
} | |
}, REFS); | |
function toParent(node) { | |
let parent = node; | |
let RGX = /(Function|Variable)Declaration|Expression/; | |
while (parent = parent.path.parent) { | |
if (RGX.test(parent.type)) return parent; | |
} | |
} | |
for (let [key, val] of REFS) { | |
console.log(key, val); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
intro { | |
source: { | |
type: 'VariableDeclaration', | |
kind: 'var', | |
declarations: [ [Object] ], | |
path: { parent: [Object] } | |
}, | |
refs: [ | |
{ | |
type: 'CallExpression', | |
callee: [Object], | |
arguments: [Array], | |
path: [Object] | |
} | |
] | |
} | |
greeting { | |
source: { | |
type: 'FunctionDeclaration', | |
id: { type: 'Identifier', name: 'greeting', path: [Object] }, | |
params: [], | |
body: { type: 'BlockStatement', body: [Array], path: [Object] }, | |
async: false, | |
generator: false, | |
path: { parent: [Object] } | |
}, | |
refs: [ | |
{ | |
type: 'CallExpression', | |
callee: [Object], | |
arguments: [], | |
path: [Object] | |
}, | |
{ | |
type: 'CallExpression', | |
callee: [Object], | |
arguments: [], | |
path: [Object] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment