mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #1204 from Microsoft/taggedSigHelp
Tagged Template Signature Help Support in Language Service
This commit is contained in:
+15
-1
@@ -487,6 +487,15 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getInvokedExpression(node: CallLikeExpression): Expression {
|
||||
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
return (<TaggedTemplateExpression>node).tag;
|
||||
}
|
||||
|
||||
// Will either be a CallExpression or NewExpression.
|
||||
return (<CallExpression>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;
|
||||
|
||||
@@ -760,7 +760,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;
|
||||
|
||||
+215
-80
@@ -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 = <CallExpression>argumentInfo.list.parent;
|
||||
var call = argumentInfo.invocation;
|
||||
var candidates = <Signature[]>[];
|
||||
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 = <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<T, U>#(a, b)# -> The token is either not associated with a list, or ends a list, so the session should end
|
||||
// Case 3:
|
||||
// foo<T#, U#>(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)
|
||||
};
|
||||
}
|
||||
|
||||
// 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<T, U>$(a, b)$ -> The token is either not associated with a list, or ends a list, so the session should end
|
||||
// Case 3:
|
||||
// foo<T$, U$>(a$, $b$) -> The token is buried inside a list, and should give sig help
|
||||
var parent = <CallExpression>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
|
||||
};
|
||||
}
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
// 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(<LiteralExpression>node, position)) {
|
||||
return getArgumentListInfoForTemplate(<TaggedTemplateExpression>node.parent, /*argumentIndex*/ 0);
|
||||
}
|
||||
}
|
||||
else if (node.kind === SyntaxKind.TemplateHead && node.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
var templateExpression = <TemplateExpression>node.parent;
|
||||
var tagExpression = <TaggedTemplateExpression>templateExpression.parent;
|
||||
Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression);
|
||||
|
||||
var argumentIndex = isInsideTemplateLiteral(<LiteralExpression>node, position) ? 0 : 1;
|
||||
|
||||
return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
|
||||
}
|
||||
else if (node.parent.kind === SyntaxKind.TemplateSpan && node.parent.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
var templateSpan = <TemplateSpan>node.parent;
|
||||
var templateExpression = <TemplateExpression>templateSpan.parent;
|
||||
var tagExpression = <TaggedTemplateExpression>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(<LiteralExpression>node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
|
||||
var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node);
|
||||
|
||||
return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getContainingArgumentInfo(node: Node): ListItemInfo {
|
||||
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(<LiteralExpression>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
|
||||
: (<TemplateExpression>tagExpression.template).templateSpans.length + 1;
|
||||
|
||||
return {
|
||||
kind: ArgumentListKind.TaggedTemplateArguments,
|
||||
invocation: tagExpression,
|
||||
argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression),
|
||||
argumentIndex: argumentIndex,
|
||||
argumentCount: argumentCount
|
||||
};
|
||||
}
|
||||
|
||||
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,
|
||||
//
|
||||
// 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 = 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((<TemplateExpression>template).templateSpans);
|
||||
if (lastSpan.literal.kind === SyntaxKind.Missing) {
|
||||
applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
return new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
|
||||
}
|
||||
|
||||
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 = <CallExpression>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 = (<CallExpression>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);
|
||||
var argumentIndex = argumentListInfo.argumentIndex;
|
||||
|
||||
// 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);
|
||||
// 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,
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
////testFunction<, ,/*5*/>(null, null, null);
|
||||
|
||||
// goTo.marker("1");
|
||||
// verify.currentSignatureParamterCountIs(3);
|
||||
// verify.currentSignatureParameterCountIs(3);
|
||||
// verify.currentSignatureHelpIs("testFunction<T extends IFoo, U, M extends IFoo>(a: T, b: U, c: M): M");
|
||||
|
||||
// verify.currentParameterHelpArgumentNameIs("T");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
@@ -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");
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
@@ -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");
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
goTo.marker();
|
||||
verify.signatureHelpCountIs(1);
|
||||
verify.currentSignatureHelpIs("ImplicitConstructor(): ImplicitConstructor");
|
||||
verify.currentSignatureParamterCountIs(0);
|
||||
verify.currentSignatureParameterCountIs(0);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////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");
|
||||
@@ -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);
|
||||
verify.currentSignatureParameterCountIs(2);
|
||||
@@ -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");
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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();
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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');
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="./fourslash.ts"/>
|
||||
|
||||
//// 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');
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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[]");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// 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");
|
||||
});
|
||||
Reference in New Issue
Block a user