ts-morph
ts-morph copied to clipboard
`getChildrenOfKind` does not work for `StringLiteral`
Describe the bug
Hi,
getChildrenOfKind returns nothing for SyntaxKind.StringLiteral because useParseTreeSearchForKind returns false which should be true.
Version: 25.0.1
To Reproduce
import { Project, SyntaxKind } from 'ts-morph';
const src = '["abc", "def"];';
const project = new Project();
const source = project.createSourceFile('dummy.js', src);
for (const es of source.getChildrenOfKind(SyntaxKind.ExpressionStatement)) {
for (const ale of es.getChildrenOfKind(SyntaxKind.ArrayLiteralExpression)) {
for (const sl of ale.getChildrenOfKind(SyntaxKind.StringLiteral)) {
console.log(sl); // not found
}
for (const sl of ale._getCompilerForEachChildren().filter((c) => c.kind === SyntaxKind.StringLiteral)) {
console.log(sl); // found
}
}
}
Expected behavior
getChildrenOfKind returns the children of StringLiteral.
Array literal expressions do not have a direct StringLiteral child when using getChildren()/getChildrenOfKind(). There's a SyntaxList inbetween them.
https://ts-ast-viewer.com/#code/NoIghgRgxiA0AEIAmBTAZiAugbiA (turn on Options > Tree mode > node.getChildren())
In this case, I would recommend using getElements() (or whatever it's called) on ArrayLiteralExpression then filter for string literals.
There is also a SyntaxList under CallExpression in the example below, but why could call.getChildrenOfKind(SyntaxKind.ArrayLiteralExpression) find the ArrayLiteralExpression node?
import { Project, SyntaxKind } from 'ts-morph';
// SourceFile
// SyntaxList
// ExpressionStatement
// CallExpression
// Identifier
// OpenParenToken
// SyntaxList
// ArrayLiteralExpression
// OpenBracketToken
// SyntaxList
// StringLiteral
// CommaToken
// StringLiteral
// CloseBracketToken
// CloseParenToken
// SemicolonToken
// EndOfFileToken
const project = new Project();
const source = project.createSourceFile('script.js', 'defineProps(["abc", "def"]);');
source.forEachChild((c) => {
if (c.getKind() === SyntaxKind.ExpressionStatement) {
const call = c.getFirstChildByKind(SyntaxKind.CallExpression);
// there is a SyntaxList under call
for (const ale of call.getChildrenOfKind(SyntaxKind.ArrayLiteralExpression)) {
console.log(ale.getKindName()); // found: ArrayLiteralExpression
// there is a SyntaxList under ArrayLiteralExpression
for (const sl of ale.getChildrenOfKind(SyntaxKind.StringLiteral)) {
console.log(sl.getKindName()); // nothing printed
}
}
}
});
Oh, sorry. I just looked at the code and see that it's not always using getChildren() internally. It's too late to change this as it would be a breaking change and I highly recommend not using getChildrenOfKind in this case, but rather use ale.getElements().
Actually, I kind of feel like it should just return it anyway. Probably a low chance of breaking anyone.