From 986a0b7343d6211fb51673f06a2ecf1a2f5f507a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 7 Nov 2014 16:23:59 -0800 Subject: [PATCH] Fixed issues with incomplete calls, cleaned some code up. --- src/compiler/checker.ts | 55 +++++++++++-------- src/compiler/parser.ts | 15 ++++- src/compiler/types.ts | 2 + ...completeNoSubstitutionTemplate1.errors.txt | 12 ++++ ...completeNoSubstitutionTemplate2.errors.txt | 12 ++++ ...hIncompleteTemplateExpressions1.errors.txt | 12 ++++ ...hIncompleteTemplateExpressions2.errors.txt | 15 +++++ ...hIncompleteTemplateExpressions3.errors.txt | 15 +++++ ...hIncompleteTemplateExpressions4.errors.txt | 18 ++++++ ...hIncompleteTemplateExpressions5.errors.txt | 15 +++++ ...hIncompleteTemplateExpressions6.errors.txt | 15 +++++ ...esWithIncompleteNoSubstitutionTemplate1.ts | 7 +++ ...esWithIncompleteNoSubstitutionTemplate2.ts | 7 +++ ...latesWithIncompleteTemplateExpressions1.ts | 7 +++ ...latesWithIncompleteTemplateExpressions2.ts | 7 +++ ...latesWithIncompleteTemplateExpressions3.ts | 7 +++ ...latesWithIncompleteTemplateExpressions4.ts | 7 +++ ...latesWithIncompleteTemplateExpressions5.ts | 7 +++ ...latesWithIncompleteTemplateExpressions6.ts | 7 +++ 19 files changed, 218 insertions(+), 24 deletions(-) create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions1.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions2.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions3.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions4.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions5.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions6.errors.txt create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.ts create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.ts create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions1.ts create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions3.ts create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions5.ts create mode 100644 tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bacce85a34f..436200d94bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -56,8 +56,6 @@ module ts { return stringWriters.pop(); } - type CallLikeExpression = CallExpression | TaggedTemplateExpression; - /// fullTypeCheck denotes if this instance of the typechecker will be used to get semantic diagnostics. /// If fullTypeCheck === true, then the typechecker should do every possible check to produce all errors /// If fullTypeCheck === false, the typechecker can take shortcuts and skip checks that only produce errors. @@ -5204,20 +5202,30 @@ module ts { function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature) { var adjustedArgCount: number; var typeArguments: NodeArray; - var callIsIncomplete = false; + var callIsIncomplete: boolean; if (node.kind === SyntaxKind.TaggedTemplateExpression) { var tagExpression = node; + // Even if the call is incomplete, we'll have a missing expression as our last argument, + // so we can say the count is just the arg list length adjustedArgCount = args.length; typeArguments = undefined; - if (tagExpression.kind === SyntaxKind.TemplateExpression) { + if (tagExpression.template.kind === SyntaxKind.TemplateExpression) { // If a tagged template expression lacks a tail literal, the call is incomplete. - var template = tagExpression.template; - var lastSpan = lastOrUndefined(template.templateSpans); + // Specifically, a template only can end in a TemplateTail or a Missing literal. + var templateExpression = tagExpression.template; + var lastSpan = lastOrUndefined(templateExpression.templateSpans); Debug.assert(lastSpan !== undefined); // we should always have at least one span. - callIsIncomplete = lastSpan === undefined || lastSpan.literal.kind !== SyntaxKind.TemplateTail; + callIsIncomplete = lastSpan.literal.kind === SyntaxKind.Missing || isUnterminatedTemplateEnd(lastSpan.literal); + } + else { + // If the template didn't end in a backtick, or its beginning occurred right prior to EOF, + // then this might actually turn out to be a TemplateHead in the future; + // so we consider the call to be incomplete. + var templateLiteral = tagExpression.template; + callIsIncomplete = isUnterminatedTemplateEnd(templateLiteral); } } else { @@ -5228,17 +5236,17 @@ module ts { return signature.minArgumentCount === 0; } - else { - // For IDE scenarios we may have an incomplete call, so a trailing comma is tantamount to adding another argument. - adjustedArgCount = callExpression.arguments.hasTrailingComma ? args.length + 1 : args.length; + + // For IDE scenarios we may have an incomplete call, so a trailing comma is tantamount to adding another argument. + adjustedArgCount = callExpression.arguments.hasTrailingComma ? args.length + 1 : args.length; - // If we are missing the close paren, the call is incomplete. - callIsIncomplete = (callExpression).arguments.end === callExpression.end; - } + // If we are missing the close paren, the call is incomplete. + callIsIncomplete = (callExpression).arguments.end === callExpression.end; typeArguments = callExpression.typeArguments; } + return checkArity(adjustedArgCount, typeArguments, callIsIncomplete, signature); /** @@ -5420,7 +5428,9 @@ module ts { } function resolveCall(node: CallLikeExpression, signatures: Signature[], candidatesOutArray: Signature[]): Signature { - var typeArguments = (node).typeArguments; + var isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; + + var typeArguments = isTaggedTemplate ? undefined : (node).typeArguments; forEach(typeArguments, checkSourceElement); var candidates = candidatesOutArray || []; @@ -5432,7 +5442,6 @@ module ts { } var args = getEffectiveCallArguments(node); - var isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; // The following applies to any value of 'excludeArgument[i]': // - true: the argument at 'i' is susceptible to a one-time permanent contextual typing. @@ -5440,8 +5449,8 @@ module ts { // - false: the argument at 'i' *was* and *has been* permanently contextually typed. // // The idea is that we will perform type argument inference & assignability checking once - // without using the susceptible parameters, and once more for each susceptible parameter, - // contextually typing each as we go along. + // without using the susceptible parameters that are functions, and once more for each of those + // parameters, contextually typing each as we go along. // // For a tagged template, then the first argument be 'undefined' if necessary // because it represents a TemplateStringsArray. @@ -5492,14 +5501,14 @@ module ts { // is just important for choosing the best signature. So in the case where there is only one // signature, the subtype pass is useless. So skipping it is an optimization. if (candidates.length > 1) { - result = chooseOverload(candidates, subtypeRelation, excludeArgument); + result = chooseOverload(candidates, subtypeRelation); } if (!result) { // Reinitialize these pointers for round two candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; resultOfFailedInference = undefined; - result = chooseOverload(candidates, assignableRelation, excludeArgument); + result = chooseOverload(candidates, assignableRelation); } if (result) { return result; @@ -5552,7 +5561,7 @@ module ts { return resolveErrorCall(node); - function chooseOverload(candidates: Signature[], relation: Map, excludeArgument: boolean[]) { + function chooseOverload(candidates: Signature[], relation: Map) { for (var i = 0; i < candidates.length; i++) { if (!hasCorrectArity(node, args, candidates[i])) { continue; @@ -5566,9 +5575,9 @@ module ts { if (candidate.typeParameters) { var typeArgumentTypes: Type[]; var typeArgumentsAreValid: boolean; - if ((node).typeArguments) { + if (typeArguments) { typeArgumentTypes = new Array(candidate.typeParameters.length); - typeArgumentsAreValid = checkTypeArguments(candidate, (node).typeArguments, typeArgumentTypes, /*reportErrors*/ false) + typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false) } else { inferenceResult = inferTypeArguments(candidate, args, excludeArgument); @@ -5602,7 +5611,7 @@ module ts { } else { candidateForTypeArgumentError = originalCandidate; - if (!(node).typeArguments) { + if (!typeArguments) { resultOfFailedInference = inferenceResult; } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5da1952ab27..1a33b69a706 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -564,7 +564,6 @@ module ts { return false; } - export function isDeclaration(node: Node): boolean { switch (node.kind) { case SyntaxKind.TypeParameter: @@ -752,6 +751,20 @@ module ts { return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken; } + export function isUnterminatedTemplateEnd(node: LiteralExpression) { + Debug.assert(node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail); + var sourceText = getSourceFileOfNode(node).text; + + // If we're not at the EOF, we know we must be terminated. + if (node.end !== sourceText.length) { + 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; + } + export function isModifier(token: SyntaxKind): boolean { switch (token) { case SyntaxKind.PublicKeyword: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 421f142c251..586f8249688 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -445,6 +445,8 @@ module ts { template: LiteralExpression | TemplateExpression; } + export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression; + export interface TypeAssertion extends Expression { type: TypeNode; operand: Expression; diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.errors.txt new file mode 100644 index 00000000000..51e362deb5d --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.ts(6,15): error TS1126: Unexpected end of text. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.ts (1 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, not enough parameters. + f `123qdawdrqw + +!!! error TS1126: Unexpected end of text. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.errors.txt new file mode 100644 index 00000000000..1aa00658d80 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.ts(6,4): error TS1126: Unexpected end of text. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.ts (1 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, not enough parameters, at EOF. + f ` + +!!! error TS1126: Unexpected end of text. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions1.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions1.errors.txt new file mode 100644 index 00000000000..56a557e1a8c --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions1.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions1.ts(6,17): error TS1109: Expression expected. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions1.ts (1 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, not enough parameters. + f `123qdawdrqw${ + +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions2.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions2.errors.txt new file mode 100644 index 00000000000..065cc2f4787 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions2.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts(6,18): error TS1109: Expression expected. +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts(6,21): error TS1109: Expression expected. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts (2 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, enough parameters. + f `123qdawdrqw${ }${ + ~ +!!! error TS1109: Expression expected. + +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions3.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions3.errors.txt new file mode 100644 index 00000000000..deb8b166699 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions3.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions3.ts(6,23): error TS1109: Expression expected. +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions3.ts(6,18): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions3.ts (2 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, not enough parameters. + f `123qdawdrqw${ 1 }${ + +!!! error TS1109: Expression expected. + ~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions4.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions4.errors.txt new file mode 100644 index 00000000000..49d55dc2bfd --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions4.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts(6,24): error TS1109: Expression expected. +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts(6,28): error TS1109: Expression expected. +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts(6,1): error TS2346: Supplied parameters do not match any signature of call target. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts (3 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, but too many parameters. + f `123qdawdrqw${ 1 }${ }${ + ~ +!!! error TS1109: Expression expected. + +!!! error TS1109: Expression expected. + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions5.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions5.errors.txt new file mode 100644 index 00000000000..27a6263c391 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions5.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions5.ts(6,30): error TS1109: Expression expected. +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions5.ts(6,1): error TS2346: Supplied parameters do not match any signature of call target. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions5.ts (2 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, but too many parameters. + f `123qdawdrqw${ 1 }${ 2 }${ + +!!! error TS1109: Expression expected. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions6.errors.txt b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions6.errors.txt new file mode 100644 index 00000000000..d8a045b0615 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithIncompleteTemplateExpressions6.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions6.ts(6,23): error TS1109: Expression expected. +tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions6.ts(6,18): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + + +==== tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions6.ts (2 errors) ==== + + function f(x: TemplateStringsArray, y: string, z: string) { + } + + // Incomplete call, not enough parameters, at EOF. + f `123qdawdrqw${ 1 }${ + +!!! error TS1109: Expression expected. + ~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.ts new file mode 100644 index 00000000000..bc28c710eed --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate1.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, not enough parameters. +f `123qdawdrqw \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.ts new file mode 100644 index 00000000000..45e2581ce9c --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteNoSubstitutionTemplate2.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, not enough parameters, at EOF. +f ` \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions1.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions1.ts new file mode 100644 index 00000000000..3fa8bd95d56 --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions1.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, not enough parameters. +f `123qdawdrqw${ \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts new file mode 100644 index 00000000000..7af49303c87 --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, enough parameters. +f `123qdawdrqw${ }${ \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions3.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions3.ts new file mode 100644 index 00000000000..5333686cc2d --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions3.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, not enough parameters. +f `123qdawdrqw${ 1 }${ \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts new file mode 100644 index 00000000000..742c4695303 --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, but too many parameters. +f `123qdawdrqw${ 1 }${ }${ \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions5.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions5.ts new file mode 100644 index 00000000000..ce806d202ed --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions5.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, but too many parameters. +f `123qdawdrqw${ 1 }${ 2 }${ \ No newline at end of file diff --git a/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions6.ts b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions6.ts new file mode 100644 index 00000000000..e73b0d70466 --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions6.ts @@ -0,0 +1,7 @@ +// @target: es6 + +function f(x: TemplateStringsArray, y: string, z: string) { +} + +// Incomplete call, not enough parameters, at EOF. +f `123qdawdrqw${ 1 }${ \ No newline at end of file