Expose flow nodes
https://stackoverflow.com/questions/72241016/how-to-access-flownode-in-typescript-ast-api
You awesome thank you!
Hey @dsherret :) The solution you give me it's works on the question example.
But I try to apply this to my code and it's not work. I think I did wrong example.
I try to resolve from components property all the components.
I need them in array of classes.
But why typescript can't resolve the classes from the exports?
https://codesandbox.io/s/eager-franklin-3w6d8j?file=/src/index.ts
This is how my code work exactly:
import { Project, SyntaxKind, PropertyAssignment } from "ts-morph";
console.clear();
const project = new Project({
skipAddingFilesFromTsConfig: true
});
const fooComponentSourceFile = project.createSourceFile(
"foo-component.ts",
`export class FooComponent {}`
);
const barComponentSourceFile = project.createSourceFile(
"bar-component.ts",
`export class BarComponent {}`
);
const indexSourceFile = project.createSourceFile(
"index.ts",
`export * from './foo-component';
export * from './bar-component';
`
);
const appSourceFile = project.createSourceFile(
"app.ts",
`
import * as COMPONENTS from './index.ts';
const result = run({
components: { ...COMPONENTS }
})
`
);
const components = appSourceFile
.getDescendantsOfKind(SyntaxKind.Identifier)
.find((n) => n.getText() === "components");
// get the identifier
const nodesIdent = (components!.getParent() as PropertyAssignment).getNameNode();
// // hack to force the type checker to create the flow node
nodesIdent.getType();
// // get the flow node
const flowNode = (nodesIdent.compilerNode as any).flowNode as ts.FlowNode;
console.log({ n: flowNode }); // <-- getting object without node.
@jon9090 check project.getPreEmitDiagnostics() for any diagnostics after creating the source files.
At a glance, it looks like the code is using the import specifier "./index.ts", which should be "./index" to work with the ts compiler.
@dsherret I add
project.getPreEmitDiagnostics();
project.resolveSourceFileDependencies();
And change to ./index;
https://codesandbox.io/s/eager-franklin-3w6d8j?file=/src/index.ts
The problem still exist. I don't get the variable flowNode.node to get the classes.
What else can I do?
@jon9090 check the output by doing something like console.log(project.getPreEmitDiagnostics())
console.log(project.getPreEmitDiagnostics()) returns empty array. no compiler errors.
@jon9090 in the example you posted I get Cannot find name 'run'. since run is not defined.
That said, once I define a run function it still returns a flow node without any information. Maybe that's just expected in this scenario?
@dsherret I update my code and add the run function: https://codesandbox.io/s/eager-franklin-3w6d8j?file=/src/index.ts
But what I try to get is the components classes value from appSourceFile.
So I found the components within the object I pass to run function. the right side is the value. but i want to get instend the actual value which is the classes array:
thats what I can't do. why typescript can't be able to resolve in flow node the classes from the exports in index file?
If I do:
const COMPONENTS = {Foo, Bar};
const some = run({ components: { ...COMPONENTS } });
Then I got the Foo and Bar Identifiers from there I can go and resolve the class.
What I try to do is to get the exports from the flow node:
// // get the flow node
const flowNode = (nodesIdent.compilerNode as any).flowNode as ts.FlowNode;
console.log({ n: flowNode.node. initializer.elements[0].escapedText }); //<--- FooComponent
Because FooComponent is exports from index.ts and consume by appSourceFile:
import * as COMPONENTS from './index'; // <-- COMPONENTS === { FooComponent, BarComponent }
run({ components: { ...COMPONENTS } ) ...
Hey @dsherret I think I made a progress with this.
https://codesandbox.io/s/mystifying-faraday-2piybb?file=/src/index.ts:0-1044
I getting the members:
const members = Array.from((components!.getType().compilerType as any).members);
But how I getting the ClassDeclaration node?
I try to do:
members[0][1].getDeclarations()[0].kind // === 256 (ClassDeclaration)
But it's not acting like ClassDeclaration. for example it don't have getName function.
How I can get the real ClassDeclaration node?