Skip to content

Instantly share code, notes, and snippets.

@phiggins42
Created September 1, 2021 12:39
Show Gist options
  • Save phiggins42/25982251da48ae2c908780d3ebf03099 to your computer and use it in GitHub Desktop.
Save phiggins42/25982251da48ae2c908780d3ebf03099 to your computer and use it in GitHub Desktop.
AST Goodtimes?
// Trying to use AST do determine _possible_ all calls to
// `Foo.prototype.emit`.
// I think I want to walk CallExpressions and look for
// property.name === 'emit', which seems accurate enough
// if not maybe giving false positives in mixed code with
// actual EventEmitters and otherwise?
class Foo {
emit(message, ...data) {}
on(event, callback) {}
doit(name) {
this.emit(name || "ouch", 90210);
}
}
const foo = new Foo();
// 90% of usecases look like this:
foo.emit("bar"); // "bar" []
foo.emit("baz", 42); // "baz" [42]
foo.emit("bam", 1, { a: 2}, 3, 4, 5); // "bam" [1,{a:2},3,4,5]
// edge casey:
const x = "bap";
foo.emit(x, 420); // "bap" [420]
foo.emit(x, x); // "bap" ["bap"]
// Dynamic first positional argument
// is edge case, would be okay with only tracking symbol names
// for dynamic properties or arguments
['a', 'b', 'c'].forEach(message => {
foo.on(message, (e) => {
foo.emit(`e${message}`, e); // "ea" [e], "eb" [e], "ec" [e]
});
});
// ideally, these would be detected without actually spying
// on Foo.prototype.emit, I was thinking AST because even
// without calling `doit` I can see
foo.doit("self"); // "self" [90210]
foo.doit(); // "ouch" [90210]
@phiggins42
Copy link
Author

Current output of a babel-based plugin during AST walking, mostly just looking at ExpressionStatement visitor

{
  '{unknown:LogicalExpression}': [ [ 90210 ] ],
  bar: [ [] ],
  baz: [ [ 42 ] ],
  bam: [ [ 1, {}, 3, 4, 5 ] ],
  '{working:Identifier, keys: type,start,end,loc,name,leadingComments,innerComments,trailingComments}': [
    [ 420 ],
    [
      '{working:Identifier, keys: type,start,end,loc,name,leadingComments,innerComments,trailingComments}'
    ]
  ],
  '{unknown:TemplateLiteral}': [
    [
      '{working:Identifier, keys: type,start,end,loc,name,leadingComments,innerComments,trailingComments}'
    ]
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment