From a870b068342165f299d619833f0fc159e186ed5e Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Mon, 13 Oct 2014 18:25:51 -0700 Subject: [PATCH 1/2] Fix signature help crash when requested outside argument list --- src/services/formatting/smartIndenter.ts | 2 +- src/services/signatureHelp.ts | 8 ++------ src/services/utilities.ts | 16 +++++++++------- .../fourslash/noSignatureHelpOnNewKeyword.ts | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 tests/cases/fourslash/noSignatureHelpOnNewKeyword.ts diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 79b238c893d..12d36dd4d2b 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -108,7 +108,7 @@ module ts.formatting { function getActualIndentationForListItemBeforeComma(commaToken: Node, sourceFile: SourceFile, options: TypeScript.FormattingOptions): number { // previous token is comma that separates items in list - find the previous item and try to derive indentation from it var commaItemInfo = findListItemInfo(commaToken); - Debug.assert(commaItemInfo.listItemIndex > 0); + Debug.assert(commaItemInfo && commaItemInfo.listItemIndex > 0); // The item we're interested in is right before the comma return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options); } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 273cfda99b8..d9d221ee65d 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -226,12 +226,8 @@ module ts.SignatureHelp { }; } - if (node.kind === SyntaxKind.GreaterThanToken - || node.kind === SyntaxKind.CloseParenToken - || node === parent.func) { - return undefined; - } - + // findListItemInfo can return undefined if we are not in parent's argument list + // or type argument list. return findListItemInfo(node); } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 4ceb20fdcee..5b77a2b84a5 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -7,6 +7,15 @@ module ts { export function findListItemInfo(node: Node): ListItemInfo { var syntaxList = findContainingList(node); + + // It is possible at this point for syntaxList to be undefined, either if + // node.parent had no list child, or if none of its list children contained + // the span of node. If this happens, return undefined. The caller should + // handle this case. + if (!syntaxList) { + return undefined; + } + var children = syntaxList.getChildren(); var index = indexOf(children, node); @@ -32,13 +41,6 @@ module ts { } }); - // syntaxList should not be undefined here. If it is, there is a problem. Find out if - // there at least is a child that is a list. - if (!syntaxList) { - Debug.assert(findChildOfKind(node.parent, SyntaxKind.SyntaxList), - "Node of kind " + SyntaxKind[node.parent.kind] + " has no list children"); - } - return syntaxList; } diff --git a/tests/cases/fourslash/noSignatureHelpOnNewKeyword.ts b/tests/cases/fourslash/noSignatureHelpOnNewKeyword.ts new file mode 100644 index 00000000000..30314b1c665 --- /dev/null +++ b/tests/cases/fourslash/noSignatureHelpOnNewKeyword.ts @@ -0,0 +1,14 @@ +/// + +////class Foo { } +////new/*1*/ Foo +////new /*2*/Foo(/*3*/) + +goTo.marker('1'); +verify.not.signatureHelpPresent(); + +goTo.marker('2'); +verify.not.signatureHelpPresent(); + +goTo.marker('3'); +verify.signatureHelpPresent(); \ No newline at end of file From 8b4bbb9311cb193ed1e310668c78da47d103078b Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 14 Oct 2014 11:23:36 -0700 Subject: [PATCH 2/2] Comment examples of when findListItemInfo can return undefined --- src/services/signatureHelp.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index d9d221ee65d..e9375818c11 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -227,7 +227,11 @@ module ts.SignatureHelp { } // findListItemInfo can return undefined if we are not in parent's argument list - // or type argument list. + // or type argument list. This includes cases where the cursor is: + // - To the right of the closing paren + // - Between the type arguments and the arguments (greater than token) + // - On the target of the call (parent.func) + // - On the 'new' keyword in a 'new' expression return findListItemInfo(node); }