From 642583771d5f3a3175b5bfd93b9b79ce70dc0938 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 10 Jun 2016 14:10:30 -0700 Subject: [PATCH 1/7] Salsa: get members of variables whose initialisers are functions --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 8 ++++++-- src/compiler/utilities.ts | 12 ++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index db956cca647..bfe7ee31eb2 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1945,7 +1945,7 @@ namespace ts { classPrototype.parent = leftSideOfAssignment; const funcSymbol = container.locals[constructorFunction.text]; - if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function)) { + if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { return; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 044f42414b7..e3a29cce258 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11481,8 +11481,12 @@ namespace ts { // When resolved signature is a call signature (and not a construct signature) the result type is any, unless // the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations // in a JS file - const funcSymbol = checkExpression(node.expression).symbol; - if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function)) { + // Note:JS inferred classes might come from a variable declaration instead of a function declaration. + // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration. + const funcSymbol = node.expression.kind === SyntaxKind.Identifier ? + getResolvedSymbol(node.expression as Identifier) : + checkExpression(node.expression).symbol; + if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { return getInferredClassType(funcSymbol); } else if (compilerOptions.noImplicitAny) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c54775ad2af..04ea50f4e0c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1257,6 +1257,18 @@ namespace ts { return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote; } + /** + * Returns true if the node is a variable declaration whose initializer is a function expression. + * This function does not test if the node is in a JavaScript file or not. + */ + export function isDeclarationOfFunctionExpression(s: Symbol) { + if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) { + const declaration = s.valueDeclaration as VariableDeclaration; + return declaration.initializer && declaration.initializer.kind === SyntaxKind.FunctionExpression; + } + return false; + } + /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property /// assignments we treat as special in the binder export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind { From 4a9b1209aeffb33ddbc6c7358e2a0e901cb8eee9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 10 Jun 2016 14:11:31 -0700 Subject: [PATCH 2/7] Test adding members to JS variables whose initialisers are functions --- ...salsaMethodsOnAssignedFunctionExpressions.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/cases/fourslash/salsaMethodsOnAssignedFunctionExpressions.ts diff --git a/tests/cases/fourslash/salsaMethodsOnAssignedFunctionExpressions.ts b/tests/cases/fourslash/salsaMethodsOnAssignedFunctionExpressions.ts new file mode 100644 index 00000000000..a73207c01d2 --- /dev/null +++ b/tests/cases/fourslash/salsaMethodsOnAssignedFunctionExpressions.ts @@ -0,0 +1,17 @@ +/// +// @allowJs: true +// @Filename: something.js +////var C = function () { } +/////** +//// * The prototype method. +//// * @param {string} a Parameter definition. +//// */ +////function f(a) {} +////C.prototype.m = f; +//// +////var x = new C(); +////x/*1*/./*2*/m(); +goTo.marker('1'); +verify.quickInfoIs('var x: {\n m: (a: string) => void;\n}'); +goTo.marker('2'); +verify.completionListContains('m', '(property) C.m: (a: string) => void', 'The prototype method.'); From 5a7f7469eae853cbe9c21612e8e4d64324d3d5da Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 13 Jun 2016 13:21:47 -0700 Subject: [PATCH 3/7] Add isDefinition to ReferenceEntry Clients can now easily tell if the reference is to a definition or a usage. --- src/server/client.ts | 1 + src/server/protocol.d.ts | 5 +++++ src/server/session.ts | 5 +++-- src/services/services.ts | 7 +++++-- src/services/shims.ts | 4 ++-- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/server/client.ts b/src/server/client.ts index b0a1a8ec9e9..ea6c948c4fb 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -376,6 +376,7 @@ namespace ts.server { fileName: fileName, textSpan: ts.createTextSpanFromBounds(start, end), isWriteAccess: entry.isWriteAccess, + isDefinition: entry.isDefinition, }; }); } diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index d2c15b308ec..dd29411f97d 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -304,6 +304,11 @@ declare namespace ts.server.protocol { * True if reference is a write location, false otherwise. */ isWriteAccess: boolean; + + /** + * True if reference is a definition, false otherwise. + */ + isDefinition?: boolean; } /** diff --git a/src/server/session.ts b/src/server/session.ts index 0ec3d87e58c..2964dc66505 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -379,7 +379,7 @@ namespace ts.server { start, end, file: fileName, - isWriteAccess + isWriteAccess, }; }); } @@ -555,7 +555,8 @@ namespace ts.server { start: start, lineText: lineText, end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)), - isWriteAccess: ref.isWriteAccess + isWriteAccess: ref.isWriteAccess, + isDefinition: ref.isDefinition }; }); }, diff --git a/src/services/services.ts b/src/services/services.ts index 13df3a54a30..5e1b69170a5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1208,6 +1208,7 @@ namespace ts { textSpan: TextSpan; fileName: string; isWriteAccess: boolean; + isDefinition?: boolean; } export interface DocumentHighlights { @@ -6183,7 +6184,8 @@ namespace ts { references: [{ fileName: sourceFile.fileName, textSpan: createTextSpan(position, searchText.length), - isWriteAccess: false + isWriteAccess: false, + isDefinition: false }] }); } @@ -6737,7 +6739,8 @@ namespace ts { return { fileName: node.getSourceFile().fileName, textSpan: createTextSpanFromBounds(start, end), - isWriteAccess: isWriteAccess(node) + isWriteAccess: isWriteAccess(node), + isDefinition: isDeclarationName(node) }; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 94ff3367e3c..96392ca42be 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -164,7 +164,7 @@ namespace ts { /** * Returns a JSON-encoded value of the type: - * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[] + * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[] */ getReferencesAtPosition(fileName: string, position: number): string; @@ -1141,4 +1141,4 @@ namespace TypeScript.Services { /* @internal */ const toolsVersion = "1.9"; -/* tslint:enable:no-unused-variable */ \ No newline at end of file +/* tslint:enable:no-unused-variable */ From ac9e617e5e1cab0e3cdd1fd9cc1d855e72df49dc Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 13 Jun 2016 13:23:32 -0700 Subject: [PATCH 4/7] Test isDefinition --- src/harness/fourslash.ts | 11 +++++---- tests/cases/fourslash/fourslash.ts | 2 +- ...tOccurrencesIsDefinitionOfArrowFunction.ts | 8 +++++++ .../getOccurrencesIsDefinitionOfClass.ts | 13 +++++++++++ .../getOccurrencesIsDefinitionOfEnum.ts | 11 +++++++++ .../getOccurrencesIsDefinitionOfFunction.ts | 9 ++++++++ .../getOccurrencesIsDefinitionOfInterface.ts | 10 ++++++++ ...rencesIsDefinitionOfInterfaceClassMerge.ts | 19 +++++++++++++++ .../getOccurrencesIsDefinitionOfNamespace.ts | 10 ++++++++ .../getOccurrencesIsDefinitionOfParameter.ts | 9 ++++++++ .../getOccurrencesIsDefinitionOfTypeAlias.ts | 8 +++++++ .../getOccurrencesIsDefinitionOfVariable.ts | 23 +++++++++++++++++++ 12 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfArrowFunction.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfClass.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfEnum.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfFunction.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfInterface.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfInterfaceClassMerge.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfNamespace.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfParameter.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfTypeAlias.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfVariable.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c05fca5bb47..d852a0b84f3 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -728,7 +728,7 @@ namespace FourSlash { } } - public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { + public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) { const references = this.getReferencesAtCaret(); if (!references || references.length === 0) { @@ -741,11 +741,14 @@ namespace FourSlash { if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) { this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`); } + if (typeof isDefinition !== "undefined" && reference.isDefinition !== isDefinition) { + this.raiseError(`verifyReferencesAtPositionListContains failed - item isDefinition value does not match, actual: ${reference.isDefinition}, expected: ${isDefinition}.`); + } return; } } - const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; + const missingItem = { fileName, start, end, isWriteAccess, isDefinition }; this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`); } @@ -2835,8 +2838,8 @@ namespace FourSlashInterface { this.state.verifyReferencesCountIs(count, /*localFilesOnly*/ false); } - public referencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean) { - this.state.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess); + public referencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean, isDefinition?: boolean) { + this.state.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess, isDefinition); } public signatureHelpPresent() { diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 540a6503138..78de5b02358 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -125,7 +125,7 @@ declare namespace FourSlashInterface { completionListAllowsNewIdentifier(): void; memberListIsEmpty(): void; referencesCountIs(count: number): void; - referencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; + referencesAtPositionContains(range: Range, isWriteAccess?: boolean, isDefinition?: boolean): void; signatureHelpPresent(): void; errorExistsBetweenMarkers(startMarker: string, endMarker: string): void; errorExistsAfterMarker(markerName?: string): void; diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfArrowFunction.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfArrowFunction.ts new file mode 100644 index 00000000000..eb9980c946d --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfArrowFunction.ts @@ -0,0 +1,8 @@ +/// +////var [|{| "isDefinition": true |}f|] = x => x + 1; +////[|{| "isDefinition": false |}f|](12); +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfClass.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfClass.ts new file mode 100644 index 00000000000..04b1f90681a --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfClass.ts @@ -0,0 +1,13 @@ +/// +////class [|{| "isDefinition": true |}C|] { +//// n: number; +//// constructor() { +//// this.n = 12; +//// } +////} +////let c = new [|{| "isDefinition": false |}C|](); +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfEnum.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfEnum.ts new file mode 100644 index 00000000000..a5764206bce --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfEnum.ts @@ -0,0 +1,11 @@ +/// +////enum [|{| "isDefinition": true |}E|] { +//// First, +//// Second +////} +////let first = [|{| "isDefinition": false |}E|].First; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfFunction.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfFunction.ts new file mode 100644 index 00000000000..456d953092d --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfFunction.ts @@ -0,0 +1,9 @@ +/// +////function [|{| "isDefinition": true |}func|](x: number) { +////} +////[|{| "isDefinition": false |}func|](x) +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterface.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterface.ts new file mode 100644 index 00000000000..51d1e858185 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterface.ts @@ -0,0 +1,10 @@ +/// +////interface [|{| "isDefinition": true |}I|] { +//// p: number; +////} +////let i: [|{| "isDefinition": false |}I|] = { p: 12 }; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterfaceClassMerge.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterfaceClassMerge.ts new file mode 100644 index 00000000000..7efefa17a4b --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterfaceClassMerge.ts @@ -0,0 +1,19 @@ +/// +////interface [|{| "isDefinition": true |}Numbers|] { +//// p: number; +////} +////interface [|{| "isDefinition": true |}Numbers|] { +//// m: number; +////} +////class [|{| "isDefinition": true |}Numbers|] { +//// f(n: number) { +//// return this.p + this.m + n; +//// } +////} +////let i: [|{| "isDefinition": false |}Numbers|] = new [|{| "isDefinition": false |}Numbers|](); +////let x = i.f(i.p + i.m); +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNamespace.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNamespace.ts new file mode 100644 index 00000000000..86b92ec9ce7 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNamespace.ts @@ -0,0 +1,10 @@ +/// +////namespace [|{| "isDefinition": true |}Numbers|] { +//// export var n = 12; +////} +////let x = [|{| "isDefinition": false |}Numbers|].n + 1; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfParameter.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfParameter.ts new file mode 100644 index 00000000000..cdb0e281d53 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfParameter.ts @@ -0,0 +1,9 @@ +/// +////function f([|{| "isDefinition": true |}x|]: number) { +//// return [|{| "isDefinition": false |}x|] + 1 +////} +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfTypeAlias.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfTypeAlias.ts new file mode 100644 index 00000000000..44a7c64a93a --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfTypeAlias.ts @@ -0,0 +1,8 @@ +/// +////type [|{| "isDefinition": true |}Alias|]= number; +////let n: [|{| "isDefinition": false |}Alias|] = 12; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfVariable.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfVariable.ts new file mode 100644 index 00000000000..8d046c67e3a --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfVariable.ts @@ -0,0 +1,23 @@ +/// +////var [|{| "isDefinition": true |}x|] = 0; +////var assignmentRightHandSide = [|{| "isDefinition": false |}x|]; +////var assignmentRightHandSide2 = 1 + [|{| "isDefinition": false |}x|]; +//// +////[|{| "isDefinition": false |}x|] = 1; +////[|{| "isDefinition": false |}x|] = [|{| "isDefinition": false |}x|] + [|{| "isDefinition": false |}x|]; +//// +////[|{| "isDefinition": false |}x|] == 1; +////[|{| "isDefinition": false |}x|] <= 1; +//// +////var preIncrement = ++[|{| "isDefinition": false |}x|]; +////var postIncrement = [|{| "isDefinition": false |}x|]++; +////var preDecrement = --[|{| "isDefinition": false |}x|]; +////var postDecrement = [|{| "isDefinition": false |}x|]--; +//// +////[|{| "isDefinition": false |}x|] += 1; +////[|{| "isDefinition": false |}x|] <<= 1; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); From 792b23edc23684d0577143659cf9a37bab10dc73 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Tue, 14 Jun 2016 08:48:26 -0700 Subject: [PATCH 5/7] Make isDefinition required. For the deprecated getOccurrencesAtPosition, isDefinition is always false. --- src/server/client.ts | 1 + src/server/protocol.d.ts | 2 +- src/services/services.ts | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/server/client.ts b/src/server/client.ts index ea6c948c4fb..864dac9fdaa 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -537,6 +537,7 @@ namespace ts.server { fileName, textSpan: ts.createTextSpanFromBounds(start, end), isWriteAccess: entry.isWriteAccess, + isDefinition: false }; }); } diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index dd29411f97d..b62d89ae520 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -308,7 +308,7 @@ declare namespace ts.server.protocol { /** * True if reference is a definition, false otherwise. */ - isDefinition?: boolean; + isDefinition: boolean; } /** diff --git a/src/services/services.ts b/src/services/services.ts index 5e1b69170a5..4f5bdbdc469 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1208,7 +1208,7 @@ namespace ts { textSpan: TextSpan; fileName: string; isWriteAccess: boolean; - isDefinition?: boolean; + isDefinition: boolean; } export interface DocumentHighlights { @@ -5750,7 +5750,8 @@ namespace ts { result.push({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, - isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference + isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference, + isDefinition: false }); } } From 7bf40c49358edb44cfaaf79618455613158f7f4e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Tue, 14 Jun 2016 09:39:30 -0700 Subject: [PATCH 6/7] Add more isDefinition tests and fix computed property bug --- src/services/services.ts | 2 +- .../getOccurrencesIsDefinitionOfBindingPattern.ts | 8 ++++++++ .../getOccurrencesIsDefinitionOfComputedProperty.ts | 9 +++++++++ .../fourslash/getOccurrencesIsDefinitionOfExport.ts | 11 +++++++++++ ...getOccurrencesIsDefinitionOfNumberNamedProperty.ts | 8 ++++++++ ...getOccurrencesIsDefinitionOfStringNamedProperty.ts | 8 ++++++++ 6 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfBindingPattern.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts create mode 100644 tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts diff --git a/src/services/services.ts b/src/services/services.ts index 4f5bdbdc469..3cf6b432c5d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6741,7 +6741,7 @@ namespace ts { fileName: node.getSourceFile().fileName, textSpan: createTextSpanFromBounds(start, end), isWriteAccess: isWriteAccess(node), - isDefinition: isDeclarationName(node) + isDefinition: isDeclarationName(node) || node.parent.kind === SyntaxKind.ComputedPropertyName }; } diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfBindingPattern.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfBindingPattern.ts new file mode 100644 index 00000000000..9a30687c59e --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfBindingPattern.ts @@ -0,0 +1,8 @@ +/// +////const { [|{| "isDefinition": true |}x|], y } = { x: 1, y: 2 }; +////const z = [|{| "isDefinition": false |}x|]; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts new file mode 100644 index 00000000000..8896694db50 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts @@ -0,0 +1,9 @@ +/// +////let o = { ["[|{| "isDefinition": true |}foo|]"]: 12 }; +////let y = o.[|{| "isDefinition": false |}foo|]; +////let z = o['[|{| "isDefinition": false |}foo|]']; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts new file mode 100644 index 00000000000..f863af9184f --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts @@ -0,0 +1,11 @@ +/// +// @Filename: m.ts +////export var [|{| "isDefinition": true |}x|] = 12; +// @Filename: main.ts +////import { [|{| "isDefinition": true |}x|] } from "./m"; +////const y = [|{| "isDefinition": false |}x|]; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts new file mode 100644 index 00000000000..7e3e084948f --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts @@ -0,0 +1,8 @@ +/// +////let o = { [|{| "isDefinition": true |}1|]: 12 }; +////let y = o[[|{| "isDefinition": false |}1|]]; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts new file mode 100644 index 00000000000..291aec90dda --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts @@ -0,0 +1,8 @@ +/// +////let o = { "[|{| "isDefinition": true |}x|]": 12 }; +////let y = o.[|{| "isDefinition": false |}x|]; +var firstRange = test.ranges()[0]; +goTo.position(firstRange.start, firstRange.fileName); +test.ranges().forEach(range => { + verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition); +}); From 102a890214f21ef56fa5325cf8eb859beef743ae Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Tue, 14 Jun 2016 10:27:36 -0700 Subject: [PATCH 7/7] Use `isLiteralComputedPropertyDeclarationName` --- src/services/services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 3cf6b432c5d..07094df7d2b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6741,7 +6741,7 @@ namespace ts { fileName: node.getSourceFile().fileName, textSpan: createTextSpanFromBounds(start, end), isWriteAccess: isWriteAccess(node), - isDefinition: isDeclarationName(node) || node.parent.kind === SyntaxKind.ComputedPropertyName + isDefinition: isDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node) }; }