diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9014e2f43f91d..c1279ebb1cb02 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1529,6 +1529,63 @@ namespace ts { } } + function useOuterVariableScopeInParameter(result: Symbol, location: Node, lastLocation: Node) { + const target = getEmitScriptTarget(compilerOptions); + const functionLocation = location; + if (isParameter(lastLocation) && functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) { + // check for several cases where we introduce temporaries that require moving the name/initializer of the parameter to the body + // - static field in a class expression + // - optional chaining pre-es2020 + // - nullish coalesce pre-es2020 + // - spread assignment in binding pattern pre-es2017 + if (target >= ScriptTarget.ES2015) { + const links = getNodeLinks(functionLocation); + if (links.declarationRequiresScopeChange === undefined) { + links.declarationRequiresScopeChange = forEach(functionLocation.parameters, requiresScopeChange) || false; + } + return !links.declarationRequiresScopeChange; + } + } + return false; + + function requiresScopeChange(node: ParameterDeclaration): boolean { + return requiresScopeChangeWorker(node.name) + || !!node.initializer && requiresScopeChangeWorker(node.initializer); + } + + function requiresScopeChangeWorker(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.ArrowFunction: + case SyntaxKind.FunctionExpression: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.Constructor: + // do not descend into these + return false; + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.PropertyAssignment: + return requiresScopeChangeWorker((node as MethodDeclaration | AccessorDeclaration | PropertyAssignment).name); + case SyntaxKind.PropertyDeclaration: + // static properties in classes introduce temporary variables + if (hasStaticModifier(node)) { + return target < ScriptTarget.ESNext || !compilerOptions.useDefineForClassFields; + } + return requiresScopeChangeWorker((node as PropertyDeclaration).name); + default: + // null coalesce and optional chain pre-es2020 produce temporary variables + if (isNullishCoalesce(node) || isOptionalChain(node)) { + return target < ScriptTarget.ES2020; + } + if (isBindingElement(node) && node.dotDotDotToken && isObjectBindingPattern(node.parent)) { + return target < ScriptTarget.ES2017; + } + if (isTypeNode(node)) return false; + return forEachChild(node, requiresScopeChangeWorker) || false; + } + } + } + /** * Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with @@ -1563,7 +1620,7 @@ namespace ts { let lastLocation: Node | undefined; let lastSelfReferenceLocation: Node | undefined; let propertyWithInvalidInitializer: Node | undefined; - let associatedDeclarationForContainingInitializer: ParameterDeclaration | BindingElement | undefined; + let associatedDeclarationForContainingInitializerOrBindingName: ParameterDeclaration | BindingElement | undefined; let withinDeferredContext = false; const errorLocation = location; let grandparent: Node; @@ -1592,9 +1649,7 @@ namespace ts { } if (meaning & result.flags & SymbolFlags.Variable) { // expression inside parameter will lookup as normal variable scope when targeting es2015+ - const functionLocation = location; - if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && - functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) { + if (useOuterVariableScopeInParameter(result, location, lastLocation)) { useResult = false; } else if (result.flags & SymbolFlags.FunctionScopedVariable) { @@ -1822,15 +1877,21 @@ namespace ts { location = getJSDocHost(location); break; case SyntaxKind.Parameter: - if (lastLocation && lastLocation === (location as ParameterDeclaration).initializer) { - associatedDeclarationForContainingInitializer = location as ParameterDeclaration; + if (lastLocation && ( + lastLocation === (location as ParameterDeclaration).initializer || + lastLocation === (location as ParameterDeclaration).name && isBindingPattern(lastLocation))) { + if (!associatedDeclarationForContainingInitializerOrBindingName) { + associatedDeclarationForContainingInitializerOrBindingName = location as ParameterDeclaration; + } } break; case SyntaxKind.BindingElement: - if (lastLocation && lastLocation === (location as BindingElement).initializer) { + if (lastLocation && ( + lastLocation === (location as BindingElement).initializer || + lastLocation === (location as BindingElement).name && isBindingPattern(lastLocation))) { const root = getRootDeclaration(location); if (root.kind === SyntaxKind.Parameter) { - associatedDeclarationForContainingInitializer = location as BindingElement; + associatedDeclarationForContainingInitializerOrBindingName = location as BindingElement; } } break; @@ -1941,17 +2002,17 @@ namespace ts { } } - // If we're in a parameter initializer, we can't reference the values of the parameter whose initializer we're within or parameters to the right - if (result && associatedDeclarationForContainingInitializer && !withinDeferredContext && (meaning & SymbolFlags.Value) === SymbolFlags.Value) { + // If we're in a parameter initializer or binding name, we can't reference the values of the parameter whose initializer we're within or parameters to the right + if (result && associatedDeclarationForContainingInitializerOrBindingName && !withinDeferredContext && (meaning & SymbolFlags.Value) === SymbolFlags.Value) { const candidate = getMergedSymbol(getLateBoundSymbol(result)); - const root = (getRootDeclaration(associatedDeclarationForContainingInitializer) as ParameterDeclaration); + const root = (getRootDeclaration(associatedDeclarationForContainingInitializerOrBindingName) as ParameterDeclaration); // A parameter initializer or binding pattern initializer within a parameter cannot refer to itself - if (candidate === getSymbolOfNode(associatedDeclarationForContainingInitializer)) { - error(errorLocation, Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, declarationNameToString(associatedDeclarationForContainingInitializer.name)); + if (candidate === getSymbolOfNode(associatedDeclarationForContainingInitializerOrBindingName)) { + error(errorLocation, Diagnostics.Parameter_0_cannot_reference_itself, declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name)); } // And it cannot refer to any declarations which come after it - else if (candidate.valueDeclaration && candidate.valueDeclaration.pos > associatedDeclarationForContainingInitializer.pos && root.parent.locals && lookup(root.parent.locals, candidate.escapedName, meaning) === candidate) { - error(errorLocation, Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(associatedDeclarationForContainingInitializer.name), declarationNameToString(errorLocation)); + else if (candidate.valueDeclaration && candidate.valueDeclaration.pos > associatedDeclarationForContainingInitializerOrBindingName.pos && root.parent.locals && lookup(root.parent.locals, candidate.escapedName, meaning) === candidate) { + error(errorLocation, Diagnostics.Parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name), declarationNameToString(errorLocation)); } } if (result && errorLocation && meaning & SymbolFlags.Value && result.flags & SymbolFlags.Alias) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4a7c6e8b461f4..8e253075dee13 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1477,11 +1477,11 @@ "category": "Error", "code": 2371 }, - "Parameter '{0}' cannot be referenced in its initializer.": { + "Parameter '{0}' cannot reference itself.": { "category": "Error", "code": 2372 }, - "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it.": { + "Parameter '{0}' cannot reference identifier '{1}' declared after it.": { "category": "Error", "code": 2373 }, diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 2b6e19cd1791f..ed854342245cf 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -4,11 +4,14 @@ namespace ts { enableEmitNotification: noop, enableSubstitution: noop, endLexicalEnvironment: returnUndefined, - getCompilerOptions: notImplemented, + getCompilerOptions: () => ({}), getEmitHost: notImplemented, getEmitResolver: notImplemented, + setLexicalEnvironmentFlags: noop, + getLexicalEnvironmentFlags: () => 0, hoistFunctionDeclaration: noop, hoistVariableDeclaration: noop, + addInitializationStatement: noop, isEmitNotificationEnabled: notImplemented, isSubstitutionEnabled: notImplemented, onEmitNode: noop, @@ -852,13 +855,13 @@ namespace ts { * This function needs to be called whenever we transform the statement * list of a source file, namespace, or function-like body. */ - export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult): number; - export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult): number | undefined; - export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult): number | undefined { + export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number; + export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number | undefined; + export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter: (node: Node) => boolean = returnTrue): number | undefined { const numStatements = source.length; while (statementOffset !== undefined && statementOffset < numStatements) { const statement = source[statementOffset]; - if (getEmitFlags(statement) & EmitFlags.CustomPrologue) { + if (getEmitFlags(statement) & EmitFlags.CustomPrologue && filter(statement)) { append(target, visitor ? visitNode(statement, visitor, isStatement) : statement); } else { diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index a3784a62a8243..bd794d88482fb 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -148,8 +148,12 @@ namespace ts { const enabledSyntaxKindFeatures = new Array(SyntaxKind.Count); let lexicalEnvironmentVariableDeclarations: VariableDeclaration[]; let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[]; + let lexicalEnvironmentStatements: Statement[]; + let lexicalEnvironmentFlags = LexicalEnvironmentFlags.None; let lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = []; let lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = []; + let lexicalEnvironmentStatementsStack: Statement[][] = []; + let lexicalEnvironmentFlagsStack: LexicalEnvironmentFlags[] = []; let lexicalEnvironmentStackOffset = 0; let lexicalEnvironmentSuspended = false; let emitHelpers: EmitHelper[] | undefined; @@ -168,8 +172,11 @@ namespace ts { suspendLexicalEnvironment, resumeLexicalEnvironment, endLexicalEnvironment, + setLexicalEnvironmentFlags, + getLexicalEnvironmentFlags, hoistVariableDeclaration, hoistFunctionDeclaration, + addInitializationStatement, requestEmitHelper, readEmitHelpers, enableSubstitution, @@ -313,6 +320,9 @@ namespace ts { else { lexicalEnvironmentVariableDeclarations.push(decl); } + if (lexicalEnvironmentFlags & LexicalEnvironmentFlags.InParameters) { + lexicalEnvironmentFlags |= LexicalEnvironmentFlags.VariablesHoistedInParameters; + } } /** @@ -321,6 +331,7 @@ namespace ts { function hoistFunctionDeclaration(func: FunctionDeclaration): void { Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + setEmitFlags(func, EmitFlags.CustomPrologue); if (!lexicalEnvironmentFunctionDeclarations) { lexicalEnvironmentFunctionDeclarations = [func]; } @@ -329,6 +340,21 @@ namespace ts { } } + /** + * Adds an initialization statement to the top of the lexical environment. + */ + function addInitializationStatement(node: Statement): void { + Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + setEmitFlags(node, EmitFlags.CustomPrologue); + if (!lexicalEnvironmentStatements) { + lexicalEnvironmentStatements = [node]; + } + else { + lexicalEnvironmentStatements.push(node); + } + } + /** * Starts a new lexical environment. Any existing hoisted variable or function declarations * are pushed onto a stack, and the related storage variables are reset. @@ -344,9 +370,13 @@ namespace ts { // transformation. lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations; lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations; + lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentStatements; + lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFlags; lexicalEnvironmentStackOffset++; lexicalEnvironmentVariableDeclarations = undefined!; lexicalEnvironmentFunctionDeclarations = undefined!; + lexicalEnvironmentStatements = undefined!; + lexicalEnvironmentFlags = LexicalEnvironmentFlags.None; } /** Suspends the current lexical environment, usually after visiting a parameter list. */ @@ -375,7 +405,9 @@ namespace ts { Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended."); let statements: Statement[] | undefined; - if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations) { + if (lexicalEnvironmentVariableDeclarations || + lexicalEnvironmentFunctionDeclarations || + lexicalEnvironmentStatements) { if (lexicalEnvironmentFunctionDeclarations) { statements = [...lexicalEnvironmentFunctionDeclarations]; } @@ -395,19 +427,42 @@ namespace ts { statements.push(statement); } } + + if (lexicalEnvironmentStatements) { + if (!statements) { + statements = [...lexicalEnvironmentStatements]; + } + else { + statements = [...statements, ...lexicalEnvironmentStatements]; + } + } } // Restore the previous lexical environment. lexicalEnvironmentStackOffset--; lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset]; lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset]; + lexicalEnvironmentStatements = lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset]; + lexicalEnvironmentFlags = lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset]; if (lexicalEnvironmentStackOffset === 0) { lexicalEnvironmentVariableDeclarationsStack = []; lexicalEnvironmentFunctionDeclarationsStack = []; + lexicalEnvironmentStatementsStack = []; + lexicalEnvironmentFlagsStack = []; } return statements; } + function setLexicalEnvironmentFlags(flags: LexicalEnvironmentFlags, value: boolean): void { + lexicalEnvironmentFlags = value ? + lexicalEnvironmentFlags | flags : + lexicalEnvironmentFlags & ~flags; + } + + function getLexicalEnvironmentFlags(): LexicalEnvironmentFlags { + return lexicalEnvironmentFlags; + } + function requestEmitHelper(helper: EmitHelper): void { Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization."); Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 692f353b00e57..05b7cda9efc3c 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -606,7 +606,7 @@ namespace ts { createConstructor( /*decorators*/ undefined, /*modifiers*/ undefined, - parameters, + parameters ?? [], body ), constructor || node diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 6bffbe3b299b1..3e2e88d15c2d0 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1853,6 +1853,8 @@ namespace ts { // ensureUseStrict is false because no new prologue-directive should be added. // addStandardPrologue will put already-existing directives at the beginning of the target statement-array statementOffset = addStandardPrologue(prologue, body.statements, /*ensureUseStrict*/ false); + statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor, isHoistedFunction); + statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor, isHoistedVariableStatement); } multiLine = addDefaultValueAssignmentsIfNeeded(statements, node) || multiLine; diff --git a/src/compiler/transformers/es2020.ts b/src/compiler/transformers/es2020.ts index 453b3b405f421..8cf3169752094 100644 --- a/src/compiler/transformers/es2020.ts +++ b/src/compiler/transformers/es2020.ts @@ -1,209 +1,213 @@ /*@internal*/ namespace ts { - export function transformES2020(context: TransformationContext) { - const { - hoistVariableDeclaration, - } = context; - - return chainBundle(transformSourceFile); - - function transformSourceFile(node: SourceFile) { - if (node.isDeclarationFile) { - return node; - } - - return visitEachChild(node, visitor, context); - } - - function visitor(node: Node): VisitResult { - if ((node.transformFlags & TransformFlags.ContainsES2020) === 0) { - return node; - } - switch (node.kind) { - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.CallExpression: - if (node.flags & NodeFlags.OptionalChain) { - const updated = visitOptionalExpression(node as OptionalChain, /*captureThisArg*/ false, /*isDelete*/ false); - Debug.assertNotNode(updated, isSyntheticReference); - return updated; - } - return visitEachChild(node, visitor, context); - case SyntaxKind.BinaryExpression: - if ((node).operatorToken.kind === SyntaxKind.QuestionQuestionToken) { - return transformNullishCoalescingExpression(node); - } - return visitEachChild(node, visitor, context); - case SyntaxKind.DeleteExpression: - return visitDeleteExpression(node as DeleteExpression); - default: - return visitEachChild(node, visitor, context); - } - } - - function flattenChain(chain: OptionalChain) { - Debug.assertNotNode(chain, isNonNullChain); - const links: OptionalChain[] = [chain]; - while (!chain.questionDotToken && !isTaggedTemplateExpression(chain)) { - chain = cast(skipPartiallyEmittedExpressions(chain.expression), isOptionalChain); - Debug.assertNotNode(chain, isNonNullChain); - links.unshift(chain); - } - return { expression: chain.expression, chain: links }; - } - - function visitNonOptionalParenthesizedExpression(node: ParenthesizedExpression, captureThisArg: boolean, isDelete: boolean): Expression { - const expression = visitNonOptionalExpression(node.expression, captureThisArg, isDelete); - if (isSyntheticReference(expression)) { - // `(a.b)` -> { expression `((_a = a).b)`, thisArg: `_a` } - // `(a[b])` -> { expression `((_a = a)[b])`, thisArg: `_a` } - return createSyntheticReferenceExpression(updateParen(node, expression.expression), expression.thisArg); - } - return updateParen(node, expression); - } - - function visitNonOptionalPropertyOrElementAccessExpression(node: AccessExpression, captureThisArg: boolean, isDelete: boolean): Expression { - if (isOptionalChain(node)) { - // If `node` is an optional chain, then it is the outermost chain of an optional expression. - return visitOptionalExpression(node, captureThisArg, isDelete); - } - - let expression: Expression = visitNode(node.expression, visitor, isExpression); - Debug.assertNotNode(expression, isSyntheticReference); - - let thisArg: Expression | undefined; - if (captureThisArg) { - if (shouldCaptureInTempVariable(expression)) { - thisArg = createTempVariable(hoistVariableDeclaration); - expression = createAssignment(thisArg, expression); - } - else { - thisArg = expression; - } - } - - expression = node.kind === SyntaxKind.PropertyAccessExpression - ? updatePropertyAccess(node, expression, visitNode(node.name, visitor, isIdentifier)) - : updateElementAccess(node, expression, visitNode(node.argumentExpression, visitor, isExpression)); - return thisArg ? createSyntheticReferenceExpression(expression, thisArg) : expression; - } - - function visitNonOptionalCallExpression(node: CallExpression, captureThisArg: boolean): Expression { - if (isOptionalChain(node)) { - // If `node` is an optional chain, then it is the outermost chain of an optional expression. - return visitOptionalExpression(node, captureThisArg, /*isDelete*/ false); - } - return visitEachChild(node, visitor, context); - } - - function visitNonOptionalExpression(node: Expression, captureThisArg: boolean, isDelete: boolean): Expression { - switch (node.kind) { - case SyntaxKind.ParenthesizedExpression: return visitNonOptionalParenthesizedExpression(node as ParenthesizedExpression, captureThisArg, isDelete); - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: return visitNonOptionalPropertyOrElementAccessExpression(node as AccessExpression, captureThisArg, isDelete); - case SyntaxKind.CallExpression: return visitNonOptionalCallExpression(node as CallExpression, captureThisArg); - default: return visitNode(node, visitor, isExpression); - } - } - - function visitOptionalExpression(node: OptionalChain, captureThisArg: boolean, isDelete: boolean): Expression { - const { expression, chain } = flattenChain(node); - const left = visitNonOptionalExpression(expression, isCallChain(chain[0]), /*isDelete*/ false); - const leftThisArg = isSyntheticReference(left) ? left.thisArg : undefined; - let leftExpression = isSyntheticReference(left) ? left.expression : left; - let capturedLeft: Expression = leftExpression; - if (shouldCaptureInTempVariable(leftExpression)) { - capturedLeft = createTempVariable(hoistVariableDeclaration); - leftExpression = createAssignment(capturedLeft, leftExpression); - } - let rightExpression = capturedLeft; - let thisArg: Expression | undefined; - for (let i = 0; i < chain.length; i++) { - const segment = chain[i]; - switch (segment.kind) { - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - if (i === chain.length - 1 && captureThisArg) { - if (shouldCaptureInTempVariable(rightExpression)) { - thisArg = createTempVariable(hoistVariableDeclaration); - rightExpression = createAssignment(thisArg, rightExpression); - } - else { - thisArg = rightExpression; - } - } - rightExpression = segment.kind === SyntaxKind.PropertyAccessExpression - ? createPropertyAccess(rightExpression, visitNode(segment.name, visitor, isIdentifier)) - : createElementAccess(rightExpression, visitNode(segment.argumentExpression, visitor, isExpression)); - break; - case SyntaxKind.CallExpression: - if (i === 0 && leftThisArg) { - rightExpression = createFunctionCall( - rightExpression, - leftThisArg.kind === SyntaxKind.SuperKeyword ? createThis() : leftThisArg, - visitNodes(segment.arguments, visitor, isExpression) - ); - } - else { - rightExpression = createCall( - rightExpression, - /*typeArguments*/ undefined, - visitNodes(segment.arguments, visitor, isExpression) - ); - } - break; - } - setOriginalNode(rightExpression, segment); - } - - const target = isDelete - ? createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), createTrue(), createDelete(rightExpression)) - : createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), createVoidZero(), rightExpression); - return thisArg ? createSyntheticReferenceExpression(target, thisArg) : target; - } - - function createNotNullCondition(left: Expression, right: Expression, invert?: boolean) { - return createBinary( - createBinary( - left, - createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), - createNull() - ), - createToken(invert ? SyntaxKind.BarBarToken : SyntaxKind.AmpersandAmpersandToken), - createBinary( - right, - createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), - createVoidZero() - ) - ); - } - - function transformNullishCoalescingExpression(node: BinaryExpression) { - let left = visitNode(node.left, visitor, isExpression); - let right = left; - if (shouldCaptureInTempVariable(left)) { - right = createTempVariable(hoistVariableDeclaration); - left = createAssignment(right, left); - } - return createConditional( - createNotNullCondition(left, right), - right, - visitNode(node.right, visitor, isExpression), - ); - } - - function shouldCaptureInTempVariable(expression: Expression): boolean { - // don't capture identifiers and `this` in a temporary variable - // `super` cannot be captured as it's no real variable - return !isIdentifier(expression) && - expression.kind !== SyntaxKind.ThisKeyword && - expression.kind !== SyntaxKind.SuperKeyword; - } - - function visitDeleteExpression(node: DeleteExpression) { - return isOptionalChain(skipParentheses(node.expression)) - ? setOriginalNode(visitNonOptionalExpression(node.expression, /*captureThisArg*/ false, /*isDelete*/ true), node) - : updateDelete(node, visitNode(node.expression, visitor, isExpression)); - } - } + export function transformES2020(context: TransformationContext) { + const { + hoistVariableDeclaration, + } = context; + + return chainBundle(transformSourceFile); + + function transformSourceFile(node: SourceFile) { + if (node.isDeclarationFile) { + return node; + } + + return visitEachChild(node, visitor, context); + } + + function visitor(node: Node): VisitResult { + if ((node.transformFlags & TransformFlags.ContainsES2020) === 0) { + return node; + } + switch (node.kind) { + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + case SyntaxKind.CallExpression: + if (node.flags & NodeFlags.OptionalChain) { + const updated = visitOptionalExpression(node as OptionalChain, /*captureThisArg*/ false, /*isDelete*/ false); + Debug.assertNotNode(updated, isSyntheticReference); + return updated; + } + return visitEachChild(node, visitor, context); + case SyntaxKind.BinaryExpression: + if ((node).operatorToken.kind === SyntaxKind.QuestionQuestionToken) { + return transformNullishCoalescingExpression(node); + } + return visitEachChild(node, visitor, context); + case SyntaxKind.DeleteExpression: + return visitDeleteExpression(node as DeleteExpression); + default: + return visitEachChild(node, visitor, context); + } + } + + function flattenChain(chain: OptionalChain) { + Debug.assertNotNode(chain, isNonNullChain); + const links: OptionalChain[] = [chain]; + while (!chain.questionDotToken && !isTaggedTemplateExpression(chain)) { + chain = cast(skipPartiallyEmittedExpressions(chain.expression), isOptionalChain); + Debug.assertNotNode(chain, isNonNullChain); + links.unshift(chain); + } + return { expression: chain.expression, chain: links }; + } + + function visitNonOptionalParenthesizedExpression(node: ParenthesizedExpression, captureThisArg: boolean, isDelete: boolean): Expression { + const expression = visitNonOptionalExpression(node.expression, captureThisArg, isDelete); + if (isSyntheticReference(expression)) { + // `(a.b)` -> { expression `((_a = a).b)`, thisArg: `_a` } + // `(a[b])` -> { expression `((_a = a)[b])`, thisArg: `_a` } + return createSyntheticReferenceExpression(updateParen(node, expression.expression), expression.thisArg); + } + return updateParen(node, expression); + } + + function visitNonOptionalPropertyOrElementAccessExpression(node: AccessExpression, captureThisArg: boolean, isDelete: boolean): Expression { + if (isOptionalChain(node)) { + // If `node` is an optional chain, then it is the outermost chain of an optional expression. + return visitOptionalExpression(node, captureThisArg, isDelete); + } + + let expression: Expression = visitNode(node.expression, visitor, isExpression); + Debug.assertNotNode(expression, isSyntheticReference); + + let thisArg: Expression | undefined; + if (captureThisArg) { + if (shouldCaptureInTempVariable(expression)) { + thisArg = createTempVariable(hoistVariableDeclaration); + expression = createAssignment(thisArg, expression); + // if (inParameterInitializer) tempVariableInParameter = true; + } + else { + thisArg = expression; + } + } + + expression = node.kind === SyntaxKind.PropertyAccessExpression + ? updatePropertyAccess(node, expression, visitNode(node.name, visitor, isIdentifier)) + : updateElementAccess(node, expression, visitNode(node.argumentExpression, visitor, isExpression)); + return thisArg ? createSyntheticReferenceExpression(expression, thisArg) : expression; + } + + function visitNonOptionalCallExpression(node: CallExpression, captureThisArg: boolean): Expression { + if (isOptionalChain(node)) { + // If `node` is an optional chain, then it is the outermost chain of an optional expression. + return visitOptionalExpression(node, captureThisArg, /*isDelete*/ false); + } + return visitEachChild(node, visitor, context); + } + + function visitNonOptionalExpression(node: Expression, captureThisArg: boolean, isDelete: boolean): Expression { + switch (node.kind) { + case SyntaxKind.ParenthesizedExpression: return visitNonOptionalParenthesizedExpression(node as ParenthesizedExpression, captureThisArg, isDelete); + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: return visitNonOptionalPropertyOrElementAccessExpression(node as AccessExpression, captureThisArg, isDelete); + case SyntaxKind.CallExpression: return visitNonOptionalCallExpression(node as CallExpression, captureThisArg); + default: return visitNode(node, visitor, isExpression); + } + } + + function visitOptionalExpression(node: OptionalChain, captureThisArg: boolean, isDelete: boolean): Expression { + const { expression, chain } = flattenChain(node); + const left = visitNonOptionalExpression(expression, isCallChain(chain[0]), /*isDelete*/ false); + const leftThisArg = isSyntheticReference(left) ? left.thisArg : undefined; + let leftExpression = isSyntheticReference(left) ? left.expression : left; + let capturedLeft: Expression = leftExpression; + if (shouldCaptureInTempVariable(leftExpression)) { + capturedLeft = createTempVariable(hoistVariableDeclaration); + leftExpression = createAssignment(capturedLeft, leftExpression); + // if (inParameterInitializer) tempVariableInParameter = true; + } + let rightExpression = capturedLeft; + let thisArg: Expression | undefined; + for (let i = 0; i < chain.length; i++) { + const segment = chain[i]; + switch (segment.kind) { + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + if (i === chain.length - 1 && captureThisArg) { + if (shouldCaptureInTempVariable(rightExpression)) { + thisArg = createTempVariable(hoistVariableDeclaration); + rightExpression = createAssignment(thisArg, rightExpression); + // if (inParameterInitializer) tempVariableInParameter = true; + } + else { + thisArg = rightExpression; + } + } + rightExpression = segment.kind === SyntaxKind.PropertyAccessExpression + ? createPropertyAccess(rightExpression, visitNode(segment.name, visitor, isIdentifier)) + : createElementAccess(rightExpression, visitNode(segment.argumentExpression, visitor, isExpression)); + break; + case SyntaxKind.CallExpression: + if (i === 0 && leftThisArg) { + rightExpression = createFunctionCall( + rightExpression, + leftThisArg.kind === SyntaxKind.SuperKeyword ? createThis() : leftThisArg, + visitNodes(segment.arguments, visitor, isExpression) + ); + } + else { + rightExpression = createCall( + rightExpression, + /*typeArguments*/ undefined, + visitNodes(segment.arguments, visitor, isExpression) + ); + } + break; + } + setOriginalNode(rightExpression, segment); + } + + const target = isDelete + ? createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), createTrue(), createDelete(rightExpression)) + : createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), createVoidZero(), rightExpression); + return thisArg ? createSyntheticReferenceExpression(target, thisArg) : target; + } + + function createNotNullCondition(left: Expression, right: Expression, invert?: boolean) { + return createBinary( + createBinary( + left, + createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), + createNull() + ), + createToken(invert ? SyntaxKind.BarBarToken : SyntaxKind.AmpersandAmpersandToken), + createBinary( + right, + createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), + createVoidZero() + ) + ); + } + + function transformNullishCoalescingExpression(node: BinaryExpression) { + let left = visitNode(node.left, visitor, isExpression); + let right = left; + if (shouldCaptureInTempVariable(left)) { + right = createTempVariable(hoistVariableDeclaration); + left = createAssignment(right, left); + // if (inParameterInitializer) tempVariableInParameter = true; + } + return createConditional( + createNotNullCondition(left, right), + right, + visitNode(node.right, visitor, isExpression), + ); + } + + function shouldCaptureInTempVariable(expression: Expression): boolean { + // don't capture identifiers and `this` in a temporary variable + // `super` cannot be captured as it's no real variable + return !isIdentifier(expression) && + expression.kind !== SyntaxKind.ThisKeyword && + expression.kind !== SyntaxKind.SuperKeyword; + } + + function visitDeleteExpression(node: DeleteExpression) { + return isOptionalChain(skipParentheses(node.expression)) + ? setOriginalNode(visitNonOptionalExpression(node.expression, /*captureThisArg*/ false, /*isDelete*/ true), node) + : updateDelete(node, visitNode(node.expression, visitor, isExpression)); + } + } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8e781b23ee762..1b6f6febb6c75 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4323,6 +4323,7 @@ namespace ts { instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) isExhaustive?: boolean; // Is node an exhaustive switch statement skipDirectInference?: true; // Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type + declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. } export const enum TypeFlags { @@ -5994,6 +5995,13 @@ namespace ts { set?: Expression; } + /* @internal */ + export const enum LexicalEnvironmentFlags { + None = 0, + InParameters = 1 << 0, // currently visiting a parameter list + VariablesHoistedInParameters = 1 << 1 // a temp variable was hoisted while visiting a parameter list + } + export interface TransformationContext { /*@internal*/ getEmitResolver(): EmitResolver; /*@internal*/ getEmitHost(): EmitHost; @@ -6004,6 +6012,9 @@ namespace ts { /** Starts a new lexical environment. */ startLexicalEnvironment(): void; + /* @internal */ setLexicalEnvironmentFlags(flags: LexicalEnvironmentFlags, value: boolean): void; + /* @internal */ getLexicalEnvironmentFlags(): LexicalEnvironmentFlags; + /** Suspends the current lexical environment, usually after visiting a parameter list. */ suspendLexicalEnvironment(): void; @@ -6019,6 +6030,10 @@ namespace ts { /** Hoists a variable declaration to the containing scope. */ hoistVariableDeclaration(node: Identifier): void; + /** Adds an initialization statement to the top of the lexical environment. */ + /* @internal */ + addInitializationStatement(node: Statement): void; + /** Records a request for a non-scoped emit helper in the current context. */ requestEmitHelper(helper: EmitHelper): void; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index bab1fe7b02b31..9e1d338d8d7d2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1092,6 +1092,26 @@ namespace ts { && (node).expression.kind === SyntaxKind.StringLiteral; } + export function isCustomPrologue(node: Statement) { + return !!(getEmitFlags(node) & EmitFlags.CustomPrologue); + } + + export function isHoistedFunction(node: Statement) { + return isCustomPrologue(node) + && isFunctionDeclaration(node); + } + + function isHoistedVariable(node: VariableDeclaration) { + return isIdentifier(node.name) + && !node.initializer; + } + + export function isHoistedVariableStatement(node: Statement) { + return isCustomPrologue(node) + && isVariableStatement(node) + && every(node.declarationList.declarations, isHoistedVariable); + } + export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: SourceFile) { return node.kind !== SyntaxKind.JsxText ? getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index a7a331d4bffab..c119eff97dee1 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -520,11 +520,18 @@ namespace ts { return result; } + function findSpanEnd(array: readonly T[], test: (value: T) => boolean, start: number) { + let i = start; + while (i < array.length && test(array[i])) { + i++; + } + return i; + } + /** * Merges generated lexical declarations into a new statement list. */ export function mergeLexicalEnvironment(statements: NodeArray, declarations: readonly Statement[] | undefined): NodeArray; - /** * Appends generated lexical declarations to an array of statements. */ @@ -534,9 +541,91 @@ namespace ts { return statements; } - return isNodeArray(statements) - ? setTextRange(createNodeArray(insertStatementsAfterStandardPrologue(statements.slice(), declarations)), statements) - : insertStatementsAfterStandardPrologue(statements, declarations); + // When we merge new lexical statements into an existing statement list, we merge them in the following manner: + // + // Given: + // + // | Left | Right | + // |------------------------------------|-------------------------------------| + // | [standard prologues (left)] | [standard prologues (right)] | + // | [hoisted functions (left)] | [hoisted functions (right)] | + // | [hoisted variables (left)] | [hoisted variables (right)] | + // | [lexical init statements (left)] | [lexical init statements (right)] | + // | [other statements (left)] | | + // + // The resulting statement list will be: + // + // | Result | + // |-------------------------------------| + // | [standard prologues (right)] | + // | [standard prologues (left)] | + // | [hoisted functions (right)] | + // | [hoisted functions (left)] | + // | [hoisted variables (right)] | + // | [hoisted variables (left)] | + // | [lexical init statements (right)] | + // | [lexical init statements (left)] | + // | [other statements (left)] | + // + // NOTE: It is expected that new lexical init statements must be evaluated before existing lexical init statements, + // as the prior transformation may depend on the evaluation of the lexical init statements to be in the correct state. + + // find standard prologues on left in the following order: standard directives, hoisted functions, hoisted variables, other custom + const leftStandardPrologueEnd = findSpanEnd(statements, isPrologueDirective, 0); + const leftHoistedFunctionsEnd = findSpanEnd(statements, isHoistedFunction, leftStandardPrologueEnd); + const leftHoistedVariablesEnd = findSpanEnd(statements, isHoistedVariableStatement, leftHoistedFunctionsEnd); + + // find standard prologues on right in the following order: standard directives, hoisted functions, hoisted variables, other custom + const rightStandardPrologueEnd = findSpanEnd(declarations, isPrologueDirective, 0); + const rightHoistedFunctionsEnd = findSpanEnd(declarations, isHoistedFunction, rightStandardPrologueEnd); + const rightHoistedVariablesEnd = findSpanEnd(declarations, isHoistedVariableStatement, rightHoistedFunctionsEnd); + const rightCustomPrologueEnd = findSpanEnd(declarations, isCustomPrologue, rightHoistedVariablesEnd); + Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues"); + + // splice prologues from the right into the left. We do this in reverse order + // so that we don't need to recompute the index on the left when we insert items. + const left = isNodeArray(statements) ? statements.slice() : statements; + + // splice other custom prologues from right into left + if (rightCustomPrologueEnd > rightHoistedVariablesEnd) { + left.splice(leftHoistedVariablesEnd, 0, ...declarations.slice(rightHoistedVariablesEnd, rightCustomPrologueEnd)); + } + + // splice hoisted variables from right into left + if (rightHoistedVariablesEnd > rightHoistedFunctionsEnd) { + left.splice(leftHoistedFunctionsEnd, 0, ...declarations.slice(rightHoistedFunctionsEnd, rightHoistedVariablesEnd)); + } + + // splice hoisted functions from right into left + if (rightHoistedFunctionsEnd > rightStandardPrologueEnd) { + left.splice(leftStandardPrologueEnd, 0, ...declarations.slice(rightStandardPrologueEnd, rightHoistedFunctionsEnd)); + } + + // splice standard prologues from right into left (that are not already in left) + if (rightStandardPrologueEnd > 0) { + if (leftStandardPrologueEnd === 0) { + left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd)); + } + else { + const leftPrologues = createMap(); + for (let i = 0; i < leftStandardPrologueEnd; i++) { + const leftPrologue = statements[i] as PrologueDirective; + leftPrologues.set(leftPrologue.expression.text, true); + } + for (let i = rightStandardPrologueEnd - 1; i >= 0; i--) { + const rightPrologue = declarations[i] as PrologueDirective; + if (!leftPrologues.has(rightPrologue.expression.text)) { + left.unshift(rightPrologue); + } + } + } + } + + if (isNodeArray(statements)) { + return setTextRange(createNodeArray(left, statements.hasTrailingComma), statements); + } + + return statements; } /** diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index fa611bc9bde3e..b21af6186db2f 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -149,13 +149,124 @@ namespace ts { * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ + export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray): NodeArray; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray | undefined): NodeArray | undefined; export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { + let updated: NodeArray | undefined; context.startLexicalEnvironment(); - const updated = nodesVisitor(nodes, visitor, isParameterDeclaration); + if (nodes) { + context.setLexicalEnvironmentFlags(LexicalEnvironmentFlags.InParameters, true); + updated = nodesVisitor(nodes, visitor, isParameterDeclaration); + + // As of ES2015, any runtime execution of that occurs in for a parameter (such as evaluating an + // initializer or a binding pattern), occurs in its own lexical scope. As a result, any expression + // that we might transform that introduces a temporary variable would fail as the temporary variable + // exists in a different lexical scope. To address this, we move any binding patterns and initializers + // in a parameter list to the body if we detect a variable being hoisted while visiting a parameter list + // when the emit target is greater than ES2015. + if (context.getLexicalEnvironmentFlags() & LexicalEnvironmentFlags.VariablesHoistedInParameters && + getEmitScriptTarget(context.getCompilerOptions()) >= ScriptTarget.ES2015) { + updated = addDefaultValueAssignmentsIfNeeded(updated, context); + } + context.setLexicalEnvironmentFlags(LexicalEnvironmentFlags.InParameters, false); + } context.suspendLexicalEnvironment(); return updated; } + function addDefaultValueAssignmentsIfNeeded(parameters: NodeArray, context: TransformationContext) { + let result: ParameterDeclaration[] | undefined; + for (let i = 0; i < parameters.length; i++) { + const parameter = parameters[i]; + const updated = addDefaultValueAssignmentIfNeeded(parameter, context); + if (result || updated !== parameter) { + if (!result) result = parameters.slice(0, i); + result[i] = updated; + } + } + if (result) { + return setTextRange(createNodeArray(result, parameters.hasTrailingComma), parameters); + } + return parameters; + } + + function addDefaultValueAssignmentIfNeeded(parameter: ParameterDeclaration, context: TransformationContext) { + // A rest parameter cannot have a binding pattern or an initializer, + // so let's just ignore it. + return parameter.dotDotDotToken ? parameter : + isBindingPattern(parameter.name) ? addDefaultValueAssignmentForBindingPattern(parameter, context) : + parameter.initializer ? addDefaultValueAssignmentForInitializer(parameter, parameter.name, parameter.initializer, context) : + parameter; + } + + function addDefaultValueAssignmentForBindingPattern(parameter: ParameterDeclaration, context: TransformationContext) { + context.addInitializationStatement( + createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList([ + createVariableDeclaration( + parameter.name, + parameter.type, + parameter.initializer ? + createConditional( + createStrictEquality( + getGeneratedNameForNode(parameter), + createVoidZero() + ), + parameter.initializer, + getGeneratedNameForNode(parameter) + ) : + getGeneratedNameForNode(parameter) + ), + ]) + ) + ); + return updateParameter(parameter, + parameter.decorators, + parameter.modifiers, + parameter.dotDotDotToken, + getGeneratedNameForNode(parameter), + parameter.questionToken, + parameter.type, + /*initializer*/ undefined); + } + + function addDefaultValueAssignmentForInitializer(parameter: ParameterDeclaration, name: Identifier, initializer: Expression, context: TransformationContext) { + context.addInitializationStatement( + createIf( + createTypeCheck(getSynthesizedClone(name), "undefined"), + setEmitFlags( + setTextRange( + createBlock([ + createExpressionStatement( + setEmitFlags( + setTextRange( + createAssignment( + setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap), + setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer) | EmitFlags.NoComments) + ), + parameter + ), + EmitFlags.NoComments + ) + ) + ]), + parameter + ), + EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments + ) + ) + ); + return updateParameter(parameter, + parameter.decorators, + parameter.modifiers, + parameter.dotDotDotToken, + parameter.name, + parameter.questionToken, + parameter.type, + /*initializer*/ undefined); + } + /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/FunctionDeclaration3_es6.errors.txt b/tests/baselines/reference/FunctionDeclaration3_es6.errors.txt index 409baef3a500e..cdc50037d65a4 100644 --- a/tests/baselines/reference/FunctionDeclaration3_es6.errors.txt +++ b/tests/baselines/reference/FunctionDeclaration3_es6.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration3_es6.ts(1,20): error TS2372: Parameter 'yield' cannot be referenced in its initializer. +tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration3_es6.ts(1,20): error TS2372: Parameter 'yield' cannot reference itself. ==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration3_es6.ts (1 errors) ==== function f(yield = yield) { ~~~~~ -!!! error TS2372: Parameter 'yield' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'yield' cannot reference itself. } \ No newline at end of file diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index db6b0bc49058e..e45bd38e2de1a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4460,7 +4460,8 @@ declare namespace ts { * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes): NodeArray; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray | undefined): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3ec2b8046b96d..62e8560ae488d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4460,7 +4460,8 @@ declare namespace ts { * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes): NodeArray; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray | undefined): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt index 1c1fd7117606e..64b47bc6cd535 100644 --- a/tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt +++ b/tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts(1,20): error TS2372: Parameter 'await' cannot reference itself. ==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts (1 errors) ==== function f(await = await) { ~~~~~ -!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'await' cannot reference itself. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction3_es5.errors.txt b/tests/baselines/reference/asyncArrowFunction3_es5.errors.txt index 01c74ab362028..8540c90055960 100644 --- a/tests/baselines/reference/asyncArrowFunction3_es5.errors.txt +++ b/tests/baselines/reference/asyncArrowFunction3_es5.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction3_es5.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. +tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction3_es5.ts(1,20): error TS2372: Parameter 'await' cannot reference itself. ==== tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction3_es5.ts (1 errors) ==== function f(await = await) { ~~~~~ -!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'await' cannot reference itself. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction3_es6.errors.txt b/tests/baselines/reference/asyncArrowFunction3_es6.errors.txt index d0f56df51dab3..cfa4edcca4a71 100644 --- a/tests/baselines/reference/asyncArrowFunction3_es6.errors.txt +++ b/tests/baselines/reference/asyncArrowFunction3_es6.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction3_es6.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. +tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction3_es6.ts(1,20): error TS2372: Parameter 'await' cannot reference itself. ==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction3_es6.ts (1 errors) ==== function f(await = await) { ~~~~~ -!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'await' cannot reference itself. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt index 53a8507483435..599d481f3195b 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts(1,20): error TS2372: Parameter 'await' cannot reference itself. ==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts (1 errors) ==== function f(await = await) { ~~~~~ -!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'await' cannot reference itself. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration3_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration3_es5.errors.txt index 1192e396a6496..c5b84f0602d26 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration3_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration3_es5.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration3_es5.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. +tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration3_es5.ts(1,20): error TS2372: Parameter 'await' cannot reference itself. ==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration3_es5.ts (1 errors) ==== function f(await = await) { ~~~~~ -!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'await' cannot reference itself. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration3_es6.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration3_es6.errors.txt index a480bf3d2b8be..76ccd1269c693 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration3_es6.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration3_es6.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration3_es6.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration3_es6.ts(1,20): error TS2372: Parameter 'await' cannot reference itself. ==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration3_es6.ts (1 errors) ==== function f(await = await) { ~~~~~ -!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'await' cannot reference itself. } \ No newline at end of file diff --git a/tests/baselines/reference/capturedParametersInInitializers1.errors.txt b/tests/baselines/reference/capturedParametersInInitializers1.errors.txt index fce7c6ee488d9..bbd19e7f64de1 100644 --- a/tests/baselines/reference/capturedParametersInInitializers1.errors.txt +++ b/tests/baselines/reference/capturedParametersInInitializers1.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/capturedParametersInInitializers1.ts(18,20): error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. -tests/cases/compiler/capturedParametersInInitializers1.ts(22,26): error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. -tests/cases/compiler/capturedParametersInInitializers1.ts(38,21): error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. +tests/cases/compiler/capturedParametersInInitializers1.ts(18,20): error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. +tests/cases/compiler/capturedParametersInInitializers1.ts(22,26): error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. +tests/cases/compiler/capturedParametersInInitializers1.ts(38,21): error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. ==== tests/cases/compiler/capturedParametersInInitializers1.ts (3 errors) ==== @@ -23,13 +23,13 @@ tests/cases/compiler/capturedParametersInInitializers1.ts(38,21): error TS2373: // error - used before declaration function foo4(y = {z}, z = 1) { ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. } // error - used before declaration, IIFEs are inlined function foo5(y = (() => z)(), z = 1) { ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. } // ok - IIFE inside another function @@ -47,6 +47,6 @@ tests/cases/compiler/capturedParametersInInitializers1.ts(38,21): error TS2373: // error - used as computed name of method function foo9(y = {[z]() { return z; }}, z = 1) { ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. } \ No newline at end of file diff --git a/tests/baselines/reference/capturedParametersInInitializers2.errors.txt b/tests/baselines/reference/capturedParametersInInitializers2.errors.txt index df6c71f544b1b..4647aea937c94 100644 --- a/tests/baselines/reference/capturedParametersInInitializers2.errors.txt +++ b/tests/baselines/reference/capturedParametersInInitializers2.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/capturedParametersInInitializers2.ts(3,20): error TS2373: Initializer of parameter 'y' cannot reference identifier 'x' declared after it. -tests/cases/compiler/capturedParametersInInitializers2.ts(4,14): error TS2373: Initializer of parameter 'y' cannot reference identifier 'x' declared after it. -tests/cases/compiler/capturedParametersInInitializers2.ts(6,10): error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. +tests/cases/compiler/capturedParametersInInitializers2.ts(3,20): error TS2373: Parameter 'y' cannot reference identifier 'x' declared after it. +tests/cases/compiler/capturedParametersInInitializers2.ts(4,14): error TS2373: Parameter 'y' cannot reference identifier 'x' declared after it. +tests/cases/compiler/capturedParametersInInitializers2.ts(6,10): error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. tests/cases/compiler/capturedParametersInInitializers2.ts(13,26): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. -tests/cases/compiler/capturedParametersInInitializers2.ts(13,27): error TS2373: Initializer of parameter 'y' cannot reference identifier 'x' declared after it. +tests/cases/compiler/capturedParametersInInitializers2.ts(13,27): error TS2373: Parameter 'y' cannot reference identifier 'x' declared after it. ==== tests/cases/compiler/capturedParametersInInitializers2.ts (5 errors) ==== @@ -10,14 +10,14 @@ tests/cases/compiler/capturedParametersInInitializers2.ts(13,27): error TS2373: y = class { static c = x; ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'x' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'x' declared after it. get [x]() {return x;} ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'x' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'x' declared after it. constructor() { x; } [z]() { return z; } ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'z' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'z' declared after it. }, x = 1, z = 2 @@ -28,5 +28,5 @@ tests/cases/compiler/capturedParametersInInitializers2.ts(13,27): error TS2373: ~~~ !!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'x' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'x' declared after it. } \ No newline at end of file diff --git a/tests/baselines/reference/capturedParametersInInitializers2.js b/tests/baselines/reference/capturedParametersInInitializers2.js index 53d5da5d44532..da1f63b58e622 100644 --- a/tests/baselines/reference/capturedParametersInInitializers2.js +++ b/tests/baselines/reference/capturedParametersInInitializers2.js @@ -16,6 +16,7 @@ function foo2(y = class {[x] = x}, x = 1) { //// [capturedParametersInInitializers2.js] function foo(y, x, z) { + var _a; if (y === void 0) { y = (_a = /** @class */ (function () { function class_1() { x; @@ -32,10 +33,10 @@ function foo(y, x, z) { _a); } if (x === void 0) { x = 1; } if (z === void 0) { z = 2; } - var _a; y.c; } function foo2(y, x) { + var _a, _b; if (y === void 0) { y = (_b = /** @class */ (function () { function class_2() { this[_a] = x; @@ -45,5 +46,4 @@ function foo2(y, x) { _a = x, _b); } if (x === void 0) { x = 1; } - var _a, _b; } diff --git a/tests/baselines/reference/circularOptionalityRemoval.errors.txt b/tests/baselines/reference/circularOptionalityRemoval.errors.txt index 2b60b5b66213a..b1c55b70f04ce 100644 --- a/tests/baselines/reference/circularOptionalityRemoval.errors.txt +++ b/tests/baselines/reference/circularOptionalityRemoval.errors.txt @@ -1,11 +1,11 @@ tests/cases/compiler/circularOptionalityRemoval.ts(2,14): error TS2502: 'x' is referenced directly or indirectly in its own type annotation. -tests/cases/compiler/circularOptionalityRemoval.ts(2,38): error TS2372: Parameter 'x' cannot be referenced in its initializer. +tests/cases/compiler/circularOptionalityRemoval.ts(2,38): error TS2372: Parameter 'x' cannot reference itself. tests/cases/compiler/circularOptionalityRemoval.ts(2,38): error TS2532: Object is possibly 'undefined'. -tests/cases/compiler/circularOptionalityRemoval.ts(2,46): error TS2372: Parameter 'x' cannot be referenced in its initializer. +tests/cases/compiler/circularOptionalityRemoval.ts(2,46): error TS2372: Parameter 'x' cannot reference itself. tests/cases/compiler/circularOptionalityRemoval.ts(5,14): error TS1015: Parameter cannot have question mark and initializer. tests/cases/compiler/circularOptionalityRemoval.ts(5,14): error TS2502: 'x' is referenced directly or indirectly in its own type annotation. tests/cases/compiler/circularOptionalityRemoval.ts(5,27): error TS2304: Cannot find name 'someCondition'. -tests/cases/compiler/circularOptionalityRemoval.ts(5,54): error TS2372: Parameter 'x' cannot be referenced in its initializer. +tests/cases/compiler/circularOptionalityRemoval.ts(5,54): error TS2372: Parameter 'x' cannot reference itself. ==== tests/cases/compiler/circularOptionalityRemoval.ts (8 errors) ==== @@ -14,11 +14,11 @@ tests/cases/compiler/circularOptionalityRemoval.ts(5,54): error TS2372: Paramete ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2502: 'x' is referenced directly or indirectly in its own type annotation. ~ -!!! error TS2372: Parameter 'x' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'x' cannot reference itself. ~ !!! error TS2532: Object is possibly 'undefined'. ~ -!!! error TS2372: Parameter 'x' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'x' cannot reference itself. // Report from user function fn2(x?: string = someCondition ? 'value1' : x) { } @@ -29,4 +29,4 @@ tests/cases/compiler/circularOptionalityRemoval.ts(5,54): error TS2372: Paramete ~~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'someCondition'. ~ -!!! error TS2372: Parameter 'x' cannot be referenced in its initializer. \ No newline at end of file +!!! error TS2372: Parameter 'x' cannot reference itself. \ No newline at end of file diff --git a/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=es2015).js b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=es2015).js new file mode 100644 index 0000000000000..707f001650af7 --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=es2015).js @@ -0,0 +1,10 @@ +//// [classWithStaticFieldInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +(({ [class { static x = 1 }.x]: b = "" }) => {})(); + +//// [classWithStaticFieldInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +((_a) => { var _b; var { [(_b = class { + }, + _b.x = 1, + _b).x]: b = "" } = _a; })(); diff --git a/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=es5).js b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=es5).js new file mode 100644 index 0000000000000..32ac07f7cd174 --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=es5).js @@ -0,0 +1,16 @@ +//// [classWithStaticFieldInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +(({ [class { static x = 1 }.x]: b = "" }) => {})(); + +//// [classWithStaticFieldInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +(function (_a) { + var _b; + var _c = (_b = /** @class */ (function () { + function class_1() { + } + return class_1; + }()), + _b.x = 1, + _b).x, _d = _a[_c], b = _d === void 0 ? "" : _d; +})(); diff --git a/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=esnext).js b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=esnext).js new file mode 100644 index 0000000000000..707f001650af7 --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern(target=esnext).js @@ -0,0 +1,10 @@ +//// [classWithStaticFieldInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +(({ [class { static x = 1 }.x]: b = "" }) => {})(); + +//// [classWithStaticFieldInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +((_a) => { var _b; var { [(_b = class { + }, + _b.x = 1, + _b).x]: b = "" } = _a; })(); diff --git a/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=es2015).errors.txt b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=es2015).errors.txt new file mode 100644 index 0000000000000..b2ca477fe31aa --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=es2015).errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts(3,20): error TS2373: Parameter '{ [class extends C { static x = 1 }.x]: b = "" }' cannot reference identifier 'C' declared after it. +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts(6,57): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + class C {} + (({ [class extends C { static x = 1 }.x]: b = "" }) => { var C; })(); + ~ +!!! error TS2373: Parameter '{ [class extends C { static x = 1 }.x]: b = "" }' cannot reference identifier 'C' declared after it. + + const x = ""; + (({ [class extends C { static x = 1 }.x]: b = "" }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + \ No newline at end of file diff --git a/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=es5).errors.txt b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=es5).errors.txt new file mode 100644 index 0000000000000..b2ca477fe31aa --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=es5).errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts(3,20): error TS2373: Parameter '{ [class extends C { static x = 1 }.x]: b = "" }' cannot reference identifier 'C' declared after it. +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts(6,57): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + class C {} + (({ [class extends C { static x = 1 }.x]: b = "" }) => { var C; })(); + ~ +!!! error TS2373: Parameter '{ [class extends C { static x = 1 }.x]: b = "" }' cannot reference identifier 'C' declared after it. + + const x = ""; + (({ [class extends C { static x = 1 }.x]: b = "" }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + \ No newline at end of file diff --git a/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=esnext).errors.txt b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=esnext).errors.txt new file mode 100644 index 0000000000000..b2ca477fe31aa --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterBindingPattern.2(target=esnext).errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts(3,20): error TS2373: Parameter '{ [class extends C { static x = 1 }.x]: b = "" }' cannot reference identifier 'C' declared after it. +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts(6,57): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + class C {} + (({ [class extends C { static x = 1 }.x]: b = "" }) => { var C; })(); + ~ +!!! error TS2373: Parameter '{ [class extends C { static x = 1 }.x]: b = "" }' cannot reference identifier 'C' declared after it. + + const x = ""; + (({ [class extends C { static x = 1 }.x]: b = "" }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + \ No newline at end of file diff --git a/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=es2015).js b/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=es2015).js new file mode 100644 index 0000000000000..fd89bcefa8bb3 --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=es2015).js @@ -0,0 +1,10 @@ +//// [classWithStaticFieldInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +((b = class { static x = 1 }) => {})(); + +//// [classWithStaticFieldInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +((b) => { var _a; if (b === void 0) { b = (_a = class { + }, + _a.x = 1, + _a); } })(); diff --git a/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=es5).js b/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=es5).js new file mode 100644 index 0000000000000..30142396a8e64 --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=es5).js @@ -0,0 +1,16 @@ +//// [classWithStaticFieldInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +((b = class { static x = 1 }) => {})(); + +//// [classWithStaticFieldInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +(function (b) { + var _a; + if (b === void 0) { b = (_a = /** @class */ (function () { + function class_1() { + } + return class_1; + }()), + _a.x = 1, + _a); } +})(); diff --git a/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=esnext).js b/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=esnext).js new file mode 100644 index 0000000000000..fd89bcefa8bb3 --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterInitializer(target=esnext).js @@ -0,0 +1,10 @@ +//// [classWithStaticFieldInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +((b = class { static x = 1 }) => {})(); + +//// [classWithStaticFieldInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +((b) => { var _a; if (b === void 0) { b = (_a = class { + }, + _a.x = 1, + _a); } })(); diff --git a/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=es2015).errors.txt b/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=es2015).errors.txt new file mode 100644 index 0000000000000..56fefb8b502ae --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=es2015).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts(3,21): error TS2373: Parameter 'b' cannot reference identifier 'C' declared after it. +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts(6,45): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + class C {} + ((b = class extends C { static x = 1 }) => { var C; })(); + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'C' declared after it. + + const x = ""; + ((b = class extends C { static x = 1 }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=es5).errors.txt b/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=es5).errors.txt new file mode 100644 index 0000000000000..56fefb8b502ae --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=es5).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts(3,21): error TS2373: Parameter 'b' cannot reference identifier 'C' declared after it. +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts(6,45): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + class C {} + ((b = class extends C { static x = 1 }) => { var C; })(); + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'C' declared after it. + + const x = ""; + ((b = class extends C { static x = 1 }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=esnext).errors.txt b/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=esnext).errors.txt new file mode 100644 index 0000000000000..56fefb8b502ae --- /dev/null +++ b/tests/baselines/reference/classWithStaticFieldInParameterInitializer.2(target=esnext).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts(3,21): error TS2373: Parameter 'b' cannot reference identifier 'C' declared after it. +tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts(6,45): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + class C {} + ((b = class extends C { static x = 1 }) => { var C; })(); + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'C' declared after it. + + const x = ""; + ((b = class extends C { static x = 1 }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.errors.txt index eff1e1a65938b..af2d5b6fbd673 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts(2,22): error TS2448: Block-scoped variable 'e' used before its declaration. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts(3,22): error TS2448: Block-scoped variable 'i' used before its declaration. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts(7,27): error TS2372: Parameter 'e' cannot be referenced in its initializer. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts(9,27): error TS2373: Initializer of parameter 'h' cannot reference identifier 'i' declared after it. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts(7,27): error TS2372: Parameter 'e' cannot reference itself. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts(9,27): error TS2373: Parameter 'h' cannot reference identifier 'i' declared after it. ==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts (4 errors) ==== @@ -19,10 +19,10 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss })([1]); (function ([c, d = c, e = e]) { // error for e = e ~ -!!! error TS2372: Parameter 'e' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'e' cannot reference itself. })([1]); (function ([f, g = f, h = i, i = f]) { // error for h = i ~ -!!! error TS2373: Initializer of parameter 'h' cannot reference identifier 'i' declared after it. +!!! error TS2373: Parameter 'h' cannot reference identifier 'i' declared after it. })([1]) \ No newline at end of file diff --git a/tests/baselines/reference/functionImplementationErrors.errors.txt b/tests/baselines/reference/functionImplementationErrors.errors.txt index 5ed54e044d288..5a9ebea09be94 100644 --- a/tests/baselines/reference/functionImplementationErrors.errors.txt +++ b/tests/baselines/reference/functionImplementationErrors.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/functions/functionImplementationErrors.ts(25,16): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. -tests/cases/conformance/functions/functionImplementationErrors.ts(30,17): error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. -tests/cases/conformance/functions/functionImplementationErrors.ts(35,17): error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. +tests/cases/conformance/functions/functionImplementationErrors.ts(30,17): error TS2373: Parameter 'n' cannot reference identifier 'm' declared after it. +tests/cases/conformance/functions/functionImplementationErrors.ts(35,17): error TS2373: Parameter 'n' cannot reference identifier 'm' declared after it. ==== tests/cases/conformance/functions/functionImplementationErrors.ts (3 errors) ==== @@ -37,14 +37,14 @@ tests/cases/conformance/functions/functionImplementationErrors.ts(35,17): error // Function signature with parameter initializer referencing in scope local variable function f6(n = m) { ~ -!!! error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. +!!! error TS2373: Parameter 'n' cannot reference identifier 'm' declared after it. var m = 4; } // Function signature with initializer referencing other parameter to the right function f7(n = m, m?) { ~ -!!! error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. +!!! error TS2373: Parameter 'n' cannot reference identifier 'm' declared after it. } // FunctionExpression with non -void return type annotation with a throw, no return, and other code diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=es2015).js b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=es2015).js new file mode 100644 index 0000000000000..c7736309aba65 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=es2015).js @@ -0,0 +1,9 @@ +//// [nullishCoalescingOperatorInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +(({ [a() ?? "d"]: c = "" }) => {})(); + +//// [nullishCoalescingOperatorInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +((_a) => { var _b; var { [(_b = a()) !== null && _b !== void 0 ? _b : "d"]: c = "" } = _a; })(); diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=es5).js b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=es5).js new file mode 100644 index 0000000000000..ea103f59da687 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=es5).js @@ -0,0 +1,12 @@ +//// [nullishCoalescingOperatorInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +(({ [a() ?? "d"]: c = "" }) => {})(); + +//// [nullishCoalescingOperatorInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +var a = function () { return undefined; }; +(function (_a) { + var _b; + var _c = (_b = a()) !== null && _b !== void 0 ? _b : "d", _d = _a[_c], c = _d === void 0 ? "" : _d; +})(); diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=esnext).js b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=esnext).js new file mode 100644 index 0000000000000..07a1b1e9e735f --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern(target=esnext).js @@ -0,0 +1,9 @@ +//// [nullishCoalescingOperatorInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +(({ [a() ?? "d"]: c = "" }) => {})(); + +//// [nullishCoalescingOperatorInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +(({ [a() ?? "d"]: c = "" }) => { })(); diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern.2(target=es2015).errors.txt b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern.2(target=es2015).errors.txt new file mode 100644 index 0000000000000..6319b92a19ff1 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern.2(target=es2015).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts(3,6): error TS2373: Parameter '{ [a() ?? "d"]: c = "" }' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts(6,31): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): string | undefined => undefined; + (({ [a() ?? "d"]: c = "" }) => { var a; })(); + ~ +!!! error TS2373: Parameter '{ [a() ?? "d"]: c = "" }' cannot reference identifier 'a' declared after it. + + const x = ""; + (({ [a() ?? "d"]: c = "", d = x }) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern.2(target=es5).errors.txt b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern.2(target=es5).errors.txt new file mode 100644 index 0000000000000..6319b92a19ff1 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterBindingPattern.2(target=es5).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts(3,6): error TS2373: Parameter '{ [a() ?? "d"]: c = "" }' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts(6,31): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): string | undefined => undefined; + (({ [a() ?? "d"]: c = "" }) => { var a; })(); + ~ +!!! error TS2373: Parameter '{ [a() ?? "d"]: c = "" }' cannot reference identifier 'a' declared after it. + + const x = ""; + (({ [a() ?? "d"]: c = "", d = x }) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=es2015).js b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=es2015).js new file mode 100644 index 0000000000000..f7f2e83221d83 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=es2015).js @@ -0,0 +1,9 @@ +//// [nullishCoalescingOperatorInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +((b = a() ?? "d") => {})(); + +//// [nullishCoalescingOperatorInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +((b) => { var _a; if (b === void 0) { b = (_a = a()) !== null && _a !== void 0 ? _a : "d"; } })(); diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=es5).js b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=es5).js new file mode 100644 index 0000000000000..439a4d6ba43fc --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=es5).js @@ -0,0 +1,12 @@ +//// [nullishCoalescingOperatorInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +((b = a() ?? "d") => {})(); + +//// [nullishCoalescingOperatorInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +var a = function () { return undefined; }; +(function (b) { + var _a; + if (b === void 0) { b = (_a = a()) !== null && _a !== void 0 ? _a : "d"; } +})(); diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=esnext).js b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=esnext).js new file mode 100644 index 0000000000000..e9ae41d6bde98 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer(target=esnext).js @@ -0,0 +1,9 @@ +//// [nullishCoalescingOperatorInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +((b = a() ?? "d") => {})(); + +//// [nullishCoalescingOperatorInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +((b = a() ?? "d") => { })(); diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer.2(target=es2015).errors.txt b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer.2(target=es2015).errors.txt new file mode 100644 index 0000000000000..3c00102f39076 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer.2(target=es2015).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts(3,7): error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts(6,23): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): string | undefined => undefined; + ((b = a() ?? "d") => { var a; })(); + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. + + const x = ""; + ((b = a() ?? "d", d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer.2(target=es5).errors.txt b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer.2(target=es5).errors.txt new file mode 100644 index 0000000000000..3c00102f39076 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperatorInParameterInitializer.2(target=es5).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts(3,7): error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts(6,23): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): string | undefined => undefined; + ((b = a() ?? "d") => { var a; })(); + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. + + const x = ""; + ((b = a() ?? "d", d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=es2015).js b/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=es2015).js new file mode 100644 index 0000000000000..3870f17544e99 --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=es2015).js @@ -0,0 +1,9 @@ +//// [optionalChainingInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +(({ [a()?.d]: c = "" }) => {})(); + +//// [optionalChainingInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +((_a) => { var _b; var { [(_b = a()) === null || _b === void 0 ? void 0 : _b.d]: c = "" } = _a; })(); diff --git a/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=es5).js b/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=es5).js new file mode 100644 index 0000000000000..9fde11940ce9a --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=es5).js @@ -0,0 +1,12 @@ +//// [optionalChainingInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +(({ [a()?.d]: c = "" }) => {})(); + +//// [optionalChainingInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +var a = function () { return undefined; }; +(function (_a) { + var _b; + var _c = (_b = a()) === null || _b === void 0 ? void 0 : _b.d, _d = _a[_c], c = _d === void 0 ? "" : _d; +})(); diff --git a/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=esnext).js b/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=esnext).js new file mode 100644 index 0000000000000..088bc3f7eaeae --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterBindingPattern(target=esnext).js @@ -0,0 +1,9 @@ +//// [optionalChainingInParameterBindingPattern.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +(({ [a()?.d]: c = "" }) => {})(); + +//// [optionalChainingInParameterBindingPattern.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +(({ [a()?.d]: c = "" }) => { })(); diff --git a/tests/baselines/reference/optionalChainingInParameterBindingPattern.2(target=es2015).errors.txt b/tests/baselines/reference/optionalChainingInParameterBindingPattern.2(target=es2015).errors.txt new file mode 100644 index 0000000000000..74568e696917f --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterBindingPattern.2(target=es2015).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts(3,6): error TS2373: Parameter '{ [a()?.d]: c = "" }' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts(6,24): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): { d: string } | undefined => undefined; + (({ [a()?.d]: c = "" }) => { var a; })(); + ~ +!!! error TS2373: Parameter '{ [a()?.d]: c = "" }' cannot reference identifier 'a' declared after it. + + const x = ""; + (({ [a()?.d]: c }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/optionalChainingInParameterBindingPattern.2(target=es5).errors.txt b/tests/baselines/reference/optionalChainingInParameterBindingPattern.2(target=es5).errors.txt new file mode 100644 index 0000000000000..74568e696917f --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterBindingPattern.2(target=es5).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts(3,6): error TS2373: Parameter '{ [a()?.d]: c = "" }' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts(6,24): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): { d: string } | undefined => undefined; + (({ [a()?.d]: c = "" }) => { var a; })(); + ~ +!!! error TS2373: Parameter '{ [a()?.d]: c = "" }' cannot reference identifier 'a' declared after it. + + const x = ""; + (({ [a()?.d]: c }, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/optionalChainingInParameterInitializer(target=es2015).js b/tests/baselines/reference/optionalChainingInParameterInitializer(target=es2015).js new file mode 100644 index 0000000000000..5c8a8ec76ee14 --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterInitializer(target=es2015).js @@ -0,0 +1,9 @@ +//// [optionalChainingInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +((b = a()?.d) => {})(); + +//// [optionalChainingInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +((b) => { var _a; if (b === void 0) { b = (_a = a()) === null || _a === void 0 ? void 0 : _a.d; } })(); diff --git a/tests/baselines/reference/optionalChainingInParameterInitializer(target=es5).js b/tests/baselines/reference/optionalChainingInParameterInitializer(target=es5).js new file mode 100644 index 0000000000000..07554c92cb613 --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterInitializer(target=es5).js @@ -0,0 +1,12 @@ +//// [optionalChainingInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +((b = a()?.d) => {})(); + +//// [optionalChainingInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +var a = function () { return undefined; }; +(function (b) { + var _a; + if (b === void 0) { b = (_a = a()) === null || _a === void 0 ? void 0 : _a.d; } +})(); diff --git a/tests/baselines/reference/optionalChainingInParameterInitializer(target=esnext).js b/tests/baselines/reference/optionalChainingInParameterInitializer(target=esnext).js new file mode 100644 index 0000000000000..cdda35727ba7e --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterInitializer(target=esnext).js @@ -0,0 +1,9 @@ +//// [optionalChainingInParameterInitializer.ts] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +((b = a()?.d) => {})(); + +//// [optionalChainingInParameterInitializer.js] +// https://github.com/microsoft/TypeScript/issues/36295 +const a = () => undefined; +((b = a()?.d) => { })(); diff --git a/tests/baselines/reference/optionalChainingInParameterInitializer.2(target=es2015).errors.txt b/tests/baselines/reference/optionalChainingInParameterInitializer.2(target=es2015).errors.txt new file mode 100644 index 0000000000000..80a8657d5bfc9 --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterInitializer.2(target=es2015).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts(3,7): error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts(6,19): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): { d: string } | undefined => undefined; + ((b = a()?.d) => { var a; })(); + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. + + const x = ""; + ((b = a()?.d, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/optionalChainingInParameterInitializer.2(target=es5).errors.txt b/tests/baselines/reference/optionalChainingInParameterInitializer.2(target=es5).errors.txt new file mode 100644 index 0000000000000..80a8657d5bfc9 --- /dev/null +++ b/tests/baselines/reference/optionalChainingInParameterInitializer.2(target=es5).errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts(3,7): error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. +tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts(6,19): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + const a = (): { d: string } | undefined => undefined; + ((b = a()?.d) => { var a; })(); + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. + + const x = ""; + ((b = a()?.d, d = x) => { var x; })(); + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. \ No newline at end of file diff --git a/tests/baselines/reference/optionalParamReferencingOtherParams2.errors.txt b/tests/baselines/reference/optionalParamReferencingOtherParams2.errors.txt index fa89c3ed7610d..19eb916515a84 100644 --- a/tests/baselines/reference/optionalParamReferencingOtherParams2.errors.txt +++ b/tests/baselines/reference/optionalParamReferencingOtherParams2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/optionalParamReferencingOtherParams2.ts(2,29): error TS2373: Initializer of parameter 'y' cannot reference identifier 'b' declared after it. +tests/cases/compiler/optionalParamReferencingOtherParams2.ts(2,29): error TS2373: Parameter 'y' cannot reference identifier 'b' declared after it. ==== tests/cases/compiler/optionalParamReferencingOtherParams2.ts (1 errors) ==== var a = 1; function strange(x = a, y = b) { ~ -!!! error TS2373: Initializer of parameter 'y' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'y' cannot reference identifier 'b' declared after it. var b = ""; return y; } \ No newline at end of file diff --git a/tests/baselines/reference/optionalParamReferencingOtherParams3.errors.txt b/tests/baselines/reference/optionalParamReferencingOtherParams3.errors.txt index f2b8d3d91270a..b278a97dee77a 100644 --- a/tests/baselines/reference/optionalParamReferencingOtherParams3.errors.txt +++ b/tests/baselines/reference/optionalParamReferencingOtherParams3.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/optionalParamReferencingOtherParams3.ts(1,20): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/compiler/optionalParamReferencingOtherParams3.ts(1,20): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. ==== tests/cases/compiler/optionalParamReferencingOtherParams3.ts (1 errors) ==== function right(a = b, b = a) { ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. a; b; } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing.2(target=es2015).errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing.2(target=es2015).errors.txt new file mode 100644 index 0000000000000..dda50bbc2fd4a --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing.2(target=es2015).errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts(5,18): error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts(5,32): error TS2373: Parameter '{ b = a(), ...x }' cannot reference identifier 'a' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts(11,35): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts (3 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + + function a(): any {} + + function b({ b = a(), ...x } = a()) { + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. + ~ +!!! error TS2373: Parameter '{ b = a(), ...x }' cannot reference identifier 'a' declared after it. + var a; + } + + const x = ""; + + function c({ b, ...c } = a(), d = x) { + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + var x; + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing.2(target=es5).errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing.2(target=es5).errors.txt new file mode 100644 index 0000000000000..dda50bbc2fd4a --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing.2(target=es5).errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts(5,18): error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts(5,32): error TS2373: Parameter '{ b = a(), ...x }' cannot reference identifier 'a' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts(11,35): error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + + +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts (3 errors) ==== + // https://github.com/microsoft/TypeScript/issues/36295 + + function a(): any {} + + function b({ b = a(), ...x } = a()) { + ~ +!!! error TS2373: Parameter 'b' cannot reference identifier 'a' declared after it. + ~ +!!! error TS2373: Parameter '{ b = a(), ...x }' cannot reference identifier 'a' declared after it. + var a; + } + + const x = ""; + + function c({ b, ...c } = a(), d = x) { + ~ +!!! error TS2373: Parameter 'd' cannot reference identifier 'x' declared after it. + var x; + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing.errors.txt index 22fe5ce558dba..1bc24be31f6ec 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing.errors.txt @@ -1,13 +1,13 @@ -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(6,20): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(11,21): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(11,28): error TS2373: Initializer of parameter 'b' cannot reference identifier 'c' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(17,21): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(23,25): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(32,21): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(33,16): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37,14): error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37,21): error TS2373: Initializer of parameter 'b' cannot reference identifier 'c' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37,28): error TS2373: Initializer of parameter 'c' cannot reference identifier 'd' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(6,20): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(11,21): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(11,28): error TS2373: Parameter 'b' cannot reference identifier 'c' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(17,21): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(23,25): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(32,21): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(33,16): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37,14): error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37,21): error TS2373: Parameter 'b' cannot reference identifier 'c' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37,28): error TS2373: Parameter 'c' cannot reference identifier 'd' declared after it. ==== tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts (10 errors) ==== @@ -18,16 +18,16 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37, function right(a = b, b = a) { ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. a; b; } function right2(a = b, b = c, c = a) { ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. ~ -!!! error TS2373: Initializer of parameter 'b' cannot reference identifier 'c' declared after it. +!!! error TS2373: Parameter 'b' cannot reference identifier 'c' declared after it. a; b; c; @@ -35,7 +35,7 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37, function inside(a = b) { ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. var b; } @@ -43,7 +43,7 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37, var b; function inside(a = b) { // Still an error because b is declared inside the function ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. var b; } } @@ -54,20 +54,20 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing.ts(37, class C { constructor(a = b, b = 1) { } ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. method(a = b, b = 1) { } ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. } // Function expressions var x = (a = b, b = c, c = d) => { var d; }; ~ -!!! error TS2373: Initializer of parameter 'a' cannot reference identifier 'b' declared after it. +!!! error TS2373: Parameter 'a' cannot reference identifier 'b' declared after it. ~ -!!! error TS2373: Initializer of parameter 'b' cannot reference identifier 'c' declared after it. +!!! error TS2373: Parameter 'b' cannot reference identifier 'c' declared after it. ~ -!!! error TS2373: Initializer of parameter 'c' cannot reference identifier 'd' declared after it. +!!! error TS2373: Parameter 'c' cannot reference identifier 'd' declared after it. // Should not produce errors - can reference later parameters if they occur within a function expression initializer. function f(a, b = function () { return c; }, c = b()) { diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt index 91d200adbcdbc..3c8b2fcdc48be 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt @@ -1,16 +1,17 @@ -tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(3,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. -tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(3,20): error TS2373: Parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(13,20): error TS2373: Parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(21,18): error TS2372: Parameter 'a' cannot reference itself. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25,22): error TS2372: Parameter 'async' cannot reference itself. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29,15): error TS2373: Parameter '{[foo]: bar}' cannot reference identifier 'foo' declared after it. tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29,15): error TS2448: Block-scoped variable 'foo' used before its declaration. -==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (5 errors) ==== +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (6 errors) ==== let foo: string = ""; function f1 (bar = foo) { // unexpected compiler error; works at runtime ~~~ -!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +!!! error TS2373: Parameter 'bar' cannot reference identifier 'foo' declared after it. var foo: number = 2; return bar; // returns 1 } @@ -22,7 +23,7 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29 function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime ~~~ -!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +!!! error TS2373: Parameter 'bar' cannot reference identifier 'foo' declared after it. return bar; } @@ -32,18 +33,20 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29 function f5 (a = a) { ~ -!!! error TS2372: Parameter 'a' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'a' cannot reference itself. return a } function f6 (async = async) { ~~~~~ -!!! error TS2372: Parameter 'async' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'async' cannot reference itself. return async } function f7({[foo]: bar}: any[]) { ~~~ +!!! error TS2373: Parameter '{[foo]: bar}' cannot reference identifier 'foo' declared after it. + ~~~ !!! error TS2448: Block-scoped variable 'foo' used before its declaration. !!! related TS2728 tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts:30:9: 'foo' is declared here. let foo: number = 2; diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt index c65f327161ebe..fee18ea4964fc 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. -tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. -tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(13,20): error TS2373: Parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot reference itself. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot reference itself. tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(29,15): error TS2537: Type 'any[]' has no matching index signature for type 'string'. @@ -19,7 +19,7 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime ~~~ -!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +!!! error TS2373: Parameter 'bar' cannot reference identifier 'foo' declared after it. return bar; } @@ -29,13 +29,13 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t function f5 (a = a) { ~ -!!! error TS2372: Parameter 'a' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'a' cannot reference itself. return a } function f6 (async = async) { ~~~~~ -!!! error TS2372: Parameter 'async' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'async' cannot reference itself. return async } diff --git a/tests/baselines/reference/selfReferencesInFunctionParameters.errors.txt b/tests/baselines/reference/selfReferencesInFunctionParameters.errors.txt index 32955b0bdc2d4..6642da1d4eef6 100644 --- a/tests/baselines/reference/selfReferencesInFunctionParameters.errors.txt +++ b/tests/baselines/reference/selfReferencesInFunctionParameters.errors.txt @@ -1,28 +1,28 @@ -tests/cases/compiler/selfReferencesInFunctionParameters.ts(1,26): error TS2372: Parameter 'x' cannot be referenced in its initializer. -tests/cases/compiler/selfReferencesInFunctionParameters.ts(4,35): error TS2372: Parameter 'x' cannot be referenced in its initializer. -tests/cases/compiler/selfReferencesInFunctionParameters.ts(8,28): error TS2372: Parameter 'y' cannot be referenced in its initializer. -tests/cases/compiler/selfReferencesInFunctionParameters.ts(11,29): error TS2372: Parameter 'b' cannot be referenced in its initializer. +tests/cases/compiler/selfReferencesInFunctionParameters.ts(1,26): error TS2372: Parameter 'x' cannot reference itself. +tests/cases/compiler/selfReferencesInFunctionParameters.ts(4,35): error TS2372: Parameter 'x' cannot reference itself. +tests/cases/compiler/selfReferencesInFunctionParameters.ts(8,28): error TS2372: Parameter 'y' cannot reference itself. +tests/cases/compiler/selfReferencesInFunctionParameters.ts(11,29): error TS2372: Parameter 'b' cannot reference itself. ==== tests/cases/compiler/selfReferencesInFunctionParameters.ts (4 errors) ==== function foo(x: number = x) { ~ -!!! error TS2372: Parameter 'x' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'x' cannot reference itself. } function bar(x0 = "", x: number = x) { ~ -!!! error TS2372: Parameter 'x' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'x' cannot reference itself. } class C { constructor(x = 1, y = y) { ~ -!!! error TS2372: Parameter 'y' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'y' cannot reference itself. } bar(a = "", b: string = b.toString()) { ~ -!!! error TS2372: Parameter 'b' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'b' cannot reference itself. } } \ No newline at end of file diff --git a/tests/baselines/reference/witness.errors.txt b/tests/baselines/reference/witness.errors.txt index efaed3cc43cdd..c005239eb9606 100644 --- a/tests/baselines/reference/witness.errors.txt +++ b/tests/baselines/reference/witness.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/witness/witness.ts(4,21): error TS2372: Parameter 'pInit' cannot be referenced in its initializer. +tests/cases/conformance/types/witness/witness.ts(4,21): error TS2372: Parameter 'pInit' cannot reference itself. tests/cases/conformance/types/witness/witness.ts(8,14): error TS2729: Property 'x' is used before its initialization. tests/cases/conformance/types/witness/witness.ts(28,12): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/conformance/types/witness/witness.ts(29,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'co1' must be of type 'any', but here has type 'number'. @@ -23,7 +23,7 @@ tests/cases/conformance/types/witness/witness.ts(128,19): error TS2729: Property var pInit: any; function fn(pInit = pInit) { ~~~~~ -!!! error TS2372: Parameter 'pInit' cannot be referenced in its initializer. +!!! error TS2372: Parameter 'pInit' cannot reference itself. var pInit: any; } class InitClass { diff --git a/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts new file mode 100644 index 0000000000000..839eb3c87a9f3 --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.2.ts @@ -0,0 +1,10 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/36295 +class C {} +(({ [class extends C { static x = 1 }.x]: b = "" }) => { var C; })(); + +const x = ""; +(({ [class extends C { static x = 1 }.x]: b = "" }, d = x) => { var x; })(); diff --git a/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.3.ts b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.3.ts new file mode 100644 index 0000000000000..7f55d82804fba --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.3.ts @@ -0,0 +1,11 @@ +// @target: esnext +// @noTypesAndSymbols: true +// @noEmit: true +// @useDefineForClassFields: true + +// https://github.com/microsoft/TypeScript/issues/36295 +class C {} +(({ [class extends C { static x = 1 }.x]: b = "" }) => { var C; })(); + +const x = ""; +(({ [class extends C { static x = 1 }.x]: b = "" }, d = x) => { var x; })(); diff --git a/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.ts b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.ts new file mode 100644 index 0000000000000..1d6c683dc7486 --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterBindingPattern.ts @@ -0,0 +1,5 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/36295 +(({ [class { static x = 1 }.x]: b = "" }) => {})(); \ No newline at end of file diff --git a/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts new file mode 100644 index 0000000000000..e70f19006df67 --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.2.ts @@ -0,0 +1,10 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/36295 +class C {} +((b = class extends C { static x = 1 }) => { var C; })(); + +const x = ""; +((b = class extends C { static x = 1 }, d = x) => { var x; })(); \ No newline at end of file diff --git a/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.3.ts b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.3.ts new file mode 100644 index 0000000000000..ba2b2db8e257d --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.3.ts @@ -0,0 +1,11 @@ +// @target: esnext +// @noTypesAndSymbols: true +// @noEmit: true +// @useDefineForClassFields: true + +// https://github.com/microsoft/TypeScript/issues/36295 +class C {} +((b = class extends C { static x = 1 }) => { var C; })(); + +const x = ""; +((b = class extends C { static x = 1 }, d = x) => { var x; })(); \ No newline at end of file diff --git a/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.ts b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.ts new file mode 100644 index 0000000000000..8b32f84feb356 --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classWithStaticFieldInParameterInitializer.ts @@ -0,0 +1,5 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/36295 +((b = class { static x = 1 }) => {})(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts new file mode 100644 index 0000000000000..5925fe4d86327 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.2.ts @@ -0,0 +1,10 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +(({ [a() ?? "d"]: c = "" }) => { var a; })(); + +const x = ""; +(({ [a() ?? "d"]: c = "", d = x }) => { var x; })(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.ts new file mode 100644 index 0000000000000..1231cb5d0fea5 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterBindingPattern.ts @@ -0,0 +1,6 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +(({ [a() ?? "d"]: c = "" }) => {})(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts new file mode 100644 index 0000000000000..c3da31aa20300 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.2.ts @@ -0,0 +1,10 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +((b = a() ?? "d") => { var a; })(); + +const x = ""; +((b = a() ?? "d", d = x) => { var x; })(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.ts new file mode 100644 index 0000000000000..f8c5da3042582 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperatorInParameterInitializer.ts @@ -0,0 +1,6 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): string | undefined => undefined; +((b = a() ?? "d") => {})(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts new file mode 100644 index 0000000000000..423e8a465139d --- /dev/null +++ b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.2.ts @@ -0,0 +1,10 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +(({ [a()?.d]: c = "" }) => { var a; })(); + +const x = ""; +(({ [a()?.d]: c }, d = x) => { var x; })(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.ts b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.ts new file mode 100644 index 0000000000000..38cabea7aeef2 --- /dev/null +++ b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.ts @@ -0,0 +1,6 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +(({ [a()?.d]: c = "" }) => {})(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts new file mode 100644 index 0000000000000..707be27f114c1 --- /dev/null +++ b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.2.ts @@ -0,0 +1,10 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +((b = a()?.d) => { var a; })(); + +const x = ""; +((b = a()?.d, d = x) => { var x; })(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.ts b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.ts new file mode 100644 index 0000000000000..867887fc26034 --- /dev/null +++ b/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.ts @@ -0,0 +1,6 @@ +// @target: esnext,es2015,es5 +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/36295 +const a = (): { d: string } | undefined => undefined; +((b = a()?.d) => {})(); \ No newline at end of file diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts new file mode 100644 index 0000000000000..7aa08e2dbf03d --- /dev/null +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing.2.ts @@ -0,0 +1,17 @@ +// @target: es5, es2015, esnext +// @noEmit: true +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/36295 + +function a(): any {} + +function b({ b = a(), ...x } = a()) { + var a; +} + +const x = ""; + +function c({ b, ...c } = a(), d = x) { + var x; +} \ No newline at end of file