From c57adeda1f32b9bd95f44316113e5bc99460baac Mon Sep 17 00:00:00 2001 From: Yui T Date: Sat, 15 Aug 2015 17:02:08 -0700 Subject: [PATCH 01/10] Fix null reference in type parametr of type alias --- src/services/services.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index bfee19b3a6a..78aeb4bfeea 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4076,16 +4076,19 @@ namespace ts { } else { // Method/function type parameter - let signatureDeclaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; - let signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === SyntaxKind.ConstructSignature) { - displayParts.push(keywordPart(SyntaxKind.NewKeyword)); - displayParts.push(spacePart()); + let container = getContainingFunction(location); + if (container) { + let signatureDeclaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; + let signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === SyntaxKind.ConstructSignature) { + displayParts.push(keywordPart(SyntaxKind.NewKeyword)); + displayParts.push(spacePart()); + } + else if (signatureDeclaration.kind !== SyntaxKind.CallSignature && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature)); } - else if (signatureDeclaration.kind !== SyntaxKind.CallSignature && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature)); } } if (symbolFlags & SymbolFlags.EnumMember) { From abc96936b52ad35a086348873fc76eb24e984e39 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 17 Aug 2015 10:48:36 -0700 Subject: [PATCH 02/10] Do not show completions in type parameter of type alias --- src/services/services.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/services.ts b/src/services/services.ts index 78aeb4bfeea..878d81fe195 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3492,6 +3492,7 @@ namespace ts { return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | containingNodeKind === SyntaxKind.FunctionDeclaration || // function A< | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< | + containingNodeKind === SyntaxKind.TypeAliasDeclaration || isFunction(containingNodeKind); case SyntaxKind.StaticKeyword: From ab20cf9f141c9d5bdc28eb3bb0ddf7ff9add07de Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 17 Aug 2015 22:02:05 -0700 Subject: [PATCH 03/10] Add test for completion in type parater of type alias --- ...mpletionListInTypeParameterOfTypeAlias1.ts | 18 ++++++++++++++++ ...mpletionListInTypeParameterOfTypeAlias2.ts | 21 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts create mode 100644 tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts new file mode 100644 index 00000000000..ec20cdb409f --- /dev/null +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts @@ -0,0 +1,18 @@ +/// + +////type List1 = T[]; +////type List4 = /*2*/T[]; +////type List3 = /*3*/; + +/*goTo.marker("0"); +verify.completionListIsEmpty(); +goTo.marker("1"); +verify.not.completionListIsEmpty(); +goTo.marker("2"); +verify.completionListContains("T"); +*/ +goTo.marker("3"); +verify.not.completionListIsEmpty(); +verify.not.completionListContains("T"); +verify.completionListContains("T1"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts new file mode 100644 index 00000000000..e804fb8946a --- /dev/null +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts @@ -0,0 +1,21 @@ +/// + +////type Map1 = []; +////type Map1 = /*2*/[]; +////type Map1 = Date: Mon, 17 Aug 2015 22:02:45 -0700 Subject: [PATCH 04/10] Add comment and prevent completion in type paramter of class expression --- src/services/services.ts | 7 +++++-- ...letionListInTypeParameterOfClassExpression1.ts | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts diff --git a/src/services/services.ts b/src/services/services.ts index 878d81fe195..9c00b92a063 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3460,9 +3460,11 @@ namespace ts { containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, | isFunction(containingNodeKind) || containingNodeKind === SyntaxKind.ClassDeclaration || // class A + +////var C0 = class D {} +////var C3 = class D{} + +goTo.marker("0"); +verify.completionListIsEmpty(); +goTo.marker("1"); +verify.completionListIsEmpty(); +goTo.marker("2"); +verify.completionListIsEmpty(); +goTo.marker("3"); +verify.completionListIsEmpty(); \ No newline at end of file From bef4e8d58e8ce09bd6629d6e302edcb0f0cf7db0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 17 Aug 2015 22:04:54 -0700 Subject: [PATCH 05/10] remove commented test --- .../fourslash/completionListInTypeParameterOfTypeAlias1.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts index ec20cdb409f..e6017eedbfc 100644 --- a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias1.ts @@ -5,13 +5,12 @@ ////type List4 = /*2*/T[]; ////type List3 = /*3*/; -/*goTo.marker("0"); +goTo.marker("0"); verify.completionListIsEmpty(); goTo.marker("1"); verify.not.completionListIsEmpty(); goTo.marker("2"); verify.completionListContains("T"); -*/ goTo.marker("3"); verify.not.completionListIsEmpty(); verify.not.completionListContains("T"); From ed1383842c49ad5f917b3cef61fcd5863cd27df8 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Aug 2015 12:38:08 -0700 Subject: [PATCH 06/10] Fix space --- src/compiler/utilities.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 70d17e4290b..e1f5d31b26c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -385,7 +385,10 @@ namespace ts { } export function getJsDocComments(node: Node, sourceFileOfNode: SourceFile) { - let commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ? concatenate(getTrailingCommentRanges(sourceFileOfNode.text, node.pos), getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) : getLeadingCommentRangesOfNode(node, sourceFileOfNode); + let commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ? + concatenate(getTrailingCommentRanges(sourceFileOfNode.text, node.pos), + getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) : + getLeadingCommentRangesOfNode(node, sourceFileOfNode); return filter(commentRanges, isJsDocComment); function isJsDocComment(comment: CommentRange) { From 4c44de6c5f438e5c84b792e71f2ac98941818cd0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Aug 2015 12:38:36 -0700 Subject: [PATCH 07/10] Write out type parameter in type alias in quick-info --- src/compiler/checker.ts | 2 +- src/services/services.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b5b4eb9e748..ba43bc585f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1902,7 +1902,7 @@ namespace ts { function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags) { let targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface) { + if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface || targetSymbol.flags & SymbolFlags.TypeAlias) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } diff --git a/src/services/services.ts b/src/services/services.ts index 9c00b92a063..14374e58192 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4040,6 +4040,7 @@ namespace ts { displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); displayParts.push(spacePart()); @@ -4093,6 +4094,16 @@ namespace ts { } addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature)); } + else { + // Type aliash type parameter + // For example + // type list = T[]; // Both T will go through same code path + let declaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; + displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); + displayParts.push(spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); + } } } if (symbolFlags & SymbolFlags.EnumMember) { From dddc76b15675621d6996a45549f386a5a8630831 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Aug 2015 12:39:36 -0700 Subject: [PATCH 08/10] Add quick info test for type parameter in type alias --- ...nfoDisplayPartsTypeParameterInTypeAlias.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts diff --git a/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts new file mode 100644 index 00000000000..1bec6868e95 --- /dev/null +++ b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts @@ -0,0 +1,22 @@ +/// + +////type /*0*/List = /*2*/T[] + +type L = T[] +let typeAliashDisplayParts = [{ text: "type", kind: "keyword" }, { text: " ", kind: "space" }, { text: "List", kind: "aliasName" }, + { text: "<", kind: "punctuation" }, { text: "T", kind: "typeParameterName" }, { text: ">", kind: "punctuation" }]; +let typeParameterDisplayParts = [{ text: "(", kind: "punctuation" }, { text: "type parameter", kind: "text" }, { text: ")", kind: "punctuation" }, { text: " ", kind: "space" }, + { text: "T", kind: "typeParameterName" }, { text: " ", kind: "space" }, { text: "in", kind: "keyword" }, { text: " ", kind: "space" } ] + +goTo.marker('0'); +verify.verifyQuickInfoDisplayParts("type", "", { start: test.markerByName("0").position, length: "List".length }, + typeAliashDisplayParts.concat([{ text: " ", kind: "space" }, { text: "=", kind: "operator" }, { "text": " ", "kind": "space" }, { text: "T", kind: "typeParameterName" }, + { text: "[", kind: "punctuation" }, { text: "]", kind: "punctuation" }]), []); + +goTo.marker('1'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("1").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts), []); + +goTo.marker('2'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("2").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts), []); From bb7a132b0e6669e362bc069ce37fdbaf383624e9 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 20 Aug 2015 09:25:02 -0700 Subject: [PATCH 09/10] Address code review --- src/services/services.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 14374e58192..ea667936146 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3493,7 +3493,6 @@ namespace ts { case SyntaxKind.LessThanToken: return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | containingNodeKind === SyntaxKind.ClassExpression || // var C = class D< | - containingNodeKind === SyntaxKind.FunctionDeclaration || // function A< | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< | containingNodeKind === SyntaxKind.TypeAliasDeclaration || // type List< | isFunction(containingNodeKind); From 9b04405e201b61134aaa820e34b83de869296923 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 25 Aug 2015 16:53:12 -0700 Subject: [PATCH 10/10] Add test and address PR --- ...onListInTypeParameterOfClassExpression1.ts | 5 ++++- ...mpletionListInTypeParameterOfTypeAlias2.ts | 2 -- ...nfoDisplayPartsTypeParameterInTypeAlias.ts | 22 +++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts b/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts index 1398b05e701..f8afcdc418c 100644 --- a/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts +++ b/tests/cases/fourslash/completionListInTypeParameterOfClassExpression1.ts @@ -4,6 +4,7 @@ ////var C1 = class D {} ////var C3 = class D{} +////var C5 = class D{} goTo.marker("0"); verify.completionListIsEmpty(); @@ -12,4 +13,6 @@ verify.completionListIsEmpty(); goTo.marker("2"); verify.completionListIsEmpty(); goTo.marker("3"); -verify.completionListIsEmpty(); \ No newline at end of file +verify.completionListIsEmpty(); +goTo.marker("4"); +verify.not.completionListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts index e804fb8946a..80a910da798 100644 --- a/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts +++ b/tests/cases/fourslash/completionListInTypeParameterOfTypeAlias2.ts @@ -10,11 +10,9 @@ verify.completionListIsEmpty(); goTo.marker("1"); verify.completionListContains("V"); goTo.marker("2"); -verify.not.completionListIsEmpty(); verify.completionListContains("K"); verify.completionListContains("V"); goTo.marker("3"); -verify.not.completionListIsEmpty(); verify.not.completionListContains("K"); verify.not.completionListContains("V"); verify.completionListContains("K1"); diff --git a/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts index 1bec6868e95..b6a10e086c2 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsTypeParameterInTypeAlias.ts @@ -1,13 +1,22 @@ /// ////type /*0*/List = /*2*/T[] +////type /*3*/List2 = /*5*/T[]; + +type List2 = T[]; type L = T[] let typeAliashDisplayParts = [{ text: "type", kind: "keyword" }, { text: " ", kind: "space" }, { text: "List", kind: "aliasName" }, { text: "<", kind: "punctuation" }, { text: "T", kind: "typeParameterName" }, { text: ">", kind: "punctuation" }]; + +let typeAliashDisplayParts2 = [{ text: "type", kind: "keyword" }, { text: " ", kind: "space" }, { text: "List2", kind: "aliasName" }, + { text: "<", kind: "punctuation" }, { text: "T", kind: "typeParameterName" }, { text: " ", kind: "space" }, { text: "extends", kind: "keyword" }, + { text: " ", kind: "space" }, { text: "string", kind: "keyword" }, { text: ">", kind: "punctuation" }]; + let typeParameterDisplayParts = [{ text: "(", kind: "punctuation" }, { text: "type parameter", kind: "text" }, { text: ")", kind: "punctuation" }, { text: " ", kind: "space" }, { text: "T", kind: "typeParameterName" }, { text: " ", kind: "space" }, { text: "in", kind: "keyword" }, { text: " ", kind: "space" } ] + goTo.marker('0'); verify.verifyQuickInfoDisplayParts("type", "", { start: test.markerByName("0").position, length: "List".length }, typeAliashDisplayParts.concat([{ text: " ", kind: "space" }, { text: "=", kind: "operator" }, { "text": " ", "kind": "space" }, { text: "T", kind: "typeParameterName" }, @@ -20,3 +29,16 @@ verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByN goTo.marker('2'); verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("2").position, length: "T".length }, typeParameterDisplayParts.concat(typeAliashDisplayParts), []); + +goTo.marker('3'); +verify.verifyQuickInfoDisplayParts("type", "", { start: test.markerByName("3").position, length: "List2".length }, + typeAliashDisplayParts2.concat([{ text: " ", kind: "space" }, { text: "=", kind: "operator" }, { "text": " ", "kind": "space" }, { text: "T", kind: "typeParameterName" }, + { text: "[", kind: "punctuation" }, { text: "]", kind: "punctuation" }]), []); + +goTo.marker('4'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("4").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts2), []); + +goTo.marker('5'); +verify.verifyQuickInfoDisplayParts("type parameter", "", { start: test.markerByName("5").position, length: "T".length }, + typeParameterDisplayParts.concat(typeAliashDisplayParts2), []); \ No newline at end of file