From a47e02aeac8c952832ec12f320693499b032a9b2 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Fri, 24 Jul 2015 13:59:20 -0700 Subject: [PATCH] Adjust notion of minArgumentCount to account for required parameters with default initializers --- src/compiler/checker.ts | 23 ++++++++++++++++++++--- src/compiler/utilities.ts | 4 +--- src/services/signatureHelp.ts | 18 +++++++++++++++--- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 217a6103198..ec6c6d2f8e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3517,7 +3517,19 @@ namespace ts { } function isOptionalParameter(node: ParameterDeclaration) { - return hasQuestionToken(node) || !!node.initializer; + if (hasQuestionToken(node)) { + return true; + } + + if (node.initializer) { + let signatureDeclaration = node.parent; + let signature = getSignatureFromDeclaration(signatureDeclaration); + let parameterIndex = signatureDeclaration.parameters.indexOf(node); + Debug.assert(parameterIndex >= 0); + return parameterIndex >= signature.minArgumentCount; + } + + return false; } function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature { @@ -3535,11 +3547,16 @@ namespace ts { if (param.type && param.type.kind === SyntaxKind.StringLiteral) { hasStringLiterals = true; } - if (minArgumentCount < 0) { - if (param.initializer || param.questionToken || param.dotDotDotToken) { + + if (param.initializer || param.questionToken || param.dotDotDotToken) { + if (minArgumentCount < 0) { minArgumentCount = i; } } + else { + // If we see any required parameters, it means the prior ones were not in fact optional. + minArgumentCount = -1; + } } if (minArgumentCount < 0) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 56eb2415cf9..312a3666757 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -988,15 +988,13 @@ namespace ts { if (node) { switch (node.kind) { case SyntaxKind.Parameter: - return (node).questionToken !== undefined; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - return (node).questionToken !== undefined; case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.PropertyAssignment: case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - return (node).questionToken !== undefined; + return (node).questionToken !== undefined; } } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index f44ebade2a7..6230a66910e 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -569,7 +569,15 @@ namespace ts.SignatureHelp { prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); let parameters = candidateSignature.parameters; - signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray; + if (parameters.length > 0) { + signatureHelpParameters = []; + for (let i = 0; i < parameters.length; i++) { + signatureHelpParameters.push(createSignatureHelpParameterAtIndex(candidateSignature, i)); + } + } + else { + signatureHelpParameters = emptyArray; + } suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } @@ -607,11 +615,15 @@ namespace ts.SignatureHelp { argumentCount }; - function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { + function createSignatureHelpParameterAtIndex(signature: Signature, parameterIndex: number): SignatureHelpParameter { + let parameter = signature.parameters[parameterIndex]; let displayParts = mapToDisplayParts(writer => typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); - let isOptional = hasQuestionToken(parameter.valueDeclaration); + let parameterDeclaration = parameter.valueDeclaration; + let isOptional = + hasQuestionToken(parameterDeclaration) || + parameterDeclaration.initializer && parameterIndex >= signature.minArgumentCount; return { name: parameter.name,