Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to use esquery with ts-morph? #142

Open
jon9090 opened this issue Mar 9, 2023 · 2 comments
Open

how to use esquery with ts-morph? #142

jon9090 opened this issue Mar 9, 2023 · 2 comments

Comments

@jon9090
Copy link

jon9090 commented Mar 9, 2023

How can I use esquery in conjunction with ts-morph to retrieve nodes from the Abstract Syntax Tree (AST) by query path similar to CSS? For instance, given the query path CallExpression > ObjectLiteralExpression > PropertyAssignment[name="arg1"], how can I retrieve the node of type PropertyAssignment with the name arg1?

Here's an example code I've been trying to use to accomplish this, but it doesn't seem to work:

codesandbox

import "./styles.css";
import esquery from "esquery";
import { Project } from "ts-morph";

const project = new Project();
const sourceFile = project.createSourceFile(
  "foo.ts",
  `
class Foo {
  bar() {
    const result = create({
      arg1: true,
      arg2: false
    });
  }
}
`
);

const fooClass = sourceFile.getClass("Foo");

const matches = esquery(
  fooClass,
  'CallExpression > ObjectLiteralExpression > PropertyAssignment[name="arg1"]'
);

console.log({ matches });

Although I'm aware that ts-morph allows me to parse code into an AST, I'm specifically interested in using esquery to retrieve nodes by query path similar to CSS. Is there a way to combine the two approaches or is there an alternative solution that achieves a similar outcome?

@jon9090
Copy link
Author

jon9090 commented Mar 9, 2023

After I dig into source code I found esquery is getting the type of the node by access property, while in ts-morph is by function: getKindName().

  return function (node, ancestry, options) {
            var nodeTypeKey = options && options.nodeTypeKey || 'type';
            console.log({value, nodeTypeKey, node })
            return value === node[nodeTypeKey].toLowerCase();
          };

contributors could you support a function call? for example:

const matches = esquery(node, 'PropertyAssignment', {
  nodeTypeKey: (node) => node.getKindName();
});

@michaelficarra
Copy link
Member

@jon9090 We could allow a function there, but it's kind of strange for that information to only be available via a method call. Why is ts-morph designed like that? Can you post-process the AST to eagerly pull out the node types and attach the result as a property? Do the AST nodes have a shared prototype where you could stick a getter?

I hesitate to just add support for a function, as it will slow the typical case to accommodate what I feel is a very unusual case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants