diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..d32c6735 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Tests", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "test"] + } + ] +} diff --git a/snapshots/output/enclosing-ranges/range.js b/snapshots/output/enclosing-ranges/range.js index 89afef4b..4684c559 100644 --- a/snapshots/output/enclosing-ranges/range.js +++ b/snapshots/output/enclosing-ranges/range.js @@ -34,6 +34,7 @@ function test2() { // < start enclosing_range enclosing-ranges 0.0.1 `range.js`/Test# class Test { // ^^^^ definition enclosing-ranges 0.0.1 `range.js`/Test# +// ⌄ start enclosing_range enclosing-ranges 0.0.1 `range.js`/Test#``(). constructor() { //^^^^^^^^^^^ definition enclosing-ranges 0.0.1 `range.js`/Test#``(). const a = 'a' @@ -45,6 +46,7 @@ class Test { // ^ reference local 14 // ^ reference local 17 } +// ^ end enclosing_range enclosing-ranges 0.0.1 `range.js`/Test#``(). // ⌄ start enclosing_range enclosing-ranges 0.0.1 `range.js`/Test#test(). test() { diff --git a/src/FileIndexer.ts b/src/FileIndexer.ts index a71d7192..a93a2f56 100644 --- a/src/FileIndexer.ts +++ b/src/FileIndexer.ts @@ -166,7 +166,13 @@ export class FileIndexer { } private visitSymbolOccurrence(node: ts.Node, sym: ts.Symbol): void { - const range = Range.fromNode(node).toLsif() + const isConstructor = ts.isConstructorDeclaration(node) + // For constructors, this method is passed the declaration node and not the identifier node. + // In either case, this method needs to get the range of the "name" of the declaration, for constructors we + // get the firstToken which contains the text "constructor". + const range = Range.fromNode( + isConstructor ? node.getFirstToken() ?? node : node + ).toLsif() let role = 0 let declarations: ts.Node[] = this.getDeclarationsForPropertyAssignment(node) ?? [] @@ -207,7 +213,8 @@ export class FileIndexer { ts.isTypeAliasDeclaration(declaration) || ts.isClassDeclaration(declaration) || ts.isMethodDeclaration(declaration) || - ts.isInterfaceDeclaration(declaration) + ts.isInterfaceDeclaration(declaration) || + ts.isConstructorDeclaration(declaration) ) { enclosingRange = Range.fromNode(declaration).toLsif() } diff --git a/src/Range.ts b/src/Range.ts index 214b5dc0..1207f232 100644 --- a/src/Range.ts +++ b/src/Range.ts @@ -33,18 +33,17 @@ export class Range { new Position(endLine, endCharacter) ) } + public static fromNode(node: ts.Node): Range { const sourceFile = node.getSourceFile() - const rangeNode: ts.Node = ts.isConstructorDeclaration(node) - ? node.getFirstToken() ?? node - : node - const start = sourceFile.getLineAndCharacterOfPosition(rangeNode.getStart()) - const end = sourceFile.getLineAndCharacterOfPosition(rangeNode.getEnd()) + const start = sourceFile.getLineAndCharacterOfPosition(node.getStart()) + const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd()) return new Range( new Position(start.line, start.character), new Position(end.line, end.character) ) } + public isSingleLine(): boolean { return this.start.line === this.end.line }