diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 50672e136a7aa..256354b1115c0 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -487,6 +487,15 @@ module ts { } } + export function getInvokedExpression(node: CallLikeExpression): Expression { + if (node.kind === SyntaxKind.TaggedTemplateExpression) { + return (node).tag; + } + + // Will either be a CallExpression or NewExpression. + return (node).func; + } + export function isExpression(node: Node): boolean { switch (node.kind) { case SyntaxKind.ThisKeyword: @@ -801,7 +810,7 @@ module ts { } export function isUnterminatedTemplateEnd(node: LiteralExpression) { - Debug.assert(node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail); + Debug.assert(isTemplateLiteralKind(node.kind)); var sourceText = getSourceFileOfNode(node).text; // If we're not at the EOF, we know we must be terminated. @@ -809,6 +818,11 @@ module ts { return false; } + // The literal can only be unterminated if it is a template tail or a no-sub template. + if (node.kind !== SyntaxKind.TemplateTail && node.kind !== SyntaxKind.NoSubstitutionTemplateLiteral) { + return false; + } + // If we didn't end in a backtick, we must still be in the middle of a template. // If we did, make sure that it's not the *initial* backtick. return sourceText.charCodeAt(node.end - 1) !== CharacterCodes.backtick || node.text.length === 0; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0188067f108c9..9cf10807c1bfd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -758,7 +758,7 @@ module ts { getAugmentedPropertiesOfType(type: Type): Symbol[]; getRootSymbols(symbol: Symbol): Symbol[]; getContextualType(node: Node): Type; - getResolvedSignature(node: CallExpression, candidatesOutArray?: Signature[]): Signature; + getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature; getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature; isImplementationOfOverload(node: FunctionLikeDeclaration): boolean; isUndefinedSymbol(symbol: Symbol): boolean; diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 7d063ae069d76..e2b65e3c6e10b 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -164,6 +164,20 @@ module ts.SignatureHelp { //} var emptyArray: any[] = []; + const enum ArgumentListKind { + TypeArguments, + CallArguments, + TaggedTemplateArguments + } + + interface ArgumentListInfo { + kind: ArgumentListKind; + invocation: CallLikeExpression; + argumentsSpan: TextSpan; + argumentIndex?: number; + argumentCount: number; + } + export function getSignatureHelpItems(sourceFile: SourceFile, position: number, typeInfoResolver: TypeChecker, cancellationToken: CancellationTokenObject): SignatureHelpItems { // Decide whether to show signature help var startingToken = findTokenOnLeftOfPosition(sourceFile, position); @@ -180,7 +194,7 @@ module ts.SignatureHelp { return undefined; } - var call = argumentInfo.list.parent; + var call = argumentInfo.invocation; var candidates = []; var resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates); cancellationToken.throwIfCancellationRequested(); @@ -192,50 +206,195 @@ module ts.SignatureHelp { return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo); /** - * If node is an argument, returns its index in the argument list. - * If not, returns -1. + * Returns relevant information for the argument list and the current argument if we are + * in the argument of an invocation; returns undefined otherwise. */ - function getImmediatelyContainingArgumentInfo(node: Node): ListItemInfo { - if (node.parent.kind !== SyntaxKind.CallExpression && node.parent.kind !== SyntaxKind.NewExpression) { - return undefined; + function getImmediatelyContainingArgumentInfo(node: Node): ArgumentListInfo { + if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) { + var callExpression = node.parent; + // There are 3 cases to handle: + // 1. The token introduces a list, and should begin a sig help session + // 2. The token is either not associated with a list, or ends a list, so the session should end + // 3. The token is buried inside a list, and should give sig help + // + // The following are examples of each: + // + // Case 1: + // foo<#T, U>(#a, b) -> The token introduces a list, and should begin a sig help session + // Case 2: + // fo#o#(a, b)# -> The token is either not associated with a list, or ends a list, so the session should end + // Case 3: + // foo(a#, #b#) -> The token is buried inside a list, and should give sig help + // Find out if 'node' is an argument, a type argument, or neither + if (node.kind === SyntaxKind.LessThanToken || + node.kind === SyntaxKind.OpenParenToken) { + // Find the list that starts right *after* the < or ( token. + // If the user has just opened a list, consider this item 0. + var list = getChildListThatStartsWithOpenerToken(callExpression, node, sourceFile); + var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos; + Debug.assert(list !== undefined); + return { + kind: isTypeArgList ? ArgumentListKind.TypeArguments : ArgumentListKind.CallArguments, + invocation: callExpression, + argumentsSpan: getApplicableSpanForArguments(list), + argumentIndex: 0, + argumentCount: getCommaBasedArgCount(list) + }; + } + + // findListItemInfo can return undefined if we are not in parent's argument list + // or type argument list. This includes cases where the cursor is: + // - To the right of the closing paren, non-substitution template, or template tail. + // - 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 + var listItemInfo = findListItemInfo(node); + if (listItemInfo) { + var list = listItemInfo.list; + var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos; + + // The listItemIndex we got back includes commas. Our goal is to return the index of the proper + // item (not including commas). Here are some examples: + // 1. foo(a, b, c #) -> the listItemIndex is 4, we want to return 2 + // 2. foo(a, b, # c) -> listItemIndex is 3, we want to return 2 + // 3. foo(#a) -> listItemIndex is 0, we want to return 0 + // + // In general, we want to subtract the number of commas before the current index. + // But if we are on a comma, we also want to pretend we are on the argument *following* + // the comma. That amounts to taking the ceiling of half the index. + var argumentIndex = (listItemInfo.listItemIndex + 1) >> 1; + + return { + kind: isTypeArgList ? ArgumentListKind.TypeArguments : ArgumentListKind.CallArguments, + invocation: callExpression, + argumentsSpan: getApplicableSpanForArguments(list), + argumentIndex: argumentIndex, + argumentCount: getCommaBasedArgCount(list) + }; + } } + else if (node.kind === SyntaxKind.NoSubstitutionTemplateLiteral && node.parent.kind === SyntaxKind.TaggedTemplateExpression) { + // Check if we're actually inside the template; + // otherwise we'll fall out and return undefined. + if (isInsideTemplateLiteral(node, position)) { + return getArgumentListInfoForTemplate(node.parent, /*argumentIndex*/ 0); + } + } + else if (node.kind === SyntaxKind.TemplateHead && node.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) { + var templateExpression = node.parent; + var tagExpression = templateExpression.parent; + Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression); + + var argumentIndex = isInsideTemplateLiteral(node, position) ? 0 : 1; + + return getArgumentListInfoForTemplate(tagExpression, argumentIndex); + } + else if (node.parent.kind === SyntaxKind.TemplateSpan && node.parent.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) { + var templateSpan = node.parent; + var templateExpression = templateSpan.parent; + var tagExpression = templateExpression.parent; + Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression); + + // If we're just after a template tail, don't show signature help. + if (node.kind === SyntaxKind.TemplateTail && position >= node.getEnd() && !isUnterminatedTemplateEnd(node)) { + return undefined; + } + + var spanIndex = templateExpression.templateSpans.indexOf(templateSpan); + var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node); + + return getArgumentListInfoForTemplate(tagExpression, argumentIndex); + } + + return undefined; + } + + function getCommaBasedArgCount(argumentsList: Node) { + // The number of arguments is the number of commas plus one, unless the list + // is completely empty, in which case there are 0 arguments. + return argumentsList.getChildCount() === 0 + ? 0 + : 1 + countWhere(argumentsList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken); + } + + // spanIndex is either the index for a given template span. + // This does not give appropriate results for a NoSubstitutionTemplateLiteral + function getArgumentIndexForTemplatePiece(spanIndex: number, node: Node): number { + // Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1. + // There are three cases we can encounter: + // 1. We are precisely in the template literal (argIndex = 0). + // 2. We are in or to the right of the substitution expression (argIndex = spanIndex + 1). + // 3. We are directly to the right of the template literal, but because we look for the token on the left, + // not enough to put us in the substitution expression; we should consider ourselves part of + // the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1). + // + // Example: f `# abcd $#{# 1 + 1# }# efghi ${ #"#hello"# } # ` + // ^ ^ ^ ^ ^ ^ ^ ^ ^ + // Case: 1 1 3 2 1 3 2 2 1 + Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node."); + if (isTemplateLiteralKind(node.kind)) { + if (isInsideTemplateLiteral(node, position)) { + return 0; + } + return spanIndex + 2; + } + return spanIndex + 1; + } + + function getArgumentListInfoForTemplate(tagExpression: TaggedTemplateExpression, argumentIndex: number): ArgumentListInfo { + // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument. + var argumentCount = tagExpression.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral + ? 1 + : (tagExpression.template).templateSpans.length + 1; + + return { + kind: ArgumentListKind.TaggedTemplateArguments, + invocation: tagExpression, + argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression), + argumentIndex: argumentIndex, + argumentCount: argumentCount + }; + } - // There are 3 cases to handle: - // 1. The token introduces a list, and should begin a sig help session - // 2. The token is either not associated with a list, or ends a list, so the session should end - // 3. The token is buried inside a list, and should give sig help + function getApplicableSpanForArguments(argumentsList: Node): TextSpan { + // We use full start and skip trivia on the end because we want to include trivia on + // both sides. For example, // - // The following are examples of each: + // foo( /*comment */ a, b, c /*comment*/ ) + // | | // - // Case 1: - // foo<$T, U>($a, b) -> The token introduces a list, and should begin a sig help session - // Case 2: - // fo$o$(a, b)$ -> The token is either not associated with a list, or ends a list, so the session should end - // Case 3: - // foo(a$, $b$) -> The token is buried inside a list, and should give sig help - var parent = node.parent; - // Find out if 'node' is an argument, a type argument, or neither - if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) { - // Find the list that starts right *after* the < or ( token. - // If the user has just opened a list, consider this item 0. - var list = getChildListThatStartsWithOpenerToken(parent, node, sourceFile); - Debug.assert(list !== undefined); - return { - list, - listItemIndex: 0 - }; + // The applicable span is from the first bar to the second bar (inclusive, + // but not including parentheses) + var applicableSpanStart = argumentsList.getFullStart(); + var applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false); + return new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); + } + + function getApplicableSpanForTaggedTemplate(taggedTemplate: TaggedTemplateExpression): TextSpan { + var template = taggedTemplate.template; + var applicableSpanStart = template.getStart(); + var applicableSpanEnd = template.getEnd(); + + // We need to adjust the end position for the case where the template does not have a tail. + // Otherwise, we will not show signature help past the expression. + // For example, + // + // ` ${ 1 + 1 foo(10) + // | | + // + // This is because a Missing node has no width. However, what we actually want is to include trivia + // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. + if (template.kind === SyntaxKind.TemplateExpression) { + var lastSpan = lastOrUndefined((template).templateSpans); + if (lastSpan.literal.kind === SyntaxKind.Missing) { + applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false); + } } - // findListItemInfo can return undefined if we are not in parent's 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); + return new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); } - function getContainingArgumentInfo(node: Node): ListItemInfo { + function getContainingArgumentInfo(node: Node): ArgumentListInfo { for (var n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) { if (n.kind === SyntaxKind.FunctionBlock) { return undefined; @@ -292,14 +451,13 @@ module ts.SignatureHelp { return maxParamsSignatureIndex; } - function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentInfoOrTypeArgumentInfo: ListItemInfo): SignatureHelpItems { - var argumentListOrTypeArgumentList = argumentInfoOrTypeArgumentInfo.list; - var parent = argumentListOrTypeArgumentList.parent; - var isTypeParameterHelp = parent.typeArguments && parent.typeArguments.pos === argumentListOrTypeArgumentList.pos; - Debug.assert(isTypeParameterHelp || parent.arguments.pos === argumentListOrTypeArgumentList.pos); + function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentListInfo: ArgumentListInfo): SignatureHelpItems { + var applicableSpan = argumentListInfo.argumentsSpan; + var isTypeParameterList = argumentListInfo.kind === ArgumentListKind.TypeArguments; - var callTargetNode = (argumentListOrTypeArgumentList.parent).func; - var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode); + var invocation = argumentListInfo.invocation; + var callTarget = getInvokedExpression(invocation) + var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTarget); var callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined); var items: SignatureHelpItem[] = map(candidates, candidateSignature => { var signatureHelpParameters: SignatureHelpParameter[]; @@ -310,27 +468,28 @@ module ts.SignatureHelp { prefixDisplayParts.push.apply(prefixDisplayParts, callTargetDisplayParts); } - if (isTypeParameterHelp) { + if (isTypeParameterList) { prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken)); var typeParameters = candidateSignature.typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken)); var parameterParts = mapToDisplayParts(writer => - typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, argumentListOrTypeArgumentList)); + typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, invocation)); suffixDisplayParts.push.apply(suffixDisplayParts, parameterParts); } else { var typeParameterParts = mapToDisplayParts(writer => - typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, argumentListOrTypeArgumentList)); + typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation)); prefixDisplayParts.push.apply(prefixDisplayParts, typeParameterParts); prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); + var parameters = candidateSignature.parameters; signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } var returnTypeParts = mapToDisplayParts(writer => - typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, argumentListOrTypeArgumentList)); + typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation)); suffixDisplayParts.push.apply(suffixDisplayParts, returnTypeParts); return { @@ -343,34 +502,10 @@ module ts.SignatureHelp { }; }); - // We use full start and skip trivia on the end because we want to include trivia on - // both sides. For example, - // - // foo( /*comment */ a, b, c /*comment*/ ) - // | | - // - // The applicable span is from the first bar to the second bar (inclusive, - // but not including parentheses) - var applicableSpanStart = argumentListOrTypeArgumentList.getFullStart(); - var applicableSpanEnd = skipTrivia(sourceFile.text, argumentListOrTypeArgumentList.end, /*stopAfterLineBreak*/ false); - var applicableSpan = new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); - - // The listItemIndex we got back includes commas. Our goal is to return the index of the proper - // item (not including commas). Here are some examples: - // 1. foo(a, b, c $) -> the listItemIndex is 4, we want to return 2 - // 2. foo(a, b, $ c) -> listItemIndex is 3, we want to return 2 - // 3. foo($a) -> listItemIndex is 0, we want to return 0 - // - // In general, we want to subtract the number of commas before the current index. - // But if we are on a comma, we also want to pretend we are on the argument *following* - // the comma. That amounts to taking the ceiling of half the index. - var argumentIndex = (argumentInfoOrTypeArgumentInfo.listItemIndex + 1) >> 1; - - // argumentCount is the number of commas plus one, unless the list is completely empty, - // in which case there are 0. - var argumentCount = argumentListOrTypeArgumentList.getChildCount() === 0 - ? 0 - : 1 + countWhere(argumentListOrTypeArgumentList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken); + var argumentIndex = argumentListInfo.argumentIndex; + + // argumentCount is the *apparent* number of arguments. + var argumentCount = argumentListInfo.argumentCount; var selectedItemIndex = candidates.indexOf(bestSignature); if (selectedItemIndex < 0) { @@ -387,7 +522,7 @@ module ts.SignatureHelp { function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { var displayParts = mapToDisplayParts(writer => - typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, argumentListOrTypeArgumentList)); + typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); var isOptional = !!(parameter.valueDeclaration.flags & NodeFlags.QuestionMark); @@ -401,7 +536,7 @@ module ts.SignatureHelp { function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter { var displayParts = mapToDisplayParts(writer => - typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, argumentListOrTypeArgumentList)); + typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation)); return { name: typeParameter.symbol.name, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index b0a216c7dcd17..75bea36bf3a57 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -320,4 +320,9 @@ module ts { export function isPunctuation(kind: SyntaxKind): boolean { return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation; } + + export function isInsideTemplateLiteral(node: LiteralExpression, position: number) { + return (node.getStart() < position && position < node.getEnd()) + || (isUnterminatedTemplateEnd(node) && position === node.getEnd()); + } } \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index c71f8987bdfe1..c0372d4606378 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -301,11 +301,11 @@ module FourSlashInterface { FourSlash.currentTestState.verifySignatureHelpArgumentCount(expected); } - public currentSignatureParamterCountIs(expected: number) { + public currentSignatureParameterCountIs(expected: number) { FourSlash.currentTestState.verifyCurrentSignatureHelpParameterCount(expected); } - public currentSignatureTypeParamterCountIs(expected: number) { + public currentSignatureTypeParameterCountIs(expected: number) { FourSlash.currentTestState.verifyCurrentSignatureHelpTypeParameterCount(expected); } diff --git a/tests/cases/fourslash/genericParameterHelp.ts b/tests/cases/fourslash/genericParameterHelp.ts index 17882485fd746..6bbb957f0f9c3 100644 --- a/tests/cases/fourslash/genericParameterHelp.ts +++ b/tests/cases/fourslash/genericParameterHelp.ts @@ -14,7 +14,7 @@ ////testFunction<, ,/*5*/>(null, null, null); // goTo.marker("1"); -// verify.currentSignatureParamterCountIs(3); +// verify.currentSignatureParameterCountIs(3); // verify.currentSignatureHelpIs("testFunction(a: T, b: U, c: M): M"); // verify.currentParameterHelpArgumentNameIs("T"); diff --git a/tests/cases/fourslash/signatureHelpAnonymousFunction.ts b/tests/cases/fourslash/signatureHelpAnonymousFunction.ts index cc723c713d627..ba812a2f8d31a 100644 --- a/tests/cases/fourslash/signatureHelpAnonymousFunction.ts +++ b/tests/cases/fourslash/signatureHelpAnonymousFunction.ts @@ -7,7 +7,7 @@ goTo.marker('anonymousFunction1'); verify.signatureHelpCountIs(1); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentSignatureHelpIs('(a: number, b: string): string'); verify.currentParameterHelpArgumentNameIs("a"); verify.currentParameterSpanIs("a: number"); diff --git a/tests/cases/fourslash/signatureHelpAtEOF.ts b/tests/cases/fourslash/signatureHelpAtEOF.ts index 64c4aaeeb2c0c..d2e1fa0418dad 100644 --- a/tests/cases/fourslash/signatureHelpAtEOF.ts +++ b/tests/cases/fourslash/signatureHelpAtEOF.ts @@ -10,6 +10,6 @@ verify.signatureHelpPresent(); verify.signatureHelpCountIs(1); verify.currentSignatureHelpIs("Foo(arg1: string, arg2: string): void"); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentParameterHelpArgumentNameIs("arg1"); verify.currentParameterSpanIs("arg1: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpBeforeSemicolon1.ts b/tests/cases/fourslash/signatureHelpBeforeSemicolon1.ts index 2b0b07056bf0f..d3bdd42ef1af8 100644 --- a/tests/cases/fourslash/signatureHelpBeforeSemicolon1.ts +++ b/tests/cases/fourslash/signatureHelpBeforeSemicolon1.ts @@ -10,6 +10,6 @@ verify.signatureHelpPresent(); verify.signatureHelpCountIs(1); verify.currentSignatureHelpIs("Foo(arg1: string, arg2: string): void"); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentParameterHelpArgumentNameIs("arg1"); verify.currentParameterSpanIs("arg1: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpCallExpression.ts b/tests/cases/fourslash/signatureHelpCallExpression.ts index 50d89aaae4e22..fd9758cfa5459 100644 --- a/tests/cases/fourslash/signatureHelpCallExpression.ts +++ b/tests/cases/fourslash/signatureHelpCallExpression.ts @@ -5,7 +5,7 @@ goTo.marker('1'); verify.signatureHelpCountIs(1); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentSignatureHelpIs('fnTest(str: string, num: number): void'); verify.currentParameterHelpArgumentNameIs('str'); diff --git a/tests/cases/fourslash/signatureHelpConstructExpression.ts b/tests/cases/fourslash/signatureHelpConstructExpression.ts index a88cb3fce6897..00efee0a47969 100644 --- a/tests/cases/fourslash/signatureHelpConstructExpression.ts +++ b/tests/cases/fourslash/signatureHelpConstructExpression.ts @@ -6,7 +6,7 @@ goTo.marker('1'); verify.signatureHelpCountIs(1); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentSignatureHelpIs('sampleCls(str: string, num: number): sampleCls'); verify.currentParameterHelpArgumentNameIs('str'); diff --git a/tests/cases/fourslash/signatureHelpConstructorInheritance.ts b/tests/cases/fourslash/signatureHelpConstructorInheritance.ts index b066eab3fd47a..a2e683d69bbb8 100644 --- a/tests/cases/fourslash/signatureHelpConstructorInheritance.ts +++ b/tests/cases/fourslash/signatureHelpConstructorInheritance.ts @@ -16,7 +16,7 @@ goTo.marker('indirectSuperCall'); verify.signatureHelpCountIs(2); -verify.currentSignatureParamterCountIs(1); +verify.currentSignatureParameterCountIs(1); verify.currentSignatureHelpIs('B2(n: number): B2'); verify.currentParameterHelpArgumentNameIs("n"); verify.currentParameterSpanIs("n: number"); diff --git a/tests/cases/fourslash/signatureHelpConstructorOverload.ts b/tests/cases/fourslash/signatureHelpConstructorOverload.ts index ce276e09d8f42..9aab48f71aef7 100644 --- a/tests/cases/fourslash/signatureHelpConstructorOverload.ts +++ b/tests/cases/fourslash/signatureHelpConstructorOverload.ts @@ -6,11 +6,11 @@ goTo.marker('1'); verify.signatureHelpCountIs(2); -verify.currentSignatureParamterCountIs(0); +verify.currentSignatureParameterCountIs(0); verify.currentSignatureHelpIs('clsOverload(): clsOverload'); goTo.marker('2'); -verify.currentSignatureParamterCountIs(1); +verify.currentSignatureParameterCountIs(1); verify.currentSignatureHelpIs('clsOverload(test: string): clsOverload'); verify.currentParameterHelpArgumentNameIs('test'); verify.currentParameterSpanIs("test: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpEmptyList.ts b/tests/cases/fourslash/signatureHelpEmptyList.ts index 6ea70159dccfa..b6318656f4fc2 100644 --- a/tests/cases/fourslash/signatureHelpEmptyList.ts +++ b/tests/cases/fourslash/signatureHelpEmptyList.ts @@ -12,7 +12,7 @@ verify.signatureHelpPresent(); verify.signatureHelpCountIs(1); verify.currentSignatureHelpIs("Foo(arg1: string, arg2: string): void"); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentParameterHelpArgumentNameIs("arg1"); verify.currentParameterSpanIs("arg1: string"); diff --git a/tests/cases/fourslash/signatureHelpFunctionOverload.ts b/tests/cases/fourslash/signatureHelpFunctionOverload.ts index 2c1cdb51291a5..cc02ba12570d8 100644 --- a/tests/cases/fourslash/signatureHelpFunctionOverload.ts +++ b/tests/cases/fourslash/signatureHelpFunctionOverload.ts @@ -8,11 +8,11 @@ goTo.marker('functionOverload1'); verify.signatureHelpCountIs(2); -verify.currentSignatureParamterCountIs(0); +verify.currentSignatureParameterCountIs(0); verify.currentSignatureHelpIs('functionOverload(): any'); goTo.marker('functionOverload2'); -verify.currentSignatureParamterCountIs(1); +verify.currentSignatureParameterCountIs(1); verify.currentSignatureHelpIs('functionOverload(test: string): any'); verify.currentParameterHelpArgumentNameIs("test"); verify.currentParameterSpanIs("test: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpFunctionParameter.ts b/tests/cases/fourslash/signatureHelpFunctionParameter.ts index cb2264f2c427d..b61e56dedcbaa 100644 --- a/tests/cases/fourslash/signatureHelpFunctionParameter.ts +++ b/tests/cases/fourslash/signatureHelpFunctionParameter.ts @@ -6,7 +6,7 @@ goTo.marker('parameterFunction1'); verify.signatureHelpCountIs(1); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentSignatureHelpIs('callback(a: number, b: string): void'); verify.currentParameterHelpArgumentNameIs("a"); verify.currentParameterSpanIs("a: number"); diff --git a/tests/cases/fourslash/signatureHelpImplicitConstructor.ts b/tests/cases/fourslash/signatureHelpImplicitConstructor.ts index 9e42d25dbe98b..4324767d00aaa 100644 --- a/tests/cases/fourslash/signatureHelpImplicitConstructor.ts +++ b/tests/cases/fourslash/signatureHelpImplicitConstructor.ts @@ -7,4 +7,4 @@ goTo.marker(); verify.signatureHelpCountIs(1); verify.currentSignatureHelpIs("ImplicitConstructor(): ImplicitConstructor"); -verify.currentSignatureParamterCountIs(0); +verify.currentSignatureParameterCountIs(0); diff --git a/tests/cases/fourslash/signatureHelpIncompleteCalls.ts b/tests/cases/fourslash/signatureHelpIncompleteCalls.ts index e73217b1d8c92..ec4fcccc0fe5c 100644 --- a/tests/cases/fourslash/signatureHelpIncompleteCalls.ts +++ b/tests/cases/fourslash/signatureHelpIncompleteCalls.ts @@ -17,13 +17,13 @@ goTo.marker('incompleteCalls1'); verify.currentSignatureHelpIs("f1(): void"); -verify.currentSignatureParamterCountIs(0); +verify.currentSignatureParameterCountIs(0); goTo.marker('incompleteCalls2'); -verify.currentSignatureParamterCountIs(1); +verify.currentSignatureParameterCountIs(1); verify.currentSignatureHelpIs("f2(n: number): number"); goTo.marker('incompleteCalls3'); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentSignatureHelpIs("f3(n: number, s: string): string"); verify.currentParameterHelpArgumentNameIs("s"); diff --git a/tests/cases/fourslash/signatureHelpObjectLiteral.ts b/tests/cases/fourslash/signatureHelpObjectLiteral.ts index cbc5df697b934..6853c3fee366c 100644 --- a/tests/cases/fourslash/signatureHelpObjectLiteral.ts +++ b/tests/cases/fourslash/signatureHelpObjectLiteral.ts @@ -1,17 +1,17 @@ /// ////var objectLiteral = { n: 5, s: "", f: (a: number, b: string) => "" }; -////objectLiteral.f(/*objectLiteral1*/4, /*objectLiteral2*/""); - -goTo.marker('objectLiteral1'); -verify.signatureHelpCountIs(1); -verify.currentSignatureParamterCountIs(2); -verify.currentSignatureHelpIs('f(a: number, b: string): string'); - -verify.currentParameterHelpArgumentNameIs("a"); -verify.currentParameterSpanIs("a: number"); - -goTo.marker('objectLiteral2'); -verify.currentSignatureHelpIs('f(a: number, b: string): string'); +////objectLiteral.f(/*objectLiteral1*/4, /*objectLiteral2*/""); + +goTo.marker('objectLiteral1'); +verify.signatureHelpCountIs(1); +verify.currentSignatureParameterCountIs(2); +verify.currentSignatureHelpIs('f(a: number, b: string): string'); + +verify.currentParameterHelpArgumentNameIs("a"); +verify.currentParameterSpanIs("a: number"); + +goTo.marker('objectLiteral2'); +verify.currentSignatureHelpIs('f(a: number, b: string): string'); verify.currentParameterHelpArgumentNameIs("b"); verify.currentParameterSpanIs("b: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts b/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts index c217a12ef5890..f9754c7d1fde7 100644 --- a/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts +++ b/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts @@ -10,17 +10,17 @@ goTo.marker(); verify.signatureHelpCountIs(4); verify.currentSignatureHelpIs("f(): any"); -verify.currentSignatureParamterCountIs(0); +verify.currentSignatureParameterCountIs(0); verify.signatureHelpArgumentCountIs(0); edit.insert(", "); verify.signatureHelpCountIs(4); verify.currentSignatureHelpIs("f(s: string, b: boolean): any"); -verify.currentSignatureParamterCountIs(2); +verify.currentSignatureParameterCountIs(2); verify.currentParameterHelpArgumentNameIs("b"); verify.currentParameterSpanIs("b: boolean"); edit.insert(", "); verify.signatureHelpCountIs(4); verify.currentSignatureHelpIs("f(s: string, b: boolean): any"); -verify.currentSignatureParamterCountIs(2); \ No newline at end of file +verify.currentSignatureParameterCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpSuperConstructorOverload.ts b/tests/cases/fourslash/signatureHelpSuperConstructorOverload.ts index 1be8c3202a1dc..aa2e3e4856c8d 100644 --- a/tests/cases/fourslash/signatureHelpSuperConstructorOverload.ts +++ b/tests/cases/fourslash/signatureHelpSuperConstructorOverload.ts @@ -20,9 +20,9 @@ goTo.marker('superOverload1'); verify.signatureHelpCountIs(2); verify.currentSignatureHelpIs("SuperOverloadlBase(): SuperOverloadlBase"); -verify.currentSignatureParamterCountIs(0); +verify.currentSignatureParameterCountIs(0); goTo.marker('superOverload2'); -verify.currentSignatureParamterCountIs(1); +verify.currentSignatureParameterCountIs(1); verify.currentSignatureHelpIs("SuperOverloadlBase(test: string): SuperOverloadlBase"); verify.currentParameterHelpArgumentNameIs("test"); verify.currentParameterSpanIs("test: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts new file mode 100644 index 0000000000000..39644ba8c2435 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f `/*1*/ qwe/*2*/rty /*3*/$/*4*/{ 123 }/*5*/ as/*6*/df /*7*/$/*8*/{ 41234 }/*9*/ zxc/*10*/vb /*11*/$/*12*/{ g ` ` }/*13*/ /*14*/ /*15*/` + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(4); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts new file mode 100644 index 0000000000000..123a6cc4c2cc9 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f `/*1*/ qwe/*2*/rty /*3*/$/*4*/{ 123 }/*5*/ as/*6*/df /*7*/$/*8*/{ 41234 }/*9*/ zxc/*10*/vb /*11*/$/*12*/{ g ` ` }/*13*/ /*14*/ /*15*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(4); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts new file mode 100644 index 0000000000000..f203468ca0445 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` qwerty ${/*1*/ /*2*/123/*3*/ /*4*/} asdf ${ 41234 } zxcvb ${ g ` ` } ` + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(4); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("x"); + verify.currentParameterSpanIs("x: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts new file mode 100644 index 0000000000000..13ee47a330934 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` qwerty ${ 123 } asdf ${/*1*/ /*2*/ /*3*/41/*4*/234/*5*/ /*6*/} zxcvb ${ g ` ` } ` + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(4); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("y"); + verify.currentParameterSpanIs("y: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts new file mode 100644 index 0000000000000..7cd2affd6755d --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${/*1*/ /*2*/g/*3*/ /*4*/` `/*5*/ /*6*/} ` + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(4); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("z"); + verify.currentParameterSpanIs("z: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts new file mode 100644 index 0000000000000..7671666bb54cd --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${ g `/*1*/ /*2*/ /*3*/` } ` + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(1); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('g(templateStrings: any, x: any, y: any, z: any): string'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts new file mode 100644 index 0000000000000..35bed336f3958 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f `/*1*/ /*2*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(1); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts new file mode 100644 index 0000000000000..1da96ea5c1b01 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f `/*1*/ /*2*/${ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(2); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts new file mode 100644 index 0000000000000..68ff7202f017a --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` ${/*1*/ /*2*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(2); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("x"); + verify.currentParameterSpanIs("x: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts new file mode 100644 index 0000000000000..8165da7f67b18 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` ${ }/*1*/ /*2*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(2); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts new file mode 100644 index 0000000000000..8c970b60c7754 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` ${ } ${/*1*/ /*2*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("y"); + verify.currentParameterSpanIs("y: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts new file mode 100644 index 0000000000000..f93da36ce5c36 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` ${ } ${ }/*1*/ /*2*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts new file mode 100644 index 0000000000000..10d81eb80f458 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts @@ -0,0 +1,18 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f ` ${ 123 } ${/*1*/ } ` + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); + verify.currentParameterHelpArgumentNameIs("y"); + verify.currentParameterSpanIs("y: any"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts new file mode 100644 index 0000000000000..c61f1a871e49b --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts @@ -0,0 +1,11 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// /*1*/f/*2*/ /*3*/` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${ g ` ` } `/*4*/ + +test.markers().forEach(m => { + goTo.position(m.position); + verify.not.signatureHelpPresent(); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts new file mode 100644 index 0000000000000..a3c9f7ccce4f6 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts @@ -0,0 +1,15 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f `a ${ g `/*1*/alpha/*2*/ ${/*3*/ 12/*4*/3 /*5*/} beta /*6*/${ /*7*/456 /*8*/} gamma/*9*/` } b ${ g `/*10*/txt/*11*/` } c ${ g `/*12*/aleph /*13*/$/*14*/{ 12/*15*/3 } beit/*16*/` } d`; + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('g(templateStrings: any, x: any, y: any, z: any): string'); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts new file mode 100644 index 0000000000000..d72fa74d985c2 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts @@ -0,0 +1,15 @@ +/// + +//// function f(templateStrings, x, y, z) { return 10; } +//// function g(templateStrings, x, y, z) { return ""; } +//// +//// f `/*1*/a $/*2*/{ /*3*/g /*4*/`alpha ${ 123 } beta ${ 456 } gamma`/*5*/ }/*6*/ b $/*7*/{ /*8*/g /*9*/`txt`/*10*/ } /*11*/c ${ /*12*/g /*13*/`aleph ${ 123 } beit`/*14*/ } d/*15*/`; + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(1); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: any, x: any, y: any, z: any): number'); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts new file mode 100644 index 0000000000000..6850b1bc54faa --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `/*1*/ /*2*/$/*3*/{ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(2); + + verify.currentSignatureParameterCountIs(2); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o1: string): number'); + verify.currentParameterHelpArgumentNameIs("templateStrings"); + verify.currentParameterSpanIs("templateStrings: string[]"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts new file mode 100644 index 0000000000000..8466c6b05f246 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${/*1*/ /*2*/ /*3*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(2); + + verify.currentSignatureParameterCountIs(2); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o1: string): number'); + verify.currentParameterHelpArgumentNameIs("p1_o1"); + verify.currentParameterSpanIs("p1_o1: string"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts new file mode 100644 index 0000000000000..3843ed34b16c9 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${/*1*/ "s/*2*/tring" /*3*/ } ${ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean'); + verify.currentParameterHelpArgumentNameIs("p1_o3"); + verify.currentParameterSpanIs("p1_o3: string"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts new file mode 100644 index 0000000000000..a1072366a982f --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${/*1*/ 123.456/*2*/ /*3*/ } ${ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string'); + verify.currentParameterHelpArgumentNameIs("p1_o2"); + verify.currentParameterSpanIs("p1_o2: number"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts new file mode 100644 index 0000000000000..2646e70b39c66 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${ } ${/*1*/ /*2*/ /*3*/ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string'); + verify.currentParameterHelpArgumentNameIs("p2_o2"); + verify.currentParameterSpanIs("p2_o2: number"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts new file mode 100644 index 0000000000000..62410a5fda374 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${ } ${/*1*/ /*2*/ /*3*/} + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string'); + verify.currentParameterHelpArgumentNameIs("p2_o2"); + verify.currentParameterSpanIs("p2_o2: number"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts new file mode 100644 index 0000000000000..9a24aacf86bdf --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${ } ${/*1*/ fa/*2*/lse /*3*/} + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean'); + verify.currentParameterHelpArgumentNameIs("p2_o3"); + verify.currentParameterSpanIs("p2_o3: boolean"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts new file mode 100644 index 0000000000000..8000f15d3c6bb --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${ undefined } ${ undefined } ${/*1*/ 10/*2*/./*3*/01 /*4*/} ` + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(4); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string'); + verify.currentParameterHelpArgumentNameIs("p3_o2"); + verify.currentParameterSpanIs("p3_o2: number"); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts new file mode 100644 index 0000000000000..aee06c1df5367 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts @@ -0,0 +1,20 @@ +/// + +//// function f(templateStrings: string[], p1_o1: string): number; +//// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; +//// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; +//// function f(...foo[]: any) { return ""; } +//// +//// f `${/*1*/ /*2*/ /*3*/} ${ + +test.markers().forEach(m => { + goTo.position(m.position); + + verify.signatureHelpCountIs(3); + verify.signatureHelpArgumentCountIs(3); + + verify.currentSignatureParameterCountIs(4); + verify.currentSignatureHelpIs('f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string'); + verify.currentParameterHelpArgumentNameIs("p1_o2"); + verify.currentParameterSpanIs("p1_o2: number"); +}); \ No newline at end of file