From 114dad7f56b7a476deaba3e673c9926d47afc6ce Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 22 Dec 2019 13:24:31 -0800 Subject: [PATCH 01/16] Add top-level await for esnext and system modules (#35813) --- src/compiler/binder.ts | 7 ++- src/compiler/checker.ts | 40 ++++++++++---- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/transformers/es2017.ts | 53 ++++++++++++++----- src/compiler/transformers/es2018.ts | 28 +++++----- src/compiler/transformers/module/system.ts | 5 +- src/compiler/types.ts | 15 +++--- .../awaitInNonAsyncFunction.errors.txt | 4 +- ...it(module=esnext,target=es2015).errors.txt | 9 ++++ ...LevelAwait(module=esnext,target=es2015).js | 8 +++ ...Await(module=esnext,target=es2015).symbols | 7 +++ ...elAwait(module=esnext,target=es2015).types | 9 ++++ ...LevelAwait(module=esnext,target=es2017).js | 8 +++ ...Await(module=esnext,target=es2017).symbols | 7 +++ ...elAwait(module=esnext,target=es2017).types | 9 ++++ ...it(module=system,target=es2015).errors.txt | 9 ++++ ...LevelAwait(module=system,target=es2015).js | 18 +++++++ ...Await(module=system,target=es2015).symbols | 7 +++ ...elAwait(module=system,target=es2015).types | 9 ++++ ...LevelAwait(module=system,target=es2017).js | 18 +++++++ ...Await(module=system,target=es2017).symbols | 7 +++ ...elAwait(module=system,target=es2017).types | 9 ++++ .../topLevelAwaitNonModule.errors.txt | 11 ++++ .../reference/topLevelAwaitNonModule.js | 6 +++ .../reference/topLevelAwaitNonModule.symbols | 4 ++ .../reference/topLevelAwaitNonModule.types | 5 ++ .../externalModules/topLevelAwait.ts | 4 ++ .../externalModules/topLevelAwaitNonModule.ts | 3 ++ 28 files changed, 274 insertions(+), 49 deletions(-) create mode 100644 tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt create mode 100644 tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).js create mode 100644 tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).symbols create mode 100644 tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).types create mode 100644 tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).js create mode 100644 tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).symbols create mode 100644 tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).types create mode 100644 tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt create mode 100644 tests/baselines/reference/topLevelAwait(module=system,target=es2015).js create mode 100644 tests/baselines/reference/topLevelAwait(module=system,target=es2015).symbols create mode 100644 tests/baselines/reference/topLevelAwait(module=system,target=es2015).types create mode 100644 tests/baselines/reference/topLevelAwait(module=system,target=es2017).js create mode 100644 tests/baselines/reference/topLevelAwait(module=system,target=es2017).symbols create mode 100644 tests/baselines/reference/topLevelAwait(module=system,target=es2017).types create mode 100644 tests/baselines/reference/topLevelAwaitNonModule.errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitNonModule.js create mode 100644 tests/baselines/reference/topLevelAwaitNonModule.symbols create mode 100644 tests/baselines/reference/topLevelAwaitNonModule.types create mode 100644 tests/cases/conformance/externalModules/topLevelAwait.ts create mode 100644 tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0b19d7806ff07..8fb80a8003bea 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3902,10 +3902,13 @@ namespace ts { switch (kind) { case SyntaxKind.AsyncKeyword: - case SyntaxKind.AwaitExpression: - // async/await is ES2017 syntax, but may be ES2018 syntax (for async generators) + // async is ES2017 syntax, but may be ES2018 syntax (for async generators) transformFlags |= TransformFlags.AssertES2018 | TransformFlags.AssertES2017; break; + case SyntaxKind.AwaitExpression: + // await is ES2017 syntax, but may be ES2018 syntax (for async generators) + transformFlags |= TransformFlags.AssertES2018 | TransformFlags.AssertES2017 | TransformFlags.ContainsAwait; + break; case SyntaxKind.TypeAssertionExpression: case SyntaxKind.AsExpression: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d33fed84e584e..0a3658bde1a5b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26437,21 +26437,41 @@ namespace ts { return undefinedWideningType; } + function isTopLevelAwait(node: AwaitExpression) { + const container = getThisContainer(node, /*includeArrowFunctions*/ true); + return isSourceFile(container); + } + function checkAwaitExpression(node: AwaitExpression): Type { // Grammar checking if (produceDiagnostics) { if (!(node.flags & NodeFlags.AwaitContext)) { - // use of 'await' in non-async function - const sourceFile = getSourceFileOfNode(node); - if (!hasParseDiagnostics(sourceFile)) { - const span = getSpanOfTokenAtPosition(sourceFile, node.pos); - const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.await_expression_is_only_allowed_within_an_async_function); - const func = getContainingFunction(node); - if (func && func.kind !== SyntaxKind.Constructor && (getFunctionFlags(func) & FunctionFlags.Async) === 0) { - const relatedInfo = createDiagnosticForNode(func, Diagnostics.Did_you_mean_to_mark_this_function_as_async); - addRelatedInfo(diagnostic, relatedInfo); + if (isTopLevelAwait(node)) { + const sourceFile = getSourceFileOfNode(node); + if ((moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) || + languageVersion < ScriptTarget.ES2017 || + !isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!hasParseDiagnostics(sourceFile)) { + const span = getSpanOfTokenAtPosition(sourceFile, node.pos); + const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, + Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + diagnostics.add(diagnostic); + } + } + } + else { + // use of 'await' in non-async function + const sourceFile = getSourceFileOfNode(node); + if (!hasParseDiagnostics(sourceFile)) { + const span = getSpanOfTokenAtPosition(sourceFile, node.pos); + const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.await_expression_is_only_allowed_within_an_async_function); + const func = getContainingFunction(node); + if (func && func.kind !== SyntaxKind.Constructor && (getFunctionFlags(func) & FunctionFlags.Async) === 0) { + const relatedInfo = createDiagnosticForNode(func, Diagnostics.Did_you_mean_to_mark_this_function_as_async); + addRelatedInfo(diagnostic, relatedInfo); + } + diagnostics.add(diagnostic); } - diagnostics.add(diagnostic); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ee1f593f98c32..18b5435514a38 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1059,6 +1059,10 @@ "category": "Error", "code": 1360 }, + "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher.": { + "category": "Error", + "code": 1361 + }, "The types of '{0}' are incompatible between these types.": { "category": "Error", diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 005d5a8fdd6ed..594dc0d3e5b6d 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -7,6 +7,11 @@ namespace ts { AsyncMethodsWithSuper = 1 << 0 } + const enum ContextFlags { + NonTopLevel = 1 << 0, + HasLexicalThis = 1 << 1 + } + export function transformES2017(context: TransformationContext) { const { resumeLexicalEnvironment, @@ -41,7 +46,7 @@ namespace ts { /** A set of node IDs for generated super accessors (variable statements). */ const substitutedSuperAccessors: boolean[] = []; - let topLevel: boolean; + let contextFlags: ContextFlags = 0; // Save the previous transformation hooks. const previousOnEmitNode = context.onEmitNode; @@ -58,17 +63,35 @@ namespace ts { return node; } - topLevel = isEffectiveStrictModeSourceFile(node, compilerOptions); + setContextFlag(ContextFlags.NonTopLevel, false); + setContextFlag(ContextFlags.HasLexicalThis, !isEffectiveStrictModeSourceFile(node, compilerOptions)); const visited = visitEachChild(node, visitor, context); addEmitHelpers(visited, context.readEmitHelpers()); return visited; } - function doOutsideOfTopLevel(cb: (value: T) => U, value: T) { - if (topLevel) { - topLevel = false; + function setContextFlag(flag: ContextFlags, val: boolean) { + contextFlags = val ? contextFlags | flag : contextFlags & ~flag; + } + + function inContext(flags: ContextFlags) { + return (contextFlags & flags) !== 0; + } + + function inTopLevelContext() { + return !inContext(ContextFlags.NonTopLevel); + } + + function inHasLexicalThisContext() { + return inContext(ContextFlags.HasLexicalThis); + } + + function doWithContext(flags: ContextFlags, cb: (value: T) => U, value: T) { + const contextFlagsToSet = flags & ~contextFlags; + if (contextFlagsToSet) { + setContextFlag(contextFlagsToSet, /*val*/ true); const result = cb(value); - topLevel = true; + setContextFlag(contextFlagsToSet, /*val*/ false); return result; } return cb(value); @@ -91,16 +114,16 @@ namespace ts { return visitAwaitExpression(node); case SyntaxKind.MethodDeclaration: - return doOutsideOfTopLevel(visitMethodDeclaration, node); + return doWithContext(ContextFlags.NonTopLevel | ContextFlags.HasLexicalThis, visitMethodDeclaration, node); case SyntaxKind.FunctionDeclaration: - return doOutsideOfTopLevel(visitFunctionDeclaration, node); + return doWithContext(ContextFlags.NonTopLevel | ContextFlags.HasLexicalThis, visitFunctionDeclaration, node); case SyntaxKind.FunctionExpression: - return doOutsideOfTopLevel(visitFunctionExpression, node); + return doWithContext(ContextFlags.NonTopLevel | ContextFlags.HasLexicalThis, visitFunctionExpression, node); case SyntaxKind.ArrowFunction: - return visitArrowFunction(node); + return doWithContext(ContextFlags.NonTopLevel, visitArrowFunction, node); case SyntaxKind.PropertyAccessExpression: if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) { @@ -119,7 +142,7 @@ namespace ts { case SyntaxKind.Constructor: case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: - return doOutsideOfTopLevel(visitDefault, node); + return doWithContext(ContextFlags.NonTopLevel | ContextFlags.HasLexicalThis, visitDefault, node); default: return visitEachChild(node, visitor, context); @@ -237,6 +260,10 @@ namespace ts { * @param node The node to visit. */ function visitAwaitExpression(node: AwaitExpression): Expression { + // do not downlevel a top-level await as it is module syntax... + if (inTopLevelContext()) { + return visitEachChild(node, visitor, context); + } return setOriginalNode( setTextRange( createYield( @@ -457,7 +484,7 @@ namespace ts { createReturn( createAwaiterHelper( context, - !topLevel, + inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body, statementOffset) @@ -498,7 +525,7 @@ namespace ts { else { const expression = createAwaiterHelper( context, - !topLevel, + inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body!) diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 01cabe76e517b..f03b24fc45ee6 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -26,7 +26,7 @@ namespace ts { let enabledSubstitutions: ESNextSubstitutionFlags; let enclosingFunctionFlags: FunctionFlags; let enclosingSuperContainerFlags: NodeCheckFlags = 0; - let topLevel: boolean; + let hasLexicalThis: boolean; /** Keeps track of property names accessed on super (`super.x`) within async functions. */ let capturedSuperProperties: UnderscoreEscapedMap; @@ -43,7 +43,7 @@ namespace ts { } exportedVariableStatement = false; - topLevel = isEffectiveStrictModeSourceFile(node, compilerOptions); + hasLexicalThis = !isEffectiveStrictModeSourceFile(node, compilerOptions); const visited = visitEachChild(node, visitor, context); addEmitHelpers(visited, context.readEmitHelpers()); return visited; @@ -64,11 +64,11 @@ namespace ts { return node; } - function doOutsideOfTopLevel(cb: (value: T) => U, value: T) { - if (topLevel) { - topLevel = false; + function doWithLexicalThis(cb: (value: T) => U, value: T) { + if (!hasLexicalThis) { + hasLexicalThis = true; const result = cb(value); - topLevel = true; + hasLexicalThis = false; return result; } return cb(value); @@ -108,17 +108,17 @@ namespace ts { case SyntaxKind.VoidExpression: return visitVoidExpression(node as VoidExpression); case SyntaxKind.Constructor: - return doOutsideOfTopLevel(visitConstructorDeclaration, node as ConstructorDeclaration); + return doWithLexicalThis(visitConstructorDeclaration, node as ConstructorDeclaration); case SyntaxKind.MethodDeclaration: - return doOutsideOfTopLevel(visitMethodDeclaration, node as MethodDeclaration); + return doWithLexicalThis(visitMethodDeclaration, node as MethodDeclaration); case SyntaxKind.GetAccessor: - return doOutsideOfTopLevel(visitGetAccessorDeclaration, node as GetAccessorDeclaration); + return doWithLexicalThis(visitGetAccessorDeclaration, node as GetAccessorDeclaration); case SyntaxKind.SetAccessor: - return doOutsideOfTopLevel(visitSetAccessorDeclaration, node as SetAccessorDeclaration); + return doWithLexicalThis(visitSetAccessorDeclaration, node as SetAccessorDeclaration); case SyntaxKind.FunctionDeclaration: - return doOutsideOfTopLevel(visitFunctionDeclaration, node as FunctionDeclaration); + return doWithLexicalThis(visitFunctionDeclaration, node as FunctionDeclaration); case SyntaxKind.FunctionExpression: - return doOutsideOfTopLevel(visitFunctionExpression, node as FunctionExpression); + return doWithLexicalThis(visitFunctionExpression, node as FunctionExpression); case SyntaxKind.ArrowFunction: return visitArrowFunction(node as ArrowFunction); case SyntaxKind.Parameter: @@ -139,7 +139,7 @@ namespace ts { return visitEachChild(node, visitor, context); case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: - return doOutsideOfTopLevel(visitDefault, node); + return doWithLexicalThis(visitDefault, node); default: return visitEachChild(node, visitor, context); } @@ -774,7 +774,7 @@ namespace ts { visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset) ) ), - !topLevel + hasLexicalThis ) ); diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 7c4755924510c..bc1ba49f218ab 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -262,13 +262,16 @@ namespace ts { insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); const exportStarFunction = addExportStarIfNeeded(statements)!; // TODO: GH#18217 + const modifiers = node.transformFlags & TransformFlags.ContainsAwait ? + createModifiersFromModifierFlags(ModifierFlags.Async) : + undefined; const moduleObject = createObjectLiteral([ createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups) ), createPropertyAssignment("execute", createFunctionExpression( - /*modifiers*/ undefined, + modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5ef9e86b2544f..746eb4e546fe9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5608,9 +5608,10 @@ namespace ts { ContainsBlockScopedBinding = 1 << 15, ContainsBindingPattern = 1 << 16, ContainsYield = 1 << 17, - ContainsHoistedDeclarationOrCompletion = 1 << 18, - ContainsDynamicImport = 1 << 19, - ContainsClassFields = 1 << 20, + ContainsAwait = 1 << 18, + ContainsHoistedDeclarationOrCompletion = 1 << 19, + ContainsDynamicImport = 1 << 20, + ContainsClassFields = 1 << 21, // Please leave this as 1 << 29. // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system. @@ -5636,10 +5637,10 @@ namespace ts { OuterExpressionExcludes = HasComputedFlags, PropertyAccessExcludes = OuterExpressionExcludes, NodeExcludes = PropertyAccessExcludes, - ArrowFunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, - FunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, - ConstructorExcludes = NodeExcludes | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, - MethodOrAccessorExcludes = NodeExcludes | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, + ArrowFunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsBlockScopedBinding | ContainsYield | ContainsAwait | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, + FunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsAwait | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, + ConstructorExcludes = NodeExcludes | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsAwait | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, + MethodOrAccessorExcludes = NodeExcludes | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsAwait | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread, PropertyExcludes = NodeExcludes | ContainsLexicalThis, ClassExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsComputedPropertyName, ModuleExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion, diff --git a/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt b/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt index 5cd8468ac3eb6..d7706ed107422 100644 --- a/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt +++ b/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt @@ -13,7 +13,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(31,5): error TS1308: 'await' exp tests/cases/compiler/awaitInNonAsyncFunction.ts(34,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. tests/cases/compiler/awaitInNonAsyncFunction.ts(35,5): error TS1308: 'await' expression is only allowed within an async function. tests/cases/compiler/awaitInNonAsyncFunction.ts(39,5): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. ==== tests/cases/compiler/awaitInNonAsyncFunction.ts (16 errors) ==== @@ -100,4 +100,4 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1308: 'await' exp !!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. await null; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. \ No newline at end of file +!!! error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt new file mode 100644 index 0000000000000..9efe0c2aa612f --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/externalModules/topLevelAwait.ts(2,1): error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. + + +==== tests/cases/conformance/externalModules/topLevelAwait.ts (1 errors) ==== + export const x = 1; + await x; + ~~~~~ +!!! error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. + \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).js b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).js new file mode 100644 index 0000000000000..6a2b5fe680c2b --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).js @@ -0,0 +1,8 @@ +//// [topLevelAwait.ts] +export const x = 1; +await x; + + +//// [topLevelAwait.js] +export const x = 1; +await x; diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).symbols b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).symbols new file mode 100644 index 0000000000000..7eccf23a23169 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + +await x; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).types b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).types new file mode 100644 index 0000000000000..5f579192ee586 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : 1 +>1 : 1 + +await x; +>await x : 1 +>x : 1 + diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).js b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).js new file mode 100644 index 0000000000000..6a2b5fe680c2b --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).js @@ -0,0 +1,8 @@ +//// [topLevelAwait.ts] +export const x = 1; +await x; + + +//// [topLevelAwait.js] +export const x = 1; +await x; diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).symbols b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).symbols new file mode 100644 index 0000000000000..7eccf23a23169 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + +await x; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).types b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).types new file mode 100644 index 0000000000000..5f579192ee586 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2017).types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : 1 +>1 : 1 + +await x; +>await x : 1 +>x : 1 + diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt new file mode 100644 index 0000000000000..9efe0c2aa612f --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/externalModules/topLevelAwait.ts(2,1): error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. + + +==== tests/cases/conformance/externalModules/topLevelAwait.ts (1 errors) ==== + export const x = 1; + await x; + ~~~~~ +!!! error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. + \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2015).js b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).js new file mode 100644 index 0000000000000..c6d4e03efbd39 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).js @@ -0,0 +1,18 @@ +//// [topLevelAwait.ts] +export const x = 1; +await x; + + +//// [topLevelAwait.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var x; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: async function () { + exports_1("x", x = 1); + await x; + } + }; +}); diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2015).symbols b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).symbols new file mode 100644 index 0000000000000..7eccf23a23169 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + +await x; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2015).types b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).types new file mode 100644 index 0000000000000..5f579192ee586 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : 1 +>1 : 1 + +await x; +>await x : 1 +>x : 1 + diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2017).js b/tests/baselines/reference/topLevelAwait(module=system,target=es2017).js new file mode 100644 index 0000000000000..c6d4e03efbd39 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2017).js @@ -0,0 +1,18 @@ +//// [topLevelAwait.ts] +export const x = 1; +await x; + + +//// [topLevelAwait.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var x; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: async function () { + exports_1("x", x = 1); + await x; + } + }; +}); diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2017).symbols b/tests/baselines/reference/topLevelAwait(module=system,target=es2017).symbols new file mode 100644 index 0000000000000..7eccf23a23169 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2017).symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + +await x; +>x : Symbol(x, Decl(topLevelAwait.ts, 0, 12)) + diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2017).types b/tests/baselines/reference/topLevelAwait(module=system,target=es2017).types new file mode 100644 index 0000000000000..5f579192ee586 --- /dev/null +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2017).types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/externalModules/topLevelAwait.ts === +export const x = 1; +>x : 1 +>1 : 1 + +await x; +>await x : 1 +>x : 1 + diff --git a/tests/baselines/reference/topLevelAwaitNonModule.errors.txt b/tests/baselines/reference/topLevelAwaitNonModule.errors.txt new file mode 100644 index 0000000000000..8e2d3a6eab3cd --- /dev/null +++ b/tests/baselines/reference/topLevelAwaitNonModule.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(1,1): error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(1,7): error TS2304: Cannot find name 'x'. + + +==== tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts (2 errors) ==== + await x; + ~~~~~ +!!! error TS1361: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. + ~ +!!! error TS2304: Cannot find name 'x'. + \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwaitNonModule.js b/tests/baselines/reference/topLevelAwaitNonModule.js new file mode 100644 index 0000000000000..98fa13cb62bc7 --- /dev/null +++ b/tests/baselines/reference/topLevelAwaitNonModule.js @@ -0,0 +1,6 @@ +//// [topLevelAwaitNonModule.ts] +await x; + + +//// [topLevelAwaitNonModule.js] +await x; diff --git a/tests/baselines/reference/topLevelAwaitNonModule.symbols b/tests/baselines/reference/topLevelAwaitNonModule.symbols new file mode 100644 index 0000000000000..03c11745c102a --- /dev/null +++ b/tests/baselines/reference/topLevelAwaitNonModule.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts === +await x; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwaitNonModule.types b/tests/baselines/reference/topLevelAwaitNonModule.types new file mode 100644 index 0000000000000..8b61253fc50cc --- /dev/null +++ b/tests/baselines/reference/topLevelAwaitNonModule.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts === +await x; +>await x : any +>x : any + diff --git a/tests/cases/conformance/externalModules/topLevelAwait.ts b/tests/cases/conformance/externalModules/topLevelAwait.ts new file mode 100644 index 0000000000000..7c92e507e57cd --- /dev/null +++ b/tests/cases/conformance/externalModules/topLevelAwait.ts @@ -0,0 +1,4 @@ +// @target: es2015,es2017 +// @module: esnext,system +export const x = 1; +await x; diff --git a/tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts b/tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts new file mode 100644 index 0000000000000..5a98c9423a1a0 --- /dev/null +++ b/tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts @@ -0,0 +1,3 @@ +// @target: esnext +// @module: esnext +await x; From 6c413e0bbb5df5d8ec0061123078624091340317 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 22 Dec 2019 13:25:09 -0800 Subject: [PATCH 02/16] Add support for Call Hierarchies in language server (#35176) * Add support for Call Hierarchies in language server * Use baselines for callHierarchy tests * Clean up commented code * Support multiple hierarchy items when an implementation can't be found * Use optional chaining in a few places * Use getFileAndProject --- src/compiler/core.ts | 18 +- src/harness/client.ts | 45 ++ src/harness/fourslashImpl.ts | 243 ++++++++- src/harness/fourslashInterfaceImpl.ts | 5 + src/harness/harnessLanguageService.ts | 9 + src/server/protocol.ts | 50 +- src/server/session.ts | 100 +++- src/services/callHierarchy.ts | 485 ++++++++++++++++++ src/services/services.ts | 23 + src/services/shims.ts | 27 + src/services/tsconfig.json | 1 + src/services/types.ts | 22 + src/services/utilities.ts | 89 +++- src/testRunner/unittests/tsserver/session.ts | 3 + .../reference/api/tsserverlibrary.d.ts | 60 +++ tests/baselines/reference/api/typescript.d.ts | 18 + .../callHierarchyAccessor.callHierarchy.txt | 65 +++ .../callHierarchyClass.callHierarchy.txt | 65 +++ ...yConstNamedArrowFunction.callHierarchy.txt | 65 +++ ...onstNamedClassExpression.callHierarchy.txt | 69 +++ ...tNamedFunctionExpression.callHierarchy.txt | 65 +++ .../callHierarchyDecorator.callHierarchy.txt | 65 +++ ...rarchyExportDefaultClass.callHierarchy.txt | 69 +++ ...chyExportDefaultFunction.callHierarchy.txt | 65 +++ ...rchyExportEqualsFunction.callHierarchy.txt | 47 ++ .../callHierarchyFile.callHierarchy.txt | 41 ++ .../callHierarchyFunction.callHierarchy.txt | 95 ++++ ...archyFunctionAmbiguity.1.callHierarchy.txt | 78 +++ ...archyFunctionAmbiguity.2.callHierarchy.txt | 78 +++ ...archyFunctionAmbiguity.3.callHierarchy.txt | 78 +++ ...archyFunctionAmbiguity.4.callHierarchy.txt | 78 +++ ...archyFunctionAmbiguity.5.callHierarchy.txt | 59 +++ ...HierarchyInterfaceMethod.callHierarchy.txt | 47 ++ .../callHierarchyJsxElement.callHierarchy.txt | 65 +++ ...lHierarchyTaggedTemplate.callHierarchy.txt | 65 +++ .../cases/fourslash/callHierarchyAccessor.ts | 17 + tests/cases/fourslash/callHierarchyClass.ts | 15 + .../callHierarchyConstNamedArrowFunction.ts | 15 + .../callHierarchyConstNamedClassExpression.ts | 17 + ...llHierarchyConstNamedFunctionExpression.ts | 15 + .../cases/fourslash/callHierarchyDecorator.ts | 16 + .../callHierarchyExportDefaultClass.ts | 21 + .../callHierarchyExportDefaultFunction.ts | 19 + .../callHierarchyExportEqualsFunction.ts | 20 + tests/cases/fourslash/callHierarchyFile.ts | 8 + .../cases/fourslash/callHierarchyFunction.ts | 20 + .../callHierarchyFunctionAmbiguity.1.ts | 16 + .../callHierarchyFunctionAmbiguity.2.ts | 16 + .../callHierarchyFunctionAmbiguity.3.ts | 16 + .../callHierarchyFunctionAmbiguity.4.ts | 16 + .../callHierarchyFunctionAmbiguity.5.ts | 16 + .../fourslash/callHierarchyInterfaceMethod.ts | 12 + .../fourslash/callHierarchyJsxElement.ts | 17 + .../fourslash/callHierarchyTaggedTemplate.ts | 15 + tests/cases/fourslash/fourslash.ts | 3 +- 55 files changed, 2712 insertions(+), 55 deletions(-) create mode 100644 src/services/callHierarchy.ts create mode 100644 tests/baselines/reference/callHierarchyAccessor.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyClass.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyConstNamedArrowFunction.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyConstNamedClassExpression.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyConstNamedFunctionExpression.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyDecorator.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyExportDefaultClass.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyExportDefaultFunction.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyExportEqualsFunction.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyFile.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyFunction.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyFunctionAmbiguity.1.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyFunctionAmbiguity.2.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyFunctionAmbiguity.3.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyFunctionAmbiguity.4.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyFunctionAmbiguity.5.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyInterfaceMethod.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyJsxElement.callHierarchy.txt create mode 100644 tests/baselines/reference/callHierarchyTaggedTemplate.callHierarchy.txt create mode 100644 tests/cases/fourslash/callHierarchyAccessor.ts create mode 100644 tests/cases/fourslash/callHierarchyClass.ts create mode 100644 tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts create mode 100644 tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts create mode 100644 tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts create mode 100644 tests/cases/fourslash/callHierarchyDecorator.ts create mode 100644 tests/cases/fourslash/callHierarchyExportDefaultClass.ts create mode 100644 tests/cases/fourslash/callHierarchyExportDefaultFunction.ts create mode 100644 tests/cases/fourslash/callHierarchyExportEqualsFunction.ts create mode 100644 tests/cases/fourslash/callHierarchyFile.ts create mode 100644 tests/cases/fourslash/callHierarchyFunction.ts create mode 100644 tests/cases/fourslash/callHierarchyFunctionAmbiguity.1.ts create mode 100644 tests/cases/fourslash/callHierarchyFunctionAmbiguity.2.ts create mode 100644 tests/cases/fourslash/callHierarchyFunctionAmbiguity.3.ts create mode 100644 tests/cases/fourslash/callHierarchyFunctionAmbiguity.4.ts create mode 100644 tests/cases/fourslash/callHierarchyFunctionAmbiguity.5.ts create mode 100644 tests/cases/fourslash/callHierarchyInterfaceMethod.ts create mode 100644 tests/cases/fourslash/callHierarchyJsxElement.ts create mode 100644 tests/cases/fourslash/callHierarchyTaggedTemplate.ts diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 7a3fcac973aac..203835b49f6a9 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -630,10 +630,18 @@ namespace ts { return [...array1, ...array2]; } + function selectIndex(_: unknown, i: number) { + return i; + } + + export function indicesOf(array: readonly unknown[]): number[] { + return array.map(selectIndex); + } + function deduplicateRelational(array: readonly T[], equalityComparer: EqualityComparer, comparer: Comparer) { // Perform a stable sort of the array. This ensures the first entry in a list of // duplicates remains the first entry in the result. - const indices = array.map((_, i) => i); + const indices = indicesOf(array); stableSortIndices(array, indices, comparer); let last = array[indices[0]]; @@ -939,7 +947,7 @@ namespace ts { * Stable sort of an array. Elements equal to each other maintain their relative position in the array. */ export function stableSort(array: readonly T[], comparer: Comparer): SortedReadonlyArray { - const indices = array.map((_, i) => i); + const indices = indicesOf(array); stableSortIndices(array, indices, comparer); return indices.map(i => array[i]) as SortedArray as SortedReadonlyArray; } @@ -1245,8 +1253,10 @@ namespace ts { return result; } - export function group(values: readonly T[], getGroupId: (value: T) => string): readonly (readonly T[])[] { - return arrayFrom(arrayToMultiMap(values, getGroupId).values()); + export function group(values: readonly T[], getGroupId: (value: T) => string): readonly (readonly T[])[]; + export function group(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => R): R[]; + export function group(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => readonly T[] = identity): readonly (readonly T[])[] { + return arrayFrom(arrayToMultiMap(values, getGroupId).values(), resultSelector); } export function clone(object: T): T { diff --git a/src/harness/client.ts b/src/harness/client.ts index 78b454b565be5..63ad8b90da83c 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -743,6 +743,51 @@ namespace ts.server { return notImplemented(); } + private convertCallHierarchyItem(item: protocol.CallHierarchyItem): CallHierarchyItem { + return { + file: item.file, + name: item.name, + kind: item.kind, + span: this.decodeSpan(item.span, item.file), + selectionSpan: this.decodeSpan(item.selectionSpan, item.file) + }; + } + + prepareCallHierarchy(fileName: string, position: number): CallHierarchyItem | CallHierarchyItem[] | undefined { + const args = this.createFileLocationRequestArgs(fileName, position); + const request = this.processRequest(CommandNames.PrepareCallHierarchy, args); + const response = this.processResponse(request); + return response.body && mapOneOrMany(response.body, item => this.convertCallHierarchyItem(item)); + } + + private convertCallHierarchyIncomingCall(item: protocol.CallHierarchyIncomingCall): CallHierarchyIncomingCall { + return { + from: this.convertCallHierarchyItem(item.from), + fromSpans: item.fromSpans.map(span => this.decodeSpan(span, item.from.file)) + }; + } + + provideCallHierarchyIncomingCalls(fileName: string, position: number) { + const args = this.createFileLocationRequestArgs(fileName, position); + const request = this.processRequest(CommandNames.PrepareCallHierarchy, args); + const response = this.processResponse(request); + return response.body.map(item => this.convertCallHierarchyIncomingCall(item)); + } + + private convertCallHierarchyOutgoingCall(file: string, item: protocol.CallHierarchyOutgoingCall): CallHierarchyOutgoingCall { + return { + to: this.convertCallHierarchyItem(item.to), + fromSpans: item.fromSpans.map(span => this.decodeSpan(span, file)) + }; + } + + provideCallHierarchyOutgoingCalls(fileName: string, position: number) { + const args = this.createFileLocationRequestArgs(fileName, position); + const request = this.processRequest(CommandNames.PrepareCallHierarchy, args); + const response = this.processResponse(request); + return response.body.map(item => this.convertCallHierarchyOutgoingCall(fileName, item)); + } + getProgram(): Program { throw new Error("SourceFile objects are not serializable through the server protocol."); } diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index eaa74d9dd7285..952ba36b7598e 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -147,6 +147,12 @@ namespace FourSlash { return ts.ScriptSnapshot.fromString(sourceText); } + const enum CallHierarchyItemDirection { + Root, + Incoming, + Outgoing + } + export class TestState { // Language service instance private languageServiceAdapterHost: Harness.LanguageService.LanguageServiceAdapterHost; @@ -734,11 +740,8 @@ namespace FourSlash { if (!range) { this.raiseError(`goToDefinitionsAndBoundSpan failed - found a TextSpan ${JSON.stringify(defs.textSpan)} when it wasn't expected.`); } - else if (defs.textSpan.start !== range.pos || defs.textSpan.length !== range.end - range.pos) { - const expected: ts.TextSpan = { - start: range.pos, length: range.end - range.pos - }; - this.raiseError(`goToDefinitionsAndBoundSpan failed - expected to find TextSpan ${JSON.stringify(expected)} but got ${JSON.stringify(defs.textSpan)}`); + else { + this.assertTextSpanEqualsRange(defs.textSpan, range, "goToDefinitionsAndBoundSpan failed"); } } @@ -1411,18 +1414,91 @@ namespace FourSlash { private alignmentForExtraInfo = 50; - private spanInfoToString(spanInfo: ts.TextSpan, prefixString: string) { + private spanLines(file: FourSlashFile, spanInfo: ts.TextSpan, { selection = false, fullLines = false, lineNumbers = false } = {}) { + if (selection) { + fullLines = true; + } + + let contextStartPos = spanInfo.start; + let contextEndPos = contextStartPos + spanInfo.length; + if (fullLines) { + if (contextStartPos > 0) { + while (contextStartPos > 1) { + const ch = file.content.charCodeAt(contextStartPos - 1); + if (ch === ts.CharacterCodes.lineFeed || ch === ts.CharacterCodes.carriageReturn) { + break; + } + contextStartPos--; + } + } + if (contextEndPos < file.content.length) { + while (contextEndPos < file.content.length - 1) { + const ch = file.content.charCodeAt(contextEndPos); + if (ch === ts.CharacterCodes.lineFeed || ch === ts.CharacterCodes.carriageReturn) { + break; + } + contextEndPos++; + } + } + } + + let contextString: string; + let contextLineMap: number[]; + let contextStart: ts.LineAndCharacter; + let contextEnd: ts.LineAndCharacter; + let selectionStart: ts.LineAndCharacter; + let selectionEnd: ts.LineAndCharacter; + let lineNumberPrefixLength: number; + if (lineNumbers) { + contextString = file.content; + contextLineMap = ts.computeLineStarts(contextString); + contextStart = ts.computeLineAndCharacterOfPosition(contextLineMap, contextStartPos); + contextEnd = ts.computeLineAndCharacterOfPosition(contextLineMap, contextEndPos); + selectionStart = ts.computeLineAndCharacterOfPosition(contextLineMap, spanInfo.start); + selectionEnd = ts.computeLineAndCharacterOfPosition(contextLineMap, ts.textSpanEnd(spanInfo)); + lineNumberPrefixLength = (contextEnd.line + 1).toString().length + 2; + } + else { + contextString = file.content.substring(contextStartPos, contextEndPos); + contextLineMap = ts.computeLineStarts(contextString); + contextStart = { line: 0, character: 0 }; + contextEnd = { line: contextLineMap.length - 1, character: 0 }; + selectionStart = selection ? ts.computeLineAndCharacterOfPosition(contextLineMap, spanInfo.start - contextStartPos) : contextStart; + selectionEnd = selection ? ts.computeLineAndCharacterOfPosition(contextLineMap, ts.textSpanEnd(spanInfo) - contextStartPos) : contextEnd; + lineNumberPrefixLength = 0; + } + + const output: string[] = []; + for (let lineNumber = contextStart.line; lineNumber <= contextEnd.line; lineNumber++) { + const spanLine = contextString.substring(contextLineMap[lineNumber], contextLineMap[lineNumber + 1]); + output.push(lineNumbers ? `${`${lineNumber + 1}: `.padStart(lineNumberPrefixLength, " ")}${spanLine}` : spanLine); + if (selection) { + if (lineNumber < selectionStart.line || lineNumber > selectionEnd.line) { + continue; + } + + const isEmpty = selectionStart.line === selectionEnd.line && selectionStart.character === selectionEnd.character; + const selectionPadLength = lineNumber === selectionStart.line ? selectionStart.character : 0; + const selectionPad = " ".repeat(selectionPadLength + lineNumberPrefixLength); + const selectionLength = isEmpty ? 0 : Math.max(lineNumber < selectionEnd.line ? spanLine.trimRight().length - selectionPadLength : selectionEnd.character - selectionPadLength, 1); + const selectionLine = isEmpty ? "<" : "^".repeat(selectionLength); + output.push(`${selectionPad}${selectionLine}`); + } + } + return output; + } + + private spanInfoToString(spanInfo: ts.TextSpan, prefixString: string, file: FourSlashFile = this.activeFile) { let resultString = "SpanInfo: " + JSON.stringify(spanInfo); if (spanInfo) { - const spanString = this.activeFile.content.substr(spanInfo.start, spanInfo.length); - const spanLineMap = ts.computeLineStarts(spanString); - for (let i = 0; i < spanLineMap.length; i++) { + const spanLines = this.spanLines(file, spanInfo); + for (let i = 0; i < spanLines.length; i++) { if (!i) { resultString += "\n"; } - resultString += prefixString + spanString.substring(spanLineMap[i], spanLineMap[i + 1]); + resultString += prefixString + spanLines[i]; } - resultString += "\n" + prefixString + ":=> (" + this.getLineColStringAtPosition(spanInfo.start) + ") to (" + this.getLineColStringAtPosition(ts.textSpanEnd(spanInfo)) + ")"; + resultString += "\n" + prefixString + ":=> (" + this.getLineColStringAtPosition(spanInfo.start, file) + ") to (" + this.getLineColStringAtPosition(ts.textSpanEnd(spanInfo), file) + ")"; } return resultString; @@ -1701,13 +1777,13 @@ namespace FourSlash { Harness.IO.log(stringify(help.items[help.selectedItemIndex])); } - private getBaselineFileNameForInternalFourslashFile() { + private getBaselineFileNameForInternalFourslashFile(ext = ".baseline") { return this.testData.globalOptions[MetadataOptionNames.baselineFile] || - ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline"); + ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ext); } - private getBaselineFileNameForContainingTestFile() { - return ts.getBaseFileName(this.originalInputFileName).replace(ts.Extension.Ts, ".baseline"); + private getBaselineFileNameForContainingTestFile(ext = ".baseline") { + return ts.getBaseFileName(this.originalInputFileName).replace(ts.Extension.Ts, ext); } private getSignatureHelp({ triggerReason }: FourSlashInterface.VerifySignatureHelpOptions): ts.SignatureHelpItems | undefined { @@ -3164,6 +3240,131 @@ namespace FourSlash { Harness.IO.log(stringify(codeFixes)); } + private formatCallHierarchyItemSpan(file: FourSlashFile, span: ts.TextSpan, prefix: string, trailingPrefix = prefix) { + const startLc = this.languageServiceAdapterHost.positionToLineAndCharacter(file.fileName, span.start); + const endLc = this.languageServiceAdapterHost.positionToLineAndCharacter(file.fileName, ts.textSpanEnd(span)); + const lines = this.spanLines(file, span, { fullLines: true, lineNumbers: true, selection: true }); + let text = ""; + text += `${prefix}╭ ${file.fileName}:${startLc.line + 1}:${startLc.character + 1}-${endLc.line + 1}:${endLc.character + 1}\n`; + for (const line of lines) { + text += `${prefix}│ ${line.trimRight()}\n`; + } + text += `${trailingPrefix}╰\n`; + return text; + } + + private formatCallHierarchyItemSpans(file: FourSlashFile, spans: ts.TextSpan[], prefix: string, trailingPrefix = prefix) { + let text = ""; + for (let i = 0; i < spans.length; i++) { + text += this.formatCallHierarchyItemSpan(file, spans[i], prefix, i < spans.length - 1 ? prefix : trailingPrefix); + } + return text; + } + + private formatCallHierarchyItem(file: FourSlashFile, callHierarchyItem: ts.CallHierarchyItem, direction: CallHierarchyItemDirection, seen: ts.Map, prefix: string, trailingPrefix: string = prefix) { + const key = `${callHierarchyItem.file}|${JSON.stringify(callHierarchyItem.span)}|${direction}`; + const alreadySeen = seen.has(key); + seen.set(key, true); + + const incomingCalls = + direction === CallHierarchyItemDirection.Outgoing ? { result: "skip" } as const : + alreadySeen ? { result: "seen" } as const : + { result: "show", values: this.languageService.provideCallHierarchyIncomingCalls(callHierarchyItem.file, callHierarchyItem.selectionSpan.start) } as const; + + const outgoingCalls = + direction === CallHierarchyItemDirection.Incoming ? { result: "skip" } as const : + alreadySeen ? { result: "seen" } as const : + { result: "show", values: this.languageService.provideCallHierarchyOutgoingCalls(callHierarchyItem.file, callHierarchyItem.selectionSpan.start) } as const; + + let text = ""; + text += `${prefix}╭ name: ${callHierarchyItem.name}\n`; + text += `${prefix}├ kind: ${callHierarchyItem.kind}\n`; + text += `${prefix}├ file: ${callHierarchyItem.file}\n`; + text += `${prefix}├ span:\n`; + text += this.formatCallHierarchyItemSpan(file, callHierarchyItem.span, `${prefix}│ `); + text += `${prefix}├ selectionSpan:\n`; + text += this.formatCallHierarchyItemSpan(file, callHierarchyItem.selectionSpan, `${prefix}│ `, + incomingCalls.result !== "skip" || outgoingCalls.result !== "skip" ? `${prefix}│ ` : + `${trailingPrefix}╰ `); + + if (incomingCalls.result === "seen") { + if (outgoingCalls.result === "skip") { + text += `${trailingPrefix}╰ incoming: ...\n`; + } + else { + text += `${prefix}├ incoming: ...\n`; + } + } + else if (incomingCalls.result === "show") { + if (!ts.some(incomingCalls.values)) { + if (outgoingCalls.result === "skip") { + text += `${trailingPrefix}╰ incoming: none\n`; + } + else { + text += `${prefix}├ incoming: none\n`; + } + } + else { + text += `${prefix}├ incoming:\n`; + for (let i = 0; i < incomingCalls.values.length; i++) { + const incomingCall = incomingCalls.values[i]; + const file = this.findFile(incomingCall.from.file); + text += `${prefix}│ ╭ from:\n`; + text += this.formatCallHierarchyItem(file, incomingCall.from, CallHierarchyItemDirection.Incoming, seen, `${prefix}│ │ `); + text += `${prefix}│ ├ fromSpans:\n`; + text += this.formatCallHierarchyItemSpans(file, incomingCall.fromSpans, `${prefix}│ │ `, + i < incomingCalls.values.length - 1 ? `${prefix}│ ╰ ` : + outgoingCalls.result !== "skip" ? `${prefix}│ ╰ ` : + `${trailingPrefix}╰ ╰ `); + } + } + } + + if (outgoingCalls.result === "seen") { + text += `${trailingPrefix}╰ outgoing: ...\n`; + } + else if (outgoingCalls.result === "show") { + if (!ts.some(outgoingCalls.values)) { + text += `${trailingPrefix}╰ outgoing: none\n`; + } + else { + text += `${prefix}├ outgoing:\n`; + for (let i = 0; i < outgoingCalls.values.length; i++) { + const outgoingCall = outgoingCalls.values[i]; + text += `${prefix}│ ╭ to:\n`; + text += this.formatCallHierarchyItem(this.findFile(outgoingCall.to.file), outgoingCall.to, CallHierarchyItemDirection.Outgoing, seen, `${prefix}│ │ `); + text += `${prefix}│ ├ fromSpans:\n`; + text += this.formatCallHierarchyItemSpans(file, outgoingCall.fromSpans, `${prefix}│ │ `, + i < outgoingCalls.values.length - 1 ? `${prefix}│ ╰ ` : + `${trailingPrefix}╰ ╰ `); + } + } + } + return text; + } + + private formatCallHierarchy(callHierarchyItem: ts.CallHierarchyItem | undefined) { + let text = ""; + if (callHierarchyItem) { + const file = this.findFile(callHierarchyItem.file); + text += this.formatCallHierarchyItem(file, callHierarchyItem, CallHierarchyItemDirection.Root, ts.createMap(), ""); + } + return text; + } + + public baselineCallHierarchy() { + const baselineFile = this.getBaselineFileNameForContainingTestFile(".callHierarchy.txt"); + const callHierarchyItem = this.languageService.prepareCallHierarchy(this.activeFile.fileName, this.currentCaretPosition); + const text = callHierarchyItem ? ts.mapOneOrMany(callHierarchyItem, item => this.formatCallHierarchy(item), result => result.join("")) : "none"; + Harness.Baseline.runBaseline(baselineFile, text); + } + + private assertTextSpanEqualsRange(span: ts.TextSpan, range: Range, message?: string) { + if (!textSpanEqualsRange(span, range)) { + this.raiseError(`${prefixMessage(message)}Expected to find TextSpan ${JSON.stringify({ start: range.pos, length: range.end - range.pos })} but got ${JSON.stringify(span)} instead.`); + } + } + private getLineContent(index: number) { const text = this.getFileContent(this.activeFile.fileName); const pos = this.languageServiceAdapterHost.lineAndCharacterToPosition(this.activeFile.fileName, { line: index, character: 0 }); @@ -3243,8 +3444,8 @@ namespace FourSlash { return this.tryFindFileWorker(name).file !== undefined; } - private getLineColStringAtPosition(position: number) { - const pos = this.languageServiceAdapterHost.positionToLineAndCharacter(this.activeFile.fileName, position); + private getLineColStringAtPosition(position: number, file: FourSlashFile = this.activeFile) { + const pos = this.languageServiceAdapterHost.positionToLineAndCharacter(file.fileName, position); return `line ${(pos.line + 1)}, col ${pos.character}`; } @@ -3297,6 +3498,14 @@ namespace FourSlash { } } + function prefixMessage(message: string | undefined) { + return message ? `${message} - ` : ""; + } + + function textSpanEqualsRange(span: ts.TextSpan, range: Range) { + return span.start === range.pos && span.length === range.end - range.pos; + } + function updateTextRangeForTextChanges({ pos, end }: ts.TextRange, textChanges: readonly ts.TextChange[]): ts.TextRange { forEachTextChange(textChanges, change => { const update = (p: number): number => updatePosition(p, change.span.start, ts.textSpanEnd(change.span), change.newText); diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index b9edd175aaa28..91ddf5b6293dd 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -541,9 +541,14 @@ namespace FourSlashInterface { this.state.getEditsForFileRename(options); } + public baselineCallHierarchy() { + this.state.baselineCallHierarchy(); + } + public moveToNewFile(options: MoveToNewFileOptions): void { this.state.moveToNewFile(options); } + public noMoveToNewFile(): void { this.state.noMoveToNewFile(); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index c3ba14669bf83..759384aff3875 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -574,6 +574,15 @@ namespace Harness.LanguageService { getEditsForFileRename(): readonly ts.FileTextChanges[] { throw new Error("Not supported on the shim."); } + prepareCallHierarchy(fileName: string, position: number) { + return unwrapJSONCallResult(this.shim.prepareCallHierarchy(fileName, position)); + } + provideCallHierarchyIncomingCalls(fileName: string, position: number) { + return unwrapJSONCallResult(this.shim.provideCallHierarchyIncomingCalls(fileName, position)); + } + provideCallHierarchyOutgoingCalls(fileName: string, position: number) { + return unwrapJSONCallResult(this.shim.provideCallHierarchyOutgoingCalls(fileName, position)); + } getEmitOutput(fileName: string): ts.EmitOutput { return unwrapJSONCallResult(this.shim.getEmitOutput(fileName)); } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 00fce8b14c054..cabe7dcd55dd1 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -4,7 +4,7 @@ * Declaration module describing the TypeScript Server protocol */ namespace ts.server.protocol { - // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. + // NOTE: If updating this, be sure to also update `allCommandNames` in `testRunner/unittests/tsserver/session.ts`. export const enum CommandTypes { JsxClosingTag = "jsxClosingTag", Brace = "brace", @@ -137,7 +137,11 @@ namespace ts.server.protocol { /* @internal */ SelectionRangeFull = "selectionRange-full", - // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. + PrepareCallHierarchy = "prepareCallHierarchy", + ProvideCallHierarchyIncomingCalls = "provideCallHierarchyIncomingCalls", + ProvideCallHierarchyOutgoingCalls = "provideCallHierarchyOutgoingCalls", + + // NOTE: If updating this, be sure to also update `allCommandNames` in `testRunner/unittests/tsserver/session.ts`. } /** @@ -2983,6 +2987,48 @@ namespace ts.server.protocol { body?: NavigationTree; } + export interface CallHierarchyItem { + name: string; + kind: ScriptElementKind; + file: string; + span: TextSpan; + selectionSpan: TextSpan; + } + + export interface CallHierarchyIncomingCall { + from: CallHierarchyItem; + fromSpans: TextSpan[]; + } + + export interface CallHierarchyOutgoingCall { + to: CallHierarchyItem; + fromSpans: TextSpan[]; + } + + export interface PrepareCallHierarchyRequest extends FileLocationRequest { + command: CommandTypes.PrepareCallHierarchy; + } + + export interface PrepareCallHierarchyResponse extends Response { + readonly body: CallHierarchyItem | CallHierarchyItem[]; + } + + export interface ProvideCallHierarchyIncomingCallsRequest extends FileLocationRequest { + command: CommandTypes.ProvideCallHierarchyIncomingCalls; + } + + export interface ProvideCallHierarchyIncomingCallsResponse extends Response { + readonly body: CallHierarchyIncomingCall[]; + } + + export interface ProvideCallHierarchyOutgoingCallsRequest extends FileLocationRequest { + command: CommandTypes.ProvideCallHierarchyOutgoingCalls; + } + + export interface ProvideCallHierarchyOutgoingCallsResponse extends Response { + readonly body: CallHierarchyOutgoingCall[]; + } + export const enum IndentStyle { None = "None", Block = "Block", diff --git a/src/server/session.ts b/src/server/session.ts index a1690aee1802b..0d81e6826b939 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1060,7 +1060,7 @@ namespace ts.server { if (simplifiedResult) { return { definitions: this.mapDefinitionInfo(definitions, project), - textSpan: toProcolTextSpan(textSpan, scriptInfo) + textSpan: toProtocolTextSpan(textSpan, scriptInfo) }; } @@ -1315,7 +1315,7 @@ namespace ts.server { if (info.canRename) { const { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan } = info; return identity( - { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan: toProcolTextSpan(triggerSpan, scriptInfo) }); + { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan: toProtocolTextSpan(triggerSpan, scriptInfo) }); } else { return info; @@ -1415,8 +1415,8 @@ namespace ts.server { if (simplifiedResult) { const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!; return spans.map(s => ({ - textSpan: toProcolTextSpan(s.textSpan, scriptInfo), - hintSpan: toProcolTextSpan(s.hintSpan, scriptInfo), + textSpan: toProtocolTextSpan(s.textSpan, scriptInfo), + hintSpan: toProtocolTextSpan(s.hintSpan, scriptInfo), bannerText: s.bannerText, autoCollapse: s.autoCollapse, kind: s.kind @@ -1605,7 +1605,7 @@ namespace ts.server { const entries = mapDefined(completions.entries, entry => { if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry; - const convertedSpan = replacementSpan ? toProcolTextSpan(replacementSpan, scriptInfo) : undefined; + const convertedSpan = replacementSpan ? toProtocolTextSpan(replacementSpan, scriptInfo) : undefined; // Use `hasAction || undefined` to avoid serializing `false`. return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; } @@ -1775,7 +1775,7 @@ namespace ts.server { text: item.text, kind: item.kind, kindModifiers: item.kindModifiers, - spans: item.spans.map(span => toProcolTextSpan(span, scriptInfo)), + spans: item.spans.map(span => toProtocolTextSpan(span, scriptInfo)), childItems: this.mapLocationNavigationBarItems(item.childItems, scriptInfo), indent: item.indent })); @@ -1796,8 +1796,8 @@ namespace ts.server { text: tree.text, kind: tree.kind, kindModifiers: tree.kindModifiers, - spans: tree.spans.map(span => toProcolTextSpan(span, scriptInfo)), - nameSpan: tree.nameSpan && toProcolTextSpan(tree.nameSpan, scriptInfo), + spans: tree.spans.map(span => toProtocolTextSpan(span, scriptInfo)), + nameSpan: tree.nameSpan && toProtocolTextSpan(tree.nameSpan, scriptInfo), childItems: map(tree.childItems, item => this.toLocationNavigationTree(item, scriptInfo)) }; } @@ -2059,7 +2059,7 @@ namespace ts.server { return !spans ? undefined : simplifiedResult - ? spans.map(span => toProcolTextSpan(span, scriptInfo)) + ? spans.map(span => toProtocolTextSpan(span, scriptInfo)) : spans; } @@ -2131,7 +2131,7 @@ namespace ts.server { private mapSelectionRange(selectionRange: SelectionRange, scriptInfo: ScriptInfo): protocol.SelectionRange { const result: protocol.SelectionRange = { - textSpan: toProcolTextSpan(selectionRange.textSpan, scriptInfo), + textSpan: toProtocolTextSpan(selectionRange.textSpan, scriptInfo), }; if (selectionRange.parent) { result.parent = this.mapSelectionRange(selectionRange.parent, scriptInfo); @@ -2139,6 +2139,71 @@ namespace ts.server { return result; } + private toProtocolCallHierarchyItem(item: CallHierarchyItem, scriptInfo?: ScriptInfo): protocol.CallHierarchyItem { + if (!scriptInfo) { + const file = toNormalizedPath(item.file); + scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); + if (!scriptInfo) { + this.projectService.logErrorForScriptInfoNotFound(file); + return Errors.ThrowNoProject(); + } + } + return { + name: item.name, + kind: item.kind, + file: item.file, + span: toProtocolTextSpan(item.span, scriptInfo), + selectionSpan: toProtocolTextSpan(item.selectionSpan, scriptInfo) + }; + } + + private toProtocolCallHierarchyIncomingCall(incomingCall: CallHierarchyIncomingCall, scriptInfo: ScriptInfo): protocol.CallHierarchyIncomingCall { + return { + from: this.toProtocolCallHierarchyItem(incomingCall.from), + fromSpans: incomingCall.fromSpans.map(fromSpan => toProtocolTextSpan(fromSpan, scriptInfo)) + }; + } + + private toProtocolCallHierarchyOutgoingCall(outgoingCall: CallHierarchyOutgoingCall, scriptInfo: ScriptInfo): protocol.CallHierarchyOutgoingCall { + return { + to: this.toProtocolCallHierarchyItem(outgoingCall.to), + fromSpans: outgoingCall.fromSpans.map(fromSpan => toProtocolTextSpan(fromSpan, scriptInfo)) + }; + } + + private prepareCallHierarchy(args: protocol.FileLocationRequestArgs): protocol.CallHierarchyItem | protocol.CallHierarchyItem[] | undefined { + const { file, project } = this.getFileAndProject(args); + const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); + if (scriptInfo) { + const position = this.getPosition(args, scriptInfo); + const result = project.getLanguageService().prepareCallHierarchy(file, position); + return result && mapOneOrMany(result, item => this.toProtocolCallHierarchyItem(item, scriptInfo)); + } + return undefined; + } + + private provideCallHierarchyIncomingCalls(args: protocol.FileLocationRequestArgs): protocol.CallHierarchyIncomingCall[] { + const { file, project } = this.getFileAndProject(args); + const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); + if (!scriptInfo) { + this.projectService.logErrorForScriptInfoNotFound(file); + return Errors.ThrowNoProject(); + } + const incomingCalls = project.getLanguageService().provideCallHierarchyIncomingCalls(file, this.getPosition(args, scriptInfo)); + return incomingCalls.map(call => this.toProtocolCallHierarchyIncomingCall(call, scriptInfo)); + } + + private provideCallHierarchyOutgoingCalls(args: protocol.FileLocationRequestArgs): protocol.CallHierarchyOutgoingCall[] { + const { file, project } = this.getFileAndProject(args); + const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); + if (!scriptInfo) { + this.projectService.logErrorForScriptInfoNotFound(file); + return Errors.ThrowNoProject(); + } + const outgoingCalls = project.getLanguageService().provideCallHierarchyOutgoingCalls(file, this.getPosition(args, scriptInfo)); + return outgoingCalls.map(call => this.toProtocolCallHierarchyOutgoingCall(call, scriptInfo)); + } + getCanonicalFileName(fileName: string) { const name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); return normalizePath(name); @@ -2504,6 +2569,15 @@ namespace ts.server { [CommandNames.SelectionRangeFull]: (request: protocol.SelectionRangeRequest) => { return this.requiredResponse(this.getSmartSelectionRange(request.arguments, /*simplifiedResult*/ false)); }, + [CommandNames.PrepareCallHierarchy]: (request: protocol.PrepareCallHierarchyRequest) => { + return this.requiredResponse(this.prepareCallHierarchy(request.arguments)); + }, + [CommandNames.ProvideCallHierarchyIncomingCalls]: (request: protocol.ProvideCallHierarchyIncomingCallsRequest) => { + return this.requiredResponse(this.provideCallHierarchyIncomingCalls(request.arguments)); + }, + [CommandNames.ProvideCallHierarchyOutgoingCalls]: (request: protocol.ProvideCallHierarchyOutgoingCallsRequest) => { + return this.requiredResponse(this.provideCallHierarchyOutgoingCalls(request.arguments)); + }, }); public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) { @@ -2627,7 +2701,7 @@ namespace ts.server { readonly project: Project; } - function toProcolTextSpan(textSpan: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + function toProtocolTextSpan(textSpan: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { return { start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) @@ -2635,8 +2709,8 @@ namespace ts.server { } function toProtocolTextSpanWithContext(span: TextSpan, contextSpan: TextSpan | undefined, scriptInfo: ScriptInfo): protocol.TextSpanWithContext { - const textSpan = toProcolTextSpan(span, scriptInfo); - const contextTextSpan = contextSpan && toProcolTextSpan(contextSpan, scriptInfo); + const textSpan = toProtocolTextSpan(span, scriptInfo); + const contextTextSpan = contextSpan && toProtocolTextSpan(contextSpan, scriptInfo); return contextTextSpan ? { ...textSpan, contextStart: contextTextSpan.start, contextEnd: contextTextSpan.end } : textSpan; diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts new file mode 100644 index 0000000000000..838f9355d3dca --- /dev/null +++ b/src/services/callHierarchy.ts @@ -0,0 +1,485 @@ +/* @internal */ +namespace ts.CallHierarchy { + export type NamedExpression = + | ClassExpression & { name: Identifier } + | FunctionExpression & { name: Identifier } + ; + + /** Indictates whether a node is named function or class expression. */ + function isNamedExpression(node: Node): node is NamedExpression { + return (isFunctionExpression(node) || isClassExpression(node)) && isNamedDeclaration(node); + } + + export type ConstNamedExpression = + | ClassExpression & { name: undefined, parent: VariableDeclaration & { name: Identifier } } + | FunctionExpression & { name: undefined, parent: VariableDeclaration & { name: Identifier } } + | ArrowFunction & { name: undefined, parent: VariableDeclaration & { name: Identifier } } + ; + + /** Indicates whether a node is a function, arrow, or class expression assigned to a constant variable. */ + function isConstNamedExpression(node: Node): node is ConstNamedExpression { + return (isFunctionExpression(node) || isArrowFunction(node) || isClassExpression(node)) + && isVariableDeclaration(node.parent) + && node === node.parent.initializer + && isIdentifier(node.parent.name) + && !!(getCombinedNodeFlags(node.parent) & NodeFlags.Const); + } + + export type CallHierarchyDeclaration = + | SourceFile + | ModuleDeclaration & { name: Identifier } + | FunctionDeclaration + | ClassDeclaration + | MethodDeclaration + | GetAccessorDeclaration + | SetAccessorDeclaration + | NamedExpression + | ConstNamedExpression + ; + + /** + * Indicates whether a node could possibly be a call hierarchy declaration. + * + * See `resolveCallHierarchyDeclaration` for the specific rules. + */ + function isPossibleCallHierarchyDeclaration(node: Node) { + return isSourceFile(node) + || isModuleDeclaration(node) + || isFunctionDeclaration(node) + || isFunctionExpression(node) + || isClassDeclaration(node) + || isClassExpression(node) + || isMethodDeclaration(node) + || isMethodSignature(node) + || isGetAccessorDeclaration(node) + || isSetAccessorDeclaration(node); + } + + /** + * Indicates whether a node is a valid a call hierarchy declaration. + * + * See `resolveCallHierarchyDeclaration` for the specific rules. + */ + function isValidCallHierarchyDeclaration(node: Node): node is CallHierarchyDeclaration { + return isSourceFile(node) + || isModuleDeclaration(node) && isIdentifier(node.name) + || isFunctionDeclaration(node) + || isClassDeclaration(node) + || isMethodDeclaration(node) + || isMethodSignature(node) + || isGetAccessorDeclaration(node) + || isSetAccessorDeclaration(node) + || isNamedExpression(node) + || isConstNamedExpression(node); + } + + /** Gets the node that can be used as a reference to a call hierarchy declaration. */ + function getCallHierarchyDeclarationReferenceNode(node: CallHierarchyDeclaration) { + if (isSourceFile(node)) return node; + if (isNamedDeclaration(node)) return node.name; + if (isConstNamedExpression(node)) return node.parent.name; + return Debug.assertDefined(node.modifiers && find(node.modifiers, isDefaultModifier)); + } + + function isDefaultModifier(node: Node) { + return node.kind === SyntaxKind.DefaultKeyword; + } + + /** Gets the symbol for a call hierarchy declaration. */ + function getSymbolOfCallHierarchyDeclaration(typeChecker: TypeChecker, node: CallHierarchyDeclaration) { + const location = getCallHierarchyDeclarationReferenceNode(node); + return location && typeChecker.getSymbolAtLocation(location); + } + + /** Gets the text and range for the name of a call hierarchy declaration. */ + function getCallHierarchyItemName(program: Program, node: CallHierarchyDeclaration): { text: string, pos: number, end: number } { + if (isSourceFile(node)) { + return { text: node.fileName, pos: 0, end: 0 }; + } + + if ((isFunctionDeclaration(node) || isClassDeclaration(node)) && !isNamedDeclaration(node)) { + const defaultModifier = node.modifiers && find(node.modifiers, isDefaultModifier); + if (defaultModifier) { + return { text: "default", pos: defaultModifier.getStart(), end: defaultModifier.getEnd() }; + } + } + + const declName = isConstNamedExpression(node) ? node.parent.name : + Debug.assertDefined(getNameOfDeclaration(node), "Expected call hierarchy item to have a name"); + + let text = + isIdentifier(declName) ? idText(declName) : + isStringOrNumericLiteralLike(declName) ? declName.text : + isComputedPropertyName(declName) ? + isStringOrNumericLiteralLike(declName.expression) ? declName.expression.text : + undefined : + undefined; + if (text === undefined) { + const typeChecker = program.getTypeChecker(); + const symbol = typeChecker.getSymbolAtLocation(declName); + if (symbol) { + text = typeChecker.symbolToString(symbol, node); + } + } + if (text === undefined) { + // get the text from printing the node on a single line without comments... + const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + text = usingSingleLineStringWriter(writer => printer.writeNode(EmitHint.Unspecified, node, node.getSourceFile(), writer)); + } + return { text, pos: declName.getStart(), end: declName.getEnd() }; + } + + /** Finds the implementation of a function-like declaration, if one exists. */ + function findImplementation(typeChecker: TypeChecker, node: Extract): Extract | undefined; + function findImplementation(typeChecker: TypeChecker, node: FunctionLikeDeclaration): FunctionLikeDeclaration | undefined; + function findImplementation(typeChecker: TypeChecker, node: FunctionLikeDeclaration): FunctionLikeDeclaration | undefined { + if (node.body) { + return node; + } + if (isConstructorDeclaration(node)) { + return getFirstConstructorWithBody(node.parent); + } + if (isFunctionDeclaration(node) || isMethodDeclaration(node)) { + const symbol = getSymbolOfCallHierarchyDeclaration(typeChecker, node); + if (symbol && symbol.valueDeclaration && isFunctionLikeDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.body) { + return symbol.valueDeclaration; + } + return undefined; + } + return node; + } + + function findAllInitialDeclarations(typeChecker: TypeChecker, node: CallHierarchyDeclaration) { + const symbol = getSymbolOfCallHierarchyDeclaration(typeChecker, node); + let declarations: CallHierarchyDeclaration[] | undefined; + if (symbol && symbol.declarations) { + const indices = indicesOf(symbol.declarations); + const keys = map(symbol.declarations, decl => ({ file: decl.getSourceFile().fileName, pos: decl.pos })); + indices.sort((a, b) => compareStringsCaseSensitive(keys[a].file, keys[b].file) || keys[a].pos - keys[b].pos); + const sortedDeclarations = map(indices, i => symbol.declarations[i]); + let lastDecl: CallHierarchyDeclaration | undefined; + for (const decl of sortedDeclarations) { + if (isValidCallHierarchyDeclaration(decl)) { + if (!lastDecl || lastDecl.parent !== decl.parent || lastDecl.end !== decl.pos) { + declarations = append(declarations, decl); + } + lastDecl = decl; + } + } + } + return declarations; + } + + /** Find the implementation or the first declaration for a call hierarchy declaration. */ + function findImplementationOrAllInitialDeclarations(typeChecker: TypeChecker, node: CallHierarchyDeclaration): CallHierarchyDeclaration | CallHierarchyDeclaration[] { + if (isFunctionLikeDeclaration(node)) { + return findImplementation(typeChecker, node) ?? + findAllInitialDeclarations(typeChecker, node) ?? + node; + } + return findAllInitialDeclarations(typeChecker, node) ?? node; + } + + /** Resolves the call hierarchy declaration for a node. */ + export function resolveCallHierarchyDeclaration(program: Program, location: Node): CallHierarchyDeclaration | CallHierarchyDeclaration[] | undefined { + // A call hierarchy item must refer to either a SourceFile, Module Declaration, or something intrinsically callable that has a name: + // - Class Declarations + // - Class Expressions (with a name) + // - Function Declarations + // - Function Expressions (with a name or assigned to a const variable) + // - Arrow Functions (assigned to a const variable) + // - Constructors + // - Methods + // - Accessors + // + // If a call is contained in a non-named callable Node (function expression, arrow function, etc.), then + // its containing `CallHierarchyItem` is a containing function or SourceFile that matches the above list. + + const typeChecker = program.getTypeChecker(); + let followingSymbol = false; + while (true) { + if (isValidCallHierarchyDeclaration(location)) { + return findImplementationOrAllInitialDeclarations(typeChecker, location); + } + if (isPossibleCallHierarchyDeclaration(location)) { + const ancestor = findAncestor(location, isValidCallHierarchyDeclaration); + return ancestor && findImplementationOrAllInitialDeclarations(typeChecker, ancestor); + } + if (isDeclarationName(location)) { + if (isValidCallHierarchyDeclaration(location.parent)) { + return findImplementationOrAllInitialDeclarations(typeChecker, location.parent); + } + if (isPossibleCallHierarchyDeclaration(location.parent)) { + const ancestor = findAncestor(location.parent, isValidCallHierarchyDeclaration); + return ancestor && findImplementationOrAllInitialDeclarations(typeChecker, ancestor); + } + if (isVariableDeclaration(location.parent) && location.parent.initializer && isConstNamedExpression(location.parent.initializer)) { + return location.parent.initializer; + } + return undefined; + } + if (isConstructorDeclaration(location)) { + if (isValidCallHierarchyDeclaration(location.parent)) { + return location.parent; + } + return undefined; + } + if (!followingSymbol) { + let symbol = typeChecker.getSymbolAtLocation(location); + if (symbol) { + if (symbol.flags & SymbolFlags.Alias) { + symbol = typeChecker.getAliasedSymbol(symbol); + } + if (symbol.valueDeclaration) { + followingSymbol = true; + location = symbol.valueDeclaration; + continue; + } + } + } + return undefined; + } + } + + /** Creates a `CallHierarchyItem` for a call hierarchy declaration. */ + export function createCallHierarchyItem(program: Program, node: CallHierarchyDeclaration): CallHierarchyItem { + const sourceFile = node.getSourceFile(); + const name = getCallHierarchyItemName(program, node); + const kind = getNodeKind(node); + const span = createTextSpanFromBounds(skipTrivia(sourceFile.text, node.getFullStart(), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true), node.getEnd()); + const selectionSpan = createTextSpanFromBounds(name.pos, name.end); + return { file: sourceFile.fileName, kind, name: name.text, span, selectionSpan }; + } + + function isDefined(x: T): x is NonNullable { + return x !== undefined; + } + + interface CallSite { + declaration: CallHierarchyDeclaration; + range: TextRange; + } + + function convertEntryToCallSite(entry: FindAllReferences.Entry, _originalNode: Node, typeChecker: TypeChecker): CallSite | undefined { + if (entry.kind === FindAllReferences.EntryKind.Node) { + if (isCallOrNewExpressionTarget(entry.node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true) + || isTaggedTemplateTag(entry.node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true) + || isDecoratorTarget(entry.node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true) + || isJsxOpeningLikeElementTagName(entry.node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true) + || isRightSideOfPropertyAccess(entry.node) + || isArgumentExpressionOfElementAccess(entry.node)) { + const ancestor = findAncestor(entry.node, isValidCallHierarchyDeclaration) || entry.node.getSourceFile(); + return { declaration: firstOrOnly(findImplementationOrAllInitialDeclarations(typeChecker, ancestor)), range: createTextRangeFromNode(entry.node, entry.node.getSourceFile()) }; + } + } + } + + function getCallSiteGroupKey(entry: CallSite) { + return "" + getNodeId(entry.declaration); + } + + function createCallHierarchyIncomingCall(from: CallHierarchyItem, fromSpans: TextSpan[]): CallHierarchyIncomingCall { + return { from, fromSpans }; + } + + function convertCallSiteGroupToIncomingCall(program: Program, entries: readonly CallSite[]) { + return createCallHierarchyIncomingCall(createCallHierarchyItem(program, entries[0].declaration), map(entries, entry => createTextSpanFromRange(entry.range))); + } + + /** Gets the call sites that call into the provided call hierarchy declaration. */ + export function getIncomingCalls(program: Program, declaration: CallHierarchyDeclaration, cancellationToken: CancellationToken): CallHierarchyIncomingCall[] { + // Source files and modules have no incoming calls. + if (isSourceFile(declaration) || isModuleDeclaration(declaration)) { + return []; + } + const location = getCallHierarchyDeclarationReferenceNode(declaration); + const calls = filter(FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, program.getSourceFiles(), location, /*position*/ 0, /*options*/ undefined, convertEntryToCallSite), isDefined); + return calls ? group(calls, getCallSiteGroupKey, entries => convertCallSiteGroupToIncomingCall(program, entries)) : []; + } + + function createCallSiteCollector(program: Program, callSites: CallSite[]): (node: Node | undefined) => void { + function recordCallSite(node: CallExpression | NewExpression | TaggedTemplateExpression | PropertyAccessExpression | ElementAccessExpression | Decorator | JsxOpeningLikeElement) { + const target = + isTaggedTemplateExpression(node) ? node.tag : + isJsxOpeningLikeElement(node) ? node.tagName : + isAccessExpression(node) ? node : + node.expression; + const declaration = resolveCallHierarchyDeclaration(program, target); + if (declaration) { + const range = createTextRangeFromNode(target, node.getSourceFile()); + if (isArray(declaration)) { + for (const decl of declaration) { + callSites.push({ declaration: decl, range }); + } + } + else { + callSites.push({ declaration, range }); + } + } + } + + function collect(node: Node | undefined) { + if (!node) return; + if (node.flags & NodeFlags.Ambient) { + // do not descend into ambient nodes. + return; + } + + if (isValidCallHierarchyDeclaration(node)) { + // do not descend into other call site declarations, other than class member names + if (isClassLike(node)) { + for (const member of node.members) { + if (member.name && isComputedPropertyName(member.name)) { + collect(member.name.expression); + } + } + } + return; + } + + switch (node.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ExportDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.TypeAliasDeclaration: + // do not descend into nodes that cannot contain callable nodes + return; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + // do not descend into the type side of an assertion + collect((node as TypeAssertion | AsExpression).expression); + return; + case SyntaxKind.VariableDeclaration: + case SyntaxKind.Parameter: + // do not descend into the type of a variable or parameter declaration + collect((node as VariableDeclaration | ParameterDeclaration).name); + collect((node as VariableDeclaration | ParameterDeclaration).initializer); + return; + case SyntaxKind.CallExpression: + // do not descend into the type arguments of a call expression + recordCallSite(node as CallExpression); + collect((node as CallExpression).expression); + forEach((node as CallExpression).arguments, collect); + return; + case SyntaxKind.NewExpression: + // do not descend into the type arguments of a new expression + recordCallSite(node as NewExpression); + collect((node as NewExpression).expression); + forEach((node as NewExpression).arguments, collect); + return; + case SyntaxKind.TaggedTemplateExpression: + // do not descend into the type arguments of a tagged template expression + recordCallSite(node as TaggedTemplateExpression); + collect((node as TaggedTemplateExpression).tag); + collect((node as TaggedTemplateExpression).template); + return; + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxSelfClosingElement: + // do not descend into the type arguments of a JsxOpeningLikeElement + recordCallSite(node as JsxOpeningLikeElement); + collect((node as JsxOpeningLikeElement).tagName); + collect((node as JsxOpeningLikeElement).attributes); + return; + case SyntaxKind.Decorator: + recordCallSite(node as Decorator); + collect((node as Decorator).expression); + return; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + recordCallSite(node as AccessExpression); + forEachChild(node, collect); + break; + } + + if (isPartOfTypeNode(node)) { + // do not descend into types + return; + } + + forEachChild(node, collect); + } + return collect; + } + + function collectCallSitesOfSourceFile(node: SourceFile, collect: (node: Node | undefined) => void) { + forEach(node.statements, collect); + } + + function collectCallSitesOfModuleDeclaration(node: ModuleDeclaration, collect: (node: Node | undefined) => void) { + if (!hasModifier(node, ModifierFlags.Ambient) && node.body && isModuleBlock(node.body)) { + forEach(node.body.statements, collect); + } + } + + function collectCallSitesOfFunctionLikeDeclaration(typeChecker: TypeChecker, node: FunctionLikeDeclaration, collect: (node: Node | undefined) => void) { + const implementation = findImplementation(typeChecker, node); + if (implementation) { + forEach(implementation.parameters, collect); + collect(implementation.body); + } + } + + function collectCallSitesOfClassLikeDeclaration(node: ClassLikeDeclaration, collect: (node: Node | undefined) => void) { + forEach(node.decorators, collect); + const heritage = getClassExtendsHeritageElement(node); + if (heritage) { + collect(heritage.expression); + } + for (const member of node.members) { + forEach(member.decorators, collect); + if (isPropertyDeclaration(member)) { + collect(member.initializer); + } + else if (isConstructorDeclaration(member) && member.body) { + forEach(member.parameters, collect); + collect(member.body); + } + } + } + + function collectCallSites(program: Program, node: CallHierarchyDeclaration) { + const callSites: CallSite[] = []; + const collect = createCallSiteCollector(program, callSites); + switch (node.kind) { + case SyntaxKind.SourceFile: + collectCallSitesOfSourceFile(node, collect); + break; + case SyntaxKind.ModuleDeclaration: + collectCallSitesOfModuleDeclaration(node, collect); + break; + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + collectCallSitesOfFunctionLikeDeclaration(program.getTypeChecker(), node, collect); + break; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + collectCallSitesOfClassLikeDeclaration(node, collect); + break; + default: + Debug.assertNever(node); + } + return callSites; + } + + function createCallHierarchyOutgoingCall(to: CallHierarchyItem, fromSpans: TextSpan[]): CallHierarchyOutgoingCall { + return { to, fromSpans }; + } + + function convertCallSiteGroupToOutgoingCall(program: Program, entries: readonly CallSite[]) { + return createCallHierarchyOutgoingCall(createCallHierarchyItem(program, entries[0].declaration), map(entries, entry => createTextSpanFromRange(entry.range))); + } + + /** Gets the call sites that call out of the provided call hierarchy declaration. */ + export function getOutgoingCalls(program: Program, declaration: CallHierarchyDeclaration): CallHierarchyOutgoingCall[] { + if (declaration.flags & NodeFlags.Ambient || isMethodSignature(declaration)) { + return []; + } + return group(collectCallSites(program, declaration), getCallSiteGroupKey, entries => convertCallSiteGroupToOutgoingCall(program, entries)); + } +} \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index d43a288f90c7e..71159e71973fc 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2137,6 +2137,26 @@ namespace ts { return refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, preferences, formatOptions), refactorName, actionName); } + function prepareCallHierarchy(fileName: string, position: number): CallHierarchyItem | CallHierarchyItem[] | undefined { + synchronizeHostData(); + const declarations = CallHierarchy.resolveCallHierarchyDeclaration(program, getTouchingPropertyName(getValidSourceFile(fileName), position)); + return declarations && mapOneOrMany(declarations, declaration => CallHierarchy.createCallHierarchyItem(program, declaration)); + } + + function provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[] { + synchronizeHostData(); + const sourceFile = getValidSourceFile(fileName); + const declaration = firstOrOnly(CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : getTouchingPropertyName(sourceFile, position))); + return declaration ? CallHierarchy.getIncomingCalls(program, declaration, cancellationToken) : []; + } + + function provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[] { + synchronizeHostData(); + const sourceFile = getValidSourceFile(fileName); + const declaration = firstOrOnly(CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : getTouchingPropertyName(sourceFile, position))); + return declaration ? CallHierarchy.getOutgoingCalls(program, declaration) : []; + } + return { dispose, cleanupSemanticCache, @@ -2192,6 +2212,9 @@ namespace ts { getEditsForRefactor, toLineColumnOffset: sourceMapper.toLineColumnOffset, getSourceMapper: () => sourceMapper, + prepareCallHierarchy, + provideCallHierarchyIncomingCalls, + provideCallHierarchyOutgoingCalls }; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 66203e09996dd..58b655ef0a3ea 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -271,6 +271,10 @@ namespace ts { */ getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): string; + prepareCallHierarchy(fileName: string, position: number): string; + provideCallHierarchyIncomingCalls(fileName: string, position: number): string; + provideCallHierarchyOutgoingCalls(fileName: string, position: number): string; + getEmitOutput(fileName: string): string; getEmitOutputObject(fileName: string): EmitOutput; } @@ -1020,6 +1024,29 @@ namespace ts { ); } + /// CALL HIERARCHY + + public prepareCallHierarchy(fileName: string, position: number): string { + return this.forwardJSONCall( + `prepareCallHierarchy('${fileName}', ${position})`, + () => this.languageService.prepareCallHierarchy(fileName, position) + ); + } + + public provideCallHierarchyIncomingCalls(fileName: string, position: number): string { + return this.forwardJSONCall( + `provideCallHierarchyIncomingCalls('${fileName}', ${position})`, + () => this.languageService.provideCallHierarchyIncomingCalls(fileName, position) + ); + } + + public provideCallHierarchyOutgoingCalls(fileName: string, position: number): string { + return this.forwardJSONCall( + `provideCallHierarchyOutgoingCalls('${fileName}', ${position})`, + () => this.languageService.provideCallHierarchyOutgoingCalls(fileName, position) + ); + } + /// Emit public getEmitOutput(fileName: string): string { return this.forwardJSONCall( diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index f3cf70f353acf..674b0076848d4 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -18,6 +18,7 @@ "documentRegistry.ts", "importTracker.ts", "findAllReferences.ts", + "callHierarchy.ts", "getEditsForFileRename.ts", "goToDefinition.ts", "jsDoc.ts", diff --git a/src/services/types.ts b/src/services/types.ts index 88ab07698bee0..bb953e5f3902d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -351,6 +351,10 @@ namespace ts { getNavigationBarItems(fileName: string): NavigationBarItem[]; getNavigationTree(fileName: string): NavigationTree; + prepareCallHierarchy(fileName: string, position: number): CallHierarchyItem | CallHierarchyItem[] | undefined; + provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[]; + provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; + getOutliningSpans(fileName: string): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; @@ -522,6 +526,24 @@ namespace ts { childItems?: NavigationTree[]; } + export interface CallHierarchyItem { + name: string; + kind: ScriptElementKind; + file: string; + span: TextSpan; + selectionSpan: TextSpan; + } + + export interface CallHierarchyIncomingCall { + from: CallHierarchyItem; + fromSpans: TextSpan[]; + } + + export interface CallHierarchyOutgoingCall { + to: CallHierarchyItem; + fromSpans: TextSpan[]; + } + export interface TodoCommentDescriptor { text: string; priority: number; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 6a1f621bb9ca6..bb10faa8179ab 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -196,27 +196,58 @@ namespace ts { return false; } - export function isCallExpressionTarget(node: Node): boolean { - return isCallOrNewExpressionTargetWorker(node, isCallExpression); + export function isCallExpressionTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, isCallExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); } - export function isNewExpressionTarget(node: Node): boolean { - return isCallOrNewExpressionTargetWorker(node, isNewExpression); + export function isNewExpressionTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, isNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); } - export function isCallOrNewExpressionTarget(node: Node): boolean { - return isCallOrNewExpressionTargetWorker(node, isCallOrNewExpression); + export function isCallOrNewExpressionTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, isCallOrNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); } - function isCallOrNewExpressionTargetWorker(node: Node, pred: (node: Node) => node is T): boolean { - const target = climbPastPropertyAccess(node); - return !!target && !!target.parent && pred(target.parent) && target.parent.expression === target; + export function isTaggedTemplateTag(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, isTaggedTemplateExpression, selectTagOfTaggedTemplateExpression, includeElementAccess, skipPastOuterExpressions); + } + + export function isDecoratorTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, isDecorator, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); + } + + export function isJsxOpeningLikeElementTagName(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, isJsxOpeningLikeElement, selectTagNameOfJsxOpeningLikeElement, includeElementAccess, skipPastOuterExpressions); + } + + function selectExpressionOfCallOrNewExpressionOrDecorator(node: CallExpression | NewExpression | Decorator) { + return node.expression; + } + + function selectTagOfTaggedTemplateExpression(node: TaggedTemplateExpression) { + return node.tag; + } + + function selectTagNameOfJsxOpeningLikeElement(node: JsxOpeningLikeElement) { + return node.tagName; + } + + function isCalleeWorker(node: Node, pred: (node: Node) => node is T, calleeSelector: (node: T) => Expression, includeElementAccess: boolean, skipPastOuterExpressions: boolean) { + let target = includeElementAccess ? climbPastPropertyOrElementAccess(node) : climbPastPropertyAccess(node); + if (skipPastOuterExpressions) { + target = skipOuterExpressions(target); + } + return !!target && !!target.parent && pred(target.parent) && calleeSelector(target.parent) === target; } export function climbPastPropertyAccess(node: Node) { return isRightSideOfPropertyAccess(node) ? node.parent : node; } + export function climbPastPropertyOrElementAccess(node: Node) { + return isRightSideOfPropertyAccess(node) || isArgumentExpressionOfElementAccess(node) ? node.parent : node; + } + export function getTargetLabel(referenceNode: Node, labelName: string): Identifier | undefined { while (referenceNode) { if (referenceNode.kind === SyntaxKind.LabeledStatement && (referenceNode).label.escapedText === labelName) { @@ -236,11 +267,11 @@ namespace ts { } export function isJumpStatementTarget(node: Node): node is Identifier & { parent: BreakOrContinueStatement } { - return node.kind === SyntaxKind.Identifier && isBreakOrContinueStatement(node.parent) && node.parent.label === node; + return isIdentifier(node) && tryCast(node.parent, isBreakOrContinueStatement)?.label === node; } export function isLabelOfLabeledStatement(node: Node): node is Identifier { - return node.kind === SyntaxKind.Identifier && isLabeledStatement(node.parent) && node.parent.label === node; + return isIdentifier(node) && tryCast(node.parent, isLabeledStatement)?.label === node; } export function isLabelName(node: Node): boolean { @@ -248,24 +279,27 @@ namespace ts { } export function isTagName(node: Node): boolean { - return isJSDocTag(node.parent) && node.parent.tagName === node; + return tryCast(node.parent, isJSDocTag)?.tagName === node; } export function isRightSideOfQualifiedName(node: Node) { - return node.parent.kind === SyntaxKind.QualifiedName && (node.parent).right === node; + return tryCast(node.parent, isQualifiedName)?.right === node; } export function isRightSideOfPropertyAccess(node: Node) { - return node && node.parent && node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).name === node; + return tryCast(node.parent, isPropertyAccessExpression)?.name === node; + } + + export function isArgumentExpressionOfElementAccess(node: Node) { + return tryCast(node.parent, isElementAccessExpression)?.argumentExpression === node; } export function isNameOfModuleDeclaration(node: Node) { - return node.parent.kind === SyntaxKind.ModuleDeclaration && (node.parent).name === node; + return tryCast(node.parent, isModuleDeclaration)?.name === node; } export function isNameOfFunctionDeclaration(node: Node): boolean { - return node.kind === SyntaxKind.Identifier && - isFunctionLike(node.parent) && (node.parent).name === node; + return isIdentifier(node) && tryCast(node.parent, isFunctionLike)?.name === node; } export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral | NoSubstitutionTemplateLiteral): boolean { @@ -2298,4 +2332,23 @@ namespace ts { export function getRefactorContextSpan({ startPosition, endPosition }: RefactorContext): TextSpan { return createTextSpanFromBounds(startPosition, endPosition === undefined ? startPosition : endPosition); } -} \ No newline at end of file + + /** + * If the provided value is an array, the mapping function is applied to each element; otherwise, the mapping function is applied + * to the provided value itself. + */ + export function mapOneOrMany(valueOrArray: T | readonly T[], f: (x: T, i: number) => U): U | U[]; + export function mapOneOrMany(valueOrArray: T | readonly T[] | undefined, f: (x: T, i: number) => U): U | U[] | undefined; + export function mapOneOrMany(valueOrArray: T | readonly T[], f: (x: T, i: number) => U, resultSelector: (x: U[]) => U): U; + export function mapOneOrMany(valueOrArray: T | readonly T[] | undefined, f: (x: T, i: number) => U, resultSelector: (x: U[]) => U): U | undefined; + export function mapOneOrMany(valueOrArray: T | readonly T[] | undefined, f: (x: T, i: number) => U, resultSelector: (x: U[]) => U | U[] = identity): U | U[] | undefined { + return valueOrArray ? isArray(valueOrArray) ? resultSelector(map(valueOrArray, f)) : f(valueOrArray, 0) : undefined; + } + + /** + * If the provided value is an array, the first element of the array is returned; otherwise, the provided value is returned instead. + */ + export function firstOrOnly(valueOrArray: T | readonly T[]): T { + return isArray(valueOrArray) ? first(valueOrArray) : valueOrArray; + } +} diff --git a/src/testRunner/unittests/tsserver/session.ts b/src/testRunner/unittests/tsserver/session.ts index 61ce6001c2d51..56ef9d77634d0 100644 --- a/src/testRunner/unittests/tsserver/session.ts +++ b/src/testRunner/unittests/tsserver/session.ts @@ -267,6 +267,9 @@ namespace ts.server { CommandNames.GetEditsForFileRename, CommandNames.GetEditsForFileRenameFull, CommandNames.SelectionRange, + CommandNames.PrepareCallHierarchy, + CommandNames.ProvideCallHierarchyIncomingCalls, + CommandNames.ProvideCallHierarchyOutgoingCalls, ]; it("should not throw when commands are executed with invalid arguments", () => { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 2882282973f97..b4621798c73d3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5113,6 +5113,9 @@ declare namespace ts { getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string, excludeDtsFiles?: boolean): NavigateToItem[]; getNavigationBarItems(fileName: string): NavigationBarItem[]; getNavigationTree(fileName: string): NavigationTree; + prepareCallHierarchy(fileName: string, position: number): CallHierarchyItem | CallHierarchyItem[] | undefined; + provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[]; + provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; getOutliningSpans(fileName: string): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; @@ -5252,6 +5255,21 @@ declare namespace ts { /** Present if non-empty */ childItems?: NavigationTree[]; } + interface CallHierarchyItem { + name: string; + kind: ScriptElementKind; + file: string; + span: TextSpan; + selectionSpan: TextSpan; + } + interface CallHierarchyIncomingCall { + from: CallHierarchyItem; + fromSpans: TextSpan[]; + } + interface CallHierarchyOutgoingCall { + to: CallHierarchyItem; + fromSpans: TextSpan[]; + } interface TodoCommentDescriptor { text: string; priority: number; @@ -6113,6 +6131,9 @@ declare namespace ts.server.protocol { GetEditsForFileRename = "getEditsForFileRename", ConfigurePlugin = "configurePlugin", SelectionRange = "selectionRange", + PrepareCallHierarchy = "prepareCallHierarchy", + ProvideCallHierarchyIncomingCalls = "provideCallHierarchyIncomingCalls", + ProvideCallHierarchyOutgoingCalls = "provideCallHierarchyOutgoingCalls" } /** * A TypeScript Server message @@ -8342,6 +8363,39 @@ declare namespace ts.server.protocol { interface NavTreeResponse extends Response { body?: NavigationTree; } + interface CallHierarchyItem { + name: string; + kind: ScriptElementKind; + file: string; + span: TextSpan; + selectionSpan: TextSpan; + } + interface CallHierarchyIncomingCall { + from: CallHierarchyItem; + fromSpans: TextSpan[]; + } + interface CallHierarchyOutgoingCall { + to: CallHierarchyItem; + fromSpans: TextSpan[]; + } + interface PrepareCallHierarchyRequest extends FileLocationRequest { + command: CommandTypes.PrepareCallHierarchy; + } + interface PrepareCallHierarchyResponse extends Response { + readonly body: CallHierarchyItem | CallHierarchyItem[]; + } + interface ProvideCallHierarchyIncomingCallsRequest extends FileLocationRequest { + command: CommandTypes.ProvideCallHierarchyIncomingCalls; + } + interface ProvideCallHierarchyIncomingCallsResponse extends Response { + readonly body: CallHierarchyIncomingCall[]; + } + interface ProvideCallHierarchyOutgoingCallsRequest extends FileLocationRequest { + command: CommandTypes.ProvideCallHierarchyOutgoingCalls; + } + interface ProvideCallHierarchyOutgoingCallsResponse extends Response { + readonly body: CallHierarchyOutgoingCall[]; + } enum IndentStyle { None = "None", Block = "Block", @@ -9433,6 +9487,12 @@ declare namespace ts.server { private configurePlugin; private getSmartSelectionRange; private mapSelectionRange; + private toProtocolCallHierarchyItem; + private toProtocolCallHierarchyIncomingCall; + private toProtocolCallHierarchyOutgoingCall; + private prepareCallHierarchy; + private provideCallHierarchyIncomingCalls; + private provideCallHierarchyOutgoingCalls; getCanonicalFileName(fileName: string): string; exit(): void; private notRequired; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 41e3b8485704c..58964d920c5a9 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5113,6 +5113,9 @@ declare namespace ts { getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string, excludeDtsFiles?: boolean): NavigateToItem[]; getNavigationBarItems(fileName: string): NavigationBarItem[]; getNavigationTree(fileName: string): NavigationTree; + prepareCallHierarchy(fileName: string, position: number): CallHierarchyItem | CallHierarchyItem[] | undefined; + provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[]; + provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; getOutliningSpans(fileName: string): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; @@ -5252,6 +5255,21 @@ declare namespace ts { /** Present if non-empty */ childItems?: NavigationTree[]; } + interface CallHierarchyItem { + name: string; + kind: ScriptElementKind; + file: string; + span: TextSpan; + selectionSpan: TextSpan; + } + interface CallHierarchyIncomingCall { + from: CallHierarchyItem; + fromSpans: TextSpan[]; + } + interface CallHierarchyOutgoingCall { + to: CallHierarchyItem; + fromSpans: TextSpan[]; + } interface TodoCommentDescriptor { text: string; priority: number; diff --git a/tests/baselines/reference/callHierarchyAccessor.callHierarchy.txt b/tests/baselines/reference/callHierarchyAccessor.callHierarchy.txt new file mode 100644 index 0000000000000..0576190daf1f5 --- /dev/null +++ b/tests/baselines/reference/callHierarchyAccessor.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: bar +├ kind: getter +├ file: /tests/cases/fourslash/callHierarchyAccessor.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:6:5-8:6 +│ │ 6: get bar() { +│ │ ^^^^^^^^^^^ +│ │ 7: return baz(); +│ │ ^^^^^^^^^^^^^^^^^^^^^ +│ │ 8: } +│ │ ^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:6:9-6:12 +│ │ 6: get bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyAccessor.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: new C().bar; +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:2:13-2:16 +│ │ │ 2: new C().bar; +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyAccessor.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:11:1-12:2 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 12: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:11:10-11:13 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyAccessor.ts:7:16-7:19 +│ │ │ 7: return baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyClass.callHierarchy.txt b/tests/baselines/reference/callHierarchyClass.callHierarchy.txt new file mode 100644 index 0000000000000..e56084002c760 --- /dev/null +++ b/tests/baselines/reference/callHierarchyClass.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: bar +├ kind: function +├ file: /tests/cases/fourslash/callHierarchyClass.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyClass.ts:5:1-7:2 +│ │ 5: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: new Baz(); +│ │ ^^^^^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyClass.ts:5:10-5:13 +│ │ 5: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyClass.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyClass.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyClass.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyClass.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: Baz +│ │ ├ kind: class +│ │ ├ file: /tests/cases/fourslash/callHierarchyClass.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyClass.ts:9:1-10:2 +│ │ │ │ 9: class Baz { +│ │ │ │ ^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyClass.ts:9:7-9:10 +│ │ │ │ 9: class Baz { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyClass.ts:6:9-6:12 +│ │ │ 6: new Baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyConstNamedArrowFunction.callHierarchy.txt b/tests/baselines/reference/callHierarchyConstNamedArrowFunction.callHierarchy.txt new file mode 100644 index 0000000000000..bcc7ab9ac8a78 --- /dev/null +++ b/tests/baselines/reference/callHierarchyConstNamedArrowFunction.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: bar +├ kind: function +├ file: /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:5:13-7:2 +│ │ 5: const bar = () => { +│ │ ^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:5:7-5:10 +│ │ 5: const bar = () => { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyConstNamedClassExpression.callHierarchy.txt b/tests/baselines/reference/callHierarchyConstNamedClassExpression.callHierarchy.txt new file mode 100644 index 0000000000000..ed4a25e1641e8 --- /dev/null +++ b/tests/baselines/reference/callHierarchyConstNamedClassExpression.callHierarchy.txt @@ -0,0 +1,69 @@ +╭ name: Bar +├ kind: class +├ file: /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:5:13-9:2 +│ │ 5: const Bar = class { +│ │ ^^^^^^^ +│ │ 6: constructor() { +│ │ ^^^^^^^^^^^^^^^^^^^ +│ │ 7: baz(); +│ │ ^^^^^^^^^^^^^^ +│ │ 8: } +│ │ ^^^^^ +│ │ 9: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:5:7-5:10 +│ │ 5: const Bar = class { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: new Bar(); +│ │ │ │ ^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:2:9-2:12 +│ │ │ 2: new Bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:11:1-12:2 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 12: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:11:10-11:13 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts:7:9-7:12 +│ │ │ 7: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyConstNamedFunctionExpression.callHierarchy.txt b/tests/baselines/reference/callHierarchyConstNamedFunctionExpression.callHierarchy.txt new file mode 100644 index 0000000000000..6c92745d50d5d --- /dev/null +++ b/tests/baselines/reference/callHierarchyConstNamedFunctionExpression.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: bar +├ kind: function +├ file: /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:5:13-7:2 +│ │ 5: const bar = function () { +│ │ ^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:5:7-5:10 +│ │ 5: const bar = function () { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyDecorator.callHierarchy.txt b/tests/baselines/reference/callHierarchyDecorator.callHierarchy.txt new file mode 100644 index 0000000000000..698c9ab313b03 --- /dev/null +++ b/tests/baselines/reference/callHierarchyDecorator.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: bar +├ kind: function +├ file: /tests/cases/fourslash/callHierarchyDecorator.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:5:1-7:2 +│ │ 5: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:5:10-5:13 +│ │ 5: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: Foo +│ │ ├ kind: class +│ │ ├ file: /tests/cases/fourslash/callHierarchyDecorator.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:1:1-3:2 +│ │ │ │ 1: @bar +│ │ │ │ ^^^^ +│ │ │ │ 2: class Foo { +│ │ │ │ ^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:2:7-2:10 +│ │ │ │ 2: class Foo { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:1:2-1:5 +│ │ │ 1: @bar +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyDecorator.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyDecorator.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyExportDefaultClass.callHierarchy.txt b/tests/baselines/reference/callHierarchyExportDefaultClass.callHierarchy.txt new file mode 100644 index 0000000000000..9b1e7b9604c20 --- /dev/null +++ b/tests/baselines/reference/callHierarchyExportDefaultClass.callHierarchy.txt @@ -0,0 +1,69 @@ +╭ name: default +├ kind: class +├ file: /tests/cases/fourslash/other.ts +├ span: +│ ╭ /tests/cases/fourslash/other.ts:1:1-5:2 +│ │ 1: export default class { +│ │ ^^^^^^^^^^^^^^^^^^^^^^ +│ │ 2: constructor() { +│ │ ^^^^^^^^^^^^^^^^^^^ +│ │ 3: baz(); +│ │ ^^^^^^^^^^^^^^ +│ │ 4: } +│ │ ^^^^^ +│ │ 5: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/other.ts:1:8-1:15 +│ │ 1: export default class { +│ │ ^^^^^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:3:1-5:2 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 4: new Bar(); +│ │ │ │ ^^^^^^^^^^^^^^ +│ │ │ │ 5: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:3:10-3:13 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:4:9-4:12 +│ │ │ 4: new Bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/other.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/other.ts:7:1-8:2 +│ │ │ │ 7: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 8: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/other.ts:7:10-7:13 +│ │ │ │ 7: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/other.ts:3:9-3:12 +│ │ │ 3: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyExportDefaultFunction.callHierarchy.txt b/tests/baselines/reference/callHierarchyExportDefaultFunction.callHierarchy.txt new file mode 100644 index 0000000000000..919b219e6e88e --- /dev/null +++ b/tests/baselines/reference/callHierarchyExportDefaultFunction.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: default +├ kind: function +├ file: /tests/cases/fourslash/other.ts +├ span: +│ ╭ /tests/cases/fourslash/other.ts:1:1-3:2 +│ │ 1: export default function () { +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ 2: baz(); +│ │ ^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/other.ts:1:8-1:15 +│ │ 1: export default function () { +│ │ ^^^^^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:3:1-5:2 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 4: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 5: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:3:10-3:13 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:4:5-4:8 +│ │ │ 4: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/other.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/other.ts:5:1-6:2 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 6: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/other.ts:5:10-5:13 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/other.ts:2:5-2:8 +│ │ │ 2: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyExportEqualsFunction.callHierarchy.txt b/tests/baselines/reference/callHierarchyExportEqualsFunction.callHierarchy.txt new file mode 100644 index 0000000000000..427fc13ab1ec4 --- /dev/null +++ b/tests/baselines/reference/callHierarchyExportEqualsFunction.callHierarchy.txt @@ -0,0 +1,47 @@ +╭ name: /tests/cases/fourslash/other.ts +├ kind: module +├ file: /tests/cases/fourslash/other.ts +├ span: +│ ╭ /tests/cases/fourslash/other.ts:1:1-6:2 +│ │ 1: export = function () { +│ │ ^^^^^^^^^^^^^^^^^^^^^^ +│ │ 2: baz(); +│ │ ^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ │ 4: +│ │ ^ +│ │ 5: function baz() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/other.ts:1:1-1:1 +│ │ 1: export = function () { +│ │ < +│ ╰ +├ incoming: none +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/other.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/other.ts:5:1-6:2 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 6: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/other.ts:5:10-5:13 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/other.ts:2:5-2:8 +│ │ │ 2: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyFile.callHierarchy.txt b/tests/baselines/reference/callHierarchyFile.callHierarchy.txt new file mode 100644 index 0000000000000..acb1046489236 --- /dev/null +++ b/tests/baselines/reference/callHierarchyFile.callHierarchy.txt @@ -0,0 +1,41 @@ +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/callHierarchyFile.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyFile.ts:2:1-3:2 +│ │ 2: function foo() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyFile.ts:2:10-2:13 +│ │ 2: function foo() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: /tests/cases/fourslash/callHierarchyFile.ts +│ │ ├ kind: script +│ │ ├ file: /tests/cases/fourslash/callHierarchyFile.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFile.ts:1:1-3:2 +│ │ │ │ 1: foo(); +│ │ │ │ ^^^^^^ +│ │ │ │ 2: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFile.ts:1:1-1:1 +│ │ │ │ 1: foo(); +│ │ │ │ < +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyFile.ts:1:1-1:4 +│ │ │ 1: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none diff --git a/tests/baselines/reference/callHierarchyFunction.callHierarchy.txt b/tests/baselines/reference/callHierarchyFunction.callHierarchy.txt new file mode 100644 index 0000000000000..475737801887e --- /dev/null +++ b/tests/baselines/reference/callHierarchyFunction.callHierarchy.txt @@ -0,0 +1,95 @@ +╭ name: bar +├ kind: function +├ file: /tests/cases/fourslash/callHierarchyFunction.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:5:1-9:2 +│ │ 5: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: quxx(); +│ │ ^^^^^^^^^^^ +│ │ 8: baz(); +│ │ ^^^^^^^^^^ +│ │ 9: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:5:10-5:13 +│ │ 5: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyFunction.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyFunction.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:11:1-12:2 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 12: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:11:10-11:13 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +│ │ ╰ +│ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:8:5-8:8 +│ │ │ 8: baz(); +│ │ │ ^^^ +│ ╰ ╰ +│ ╭ to: +│ │ ╭ name: quxx +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyFunction.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:14:1-15:2 +│ │ │ │ 14: function quxx() { +│ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ 15: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:14:10-14:14 +│ │ │ │ 14: function quxx() { +│ │ │ │ ^^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyFunction.ts:7:5-7:9 +│ │ │ 7: quxx(); +│ │ │ ^^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyFunctionAmbiguity.1.callHierarchy.txt b/tests/baselines/reference/callHierarchyFunctionAmbiguity.1.callHierarchy.txt new file mode 100644 index 0000000000000..438218d45bf19 --- /dev/null +++ b/tests/baselines/reference/callHierarchyFunctionAmbiguity.1.callHierarchy.txt @@ -0,0 +1,78 @@ +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/a.d.ts +├ span: +│ ╭ /tests/cases/fourslash/a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/b.d.ts +├ span: +│ ╭ /tests/cases/fourslash/b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none diff --git a/tests/baselines/reference/callHierarchyFunctionAmbiguity.2.callHierarchy.txt b/tests/baselines/reference/callHierarchyFunctionAmbiguity.2.callHierarchy.txt new file mode 100644 index 0000000000000..438218d45bf19 --- /dev/null +++ b/tests/baselines/reference/callHierarchyFunctionAmbiguity.2.callHierarchy.txt @@ -0,0 +1,78 @@ +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/a.d.ts +├ span: +│ ╭ /tests/cases/fourslash/a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/b.d.ts +├ span: +│ ╭ /tests/cases/fourslash/b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none diff --git a/tests/baselines/reference/callHierarchyFunctionAmbiguity.3.callHierarchy.txt b/tests/baselines/reference/callHierarchyFunctionAmbiguity.3.callHierarchy.txt new file mode 100644 index 0000000000000..438218d45bf19 --- /dev/null +++ b/tests/baselines/reference/callHierarchyFunctionAmbiguity.3.callHierarchy.txt @@ -0,0 +1,78 @@ +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/a.d.ts +├ span: +│ ╭ /tests/cases/fourslash/a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/b.d.ts +├ span: +│ ╭ /tests/cases/fourslash/b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none diff --git a/tests/baselines/reference/callHierarchyFunctionAmbiguity.4.callHierarchy.txt b/tests/baselines/reference/callHierarchyFunctionAmbiguity.4.callHierarchy.txt new file mode 100644 index 0000000000000..438218d45bf19 --- /dev/null +++ b/tests/baselines/reference/callHierarchyFunctionAmbiguity.4.callHierarchy.txt @@ -0,0 +1,78 @@ +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/a.d.ts +├ span: +│ ╭ /tests/cases/fourslash/a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /tests/cases/fourslash/b.d.ts +├ span: +│ ╭ /tests/cases/fourslash/b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none diff --git a/tests/baselines/reference/callHierarchyFunctionAmbiguity.5.callHierarchy.txt b/tests/baselines/reference/callHierarchyFunctionAmbiguity.5.callHierarchy.txt new file mode 100644 index 0000000000000..7acaa23e04404 --- /dev/null +++ b/tests/baselines/reference/callHierarchyFunctionAmbiguity.5.callHierarchy.txt @@ -0,0 +1,59 @@ +╭ name: bar +├ kind: function +├ file: /tests/cases/fourslash/main.ts +├ span: +│ ╭ /tests/cases/fourslash/main.ts:1:1-3:2 +│ │ 1: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 2: foo(); +│ │ ^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/main.ts:1:10-1:13 +│ │ 1: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: none +├ outgoing: +│ ╭ to: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/a.d.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/a.d.ts:1:1-1:40 +│ │ │ │ 1: declare function foo(x?: number): void; +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/a.d.ts:1:18-1:21 +│ │ │ │ 1: declare function foo(x?: number): void; +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +│ ╭ to: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/b.d.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/b.d.ts:1:1-1:40 +│ │ │ │ 1: declare function foo(x?: string): void; +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/b.d.ts:1:18-1:21 +│ │ │ │ 1: declare function foo(x?: string): void; +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyInterfaceMethod.callHierarchy.txt b/tests/baselines/reference/callHierarchyInterfaceMethod.callHierarchy.txt new file mode 100644 index 0000000000000..c0b5e0d1a66e5 --- /dev/null +++ b/tests/baselines/reference/callHierarchyInterfaceMethod.callHierarchy.txt @@ -0,0 +1,47 @@ +╭ name: foo +├ kind: method +├ file: /tests/cases/fourslash/callHierarchyInterfaceMethod.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyInterfaceMethod.ts:2:5-2:17 +│ │ 2: foo(): void; +│ │ ^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyInterfaceMethod.ts:2:5-2:8 +│ │ 2: foo(): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: /tests/cases/fourslash/callHierarchyInterfaceMethod.ts +│ │ ├ kind: script +│ │ ├ file: /tests/cases/fourslash/callHierarchyInterfaceMethod.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyInterfaceMethod.ts:1:1-7:11 +│ │ │ │ 1: interface I { +│ │ │ │ ^^^^^^^^^^^^^ +│ │ │ │ 2: foo(): void; +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ │ 4: +│ │ │ │ ^ +│ │ │ │ 5: const obj: I = { foo() {} }; +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 6: +│ │ │ │ ^ +│ │ │ │ 7: obj.foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyInterfaceMethod.ts:1:1-1:1 +│ │ │ │ 1: interface I { +│ │ │ │ < +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyInterfaceMethod.ts:7:5-7:8 +│ │ │ 7: obj.foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none diff --git a/tests/baselines/reference/callHierarchyJsxElement.callHierarchy.txt b/tests/baselines/reference/callHierarchyJsxElement.callHierarchy.txt new file mode 100644 index 0000000000000..1ef619697f894 --- /dev/null +++ b/tests/baselines/reference/callHierarchyJsxElement.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: Bar +├ kind: function +├ file: /tests/cases/fourslash/main.tsx +├ span: +│ ╭ /tests/cases/fourslash/main.tsx:5:1-7:2 +│ │ 5: function Bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/main.tsx:5:10-5:13 +│ │ 5: function Bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.tsx +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.tsx:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: return ; +│ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.tsx:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.tsx:2:13-2:16 +│ │ │ 2: return ; +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/main.tsx +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/main.tsx:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/main.tsx:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/main.tsx:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/baselines/reference/callHierarchyTaggedTemplate.callHierarchy.txt b/tests/baselines/reference/callHierarchyTaggedTemplate.callHierarchy.txt new file mode 100644 index 0000000000000..47ef606473b2b --- /dev/null +++ b/tests/baselines/reference/callHierarchyTaggedTemplate.callHierarchy.txt @@ -0,0 +1,65 @@ +╭ name: bar +├ kind: function +├ file: /tests/cases/fourslash/callHierarchyTaggedTemplate.ts +├ span: +│ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:5:1-7:2 +│ │ 5: function bar(array: TemplateStringsArray, ...args: any[]) { +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:5:10-5:13 +│ │ 5: function bar(array: TemplateStringsArray, ...args: any[]) { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyTaggedTemplate.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar`a${1}b`; +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:2:5-2:8 +│ │ │ 2: bar`a${1}b`; +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /tests/cases/fourslash/callHierarchyTaggedTemplate.ts +│ │ ├ span: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /tests/cases/fourslash/callHierarchyTaggedTemplate.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ diff --git a/tests/cases/fourslash/callHierarchyAccessor.ts b/tests/cases/fourslash/callHierarchyAccessor.ts new file mode 100644 index 0000000000000..3ab79569d1a33 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyAccessor.ts @@ -0,0 +1,17 @@ +/// + +//// function foo() { +//// new C().bar; +//// } +//// +//// class C { +//// get /**/bar() { +//// return baz(); +//// } +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyClass.ts b/tests/cases/fourslash/callHierarchyClass.ts new file mode 100644 index 0000000000000..3b3fc7a7fae06 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyClass.ts @@ -0,0 +1,15 @@ +/// + +//// function foo() { +//// bar(); +//// } +//// +//// function /**/bar() { +//// new Baz(); +//// } +//// +//// class Baz { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts b/tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts new file mode 100644 index 0000000000000..cf4cd774c2539 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyConstNamedArrowFunction.ts @@ -0,0 +1,15 @@ +/// + +//// function foo() { +//// bar(); +//// } +//// +//// const /**/bar = () => { +//// baz(); +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts b/tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts new file mode 100644 index 0000000000000..8f5dccc238b89 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyConstNamedClassExpression.ts @@ -0,0 +1,17 @@ +/// + +//// function foo() { +//// new Bar(); +//// } +//// +//// const /**/Bar = class { +//// constructor() { +//// baz(); +//// } +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts b/tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts new file mode 100644 index 0000000000000..e8613dda8e17d --- /dev/null +++ b/tests/cases/fourslash/callHierarchyConstNamedFunctionExpression.ts @@ -0,0 +1,15 @@ +/// + +//// function foo() { +//// bar(); +//// } +//// +//// const /**/bar = function () { +//// baz(); +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyDecorator.ts b/tests/cases/fourslash/callHierarchyDecorator.ts new file mode 100644 index 0000000000000..a14d4035a2243 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyDecorator.ts @@ -0,0 +1,16 @@ +/// + +// @experimentalDecorators: true +//// @bar +//// class Foo { +//// } +//// +//// function /**/bar() { +//// baz(); +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyExportDefaultClass.ts b/tests/cases/fourslash/callHierarchyExportDefaultClass.ts new file mode 100644 index 0000000000000..19aef1dc462fd --- /dev/null +++ b/tests/cases/fourslash/callHierarchyExportDefaultClass.ts @@ -0,0 +1,21 @@ +/// + +// @filename: main.ts +//// import Bar from "./other"; +//// +//// function foo() { +//// new Bar(); +//// } + +// @filename: other.ts +//// export /**/default class { +//// constructor() { +//// baz(); +//// } +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyExportDefaultFunction.ts b/tests/cases/fourslash/callHierarchyExportDefaultFunction.ts new file mode 100644 index 0000000000000..8a41f83683c2a --- /dev/null +++ b/tests/cases/fourslash/callHierarchyExportDefaultFunction.ts @@ -0,0 +1,19 @@ +/// + +// @filename: main.ts +//// import bar from "./other"; +//// +//// function foo() { +//// bar(); +//// } + +// @filename: other.ts +//// export /**/default function () { +//// baz(); +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyExportEqualsFunction.ts b/tests/cases/fourslash/callHierarchyExportEqualsFunction.ts new file mode 100644 index 0000000000000..f2c6631909cf1 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyExportEqualsFunction.ts @@ -0,0 +1,20 @@ +/// + +// @filename: main.ts +//// import bar = require("./other"); +//// +//// function foo() { +//// bar(); +//// } + +// @filename: other.ts +//// export = /**/function () { +//// baz(); +//// } +//// +//// function baz() { +//// } + +// NOTE: exported function is unnamed, so we expand the item to the entire file... +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyFile.ts b/tests/cases/fourslash/callHierarchyFile.ts new file mode 100644 index 0000000000000..08d8fc0e92664 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyFile.ts @@ -0,0 +1,8 @@ +/// + +//// foo(); +//// function /**/foo() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyFunction.ts b/tests/cases/fourslash/callHierarchyFunction.ts new file mode 100644 index 0000000000000..72c0bed51e3c1 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyFunction.ts @@ -0,0 +1,20 @@ +/// + +//// function foo() { +//// bar(); +//// } +//// +//// function /**/bar() { +//// baz(); +//// quxx(); +//// baz(); +//// } +//// +//// function baz() { +//// } +//// +//// function quxx() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyFunctionAmbiguity.1.ts b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.1.ts new file mode 100644 index 0000000000000..ae567b3115242 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.1.ts @@ -0,0 +1,16 @@ +/// + +// @filename: a.d.ts +//// declare function foo(x?: number): void; + +// @filename: b.d.ts +//// declare function foo(x?: string): void; +//// declare function foo(x?: boolean): void; + +// @filename: main.ts +//// function bar() { +//// /**/foo(); +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyFunctionAmbiguity.2.ts b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.2.ts new file mode 100644 index 0000000000000..1d1476c0c8a63 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.2.ts @@ -0,0 +1,16 @@ +/// + +// @filename: a.d.ts +//// declare function /**/foo(x?: number): void; + +// @filename: b.d.ts +//// declare function foo(x?: string): void; +//// declare function foo(x?: boolean): void; + +// @filename: main.ts +//// function bar() { +//// foo(); +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyFunctionAmbiguity.3.ts b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.3.ts new file mode 100644 index 0000000000000..425e2a2ac00b8 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.3.ts @@ -0,0 +1,16 @@ +/// + +// @filename: a.d.ts +//// declare function foo(x?: number): void; + +// @filename: b.d.ts +//// declare function /**/foo(x?: string): void; +//// declare function foo(x?: boolean): void; + +// @filename: main.ts +//// function bar() { +//// foo(); +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyFunctionAmbiguity.4.ts b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.4.ts new file mode 100644 index 0000000000000..a960a146519d9 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.4.ts @@ -0,0 +1,16 @@ +/// + +// @filename: a.d.ts +//// declare function foo(x?: number): void; + +// @filename: b.d.ts +//// declare function foo(x?: string): void; +//// declare function /**/foo(x?: boolean): void; + +// @filename: main.ts +//// function bar() { +//// foo(); +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyFunctionAmbiguity.5.ts b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.5.ts new file mode 100644 index 0000000000000..e0c3b9a12130e --- /dev/null +++ b/tests/cases/fourslash/callHierarchyFunctionAmbiguity.5.ts @@ -0,0 +1,16 @@ +/// + +// @filename: a.d.ts +//// declare function foo(x?: number): void; + +// @filename: b.d.ts +//// declare function foo(x?: string): void; +//// declare function foo(x?: boolean): void; + +// @filename: main.ts +//// function /**/bar() { +//// foo(); +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyInterfaceMethod.ts b/tests/cases/fourslash/callHierarchyInterfaceMethod.ts new file mode 100644 index 0000000000000..7233c98c3e6a7 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyInterfaceMethod.ts @@ -0,0 +1,12 @@ +/// + +//// interface I { +//// /**/foo(): void; +//// } +//// +//// const obj: I = { foo() {} }; +//// +//// obj.foo(); + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyJsxElement.ts b/tests/cases/fourslash/callHierarchyJsxElement.ts new file mode 100644 index 0000000000000..67e63efefea52 --- /dev/null +++ b/tests/cases/fourslash/callHierarchyJsxElement.ts @@ -0,0 +1,17 @@ +/// + +// @jsx: preserve +// @filename: main.tsx +//// function foo() { +//// return ; +//// } +//// +//// function /**/Bar() { +//// baz(); +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/callHierarchyTaggedTemplate.ts b/tests/cases/fourslash/callHierarchyTaggedTemplate.ts new file mode 100644 index 0000000000000..d6ad621ec7d0f --- /dev/null +++ b/tests/cases/fourslash/callHierarchyTaggedTemplate.ts @@ -0,0 +1,15 @@ +/// + +//// function foo() { +//// bar`a${1}b`; +//// } +//// +//// function /**/bar(array: TemplateStringsArray, ...args: any[]) { +//// baz(); +//// } +//// +//// function baz() { +//// } + +goTo.marker(); +verify.baselineCallHierarchy(); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 6d6ecc0a5ade5..84b770fc394c1 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -383,6 +383,7 @@ declare namespace FourSlashInterface { readonly newFileContents: { readonly [fileName: string]: string }; readonly preferences?: UserPreferences; }): void; + baselineCallHierarchy(): void; moveToNewFile(options: { readonly newFileContents: { readonly [fileName: string]: string }; readonly preferences?: UserPreferences; @@ -773,4 +774,4 @@ declare namespace completion { export const statementKeywordsWithTypes: ReadonlyArray; export const statementKeywords: ReadonlyArray; export const statementInJsKeywords: ReadonlyArray; -} +} \ No newline at end of file From 0f09ecb455e7b6550fedd18dbbb0dbef7d2f8b86 Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Sat, 21 Dec 2019 19:41:37 +0000 Subject: [PATCH 03/16] Parse private names Signed-off-by: Max Heiber --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 24 +- src/compiler/diagnosticMessages.json | 5 + src/compiler/factory.ts | 15 +- src/compiler/factoryPublic.ts | 12 +- src/compiler/parser.ts | 14 + src/compiler/scanner.ts | 19 + src/compiler/transformers/es5.ts | 2 +- src/compiler/types.ts | 19 +- src/compiler/utilities.ts | 23 +- src/compiler/utilitiesPublic.ts | 16 +- src/compiler/visitorPublic.ts | 2 +- src/services/codefixes/convertToEs6Module.ts | 8 +- src/services/codefixes/helpers.ts | 2 +- src/services/codefixes/inferFromUsage.ts | 2 +- src/services/refactors/moveToNewFile.ts | 2 +- src/services/types.ts | 4 + .../reference/api/tsserverlibrary.d.ts | 566 +++++++++--------- tests/baselines/reference/api/typescript.d.ts | 566 +++++++++--------- .../reference/privateNameAndIndexSignature.js | 16 + .../privateNameAndIndexSignature.symbols | 15 + .../privateNameAndIndexSignature.types | 19 + .../reference/privateNameField.errors.txt | 12 + tests/baselines/reference/privateNameField.js | 15 + .../reference/privateNameField.symbols | 15 + .../reference/privateNameField.types | 18 + .../privateNameAndIndexSignature.ts | 6 + .../members/privateNames/privateNameField.ts | 6 + tests/cases/fourslash/hoverOverPrivateName.ts | 15 + 29 files changed, 845 insertions(+), 595 deletions(-) create mode 100644 tests/baselines/reference/privateNameAndIndexSignature.js create mode 100644 tests/baselines/reference/privateNameAndIndexSignature.symbols create mode 100644 tests/baselines/reference/privateNameAndIndexSignature.types create mode 100644 tests/baselines/reference/privateNameField.errors.txt create mode 100644 tests/baselines/reference/privateNameField.js create mode 100644 tests/baselines/reference/privateNameField.symbols create mode 100644 tests/baselines/reference/privateNameField.types create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameField.ts create mode 100644 tests/cases/fourslash/hoverOverPrivateName.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8fb80a8003bea..70532287217ee 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1599,7 +1599,7 @@ namespace ts { } if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { const propertyAccess = node.expression; - if (isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) { + if (isIdentifier(propertyAccess.name) && isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) { currentFlow = createFlowMutation(FlowFlags.ArrayMutation, currentFlow, node); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0a3658bde1a5b..b27f553ba014a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11963,7 +11963,7 @@ namespace ts { return false; } - function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) { + function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | PrivateName | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; return isTypeUsableAsPropertyName(indexType) ? getPropertyNameFromType(indexType) : @@ -18902,9 +18902,11 @@ namespace ts { function isEvolvingArrayOperationTarget(node: Node) { const root = getReferenceRoot(node); const parent = root.parent; - const isLengthPushOrUnshift = parent.kind === SyntaxKind.PropertyAccessExpression && ( - (parent).name.escapedText === "length" || - parent.parent.kind === SyntaxKind.CallExpression && isPushOrUnshiftIdentifier((parent).name)); + const isLengthPushOrUnshift = isPropertyAccessExpression(parent) && ( + parent.name.escapedText === "length" || + parent.parent.kind === SyntaxKind.CallExpression + && isIdentifier(parent.name) + && isPushOrUnshiftIdentifier(parent.name)); const isElementAssignment = parent.kind === SyntaxKind.ElementAccessExpression && (parent).expression === root && parent.parent.kind === SyntaxKind.BinaryExpression && @@ -23023,7 +23025,7 @@ namespace ts { return isCallOrNewExpression(node.parent) && node.parent.expression === node; } - function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier) { + function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateName) { const parentSymbol = getNodeLinks(left).resolvedSymbol; const assignmentKind = getAssignmentTargetKind(node); const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); @@ -23117,7 +23119,7 @@ namespace ts { return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } - function checkPropertyNotUsedBeforeDeclaration(prop: Symbol, node: PropertyAccessExpression | QualifiedName, right: Identifier): void { + function checkPropertyNotUsedBeforeDeclaration(prop: Symbol, node: PropertyAccessExpression | QualifiedName, right: Identifier | PrivateName): void { const { valueDeclaration } = prop; if (!valueDeclaration || getSourceFileOfNode(node).isDeclarationFile) { return; @@ -23199,7 +23201,7 @@ namespace ts { return getIntersectionType(x); } - function reportNonexistentProperty(propNode: Identifier, containingType: Type) { + function reportNonexistentProperty(propNode: Identifier | PrivateName, containingType: Type) { let errorInfo: DiagnosticMessageChain | undefined; let relatedInfo: Diagnostic | undefined; if (containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) { @@ -23243,7 +23245,7 @@ namespace ts { return prop !== undefined && prop.valueDeclaration && hasModifier(prop.valueDeclaration, ModifierFlags.Static); } - function getSuggestedSymbolForNonexistentProperty(name: Identifier | string, containingType: Type): Symbol | undefined { + function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateName | string, containingType: Type): Symbol | undefined { return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value); } @@ -29611,9 +29613,9 @@ namespace ts { } } - function getIdentifierFromEntityNameExpression(node: Identifier | PropertyAccessExpression): Identifier; - function getIdentifierFromEntityNameExpression(node: Expression): Identifier | undefined; - function getIdentifierFromEntityNameExpression(node: Expression): Identifier | undefined { + function getIdentifierFromEntityNameExpression(node: Identifier | PropertyAccessExpression): Identifier | PrivateName; + function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateName | undefined; + function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateName | undefined { switch (node.kind) { case SyntaxKind.Identifier: return node as Identifier; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 18b5435514a38..21a6d0fae51ae 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5357,5 +5357,10 @@ "JSX expressions may not use the comma operator. Did you mean to write an array?": { "category": "Error", "code": 18007 + }, + "'#!' can only be used at the start of a file.": { + "category": "Error", + "code": 18008 } + } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 22e490bba764c..88c53d492296e 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1740,13 +1740,13 @@ namespace ts { /** * Gets the property name of a BindingOrAssignmentElement */ - export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): PropertyName | undefined { + export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement); Debug.assert(!!propertyName || isSpreadAssignment(bindingElement), "Invalid property name for binding element."); return propertyName; } - export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): PropertyName | undefined { + export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { switch (bindingElement.kind) { case SyntaxKind.BindingElement: // `a` in `let { a: b } = ...` @@ -1755,6 +1755,9 @@ namespace ts { // `1` in `let { 1: b } = ...` if (bindingElement.propertyName) { const propertyName = bindingElement.propertyName; + if (isPrivateName(propertyName)) { + return Debug.failBadSyntaxKind(propertyName); + } return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; @@ -1769,6 +1772,9 @@ namespace ts { // `1` in `({ 1: b } = ...)` if (bindingElement.name) { const propertyName = bindingElement.name; + if (isPrivateName(propertyName)) { + return Debug.failBadSyntaxKind(propertyName); + } return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; @@ -1778,6 +1784,9 @@ namespace ts { case SyntaxKind.SpreadAssignment: // `a` in `({ ...a } = ...)` + if (bindingElement.name && isPrivateName(bindingElement.name)) { + return Debug.failBadSyntaxKind(bindingElement.name); + } return bindingElement.name; } @@ -1899,4 +1908,4 @@ namespace ts { Debug.assertNode(node, isExpression); return node; } -} \ No newline at end of file +} diff --git a/src/compiler/factoryPublic.ts b/src/compiler/factoryPublic.ts index a5a99d179db7a..5512118d73318 100644 --- a/src/compiler/factoryPublic.ts +++ b/src/compiler/factoryPublic.ts @@ -116,7 +116,7 @@ namespace ts { return node; } - function createLiteralFromNode(sourceNode: PropertyNameLiteral): StringLiteral { + function createLiteralFromNode(sourceNode: Exclude): StringLiteral { const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode)); node.textSourceNode = sourceNode; return node; @@ -1057,7 +1057,7 @@ namespace ts { : node; } - export function createPropertyAccess(expression: Expression, name: string | Identifier) { + export function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateName) { const node = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); node.expression = parenthesizeForAccess(expression); node.name = asName(name); @@ -1065,9 +1065,11 @@ namespace ts { return node; } - export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier) { - if (isOptionalChain(node)) { - return updatePropertyAccessChain(node, expression, node.questionDotToken, name); + export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateName) { + if (isOptionalChain(node) && isIdentifier(node.name) && isIdentifier(name)) { + // Not sure why this cast was necessary: the previous line should already establish that node.name is an identifier + const theNode = node as (typeof node & { name: Identifier }); + return updatePropertyAccessChain(theNode, expression, node.questionDotToken, name); } // Because we are updating existed propertyAccess we want to inherit its emitFlags // instead of using the default from createPropertyAccess diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6b7c887edfe8d..b2e2a9afbb07f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1429,6 +1429,17 @@ namespace ts { return createIdentifier(tokenIsIdentifierOrKeyword(token()), diagnosticMessage); } + function createPrivateName(): PrivateName { + const node = createNode(SyntaxKind.PrivateName) as PrivateName; + node.escapedText = escapeLeadingUnderscores(scanner.getTokenText()); + nextToken(); + return finishNode(node); + } + + function parsePrivateName(): PrivateName { + return createPrivateName(); + } + function isLiteralPropertyName(): boolean { return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.StringLiteral || @@ -1444,6 +1455,9 @@ namespace ts { if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) { return parseComputedPropertyName(); } + if (token() === SyntaxKind.PrivateName) { + return parsePrivateName(); + } return parseIdentifierName(); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index e20ab163172ab..fe7df55c916e3 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1893,6 +1893,25 @@ namespace ts { error(Diagnostics.Invalid_character); pos++; return token = SyntaxKind.Unknown; + case CharacterCodes.hash: + if (pos !== 0 && text[pos + 1] === "!") { + error(Diagnostics.can_only_be_used_at_the_start_of_a_file); + pos++; + return token = SyntaxKind.Unknown; + } + pos++; + if (isIdentifierStart(ch = text.charCodeAt(pos), languageVersion)) { + pos++; + while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion)) pos++; + tokenValue = text.substring(tokenPos, pos); + if (ch === CharacterCodes.backslash) { + tokenValue += scanIdentifierParts(); + } + return token = SyntaxKind.PrivateName; + } + error(Diagnostics.Invalid_character); + // no `pos++` because already advanced past the '#' + return token = SyntaxKind.Unknown; default: if (isIdentifierStart(ch, languageVersion)) { pos += charSize(ch); diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index 1c85e684e8cba..dc9fa61b0e0ba 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -82,7 +82,7 @@ namespace ts { * @param node A PropertyAccessExpression */ function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression { - const literalName = trySubstituteReservedName(node.name); + const literalName = trySubstituteReservedName(cast(node.name, isIdentifier)); if (literalName) { return setTextRange(createElementAccess(node.expression, literalName), node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 746eb4e546fe9..d6d68c6482a08 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -201,8 +201,9 @@ namespace ts { AmpersandEqualsToken, BarEqualsToken, CaretEqualsToken, - // Identifiers + // Identifiers and Private Names Identifier, + PrivateName, // Reserved words BreakKeyword, CaseKeyword, @@ -831,10 +832,11 @@ namespace ts { export type EntityName = Identifier | QualifiedName; - export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName; + export type PropertyName = Identifier | PrivateName | StringLiteral | NumericLiteral | ComputedPropertyName; export type DeclarationName = | Identifier + | PrivateName | StringLiteralLike | NumericLiteral | ComputedPropertyName @@ -886,6 +888,14 @@ namespace ts { expression: Expression; } + export interface PrivateName extends PrimaryExpression, Declaration { + kind: SyntaxKind.PrivateName; + // escaping not strictly necessary + // avoids gotchas in transforms and utils + escapedText: __String; + } + + /* @internal */ // A name that supports late-binding (used in checker) export interface LateBoundName extends ComputedPropertyName { @@ -1831,11 +1841,12 @@ namespace ts { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; questionDotToken?: QuestionDotToken; - name: Identifier; + name: Identifier | PrivateName; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; + name: Identifier; } /* @internal */ @@ -1851,6 +1862,7 @@ namespace ts { export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; expression: EntityNameExpression; + name: Identifier; } export interface ElementAccessExpression extends MemberExpression { @@ -1909,6 +1921,7 @@ namespace ts { /** @internal */ export interface WellKnownSymbolExpression extends PropertyAccessExpression { expression: Identifier & { escapedText: "Symbol" }; + name: Identifier; } /** @internal */ export type BindableObjectDefinePropertyCall = CallExpression & { arguments: { 0: BindableStaticNameExpression, 1: StringLiteralLike | NumericLiteral, 2: ObjectLiteralExpression } }; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a28a9dc7bfe21..c087b1e2eb05d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -840,6 +840,7 @@ namespace ts { export function getTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String { switch (name.kind) { case SyntaxKind.Identifier: + case SyntaxKind.PrivateName: return name.escapedText; case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: @@ -860,7 +861,12 @@ namespace ts { case SyntaxKind.QualifiedName: return entityNameToString(name.left) + "." + entityNameToString(name.right); case SyntaxKind.PropertyAccessExpression: - return entityNameToString(name.expression) + "." + entityNameToString(name.name); + if (isIdentifier(name.name)) { + return entityNameToString(name.expression) + "." + entityNameToString(name.name); + } + else { + return Debug.assertNever(name.name); + } default: throw Debug.assertNever(name); } @@ -2111,7 +2117,7 @@ namespace ts { * throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand) */ /* @internal */ - export function getElementOrPropertyAccessArgumentExpressionOrName(node: AccessExpression): Identifier | StringLiteralLike | NumericLiteral | ElementAccessExpression | undefined { + export function getElementOrPropertyAccessArgumentExpressionOrName(node: AccessExpression): Identifier | PrivateName | StringLiteralLike | NumericLiteral | ElementAccessExpression | undefined { if (isPropertyAccessExpression(node)) { return node.name; } @@ -2913,6 +2919,7 @@ namespace ts { export function getPropertyNameForPropertyNameNode(name: PropertyName): __String | undefined { switch (name.kind) { case SyntaxKind.Identifier: + case SyntaxKind.PrivateName: return name.escapedText; case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: @@ -2931,7 +2938,7 @@ namespace ts { } } - export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; + export type PropertyNameLiteral = Identifier | PrivateName | StringLiteralLike | NumericLiteral; export function isPropertyNameLiteral(node: Node): node is PropertyNameLiteral { switch (node.kind) { case SyntaxKind.Identifier: @@ -2944,11 +2951,17 @@ namespace ts { } } export function getTextOfIdentifierOrLiteral(node: PropertyNameLiteral): string { - return node.kind === SyntaxKind.Identifier ? idText(node) : node.text; + return isIdentifierOrPrivateName(node) ? idText(node) : node.text; } export function getEscapedTextOfIdentifierOrLiteral(node: PropertyNameLiteral): __String { - return node.kind === SyntaxKind.Identifier ? node.escapedText : escapeLeadingUnderscores(node.text); + switch(node.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.PrivateName: + return node.escapedText; + default: + return escapeLeadingUnderscores(node.text); + } } export function getPropertyNameForKnownSymbolName(symbolName: string): __String { diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index c67abd16d8697..388d58f598a25 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -453,8 +453,8 @@ namespace ts { return id.length >= 3 && id.charCodeAt(0) === CharacterCodes._ && id.charCodeAt(1) === CharacterCodes._ && id.charCodeAt(2) === CharacterCodes._ ? id.substr(1) : id; } - export function idText(identifier: Identifier): string { - return unescapeLeadingUnderscores(identifier.escapedText); + export function idText(identifierOrPrivateName: Identifier | PrivateName): string { + return unescapeLeadingUnderscores(identifierOrPrivateName.escapedText); } export function symbolName(symbol: Symbol): string { return unescapeLeadingUnderscores(symbol.escapedName); @@ -465,7 +465,7 @@ namespace ts { * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol * will be merged with) */ - function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag | JSDocEnumTag): Identifier | undefined { + function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag | JSDocEnumTag): Identifier | PrivateName | undefined { const hostNode = declaration.parent.parent; if (!hostNode) { return undefined; @@ -524,7 +524,7 @@ namespace ts { return false; } - export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined { + export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateName | undefined { return declaration.name || nameForNamelessJSDocTypedef(declaration); } @@ -878,6 +878,14 @@ namespace ts { return node.kind === SyntaxKind.ComputedPropertyName; } + export function isPrivateName(node: Node): node is PrivateName { + return node.kind === SyntaxKind.PrivateName; + } + + export function isIdentifierOrPrivateName(node: Node): node is Identifier | PrivateName { + return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateName; + } + // Signature elements export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration { diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index c48b27bdce01c..65608e2ffee6f 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -464,7 +464,7 @@ namespace ts { } return updatePropertyAccess(node, visitNode((node).expression, visitor, isExpression), - visitNode((node).name, visitor, isIdentifier)); + visitNode((node).name, visitor, isIdentifierOrPrivateName)); case SyntaxKind.ElementAccessExpression: if (node.flags & NodeFlags.OptionalChain) { diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 25c42288355f3..70abac28bb6da 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -67,7 +67,7 @@ namespace ts.codefix { forEachExportReference(sourceFile, node => { const { text, originalKeywordKind } = node.name; if (!res.has(text) && (originalKeywordKind !== undefined && isNonContextualKeyword(originalKeywordKind) - || checker.resolveName(node.name.text, node, SymbolFlags.Value, /*excludeGlobals*/ true))) { + || checker.resolveName(text, node, SymbolFlags.Value, /*excludeGlobals*/ true))) { // Unconditionally add an underscore in case `text` is a keyword. res.set(text, makeUniqueName(`_${text}`, identifiers)); } @@ -85,11 +85,11 @@ namespace ts.codefix { }); } - function forEachExportReference(sourceFile: SourceFile, cb: (node: PropertyAccessExpression, isAssignmentLhs: boolean) => void): void { + function forEachExportReference(sourceFile: SourceFile, cb: (node: (PropertyAccessExpression & { name: Identifier }), isAssignmentLhs: boolean) => void): void { sourceFile.forEachChild(function recur(node) { - if (isPropertyAccessExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node.expression)) { + if (isPropertyAccessExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node.expression) && isIdentifier(node.name)) { const { parent } = node; - cb(node, isBinaryExpression(parent) && parent.left === node && parent.operatorToken.kind === SyntaxKind.EqualsToken); + cb(node as typeof node & { name: Identifier }, isBinaryExpression(parent) && parent.left === node && parent.operatorToken.kind === SyntaxKind.EqualsToken); } node.forEachChild(recur); }); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index b127fa240487f..95fc499a2f9c6 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -185,7 +185,7 @@ namespace ts.codefix { // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg)), contextNode, /*flags*/ undefined, tracker)); const names = map(args, arg => - isIdentifier(arg) ? arg.text : isPropertyAccessExpression(arg) ? arg.name.text : undefined); + isIdentifier(arg) ? arg.text : isPropertyAccessExpression(arg) && isIdentifier(arg.name) ? arg.name.text : undefined); const contextualType = checker.getContextualType(call); const returnType = (inJs || !contextualType) ? undefined : checker.typeToTypeNode(contextualType, contextNode, /*flags*/ undefined, tracker); return createMethod( diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index c19c625ba6424..df77e281cf0a4 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -403,7 +403,7 @@ namespace ts.codefix { entry.kind !== FindAllReferences.EntryKind.Span ? tryCast(entry.node, isIdentifier) : undefined); } - function inferTypeForVariableFromUsage(token: Identifier, program: Program, cancellationToken: CancellationToken): Type { + function inferTypeForVariableFromUsage(token: Identifier | PrivateName, program: Program, cancellationToken: CancellationToken): Type { const references = getReferences(token, program, cancellationToken); return inferTypeFromReferences(program, references, cancellationToken).single(); } diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index b187a0f953b59..337afdc4214a6 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -708,7 +708,7 @@ namespace ts.refactor { } function nameOfTopLevelDeclaration(d: TopLevelDeclaration): Identifier | undefined { - return isExpressionStatement(d) ? d.expression.left.name : tryCast(d.name, isIdentifier); + return isExpressionStatement(d) ? tryCast(d.expression.left.name, isIdentifier) : tryCast(d.name, isIdentifier); } function getTopLevelDeclarationStatement(d: TopLevelDeclaration): TopLevelDeclarationStatement { diff --git a/src/services/types.ts b/src/services/types.ts index bb953e5f3902d..4d82fbbe00587 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -30,6 +30,10 @@ namespace ts { readonly text: string; } + export interface PrivateName { + readonly text: string; + } + export interface Symbol { readonly name: string; getFlags(): SymbolFlags; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b4621798c73d3..a58f546780f66 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -151,276 +151,277 @@ declare namespace ts { BarEqualsToken = 73, CaretEqualsToken = 74, Identifier = 75, - BreakKeyword = 76, - CaseKeyword = 77, - CatchKeyword = 78, - ClassKeyword = 79, - ConstKeyword = 80, - ContinueKeyword = 81, - DebuggerKeyword = 82, - DefaultKeyword = 83, - DeleteKeyword = 84, - DoKeyword = 85, - ElseKeyword = 86, - EnumKeyword = 87, - ExportKeyword = 88, - ExtendsKeyword = 89, - FalseKeyword = 90, - FinallyKeyword = 91, - ForKeyword = 92, - FunctionKeyword = 93, - IfKeyword = 94, - ImportKeyword = 95, - InKeyword = 96, - InstanceOfKeyword = 97, - NewKeyword = 98, - NullKeyword = 99, - ReturnKeyword = 100, - SuperKeyword = 101, - SwitchKeyword = 102, - ThisKeyword = 103, - ThrowKeyword = 104, - TrueKeyword = 105, - TryKeyword = 106, - TypeOfKeyword = 107, - VarKeyword = 108, - VoidKeyword = 109, - WhileKeyword = 110, - WithKeyword = 111, - ImplementsKeyword = 112, - InterfaceKeyword = 113, - LetKeyword = 114, - PackageKeyword = 115, - PrivateKeyword = 116, - ProtectedKeyword = 117, - PublicKeyword = 118, - StaticKeyword = 119, - YieldKeyword = 120, - AbstractKeyword = 121, - AsKeyword = 122, - AssertsKeyword = 123, - AnyKeyword = 124, - AsyncKeyword = 125, - AwaitKeyword = 126, - BooleanKeyword = 127, - ConstructorKeyword = 128, - DeclareKeyword = 129, - GetKeyword = 130, - InferKeyword = 131, - IsKeyword = 132, - KeyOfKeyword = 133, - ModuleKeyword = 134, - NamespaceKeyword = 135, - NeverKeyword = 136, - ReadonlyKeyword = 137, - RequireKeyword = 138, - NumberKeyword = 139, - ObjectKeyword = 140, - SetKeyword = 141, - StringKeyword = 142, - SymbolKeyword = 143, - TypeKeyword = 144, - UndefinedKeyword = 145, - UniqueKeyword = 146, - UnknownKeyword = 147, - FromKeyword = 148, - GlobalKeyword = 149, - BigIntKeyword = 150, - OfKeyword = 151, - QualifiedName = 152, - ComputedPropertyName = 153, - TypeParameter = 154, - Parameter = 155, - Decorator = 156, - PropertySignature = 157, - PropertyDeclaration = 158, - MethodSignature = 159, - MethodDeclaration = 160, - Constructor = 161, - GetAccessor = 162, - SetAccessor = 163, - CallSignature = 164, - ConstructSignature = 165, - IndexSignature = 166, - TypePredicate = 167, - TypeReference = 168, - FunctionType = 169, - ConstructorType = 170, - TypeQuery = 171, - TypeLiteral = 172, - ArrayType = 173, - TupleType = 174, - OptionalType = 175, - RestType = 176, - UnionType = 177, - IntersectionType = 178, - ConditionalType = 179, - InferType = 180, - ParenthesizedType = 181, - ThisType = 182, - TypeOperator = 183, - IndexedAccessType = 184, - MappedType = 185, - LiteralType = 186, - ImportType = 187, - ObjectBindingPattern = 188, - ArrayBindingPattern = 189, - BindingElement = 190, - ArrayLiteralExpression = 191, - ObjectLiteralExpression = 192, - PropertyAccessExpression = 193, - ElementAccessExpression = 194, - CallExpression = 195, - NewExpression = 196, - TaggedTemplateExpression = 197, - TypeAssertionExpression = 198, - ParenthesizedExpression = 199, - FunctionExpression = 200, - ArrowFunction = 201, - DeleteExpression = 202, - TypeOfExpression = 203, - VoidExpression = 204, - AwaitExpression = 205, - PrefixUnaryExpression = 206, - PostfixUnaryExpression = 207, - BinaryExpression = 208, - ConditionalExpression = 209, - TemplateExpression = 210, - YieldExpression = 211, - SpreadElement = 212, - ClassExpression = 213, - OmittedExpression = 214, - ExpressionWithTypeArguments = 215, - AsExpression = 216, - NonNullExpression = 217, - MetaProperty = 218, - SyntheticExpression = 219, - TemplateSpan = 220, - SemicolonClassElement = 221, - Block = 222, - EmptyStatement = 223, - VariableStatement = 224, - ExpressionStatement = 225, - IfStatement = 226, - DoStatement = 227, - WhileStatement = 228, - ForStatement = 229, - ForInStatement = 230, - ForOfStatement = 231, - ContinueStatement = 232, - BreakStatement = 233, - ReturnStatement = 234, - WithStatement = 235, - SwitchStatement = 236, - LabeledStatement = 237, - ThrowStatement = 238, - TryStatement = 239, - DebuggerStatement = 240, - VariableDeclaration = 241, - VariableDeclarationList = 242, - FunctionDeclaration = 243, - ClassDeclaration = 244, - InterfaceDeclaration = 245, - TypeAliasDeclaration = 246, - EnumDeclaration = 247, - ModuleDeclaration = 248, - ModuleBlock = 249, - CaseBlock = 250, - NamespaceExportDeclaration = 251, - ImportEqualsDeclaration = 252, - ImportDeclaration = 253, - ImportClause = 254, - NamespaceImport = 255, - NamedImports = 256, - ImportSpecifier = 257, - ExportAssignment = 258, - ExportDeclaration = 259, - NamedExports = 260, - NamespaceExport = 261, - ExportSpecifier = 262, - MissingDeclaration = 263, - ExternalModuleReference = 264, - JsxElement = 265, - JsxSelfClosingElement = 266, - JsxOpeningElement = 267, - JsxClosingElement = 268, - JsxFragment = 269, - JsxOpeningFragment = 270, - JsxClosingFragment = 271, - JsxAttribute = 272, - JsxAttributes = 273, - JsxSpreadAttribute = 274, - JsxExpression = 275, - CaseClause = 276, - DefaultClause = 277, - HeritageClause = 278, - CatchClause = 279, - PropertyAssignment = 280, - ShorthandPropertyAssignment = 281, - SpreadAssignment = 282, - EnumMember = 283, - UnparsedPrologue = 284, - UnparsedPrepend = 285, - UnparsedText = 286, - UnparsedInternalText = 287, - UnparsedSyntheticReference = 288, - SourceFile = 289, - Bundle = 290, - UnparsedSource = 291, - InputFiles = 292, - JSDocTypeExpression = 293, - JSDocAllType = 294, - JSDocUnknownType = 295, - JSDocNullableType = 296, - JSDocNonNullableType = 297, - JSDocOptionalType = 298, - JSDocFunctionType = 299, - JSDocVariadicType = 300, - JSDocNamepathType = 301, - JSDocComment = 302, - JSDocTypeLiteral = 303, - JSDocSignature = 304, - JSDocTag = 305, - JSDocAugmentsTag = 306, - JSDocAuthorTag = 307, - JSDocClassTag = 308, - JSDocPublicTag = 309, - JSDocPrivateTag = 310, - JSDocProtectedTag = 311, - JSDocReadonlyTag = 312, - JSDocCallbackTag = 313, - JSDocEnumTag = 314, - JSDocParameterTag = 315, - JSDocReturnTag = 316, - JSDocThisTag = 317, - JSDocTypeTag = 318, - JSDocTemplateTag = 319, - JSDocTypedefTag = 320, - JSDocPropertyTag = 321, - SyntaxList = 322, - NotEmittedStatement = 323, - PartiallyEmittedExpression = 324, - CommaListExpression = 325, - MergeDeclarationMarker = 326, - EndOfDeclarationMarker = 327, - SyntheticReferenceExpression = 328, - Count = 329, + PrivateName = 76, + BreakKeyword = 77, + CaseKeyword = 78, + CatchKeyword = 79, + ClassKeyword = 80, + ConstKeyword = 81, + ContinueKeyword = 82, + DebuggerKeyword = 83, + DefaultKeyword = 84, + DeleteKeyword = 85, + DoKeyword = 86, + ElseKeyword = 87, + EnumKeyword = 88, + ExportKeyword = 89, + ExtendsKeyword = 90, + FalseKeyword = 91, + FinallyKeyword = 92, + ForKeyword = 93, + FunctionKeyword = 94, + IfKeyword = 95, + ImportKeyword = 96, + InKeyword = 97, + InstanceOfKeyword = 98, + NewKeyword = 99, + NullKeyword = 100, + ReturnKeyword = 101, + SuperKeyword = 102, + SwitchKeyword = 103, + ThisKeyword = 104, + ThrowKeyword = 105, + TrueKeyword = 106, + TryKeyword = 107, + TypeOfKeyword = 108, + VarKeyword = 109, + VoidKeyword = 110, + WhileKeyword = 111, + WithKeyword = 112, + ImplementsKeyword = 113, + InterfaceKeyword = 114, + LetKeyword = 115, + PackageKeyword = 116, + PrivateKeyword = 117, + ProtectedKeyword = 118, + PublicKeyword = 119, + StaticKeyword = 120, + YieldKeyword = 121, + AbstractKeyword = 122, + AsKeyword = 123, + AssertsKeyword = 124, + AnyKeyword = 125, + AsyncKeyword = 126, + AwaitKeyword = 127, + BooleanKeyword = 128, + ConstructorKeyword = 129, + DeclareKeyword = 130, + GetKeyword = 131, + InferKeyword = 132, + IsKeyword = 133, + KeyOfKeyword = 134, + ModuleKeyword = 135, + NamespaceKeyword = 136, + NeverKeyword = 137, + ReadonlyKeyword = 138, + RequireKeyword = 139, + NumberKeyword = 140, + ObjectKeyword = 141, + SetKeyword = 142, + StringKeyword = 143, + SymbolKeyword = 144, + TypeKeyword = 145, + UndefinedKeyword = 146, + UniqueKeyword = 147, + UnknownKeyword = 148, + FromKeyword = 149, + GlobalKeyword = 150, + BigIntKeyword = 151, + OfKeyword = 152, + QualifiedName = 153, + ComputedPropertyName = 154, + TypeParameter = 155, + Parameter = 156, + Decorator = 157, + PropertySignature = 158, + PropertyDeclaration = 159, + MethodSignature = 160, + MethodDeclaration = 161, + Constructor = 162, + GetAccessor = 163, + SetAccessor = 164, + CallSignature = 165, + ConstructSignature = 166, + IndexSignature = 167, + TypePredicate = 168, + TypeReference = 169, + FunctionType = 170, + ConstructorType = 171, + TypeQuery = 172, + TypeLiteral = 173, + ArrayType = 174, + TupleType = 175, + OptionalType = 176, + RestType = 177, + UnionType = 178, + IntersectionType = 179, + ConditionalType = 180, + InferType = 181, + ParenthesizedType = 182, + ThisType = 183, + TypeOperator = 184, + IndexedAccessType = 185, + MappedType = 186, + LiteralType = 187, + ImportType = 188, + ObjectBindingPattern = 189, + ArrayBindingPattern = 190, + BindingElement = 191, + ArrayLiteralExpression = 192, + ObjectLiteralExpression = 193, + PropertyAccessExpression = 194, + ElementAccessExpression = 195, + CallExpression = 196, + NewExpression = 197, + TaggedTemplateExpression = 198, + TypeAssertionExpression = 199, + ParenthesizedExpression = 200, + FunctionExpression = 201, + ArrowFunction = 202, + DeleteExpression = 203, + TypeOfExpression = 204, + VoidExpression = 205, + AwaitExpression = 206, + PrefixUnaryExpression = 207, + PostfixUnaryExpression = 208, + BinaryExpression = 209, + ConditionalExpression = 210, + TemplateExpression = 211, + YieldExpression = 212, + SpreadElement = 213, + ClassExpression = 214, + OmittedExpression = 215, + ExpressionWithTypeArguments = 216, + AsExpression = 217, + NonNullExpression = 218, + MetaProperty = 219, + SyntheticExpression = 220, + TemplateSpan = 221, + SemicolonClassElement = 222, + Block = 223, + EmptyStatement = 224, + VariableStatement = 225, + ExpressionStatement = 226, + IfStatement = 227, + DoStatement = 228, + WhileStatement = 229, + ForStatement = 230, + ForInStatement = 231, + ForOfStatement = 232, + ContinueStatement = 233, + BreakStatement = 234, + ReturnStatement = 235, + WithStatement = 236, + SwitchStatement = 237, + LabeledStatement = 238, + ThrowStatement = 239, + TryStatement = 240, + DebuggerStatement = 241, + VariableDeclaration = 242, + VariableDeclarationList = 243, + FunctionDeclaration = 244, + ClassDeclaration = 245, + InterfaceDeclaration = 246, + TypeAliasDeclaration = 247, + EnumDeclaration = 248, + ModuleDeclaration = 249, + ModuleBlock = 250, + CaseBlock = 251, + NamespaceExportDeclaration = 252, + ImportEqualsDeclaration = 253, + ImportDeclaration = 254, + ImportClause = 255, + NamespaceImport = 256, + NamedImports = 257, + ImportSpecifier = 258, + ExportAssignment = 259, + ExportDeclaration = 260, + NamedExports = 261, + NamespaceExport = 262, + ExportSpecifier = 263, + MissingDeclaration = 264, + ExternalModuleReference = 265, + JsxElement = 266, + JsxSelfClosingElement = 267, + JsxOpeningElement = 268, + JsxClosingElement = 269, + JsxFragment = 270, + JsxOpeningFragment = 271, + JsxClosingFragment = 272, + JsxAttribute = 273, + JsxAttributes = 274, + JsxSpreadAttribute = 275, + JsxExpression = 276, + CaseClause = 277, + DefaultClause = 278, + HeritageClause = 279, + CatchClause = 280, + PropertyAssignment = 281, + ShorthandPropertyAssignment = 282, + SpreadAssignment = 283, + EnumMember = 284, + UnparsedPrologue = 285, + UnparsedPrepend = 286, + UnparsedText = 287, + UnparsedInternalText = 288, + UnparsedSyntheticReference = 289, + SourceFile = 290, + Bundle = 291, + UnparsedSource = 292, + InputFiles = 293, + JSDocTypeExpression = 294, + JSDocAllType = 295, + JSDocUnknownType = 296, + JSDocNullableType = 297, + JSDocNonNullableType = 298, + JSDocOptionalType = 299, + JSDocFunctionType = 300, + JSDocVariadicType = 301, + JSDocNamepathType = 302, + JSDocComment = 303, + JSDocTypeLiteral = 304, + JSDocSignature = 305, + JSDocTag = 306, + JSDocAugmentsTag = 307, + JSDocAuthorTag = 308, + JSDocClassTag = 309, + JSDocPublicTag = 310, + JSDocPrivateTag = 311, + JSDocProtectedTag = 312, + JSDocReadonlyTag = 313, + JSDocCallbackTag = 314, + JSDocEnumTag = 315, + JSDocParameterTag = 316, + JSDocReturnTag = 317, + JSDocThisTag = 318, + JSDocTypeTag = 319, + JSDocTemplateTag = 320, + JSDocTypedefTag = 321, + JSDocPropertyTag = 322, + SyntaxList = 323, + NotEmittedStatement = 324, + PartiallyEmittedExpression = 325, + CommaListExpression = 326, + MergeDeclarationMarker = 327, + EndOfDeclarationMarker = 328, + SyntheticReferenceExpression = 329, + Count = 330, FirstAssignment = 62, LastAssignment = 74, FirstCompoundAssignment = 63, LastCompoundAssignment = 74, - FirstReservedWord = 76, - LastReservedWord = 111, - FirstKeyword = 76, - LastKeyword = 151, - FirstFutureReservedWord = 112, - LastFutureReservedWord = 120, - FirstTypeNode = 167, - LastTypeNode = 187, + FirstReservedWord = 77, + LastReservedWord = 112, + FirstKeyword = 77, + LastKeyword = 152, + FirstFutureReservedWord = 113, + LastFutureReservedWord = 121, + FirstTypeNode = 168, + LastTypeNode = 188, FirstPunctuation = 18, LastPunctuation = 74, FirstToken = 0, - LastToken = 151, + LastToken = 152, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -429,13 +430,13 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 29, LastBinaryOperator = 74, - FirstStatement = 224, - LastStatement = 240, - FirstNode = 152, - FirstJSDocNode = 293, - LastJSDocNode = 321, - FirstJSDocTagNode = 305, - LastJSDocTagNode = 321, + FirstStatement = 225, + LastStatement = 241, + FirstNode = 153, + FirstJSDocNode = 294, + LastJSDocNode = 322, + FirstJSDocTagNode = 306, + LastJSDocTagNode = 322, } export enum NodeFlags { None = 0, @@ -552,8 +553,8 @@ declare namespace ts { right: Identifier; } export type EntityName = Identifier | QualifiedName; - export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName; - export type DeclarationName = Identifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; + export type PropertyName = Identifier | PrivateName | StringLiteral | NumericLiteral | ComputedPropertyName; + export type DeclarationName = Identifier | PrivateName | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; export interface Declaration extends Node { _declarationBrand: any; } @@ -568,6 +569,10 @@ declare namespace ts { kind: SyntaxKind.ComputedPropertyName; expression: Expression; } + export interface PrivateName extends PrimaryExpression, Declaration { + kind: SyntaxKind.PrivateName; + escapedText: __String; + } export interface Decorator extends Node { kind: SyntaxKind.Decorator; parent: NamedDeclaration; @@ -1093,10 +1098,11 @@ declare namespace ts { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; questionDotToken?: QuestionDotToken; - name: Identifier; + name: Identifier | PrivateName; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; + name: Identifier; } export interface SuperPropertyAccessExpression extends PropertyAccessExpression { expression: SuperExpression; @@ -1105,6 +1111,7 @@ declare namespace ts { export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; expression: EntityNameExpression; + name: Identifier; } export interface ElementAccessExpression extends MemberExpression { kind: SyntaxKind.ElementAccessExpression; @@ -3440,9 +3447,9 @@ declare namespace ts { * @returns The unescaped identifier text. */ function unescapeLeadingUnderscores(identifier: __String): string; - function idText(identifier: Identifier): string; + function idText(identifierOrPrivateName: Identifier | PrivateName): string; function symbolName(symbol: Symbol): string; - function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined; + function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateName | undefined; function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** * Gets the JSDoc parameter tags for the node if present. @@ -3538,6 +3545,8 @@ declare namespace ts { function isIdentifier(node: Node): node is Identifier; function isQualifiedName(node: Node): node is QualifiedName; function isComputedPropertyName(node: Node): node is ComputedPropertyName; + function isPrivateName(node: Node): node is PrivateName; + function isIdentifierOrPrivateName(node: Node): node is Identifier | PrivateName; function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration; function isParameter(node: Node): node is ParameterDeclaration; function isDecorator(node: Node): node is Decorator; @@ -4031,8 +4040,8 @@ declare namespace ts { function updateArrayLiteral(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; function createObjectLiteral(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; - function createPropertyAccess(expression: Expression, name: string | Identifier): PropertyAccessExpression; - function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression; + function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateName): PropertyAccessExpression; + function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateName): PropertyAccessExpression; function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain; function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain; function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; @@ -4942,6 +4951,9 @@ declare namespace ts { interface Identifier { readonly text: string; } + interface PrivateName { + readonly text: string; + } interface Symbol { readonly name: string; getFlags(): SymbolFlags; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 58964d920c5a9..6a52d40623c03 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -151,276 +151,277 @@ declare namespace ts { BarEqualsToken = 73, CaretEqualsToken = 74, Identifier = 75, - BreakKeyword = 76, - CaseKeyword = 77, - CatchKeyword = 78, - ClassKeyword = 79, - ConstKeyword = 80, - ContinueKeyword = 81, - DebuggerKeyword = 82, - DefaultKeyword = 83, - DeleteKeyword = 84, - DoKeyword = 85, - ElseKeyword = 86, - EnumKeyword = 87, - ExportKeyword = 88, - ExtendsKeyword = 89, - FalseKeyword = 90, - FinallyKeyword = 91, - ForKeyword = 92, - FunctionKeyword = 93, - IfKeyword = 94, - ImportKeyword = 95, - InKeyword = 96, - InstanceOfKeyword = 97, - NewKeyword = 98, - NullKeyword = 99, - ReturnKeyword = 100, - SuperKeyword = 101, - SwitchKeyword = 102, - ThisKeyword = 103, - ThrowKeyword = 104, - TrueKeyword = 105, - TryKeyword = 106, - TypeOfKeyword = 107, - VarKeyword = 108, - VoidKeyword = 109, - WhileKeyword = 110, - WithKeyword = 111, - ImplementsKeyword = 112, - InterfaceKeyword = 113, - LetKeyword = 114, - PackageKeyword = 115, - PrivateKeyword = 116, - ProtectedKeyword = 117, - PublicKeyword = 118, - StaticKeyword = 119, - YieldKeyword = 120, - AbstractKeyword = 121, - AsKeyword = 122, - AssertsKeyword = 123, - AnyKeyword = 124, - AsyncKeyword = 125, - AwaitKeyword = 126, - BooleanKeyword = 127, - ConstructorKeyword = 128, - DeclareKeyword = 129, - GetKeyword = 130, - InferKeyword = 131, - IsKeyword = 132, - KeyOfKeyword = 133, - ModuleKeyword = 134, - NamespaceKeyword = 135, - NeverKeyword = 136, - ReadonlyKeyword = 137, - RequireKeyword = 138, - NumberKeyword = 139, - ObjectKeyword = 140, - SetKeyword = 141, - StringKeyword = 142, - SymbolKeyword = 143, - TypeKeyword = 144, - UndefinedKeyword = 145, - UniqueKeyword = 146, - UnknownKeyword = 147, - FromKeyword = 148, - GlobalKeyword = 149, - BigIntKeyword = 150, - OfKeyword = 151, - QualifiedName = 152, - ComputedPropertyName = 153, - TypeParameter = 154, - Parameter = 155, - Decorator = 156, - PropertySignature = 157, - PropertyDeclaration = 158, - MethodSignature = 159, - MethodDeclaration = 160, - Constructor = 161, - GetAccessor = 162, - SetAccessor = 163, - CallSignature = 164, - ConstructSignature = 165, - IndexSignature = 166, - TypePredicate = 167, - TypeReference = 168, - FunctionType = 169, - ConstructorType = 170, - TypeQuery = 171, - TypeLiteral = 172, - ArrayType = 173, - TupleType = 174, - OptionalType = 175, - RestType = 176, - UnionType = 177, - IntersectionType = 178, - ConditionalType = 179, - InferType = 180, - ParenthesizedType = 181, - ThisType = 182, - TypeOperator = 183, - IndexedAccessType = 184, - MappedType = 185, - LiteralType = 186, - ImportType = 187, - ObjectBindingPattern = 188, - ArrayBindingPattern = 189, - BindingElement = 190, - ArrayLiteralExpression = 191, - ObjectLiteralExpression = 192, - PropertyAccessExpression = 193, - ElementAccessExpression = 194, - CallExpression = 195, - NewExpression = 196, - TaggedTemplateExpression = 197, - TypeAssertionExpression = 198, - ParenthesizedExpression = 199, - FunctionExpression = 200, - ArrowFunction = 201, - DeleteExpression = 202, - TypeOfExpression = 203, - VoidExpression = 204, - AwaitExpression = 205, - PrefixUnaryExpression = 206, - PostfixUnaryExpression = 207, - BinaryExpression = 208, - ConditionalExpression = 209, - TemplateExpression = 210, - YieldExpression = 211, - SpreadElement = 212, - ClassExpression = 213, - OmittedExpression = 214, - ExpressionWithTypeArguments = 215, - AsExpression = 216, - NonNullExpression = 217, - MetaProperty = 218, - SyntheticExpression = 219, - TemplateSpan = 220, - SemicolonClassElement = 221, - Block = 222, - EmptyStatement = 223, - VariableStatement = 224, - ExpressionStatement = 225, - IfStatement = 226, - DoStatement = 227, - WhileStatement = 228, - ForStatement = 229, - ForInStatement = 230, - ForOfStatement = 231, - ContinueStatement = 232, - BreakStatement = 233, - ReturnStatement = 234, - WithStatement = 235, - SwitchStatement = 236, - LabeledStatement = 237, - ThrowStatement = 238, - TryStatement = 239, - DebuggerStatement = 240, - VariableDeclaration = 241, - VariableDeclarationList = 242, - FunctionDeclaration = 243, - ClassDeclaration = 244, - InterfaceDeclaration = 245, - TypeAliasDeclaration = 246, - EnumDeclaration = 247, - ModuleDeclaration = 248, - ModuleBlock = 249, - CaseBlock = 250, - NamespaceExportDeclaration = 251, - ImportEqualsDeclaration = 252, - ImportDeclaration = 253, - ImportClause = 254, - NamespaceImport = 255, - NamedImports = 256, - ImportSpecifier = 257, - ExportAssignment = 258, - ExportDeclaration = 259, - NamedExports = 260, - NamespaceExport = 261, - ExportSpecifier = 262, - MissingDeclaration = 263, - ExternalModuleReference = 264, - JsxElement = 265, - JsxSelfClosingElement = 266, - JsxOpeningElement = 267, - JsxClosingElement = 268, - JsxFragment = 269, - JsxOpeningFragment = 270, - JsxClosingFragment = 271, - JsxAttribute = 272, - JsxAttributes = 273, - JsxSpreadAttribute = 274, - JsxExpression = 275, - CaseClause = 276, - DefaultClause = 277, - HeritageClause = 278, - CatchClause = 279, - PropertyAssignment = 280, - ShorthandPropertyAssignment = 281, - SpreadAssignment = 282, - EnumMember = 283, - UnparsedPrologue = 284, - UnparsedPrepend = 285, - UnparsedText = 286, - UnparsedInternalText = 287, - UnparsedSyntheticReference = 288, - SourceFile = 289, - Bundle = 290, - UnparsedSource = 291, - InputFiles = 292, - JSDocTypeExpression = 293, - JSDocAllType = 294, - JSDocUnknownType = 295, - JSDocNullableType = 296, - JSDocNonNullableType = 297, - JSDocOptionalType = 298, - JSDocFunctionType = 299, - JSDocVariadicType = 300, - JSDocNamepathType = 301, - JSDocComment = 302, - JSDocTypeLiteral = 303, - JSDocSignature = 304, - JSDocTag = 305, - JSDocAugmentsTag = 306, - JSDocAuthorTag = 307, - JSDocClassTag = 308, - JSDocPublicTag = 309, - JSDocPrivateTag = 310, - JSDocProtectedTag = 311, - JSDocReadonlyTag = 312, - JSDocCallbackTag = 313, - JSDocEnumTag = 314, - JSDocParameterTag = 315, - JSDocReturnTag = 316, - JSDocThisTag = 317, - JSDocTypeTag = 318, - JSDocTemplateTag = 319, - JSDocTypedefTag = 320, - JSDocPropertyTag = 321, - SyntaxList = 322, - NotEmittedStatement = 323, - PartiallyEmittedExpression = 324, - CommaListExpression = 325, - MergeDeclarationMarker = 326, - EndOfDeclarationMarker = 327, - SyntheticReferenceExpression = 328, - Count = 329, + PrivateName = 76, + BreakKeyword = 77, + CaseKeyword = 78, + CatchKeyword = 79, + ClassKeyword = 80, + ConstKeyword = 81, + ContinueKeyword = 82, + DebuggerKeyword = 83, + DefaultKeyword = 84, + DeleteKeyword = 85, + DoKeyword = 86, + ElseKeyword = 87, + EnumKeyword = 88, + ExportKeyword = 89, + ExtendsKeyword = 90, + FalseKeyword = 91, + FinallyKeyword = 92, + ForKeyword = 93, + FunctionKeyword = 94, + IfKeyword = 95, + ImportKeyword = 96, + InKeyword = 97, + InstanceOfKeyword = 98, + NewKeyword = 99, + NullKeyword = 100, + ReturnKeyword = 101, + SuperKeyword = 102, + SwitchKeyword = 103, + ThisKeyword = 104, + ThrowKeyword = 105, + TrueKeyword = 106, + TryKeyword = 107, + TypeOfKeyword = 108, + VarKeyword = 109, + VoidKeyword = 110, + WhileKeyword = 111, + WithKeyword = 112, + ImplementsKeyword = 113, + InterfaceKeyword = 114, + LetKeyword = 115, + PackageKeyword = 116, + PrivateKeyword = 117, + ProtectedKeyword = 118, + PublicKeyword = 119, + StaticKeyword = 120, + YieldKeyword = 121, + AbstractKeyword = 122, + AsKeyword = 123, + AssertsKeyword = 124, + AnyKeyword = 125, + AsyncKeyword = 126, + AwaitKeyword = 127, + BooleanKeyword = 128, + ConstructorKeyword = 129, + DeclareKeyword = 130, + GetKeyword = 131, + InferKeyword = 132, + IsKeyword = 133, + KeyOfKeyword = 134, + ModuleKeyword = 135, + NamespaceKeyword = 136, + NeverKeyword = 137, + ReadonlyKeyword = 138, + RequireKeyword = 139, + NumberKeyword = 140, + ObjectKeyword = 141, + SetKeyword = 142, + StringKeyword = 143, + SymbolKeyword = 144, + TypeKeyword = 145, + UndefinedKeyword = 146, + UniqueKeyword = 147, + UnknownKeyword = 148, + FromKeyword = 149, + GlobalKeyword = 150, + BigIntKeyword = 151, + OfKeyword = 152, + QualifiedName = 153, + ComputedPropertyName = 154, + TypeParameter = 155, + Parameter = 156, + Decorator = 157, + PropertySignature = 158, + PropertyDeclaration = 159, + MethodSignature = 160, + MethodDeclaration = 161, + Constructor = 162, + GetAccessor = 163, + SetAccessor = 164, + CallSignature = 165, + ConstructSignature = 166, + IndexSignature = 167, + TypePredicate = 168, + TypeReference = 169, + FunctionType = 170, + ConstructorType = 171, + TypeQuery = 172, + TypeLiteral = 173, + ArrayType = 174, + TupleType = 175, + OptionalType = 176, + RestType = 177, + UnionType = 178, + IntersectionType = 179, + ConditionalType = 180, + InferType = 181, + ParenthesizedType = 182, + ThisType = 183, + TypeOperator = 184, + IndexedAccessType = 185, + MappedType = 186, + LiteralType = 187, + ImportType = 188, + ObjectBindingPattern = 189, + ArrayBindingPattern = 190, + BindingElement = 191, + ArrayLiteralExpression = 192, + ObjectLiteralExpression = 193, + PropertyAccessExpression = 194, + ElementAccessExpression = 195, + CallExpression = 196, + NewExpression = 197, + TaggedTemplateExpression = 198, + TypeAssertionExpression = 199, + ParenthesizedExpression = 200, + FunctionExpression = 201, + ArrowFunction = 202, + DeleteExpression = 203, + TypeOfExpression = 204, + VoidExpression = 205, + AwaitExpression = 206, + PrefixUnaryExpression = 207, + PostfixUnaryExpression = 208, + BinaryExpression = 209, + ConditionalExpression = 210, + TemplateExpression = 211, + YieldExpression = 212, + SpreadElement = 213, + ClassExpression = 214, + OmittedExpression = 215, + ExpressionWithTypeArguments = 216, + AsExpression = 217, + NonNullExpression = 218, + MetaProperty = 219, + SyntheticExpression = 220, + TemplateSpan = 221, + SemicolonClassElement = 222, + Block = 223, + EmptyStatement = 224, + VariableStatement = 225, + ExpressionStatement = 226, + IfStatement = 227, + DoStatement = 228, + WhileStatement = 229, + ForStatement = 230, + ForInStatement = 231, + ForOfStatement = 232, + ContinueStatement = 233, + BreakStatement = 234, + ReturnStatement = 235, + WithStatement = 236, + SwitchStatement = 237, + LabeledStatement = 238, + ThrowStatement = 239, + TryStatement = 240, + DebuggerStatement = 241, + VariableDeclaration = 242, + VariableDeclarationList = 243, + FunctionDeclaration = 244, + ClassDeclaration = 245, + InterfaceDeclaration = 246, + TypeAliasDeclaration = 247, + EnumDeclaration = 248, + ModuleDeclaration = 249, + ModuleBlock = 250, + CaseBlock = 251, + NamespaceExportDeclaration = 252, + ImportEqualsDeclaration = 253, + ImportDeclaration = 254, + ImportClause = 255, + NamespaceImport = 256, + NamedImports = 257, + ImportSpecifier = 258, + ExportAssignment = 259, + ExportDeclaration = 260, + NamedExports = 261, + NamespaceExport = 262, + ExportSpecifier = 263, + MissingDeclaration = 264, + ExternalModuleReference = 265, + JsxElement = 266, + JsxSelfClosingElement = 267, + JsxOpeningElement = 268, + JsxClosingElement = 269, + JsxFragment = 270, + JsxOpeningFragment = 271, + JsxClosingFragment = 272, + JsxAttribute = 273, + JsxAttributes = 274, + JsxSpreadAttribute = 275, + JsxExpression = 276, + CaseClause = 277, + DefaultClause = 278, + HeritageClause = 279, + CatchClause = 280, + PropertyAssignment = 281, + ShorthandPropertyAssignment = 282, + SpreadAssignment = 283, + EnumMember = 284, + UnparsedPrologue = 285, + UnparsedPrepend = 286, + UnparsedText = 287, + UnparsedInternalText = 288, + UnparsedSyntheticReference = 289, + SourceFile = 290, + Bundle = 291, + UnparsedSource = 292, + InputFiles = 293, + JSDocTypeExpression = 294, + JSDocAllType = 295, + JSDocUnknownType = 296, + JSDocNullableType = 297, + JSDocNonNullableType = 298, + JSDocOptionalType = 299, + JSDocFunctionType = 300, + JSDocVariadicType = 301, + JSDocNamepathType = 302, + JSDocComment = 303, + JSDocTypeLiteral = 304, + JSDocSignature = 305, + JSDocTag = 306, + JSDocAugmentsTag = 307, + JSDocAuthorTag = 308, + JSDocClassTag = 309, + JSDocPublicTag = 310, + JSDocPrivateTag = 311, + JSDocProtectedTag = 312, + JSDocReadonlyTag = 313, + JSDocCallbackTag = 314, + JSDocEnumTag = 315, + JSDocParameterTag = 316, + JSDocReturnTag = 317, + JSDocThisTag = 318, + JSDocTypeTag = 319, + JSDocTemplateTag = 320, + JSDocTypedefTag = 321, + JSDocPropertyTag = 322, + SyntaxList = 323, + NotEmittedStatement = 324, + PartiallyEmittedExpression = 325, + CommaListExpression = 326, + MergeDeclarationMarker = 327, + EndOfDeclarationMarker = 328, + SyntheticReferenceExpression = 329, + Count = 330, FirstAssignment = 62, LastAssignment = 74, FirstCompoundAssignment = 63, LastCompoundAssignment = 74, - FirstReservedWord = 76, - LastReservedWord = 111, - FirstKeyword = 76, - LastKeyword = 151, - FirstFutureReservedWord = 112, - LastFutureReservedWord = 120, - FirstTypeNode = 167, - LastTypeNode = 187, + FirstReservedWord = 77, + LastReservedWord = 112, + FirstKeyword = 77, + LastKeyword = 152, + FirstFutureReservedWord = 113, + LastFutureReservedWord = 121, + FirstTypeNode = 168, + LastTypeNode = 188, FirstPunctuation = 18, LastPunctuation = 74, FirstToken = 0, - LastToken = 151, + LastToken = 152, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -429,13 +430,13 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 29, LastBinaryOperator = 74, - FirstStatement = 224, - LastStatement = 240, - FirstNode = 152, - FirstJSDocNode = 293, - LastJSDocNode = 321, - FirstJSDocTagNode = 305, - LastJSDocTagNode = 321, + FirstStatement = 225, + LastStatement = 241, + FirstNode = 153, + FirstJSDocNode = 294, + LastJSDocNode = 322, + FirstJSDocTagNode = 306, + LastJSDocTagNode = 322, } export enum NodeFlags { None = 0, @@ -552,8 +553,8 @@ declare namespace ts { right: Identifier; } export type EntityName = Identifier | QualifiedName; - export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName; - export type DeclarationName = Identifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; + export type PropertyName = Identifier | PrivateName | StringLiteral | NumericLiteral | ComputedPropertyName; + export type DeclarationName = Identifier | PrivateName | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; export interface Declaration extends Node { _declarationBrand: any; } @@ -568,6 +569,10 @@ declare namespace ts { kind: SyntaxKind.ComputedPropertyName; expression: Expression; } + export interface PrivateName extends PrimaryExpression, Declaration { + kind: SyntaxKind.PrivateName; + escapedText: __String; + } export interface Decorator extends Node { kind: SyntaxKind.Decorator; parent: NamedDeclaration; @@ -1093,10 +1098,11 @@ declare namespace ts { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; questionDotToken?: QuestionDotToken; - name: Identifier; + name: Identifier | PrivateName; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; + name: Identifier; } export interface SuperPropertyAccessExpression extends PropertyAccessExpression { expression: SuperExpression; @@ -1105,6 +1111,7 @@ declare namespace ts { export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; expression: EntityNameExpression; + name: Identifier; } export interface ElementAccessExpression extends MemberExpression { kind: SyntaxKind.ElementAccessExpression; @@ -3440,9 +3447,9 @@ declare namespace ts { * @returns The unescaped identifier text. */ function unescapeLeadingUnderscores(identifier: __String): string; - function idText(identifier: Identifier): string; + function idText(identifierOrPrivateName: Identifier | PrivateName): string; function symbolName(symbol: Symbol): string; - function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined; + function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateName | undefined; function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** * Gets the JSDoc parameter tags for the node if present. @@ -3538,6 +3545,8 @@ declare namespace ts { function isIdentifier(node: Node): node is Identifier; function isQualifiedName(node: Node): node is QualifiedName; function isComputedPropertyName(node: Node): node is ComputedPropertyName; + function isPrivateName(node: Node): node is PrivateName; + function isIdentifierOrPrivateName(node: Node): node is Identifier | PrivateName; function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration; function isParameter(node: Node): node is ParameterDeclaration; function isDecorator(node: Node): node is Decorator; @@ -4031,8 +4040,8 @@ declare namespace ts { function updateArrayLiteral(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; function createObjectLiteral(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; - function createPropertyAccess(expression: Expression, name: string | Identifier): PropertyAccessExpression; - function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression; + function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateName): PropertyAccessExpression; + function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateName): PropertyAccessExpression; function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain; function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain; function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; @@ -4942,6 +4951,9 @@ declare namespace ts { interface Identifier { readonly text: string; } + interface PrivateName { + readonly text: string; + } interface Symbol { readonly name: string; getFlags(): SymbolFlags; diff --git a/tests/baselines/reference/privateNameAndIndexSignature.js b/tests/baselines/reference/privateNameAndIndexSignature.js new file mode 100644 index 0000000000000..d1271acca8ce9 --- /dev/null +++ b/tests/baselines/reference/privateNameAndIndexSignature.js @@ -0,0 +1,16 @@ +//// [privateNameAndIndexSignature.ts] +class A { + [k: string]: any; + constructor(message: string) { + this.#f = 3 // Error Property '#f' does not exist on type 'A'. + } +} + + +//// [privateNameAndIndexSignature.js] +var A = /** @class */ (function () { + function A(message) { + this.#f = 3; // Error Property '#f' does not exist on type 'A'. + } + return A; +}()); diff --git a/tests/baselines/reference/privateNameAndIndexSignature.symbols b/tests/baselines/reference/privateNameAndIndexSignature.symbols new file mode 100644 index 0000000000000..d8a153c04270e --- /dev/null +++ b/tests/baselines/reference/privateNameAndIndexSignature.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts === +class A { +>A : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) + + [k: string]: any; +>k : Symbol(k, Decl(privateNameAndIndexSignature.ts, 1, 5)) + + constructor(message: string) { +>message : Symbol(message, Decl(privateNameAndIndexSignature.ts, 2, 16)) + + this.#f = 3 // Error Property '#f' does not exist on type 'A'. +>this : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) + } +} + diff --git a/tests/baselines/reference/privateNameAndIndexSignature.types b/tests/baselines/reference/privateNameAndIndexSignature.types new file mode 100644 index 0000000000000..450cfdef6b3bd --- /dev/null +++ b/tests/baselines/reference/privateNameAndIndexSignature.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts === +class A { +>A : A + + [k: string]: any; +>k : string + + constructor(message: string) { +>message : string + + this.#f = 3 // Error Property '#f' does not exist on type 'A'. +>this.#f = 3 : 3 +>this.#f : any +>this : this +>#f : any +>3 : 3 + } +} + diff --git a/tests/baselines/reference/privateNameField.errors.txt b/tests/baselines/reference/privateNameField.errors.txt new file mode 100644 index 0000000000000..a4539bf375f5f --- /dev/null +++ b/tests/baselines/reference/privateNameField.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/classes/members/privateNames/privateNameField.ts(4,14): error TS2339: Property '#name' does not exist on type 'A'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameField.ts (1 errors) ==== + class A { + #name: string; + constructor(name: string) { + this.#name = name; + ~~~~~ +!!! error TS2339: Property '#name' does not exist on type 'A'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameField.js b/tests/baselines/reference/privateNameField.js new file mode 100644 index 0000000000000..f432be2b3d336 --- /dev/null +++ b/tests/baselines/reference/privateNameField.js @@ -0,0 +1,15 @@ +//// [privateNameField.ts] +class A { + #name: string; + constructor(name: string) { + this.#name = name; + } +} + +//// [privateNameField.js] +var A = /** @class */ (function () { + function A(name) { + this.#name = name; + } + return A; +}()); diff --git a/tests/baselines/reference/privateNameField.symbols b/tests/baselines/reference/privateNameField.symbols new file mode 100644 index 0000000000000..1eb98dbdb030c --- /dev/null +++ b/tests/baselines/reference/privateNameField.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameField.ts === +class A { +>A : Symbol(A, Decl(privateNameField.ts, 0, 0)) + + #name: string; +>#name : Symbol(A[#name], Decl(privateNameField.ts, 0, 9)) + + constructor(name: string) { +>name : Symbol(name, Decl(privateNameField.ts, 2, 16)) + + this.#name = name; +>this : Symbol(A, Decl(privateNameField.ts, 0, 0)) +>name : Symbol(name, Decl(privateNameField.ts, 2, 16)) + } +} diff --git a/tests/baselines/reference/privateNameField.types b/tests/baselines/reference/privateNameField.types new file mode 100644 index 0000000000000..e99da97e1e562 --- /dev/null +++ b/tests/baselines/reference/privateNameField.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameField.ts === +class A { +>A : A + + #name: string; +>#name : string + + constructor(name: string) { +>name : string + + this.#name = name; +>this.#name = name : string +>this.#name : any +>this : this +>#name : any +>name : string + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts b/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts new file mode 100644 index 0000000000000..d4c0b8ad46efb --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts @@ -0,0 +1,6 @@ +class A { + [k: string]: any; + constructor(message: string) { + this.#f = 3 // Error Property '#f' does not exist on type 'A'. + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameField.ts b/tests/cases/conformance/classes/members/privateNames/privateNameField.ts new file mode 100644 index 0000000000000..02e449fb3e002 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameField.ts @@ -0,0 +1,6 @@ +class A { + #name: string; + constructor(name: string) { + this.#name = name; + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/hoverOverPrivateName.ts b/tests/cases/fourslash/hoverOverPrivateName.ts new file mode 100644 index 0000000000000..28e748b9aa43c --- /dev/null +++ b/tests/cases/fourslash/hoverOverPrivateName.ts @@ -0,0 +1,15 @@ +/// + +////class A { +//// #foo: number; +//// +//// constructor () { +//// this./**/#foo = 3; +//// } +//// +////} + +goTo.marker(); +verify.quickInfoIs(""); +verify.goToDefinitionIs([]); +verify.noReferences(); \ No newline at end of file From 8050d4f5dfa1338ce556a87f593bd6212daa8099 Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Sun, 22 Dec 2019 16:05:36 +0000 Subject: [PATCH 04/16] =?UTF-8?q?update=20parser=20error=20recovery=20test?= =?UTF-8?q?s=20to=20use=20=C2=AC=20not=20#?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The intent of the tests seemed to be to regiment the behavior of the parser when a weird symbol is encountered. The `#` is now taken by private identifiers, so `¬` seems like a good new choice for keeping the diff small, since it also fits in 16 bits (wide emojis would be treated as multiple characters, since the scanner uses ++). Signed-off-by: Max Heiber --- src/compiler/parser.ts | 16 +++++++++++----- .../MemberFunctionDeclaration8_es6.errors.txt | 2 +- .../reference/MemberFunctionDeclaration8_es6.js | 2 +- .../MemberFunctionDeclaration8_es6.symbols | 2 +- .../MemberFunctionDeclaration8_es6.types | 2 +- .../parseErrorInHeritageClause1.errors.txt | 2 +- .../reference/parseErrorInHeritageClause1.js | 2 +- .../parseErrorInHeritageClause1.symbols | 2 +- .../reference/parseErrorInHeritageClause1.types | 2 +- .../parserErrorRecovery_Block2.errors.txt | 2 +- .../reference/parserErrorRecovery_Block2.js | 2 +- .../reference/parserErrorRecovery_Block2.symbols | 2 +- .../reference/parserErrorRecovery_Block2.types | 2 +- .../parserErrorRecovery_ClassElement3.errors.txt | 4 ++-- .../parserErrorRecovery_ClassElement3.js | 4 ++-- .../parserErrorRecovery_ClassElement3.symbols | 4 ++-- .../parserErrorRecovery_ClassElement3.types | 4 ++-- ...parserErrorRecovery_ParameterList4.errors.txt | 2 +- .../parserErrorRecovery_ParameterList4.js | 2 +- .../parserErrorRecovery_ParameterList4.symbols | 2 +- .../parserErrorRecovery_ParameterList4.types | 2 +- .../reference/parserSkippedTokens16.errors.txt | 2 +- .../baselines/reference/parserSkippedTokens16.js | 2 +- .../reference/parserSkippedTokens16.symbols | 2 +- .../reference/parserSkippedTokens16.types | 2 +- .../baselines/reference/shebangError.errors.txt | 4 ++-- .../compiler/parseErrorInHeritageClause1.ts | 2 +- .../MemberFunctionDeclaration8_es6.ts | 2 +- .../Blocks/parserErrorRecovery_Block2.ts | 2 +- .../parserErrorRecovery_ClassElement3.ts | 4 ++-- .../parserErrorRecovery_ParameterList4.ts | 2 +- .../SkippedTokens/parserSkippedTokens16.ts | 2 +- 32 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b2e2a9afbb07f..9261b97def4f1 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2242,7 +2242,7 @@ namespace ts { break; } dotPos = scanner.getStartPos(); - entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords)); + entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords, /* allowPrivateNames */ false) as Identifier); } return entity; } @@ -2254,7 +2254,7 @@ namespace ts { return finishNode(node); } - function parseRightSideOfDot(allowIdentifierNames: boolean): Identifier { + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateNames: boolean): Identifier | PrivateName { // Technically a keyword is valid here as all identifiers and keywords are identifier names. // However, often we'll encounter this in error situations when the identifier or keyword // is actually starting another valid construct. @@ -2285,6 +2285,10 @@ namespace ts { } } + if (allowPrivateNames && token() === SyntaxKind.PrivateName) { + return parsePrivateName(); + } + return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); } @@ -4358,7 +4362,8 @@ namespace ts { const node = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); node.expression = expression; parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); - node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); + // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic + node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateNames*/ true); return finishNode(node); } @@ -4529,7 +4534,7 @@ namespace ts { while (parseOptional(SyntaxKind.DotToken)) { const propertyAccess: JsxTagNamePropertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); propertyAccess.expression = expression; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); + propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateNames*/ true); expression = finishNode(propertyAccess); } return expression; @@ -4646,7 +4651,8 @@ namespace ts { const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); propertyAccess.expression = expression; propertyAccess.questionDotToken = questionDotToken; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); + propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateNames*/ true); + if (questionDotToken || expression.flags & NodeFlags.OptionalChain) { propertyAccess.flags |= NodeFlags.OptionalChain; } diff --git a/tests/baselines/reference/MemberFunctionDeclaration8_es6.errors.txt b/tests/baselines/reference/MemberFunctionDeclaration8_es6.errors.txt index 94198b36c9033..d2e603d224c85 100644 --- a/tests/baselines/reference/MemberFunctionDeclaration8_es6.errors.txt +++ b/tests/baselines/reference/MemberFunctionDeclaration8_es6.errors.txt @@ -9,7 +9,7 @@ tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration class C { foo() { // Make sure we don't think of *bar as the start of a generator method. - if (a) # * bar; + if (a) ¬ * bar; ~ !!! error TS2304: Cannot find name 'a'. diff --git a/tests/baselines/reference/MemberFunctionDeclaration8_es6.js b/tests/baselines/reference/MemberFunctionDeclaration8_es6.js index 853310e5a3efe..a44ff273fa000 100644 --- a/tests/baselines/reference/MemberFunctionDeclaration8_es6.js +++ b/tests/baselines/reference/MemberFunctionDeclaration8_es6.js @@ -2,7 +2,7 @@ class C { foo() { // Make sure we don't think of *bar as the start of a generator method. - if (a) # * bar; + if (a) ¬ * bar; return bar; } } diff --git a/tests/baselines/reference/MemberFunctionDeclaration8_es6.symbols b/tests/baselines/reference/MemberFunctionDeclaration8_es6.symbols index 0229450477c63..80218909dd97a 100644 --- a/tests/baselines/reference/MemberFunctionDeclaration8_es6.symbols +++ b/tests/baselines/reference/MemberFunctionDeclaration8_es6.symbols @@ -6,7 +6,7 @@ class C { >foo : Symbol(C.foo, Decl(MemberFunctionDeclaration8_es6.ts, 0, 9)) // Make sure we don't think of *bar as the start of a generator method. - if (a) # * bar; + if (a) ¬ * bar; return bar; } } diff --git a/tests/baselines/reference/MemberFunctionDeclaration8_es6.types b/tests/baselines/reference/MemberFunctionDeclaration8_es6.types index b0234b4135ee3..2f4c7b3bb0b44 100644 --- a/tests/baselines/reference/MemberFunctionDeclaration8_es6.types +++ b/tests/baselines/reference/MemberFunctionDeclaration8_es6.types @@ -6,7 +6,7 @@ class C { >foo : () => any // Make sure we don't think of *bar as the start of a generator method. - if (a) # * bar; + if (a) ¬ * bar; >a : any > : any >* bar : number diff --git a/tests/baselines/reference/parseErrorInHeritageClause1.errors.txt b/tests/baselines/reference/parseErrorInHeritageClause1.errors.txt index 67564442b3abc..6f705d2e04978 100644 --- a/tests/baselines/reference/parseErrorInHeritageClause1.errors.txt +++ b/tests/baselines/reference/parseErrorInHeritageClause1.errors.txt @@ -3,7 +3,7 @@ tests/cases/compiler/parseErrorInHeritageClause1.ts(1,19): error TS1127: Invalid ==== tests/cases/compiler/parseErrorInHeritageClause1.ts (2 errors) ==== - class C extends A # { + class C extends A ¬ { ~ !!! error TS2304: Cannot find name 'A'. diff --git a/tests/baselines/reference/parseErrorInHeritageClause1.js b/tests/baselines/reference/parseErrorInHeritageClause1.js index da02ae9cf2547..d0d1331e44a29 100644 --- a/tests/baselines/reference/parseErrorInHeritageClause1.js +++ b/tests/baselines/reference/parseErrorInHeritageClause1.js @@ -1,5 +1,5 @@ //// [parseErrorInHeritageClause1.ts] -class C extends A # { +class C extends A ¬ { } //// [parseErrorInHeritageClause1.js] diff --git a/tests/baselines/reference/parseErrorInHeritageClause1.symbols b/tests/baselines/reference/parseErrorInHeritageClause1.symbols index 5e0d3d26d38da..f320c9da7a171 100644 --- a/tests/baselines/reference/parseErrorInHeritageClause1.symbols +++ b/tests/baselines/reference/parseErrorInHeritageClause1.symbols @@ -1,4 +1,4 @@ === tests/cases/compiler/parseErrorInHeritageClause1.ts === -class C extends A # { +class C extends A ¬ { >C : Symbol(C, Decl(parseErrorInHeritageClause1.ts, 0, 0)) } diff --git a/tests/baselines/reference/parseErrorInHeritageClause1.types b/tests/baselines/reference/parseErrorInHeritageClause1.types index 53f0a622054d3..3a15b180545c6 100644 --- a/tests/baselines/reference/parseErrorInHeritageClause1.types +++ b/tests/baselines/reference/parseErrorInHeritageClause1.types @@ -1,5 +1,5 @@ === tests/cases/compiler/parseErrorInHeritageClause1.ts === -class C extends A # { +class C extends A ¬ { >C : C >A : any } diff --git a/tests/baselines/reference/parserErrorRecovery_Block2.errors.txt b/tests/baselines/reference/parserErrorRecovery_Block2.errors.txt index 53279be443f66..5aca4625d6caf 100644 --- a/tests/baselines/reference/parserErrorRecovery_Block2.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_Block2.errors.txt @@ -3,7 +3,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecov ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block2.ts (1 errors) ==== function f() { - # + ¬ !!! error TS1127: Invalid character. return; diff --git a/tests/baselines/reference/parserErrorRecovery_Block2.js b/tests/baselines/reference/parserErrorRecovery_Block2.js index 24ddaf0db3f2a..e2b66a5e7110a 100644 --- a/tests/baselines/reference/parserErrorRecovery_Block2.js +++ b/tests/baselines/reference/parserErrorRecovery_Block2.js @@ -1,6 +1,6 @@ //// [parserErrorRecovery_Block2.ts] function f() { - # + ¬ return; } diff --git a/tests/baselines/reference/parserErrorRecovery_Block2.symbols b/tests/baselines/reference/parserErrorRecovery_Block2.symbols index 3d5a09d567ce6..2e7f029ef8eae 100644 --- a/tests/baselines/reference/parserErrorRecovery_Block2.symbols +++ b/tests/baselines/reference/parserErrorRecovery_Block2.symbols @@ -2,6 +2,6 @@ function f() { >f : Symbol(f, Decl(parserErrorRecovery_Block2.ts, 0, 0)) - # + ¬ return; } diff --git a/tests/baselines/reference/parserErrorRecovery_Block2.types b/tests/baselines/reference/parserErrorRecovery_Block2.types index 9850dc1cf0ea2..93eccb8487b5b 100644 --- a/tests/baselines/reference/parserErrorRecovery_Block2.types +++ b/tests/baselines/reference/parserErrorRecovery_Block2.types @@ -2,6 +2,6 @@ function f() { >f : () => void - # + ¬ return; } diff --git a/tests/baselines/reference/parserErrorRecovery_ClassElement3.errors.txt b/tests/baselines/reference/parserErrorRecovery_ClassElement3.errors.txt index 7f81c6114f6d2..703e7c2273824 100644 --- a/tests/baselines/reference/parserErrorRecovery_ClassElement3.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ClassElement3.errors.txt @@ -6,7 +6,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErr ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErrorRecovery_ClassElement3.ts (4 errors) ==== module M { - # + ¬ !!! error TS1127: Invalid character. class C { @@ -15,7 +15,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErr enum E { ~~~~ !!! error TS1109: Expression expected. - # + ¬ !!! error TS1127: Invalid character. diff --git a/tests/baselines/reference/parserErrorRecovery_ClassElement3.js b/tests/baselines/reference/parserErrorRecovery_ClassElement3.js index 36d98fa54003e..8a835357de61e 100644 --- a/tests/baselines/reference/parserErrorRecovery_ClassElement3.js +++ b/tests/baselines/reference/parserErrorRecovery_ClassElement3.js @@ -1,11 +1,11 @@ //// [parserErrorRecovery_ClassElement3.ts] module M { - # + ¬ class C { } @ enum E { - # + ¬ //// [parserErrorRecovery_ClassElement3.js] var M; diff --git a/tests/baselines/reference/parserErrorRecovery_ClassElement3.symbols b/tests/baselines/reference/parserErrorRecovery_ClassElement3.symbols index 5c1edc5b8f09f..47d3870a83aab 100644 --- a/tests/baselines/reference/parserErrorRecovery_ClassElement3.symbols +++ b/tests/baselines/reference/parserErrorRecovery_ClassElement3.symbols @@ -2,7 +2,7 @@ module M { >M : Symbol(M, Decl(parserErrorRecovery_ClassElement3.ts, 0, 0)) - # + ¬ class C { >C : Symbol(C, Decl(parserErrorRecovery_ClassElement3.ts, 1, 4)) } @@ -10,4 +10,4 @@ module M { enum E { >E : Symbol(E, Decl(parserErrorRecovery_ClassElement3.ts, 3, 4)) - # + ¬ diff --git a/tests/baselines/reference/parserErrorRecovery_ClassElement3.types b/tests/baselines/reference/parserErrorRecovery_ClassElement3.types index 68df4b2bbe22b..4dd701c5f8e2d 100644 --- a/tests/baselines/reference/parserErrorRecovery_ClassElement3.types +++ b/tests/baselines/reference/parserErrorRecovery_ClassElement3.types @@ -2,7 +2,7 @@ module M { >M : typeof M - # + ¬ class C { >C : C } @@ -11,4 +11,4 @@ module M { > : any >E : E - # + ¬ diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList4.errors.txt b/tests/baselines/reference/parserErrorRecovery_ParameterList4.errors.txt index fa97550dd192f..31f25375fa2f6 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList4.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList4.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserEr ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList4.ts (1 errors) ==== - function f(a,#) { + function f(a,¬) { !!! error TS1127: Invalid character. } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList4.js b/tests/baselines/reference/parserErrorRecovery_ParameterList4.js index 53775cad92ea3..a71f293479d1b 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList4.js +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList4.js @@ -1,5 +1,5 @@ //// [parserErrorRecovery_ParameterList4.ts] -function f(a,#) { +function f(a,¬) { } //// [parserErrorRecovery_ParameterList4.js] diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList4.symbols b/tests/baselines/reference/parserErrorRecovery_ParameterList4.symbols index df48ebfe04dec..01291f4cd9336 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList4.symbols +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList4.symbols @@ -1,5 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList4.ts === -function f(a,#) { +function f(a,¬) { >f : Symbol(f, Decl(parserErrorRecovery_ParameterList4.ts, 0, 0)) >a : Symbol(a, Decl(parserErrorRecovery_ParameterList4.ts, 0, 11)) } diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList4.types b/tests/baselines/reference/parserErrorRecovery_ParameterList4.types index 77b105f1d4cef..87d2ee122717b 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList4.types +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList4.types @@ -1,5 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList4.ts === -function f(a,#) { +function f(a,¬) { >f : (a: any) => void >a : any } diff --git a/tests/baselines/reference/parserSkippedTokens16.errors.txt b/tests/baselines/reference/parserSkippedTokens16.errors.txt index c35e013a22852..dc39b9c7e3113 100644 --- a/tests/baselines/reference/parserSkippedTokens16.errors.txt +++ b/tests/baselines/reference/parserSkippedTokens16.errors.txt @@ -19,7 +19,7 @@ tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens16.t !!! error TS2304: Cannot find name 'Bar'. ~ !!! error TS1005: ';' expected. - function Foo () # { } + function Foo () ¬ { } !!! error TS1127: Invalid character. 4+:5 diff --git a/tests/baselines/reference/parserSkippedTokens16.js b/tests/baselines/reference/parserSkippedTokens16.js index 2c3a9be876df5..ed11ebaa4a7ed 100644 --- a/tests/baselines/reference/parserSkippedTokens16.js +++ b/tests/baselines/reference/parserSkippedTokens16.js @@ -1,6 +1,6 @@ //// [parserSkippedTokens16.ts] foo(): Bar { } -function Foo () # { } +function Foo () ¬ { } 4+:5 module M { function a( diff --git a/tests/baselines/reference/parserSkippedTokens16.symbols b/tests/baselines/reference/parserSkippedTokens16.symbols index 213dc9965f98f..576a1dfd97d8d 100644 --- a/tests/baselines/reference/parserSkippedTokens16.symbols +++ b/tests/baselines/reference/parserSkippedTokens16.symbols @@ -1,6 +1,6 @@ === tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens16.ts === foo(): Bar { } -function Foo () # { } +function Foo () ¬ { } >Foo : Symbol(Foo, Decl(parserSkippedTokens16.ts, 0, 14)) 4+:5 diff --git a/tests/baselines/reference/parserSkippedTokens16.types b/tests/baselines/reference/parserSkippedTokens16.types index b9c24cfafbaf0..3a664ad6cded3 100644 --- a/tests/baselines/reference/parserSkippedTokens16.types +++ b/tests/baselines/reference/parserSkippedTokens16.types @@ -4,7 +4,7 @@ foo(): Bar { } >foo : any >Bar : any -function Foo () # { } +function Foo () ¬ { } >Foo : () => any 4+:5 diff --git a/tests/baselines/reference/shebangError.errors.txt b/tests/baselines/reference/shebangError.errors.txt index cba74ceaed75e..f94d4929d271e 100644 --- a/tests/baselines/reference/shebangError.errors.txt +++ b/tests/baselines/reference/shebangError.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/shebangError.ts(2,1): error TS1127: Invalid character. +tests/cases/compiler/shebangError.ts(2,1): error TS18008: '#!' can only be used at the start of a file. tests/cases/compiler/shebangError.ts(2,2): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/compiler/shebangError.ts(2,12): error TS2304: Cannot find name 'env'. tests/cases/compiler/shebangError.ts(2,16): error TS1005: ';' expected. @@ -9,7 +9,7 @@ tests/cases/compiler/shebangError.ts(2,16): error TS2304: Cannot find name 'node var foo = 'Shebang is only allowed on the first line'; #!/usr/bin/env node -!!! error TS1127: Invalid character. +!!! error TS18008: '#!' can only be used at the start of a file. ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~ diff --git a/tests/cases/compiler/parseErrorInHeritageClause1.ts b/tests/cases/compiler/parseErrorInHeritageClause1.ts index 84223192c7ad1..ac47ca740d07f 100644 --- a/tests/cases/compiler/parseErrorInHeritageClause1.ts +++ b/tests/cases/compiler/parseErrorInHeritageClause1.ts @@ -1,2 +1,2 @@ -class C extends A # { +class C extends A ¬ { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration8_es6.ts b/tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration8_es6.ts index e698257e94068..39718ce8b9529 100644 --- a/tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration8_es6.ts +++ b/tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration8_es6.ts @@ -2,7 +2,7 @@ class C { foo() { // Make sure we don't think of *bar as the start of a generator method. - if (a) # * bar; + if (a) ¬ * bar; return bar; } } \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block2.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block2.ts index 2473a9d1ffb1c..e3177accec7e9 100644 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block2.ts +++ b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block2.ts @@ -1,4 +1,4 @@ function f() { - # + ¬ return; } \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErrorRecovery_ClassElement3.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErrorRecovery_ClassElement3.ts index d4ea9d6078719..e6c6a2e10b903 100644 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErrorRecovery_ClassElement3.ts +++ b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErrorRecovery_ClassElement3.ts @@ -1,7 +1,7 @@ module M { - # + ¬ class C { } @ enum E { - # \ No newline at end of file + ¬ \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList4.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList4.ts index f46e46951454e..00770b5fba4e4 100644 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList4.ts +++ b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList4.ts @@ -1,2 +1,2 @@ -function f(a,#) { +function f(a,¬) { } \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens16.ts b/tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens16.ts index c583fc13d8229..be6281dcf80da 100644 --- a/tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens16.ts +++ b/tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens16.ts @@ -1,5 +1,5 @@ foo(): Bar { } -function Foo () # { } +function Foo () ¬ { } 4+:5 module M { function a( From 2ca8ad3b8b3a3ea2fc079705d63922b90c25c6e6 Mon Sep 17 00:00:00 2001 From: Joseph Watts Date: Tue, 9 Oct 2018 13:20:01 -0400 Subject: [PATCH 05/16] Fix display of private names in language server Signed-off-by: Joseph Watts Signed-off-by: Max Heiber --- src/compiler/checker.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b27f553ba014a..7259ae9367e45 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4882,10 +4882,13 @@ namespace ts { context.flags ^= NodeBuilderFlags.InInitialEntityName; } let firstChar = symbolName.charCodeAt(0); + if (isSingleOrDoubleQuote(firstChar) && some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { return createLiteral(getSpecifierForModuleSymbol(symbol, context)); } - const canUsePropertyAccess = isIdentifierStart(firstChar, languageVersion); + const canUsePropertyAccess = firstChar === CharacterCodes.hash ? + symbolName.length > 1 && isIdentifierStart(symbolName.charCodeAt(1), languageVersion) : + isIdentifierStart(firstChar, languageVersion); if (index === 0 || canUsePropertyAccess) { const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; From 969a4b04e7b70e9a1e1e3d738f4b1496a4cc7a01 Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Mon, 28 Jan 2019 15:23:47 -0500 Subject: [PATCH 06/16] Private Name Support in the Checker (#5) - [x] treat private names as unique: - case 1: cannot say that a variable is of a class type unless the variable points to an instance of the class - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts) - case 2: private names in class hierarchies do not conflict - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts) - [x] `#constructor` is reserved - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts) - check in `bindWorker`, where every node is visited - [x] Accessibility modifiers can't be used with private names - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts) - implemented in `checkAccessibilityModifiers`, using `ModifierFlags.AccessibilityModifier` - [x] `delete #foo` not allowed - [x] Private name accesses not allowed outside of the defining class - see test: https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts) - implemented in `checkDeleteExpression` - [x] Do [the right thing](https://gist.github.com/mheiber/b6fc7adb426c2e1cdaceb5d7786fc630) for nested classes mv private name tests together more checker tests for private names update naming and cleanup for check private names for private name support in the checker: - make names more consistent - remove unnecessary checks - add utility function to public API - other small cleanup Move getPropertyNameForUniqueESSymbol to utility for consistency with other calculation of special property names (starting with __), move the calculation of property names for unique es symbols to `utilities.ts`. private name tests strict+es6 Update private name tests to use 'strict' type checking and to target es6 instead of default. Makes the js output easier to read and tests more surface area with other checker features. error message for private names in obj literals Disallow decorating private-named properties because the spec is still in flux. Signed-off-by: Max Heiber --- src/compiler/binder.ts | 33 ++++- src/compiler/checker.ts | 134 ++++++++++++++---- src/compiler/diagnosticMessages.json | 33 ++++- src/compiler/transformers/es5.ts | 5 +- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 12 ++ .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + ...ionMapsGeneratedMapsEnableMapping.baseline | 34 +++++ ...onMapsGeneratedMapsEnableMapping2.baseline | 35 +++++ ...onMapsGeneratedMapsEnableMapping3.baseline | 34 +++++ ...neratedMapsEnableMapping_NoInline.baseline | 34 +++++ ...MapsEnableMapping_NoInlineSources.baseline | 34 +++++ .../privateNameAndIndexSignature.errors.txt | 15 ++ .../reference/privateNameAndIndexSignature.js | 24 +++- .../privateNameAndIndexSignature.symbols | 6 +- .../privateNameAndIndexSignature.types | 3 +- .../privateNameConstructorReserved.errors.txt | 12 ++ .../privateNameConstructorReserved.js | 16 +++ .../privateNameConstructorReserved.symbols | 10 ++ .../privateNameConstructorReserved.types | 10 ++ .../privateNameDuplicateField.errors.txt | 13 ++ .../reference/privateNameDuplicateField.js | 19 +++ .../privateNameDuplicateField.symbols | 13 ++ .../reference/privateNameDuplicateField.types | 15 ++ .../reference/privateNameField.errors.txt | 12 -- tests/baselines/reference/privateNameField.js | 24 +++- .../reference/privateNameField.symbols | 9 +- .../reference/privateNameField.types | 5 +- .../privateNameInObjectLiteral-1.errors.txt | 10 ++ .../reference/privateNameInObjectLiteral-1.js | 10 ++ .../privateNameInObjectLiteral-1.symbols | 9 ++ .../privateNameInObjectLiteral-1.types | 11 ++ .../privateNameInObjectLiteral-2.errors.txt | 12 ++ .../reference/privateNameInObjectLiteral-2.js | 13 ++ .../privateNameInObjectLiteral-2.symbols | 10 ++ .../privateNameInObjectLiteral-2.types | 11 ++ .../privateNameInObjectLiteral.errors.txt | 14 ++ .../reference/privateNameInObjectLiteral.js | 18 +++ .../privateNameInObjectLiteral.symbols | 17 +++ .../privateNameInObjectLiteral.types | 22 +++ ...tAccessibleOutsideDefiningClass.errors.txt | 17 +++ ...teNameNotAccessibleOutsideDefiningClass.js | 20 +++ ...eNotAccessibleOutsideDefiningClass.symbols | 13 ++ ...ameNotAccessibleOutsideDefiningClass.types | 18 +++ ...ivateNameNotAllowedOutsideClass.errors.txt | 15 ++ .../privateNameNotAllowedOutsideClass.js | 10 ++ .../privateNameNotAllowedOutsideClass.symbols | 5 + .../privateNameNotAllowedOutsideClass.types | 6 + .../privateNameSneakyRuntimeException.js | 47 ++++++ .../privateNameSneakyRuntimeException.symbols | 39 +++++ .../privateNameSneakyRuntimeException.types | 52 +++++++ .../privateNamesAndDecorators.errors.txt | 18 +++ .../reference/privateNamesAndDecorators.js | 19 +++ .../privateNamesAndDecorators.symbols | 24 ++++ .../reference/privateNamesAndDecorators.types | 22 +++ .../reference/privateNamesAndFields.js | 59 ++++++++ .../reference/privateNamesAndFields.symbols | 33 +++++ .../reference/privateNamesAndFields.types | 38 +++++ ...privateNamesAndGenericClasses-2.errors.txt | 46 ++++++ .../privateNamesAndGenericClasses-2.js | 53 +++++++ .../privateNamesAndGenericClasses-2.symbols | 82 +++++++++++ .../privateNamesAndGenericClasses-2.types | 89 ++++++++++++ .../privateNamesAndIndexedAccess.errors.txt | 41 ++++++ .../reference/privateNamesAndIndexedAccess.js | 27 ++++ .../privateNamesAndIndexedAccess.symbols | 29 ++++ .../privateNamesAndIndexedAccess.types | 30 ++++ .../reference/privateNamesAndMethods.js | 123 ++++++++++++++++ .../reference/privateNamesAndMethods.symbols | 80 +++++++++++ .../reference/privateNamesAndMethods.types | 95 +++++++++++++ .../reference/privateNamesAndStaticFields.js | 59 ++++++++ .../privateNamesAndStaticFields.symbols | 33 +++++ .../privateNamesAndStaticFields.types | 38 +++++ .../reference/privateNamesAndStaticMethods.js | 94 ++++++++++++ .../privateNamesAndStaticMethods.symbols | 80 +++++++++++ .../privateNamesAndStaticMethods.types | 95 +++++++++++++ .../reference/privateNamesAndkeyof.js | 29 ++++ .../reference/privateNamesAndkeyof.symbols | 20 +++ .../reference/privateNamesAndkeyof.types | 22 +++ .../privateNamesInGenericClasses.errors.txt | 32 +++++ .../reference/privateNamesInGenericClasses.js | 25 ++++ .../privateNamesInGenericClasses.symbols | 51 +++++++ .../privateNamesInGenericClasses.types | 46 ++++++ .../privateNamesInNestedClasses.errors.txt | 36 +++++ .../reference/privateNamesInNestedClasses.js | 62 ++++++++ .../privateNamesInNestedClasses.symbols | 79 +++++++++++ .../privateNamesInNestedClasses.types | 92 ++++++++++++ ...teNamesNoAccessibilityModifiers.errors.txt | 21 +++ .../privateNamesNoAccessibilityModifiers.js | 23 +++ ...ivateNamesNoAccessibilityModifiers.symbols | 19 +++ ...privateNamesNoAccessibilityModifiers.types | 23 +++ .../privateNamesNoConflictWhenInheriting.js | 43 ++++++ ...ivateNamesNoConflictWhenInheriting.symbols | 23 +++ ...privateNamesNoConflictWhenInheriting.types | 23 +++ .../reference/privateNamesNoDelete.errors.txt | 15 ++ .../reference/privateNamesNoDelete.js | 21 +++ .../reference/privateNamesNoDelete.symbols | 16 +++ .../reference/privateNamesNoDelete.types | 18 +++ ...vateNamesNotAllowedAsParameters.errors.txt | 21 +++ .../privateNamesNotAllowedAsParameters.js | 17 +++ ...privateNamesNotAllowedAsParameters.symbols | 11 ++ .../privateNamesNotAllowedAsParameters.types | 11 ++ ...otAllowedInVariableDeclarations.errors.txt | 15 ++ ...teNamesNotAllowedInVariableDeclarations.js | 10 ++ ...esNotAllowedInVariableDeclarations.symbols | 5 + ...amesNotAllowedInVariableDeclarations.types | 6 + .../reference/privateNamesUnique.errors.txt | 20 +++ .../baselines/reference/privateNamesUnique.js | 28 ++++ .../reference/privateNamesUnique.symbols | 22 +++ .../reference/privateNamesUnique.types | 22 +++ .../privateNameAndIndexSignature.ts | 15 +- .../privateNameConstructorReserved.ts | 5 + .../privateNames/privateNameDuplicateField.ts | 7 + .../members/privateNames/privateNameField.ts | 13 +- .../privateNameInObjectLiteral-1.ts | 3 + .../privateNameInObjectLiteral-2.ts | 5 + ...teNameNotAccessibleOutsideDefiningClass.ts | 8 ++ .../privateNameNotAllowedOutsideClass.ts | 4 + .../privateNameSneakyRuntimeException.ts | 16 +++ .../privateNames/privateNamesAndDecorators.ts | 8 ++ .../privateNames/privateNamesAndFields.ts | 17 +++ .../privateNamesAndGenericClasses-2.ts | 29 ++++ .../privateNamesAndIndexedAccess.ts | 14 ++ .../privateNames/privateNamesAndMethods.ts | 32 +++++ .../privateNamesAndStaticFields.ts | 17 +++ .../privateNamesAndStaticMethods.ts | 33 +++++ .../privateNames/privateNamesAndkeyof.ts | 10 ++ .../privateNamesInGenericClasses.ts | 15 ++ .../privateNamesInNestedClasses.ts | 28 ++++ .../privateNamesNoAccessibilityModifiers.ts | 9 ++ .../privateNamesNoConflictWhenInheriting.ts | 12 ++ .../privateNames/privateNamesNoDelete.ts | 9 ++ .../privateNamesNotAllowedAsParameters.ts | 5 + ...teNamesNotAllowedInVariableDeclarations.ts | 4 + .../privateNames/privateNamesUnique.ts | 12 ++ 135 files changed, 3482 insertions(+), 78 deletions(-) create mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline create mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline create mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline create mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline create mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline create mode 100644 tests/baselines/reference/privateNameAndIndexSignature.errors.txt create mode 100644 tests/baselines/reference/privateNameConstructorReserved.errors.txt create mode 100644 tests/baselines/reference/privateNameConstructorReserved.js create mode 100644 tests/baselines/reference/privateNameConstructorReserved.symbols create mode 100644 tests/baselines/reference/privateNameConstructorReserved.types create mode 100644 tests/baselines/reference/privateNameDuplicateField.errors.txt create mode 100644 tests/baselines/reference/privateNameDuplicateField.js create mode 100644 tests/baselines/reference/privateNameDuplicateField.symbols create mode 100644 tests/baselines/reference/privateNameDuplicateField.types delete mode 100644 tests/baselines/reference/privateNameField.errors.txt create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-1.js create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-1.symbols create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-1.types create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-2.js create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-2.symbols create mode 100644 tests/baselines/reference/privateNameInObjectLiteral-2.types create mode 100644 tests/baselines/reference/privateNameInObjectLiteral.errors.txt create mode 100644 tests/baselines/reference/privateNameInObjectLiteral.js create mode 100644 tests/baselines/reference/privateNameInObjectLiteral.symbols create mode 100644 tests/baselines/reference/privateNameInObjectLiteral.types create mode 100644 tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt create mode 100644 tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js create mode 100644 tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols create mode 100644 tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types create mode 100644 tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt create mode 100644 tests/baselines/reference/privateNameNotAllowedOutsideClass.js create mode 100644 tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols create mode 100644 tests/baselines/reference/privateNameNotAllowedOutsideClass.types create mode 100644 tests/baselines/reference/privateNameSneakyRuntimeException.js create mode 100644 tests/baselines/reference/privateNameSneakyRuntimeException.symbols create mode 100644 tests/baselines/reference/privateNameSneakyRuntimeException.types create mode 100644 tests/baselines/reference/privateNamesAndDecorators.errors.txt create mode 100644 tests/baselines/reference/privateNamesAndDecorators.js create mode 100644 tests/baselines/reference/privateNamesAndDecorators.symbols create mode 100644 tests/baselines/reference/privateNamesAndDecorators.types create mode 100644 tests/baselines/reference/privateNamesAndFields.js create mode 100644 tests/baselines/reference/privateNamesAndFields.symbols create mode 100644 tests/baselines/reference/privateNamesAndFields.types create mode 100644 tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt create mode 100644 tests/baselines/reference/privateNamesAndGenericClasses-2.js create mode 100644 tests/baselines/reference/privateNamesAndGenericClasses-2.symbols create mode 100644 tests/baselines/reference/privateNamesAndGenericClasses-2.types create mode 100644 tests/baselines/reference/privateNamesAndIndexedAccess.errors.txt create mode 100644 tests/baselines/reference/privateNamesAndIndexedAccess.js create mode 100644 tests/baselines/reference/privateNamesAndIndexedAccess.symbols create mode 100644 tests/baselines/reference/privateNamesAndIndexedAccess.types create mode 100644 tests/baselines/reference/privateNamesAndMethods.js create mode 100644 tests/baselines/reference/privateNamesAndMethods.symbols create mode 100644 tests/baselines/reference/privateNamesAndMethods.types create mode 100644 tests/baselines/reference/privateNamesAndStaticFields.js create mode 100644 tests/baselines/reference/privateNamesAndStaticFields.symbols create mode 100644 tests/baselines/reference/privateNamesAndStaticFields.types create mode 100644 tests/baselines/reference/privateNamesAndStaticMethods.js create mode 100644 tests/baselines/reference/privateNamesAndStaticMethods.symbols create mode 100644 tests/baselines/reference/privateNamesAndStaticMethods.types create mode 100644 tests/baselines/reference/privateNamesAndkeyof.js create mode 100644 tests/baselines/reference/privateNamesAndkeyof.symbols create mode 100644 tests/baselines/reference/privateNamesAndkeyof.types create mode 100644 tests/baselines/reference/privateNamesInGenericClasses.errors.txt create mode 100644 tests/baselines/reference/privateNamesInGenericClasses.js create mode 100644 tests/baselines/reference/privateNamesInGenericClasses.symbols create mode 100644 tests/baselines/reference/privateNamesInGenericClasses.types create mode 100644 tests/baselines/reference/privateNamesInNestedClasses.errors.txt create mode 100644 tests/baselines/reference/privateNamesInNestedClasses.js create mode 100644 tests/baselines/reference/privateNamesInNestedClasses.symbols create mode 100644 tests/baselines/reference/privateNamesInNestedClasses.types create mode 100644 tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt create mode 100644 tests/baselines/reference/privateNamesNoAccessibilityModifiers.js create mode 100644 tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols create mode 100644 tests/baselines/reference/privateNamesNoAccessibilityModifiers.types create mode 100644 tests/baselines/reference/privateNamesNoConflictWhenInheriting.js create mode 100644 tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols create mode 100644 tests/baselines/reference/privateNamesNoConflictWhenInheriting.types create mode 100644 tests/baselines/reference/privateNamesNoDelete.errors.txt create mode 100644 tests/baselines/reference/privateNamesNoDelete.js create mode 100644 tests/baselines/reference/privateNamesNoDelete.symbols create mode 100644 tests/baselines/reference/privateNamesNoDelete.types create mode 100644 tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt create mode 100644 tests/baselines/reference/privateNamesNotAllowedAsParameters.js create mode 100644 tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols create mode 100644 tests/baselines/reference/privateNamesNotAllowedAsParameters.types create mode 100644 tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt create mode 100644 tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js create mode 100644 tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols create mode 100644 tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types create mode 100644 tests/baselines/reference/privateNamesUnique.errors.txt create mode 100644 tests/baselines/reference/privateNamesUnique.js create mode 100644 tests/baselines/reference/privateNamesUnique.symbols create mode 100644 tests/baselines/reference/privateNamesUnique.types create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 70532287217ee..c315f6567160b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -359,6 +359,16 @@ namespace ts { if (isWellKnownSymbolSyntactically(name)) { return getPropertyNameForKnownSymbolName(idText(name.name)); } + if (isPrivateName(name)) { + // containingClass exists because private names only allowed inside classes + const containingClass = getContainingClass(name.parent); + if (!containingClass) { + // we're in a case where there's a private name outside a class (invalid) + return undefined; + } + const containingClassSymbol = containingClass.symbol; + return getPropertyNameForPrivateNameDescription(containingClassSymbol, name.escapedText); + } return isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined; } switch (node.kind) { @@ -415,6 +425,10 @@ namespace ts { const isDefaultExport = hasModifier(node, ModifierFlags.Default); + // need this before getDeclarationName + if (isNamedDeclaration(node)) { + node.name.parent = node; + } // The exported symbol for an export default function/class node is always named "default" const name = isDefaultExport && parent ? InternalSymbolName.Default : getDeclarationName(node); @@ -467,11 +481,6 @@ namespace ts { symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); } else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.Assignment)) { - // Assignment declarations are allowed to merge with variables, no matter what other flags they have. - if (isNamedDeclaration(node)) { - node.name.parent = node; - } - // Report errors every position with duplicate declaration // Report errors on previous encountered declarations let message = symbol.flags & SymbolFlags.BlockScopedVariable @@ -2026,6 +2035,18 @@ namespace ts { return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode; } + // The binder visits every node, so this is a good place to check for + // the reserved private name (there is only one) + function checkPrivateName(node: PrivateName) { + if (node.escapedText === "#constructor") { + // Report error only if there are no parse errors in file + if (!file.parseDiagnostics.length) { + file.bindDiagnostics.push(createDiagnosticForNode(node, + Diagnostics.constructor_is_a_reserved_word, declarationNameToString(node))); + } + } + } + function checkStrictModeBinaryExpression(node: BinaryExpression) { if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) { // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an @@ -2298,6 +2319,8 @@ namespace ts { node.flowNode = currentFlow; } return checkStrictModeIdentifier(node); + case SyntaxKind.PrivateName: + return checkPrivateName(node as PrivateName); case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: const expr = node as PropertyAccessExpression | ElementAccessExpression; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7259ae9367e45..e5e17085a3f6e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -365,6 +365,7 @@ namespace ts { getDeclaredTypeOfSymbol, getPropertiesOfType, getPropertyOfType: (type, name) => getPropertyOfType(type, escapeLeadingUnderscores(name)), + getPropertyForPrivateName, getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, escapeLeadingUnderscores(name)), getIndexInfoOfType, getSignaturesOfType, @@ -1880,8 +1881,8 @@ namespace ts { } } - function diagnosticName(nameArg: __String | Identifier) { - return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier); + function diagnosticName(nameArg: __String | Identifier | PrivateName) { + return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier | PrivateName); } function isTypeParameterSymbolDeclaredInContainer(symbol: Symbol, container: Node) { @@ -3184,15 +3185,16 @@ namespace ts { return type; } - // A reserved member name starts with two underscores, but the third character cannot be an underscore - // or the @ symbol. A third underscore indicates an escaped form of an identifier that started + // A reserved member name starts with two underscores, but the third character cannot be an underscore, + // @, or #. A third underscore indicates an escaped form of an identifer that started // with at least two underscores. The @ character indicates that the name is denoted by a well known ES - // Symbol instance. + // Symbol instance and the # indicates that the name is a PrivateName. function isReservedMemberName(name: __String) { return (name as string).charCodeAt(0) === CharacterCodes._ && (name as string).charCodeAt(1) === CharacterCodes._ && (name as string).charCodeAt(2) !== CharacterCodes._ && - (name as string).charCodeAt(2) !== CharacterCodes.at; + (name as string).charCodeAt(2) !== CharacterCodes.at && + (name as string).charCodeAt(2) !== CharacterCodes.hash; } function getNamedMembers(members: SymbolTable): Symbol[] { @@ -8460,7 +8462,7 @@ namespace ts { */ function getPropertyNameFromType(type: StringLiteralType | NumberLiteralType | UniqueESSymbolType): __String { if (type.flags & TypeFlags.UniqueESSymbol) { - return (type).escapedName; + return getPropertyNameForUniqueESSymbol(type.symbol); } if (type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { return escapeLeadingUnderscores("" + (type).value); @@ -11843,6 +11845,9 @@ namespace ts { } function getLiteralTypeFromPropertyName(name: PropertyName) { + if (isPrivateName(name)) { + return neverType; + } return isIdentifier(name) ? getLiteralType(unescapeLeadingUnderscores(name.escapedText)) : getRegularTypeOfLiteralType(isComputedPropertyName(name) ? checkComputedPropertyName(name) : checkExpression(name)); } @@ -15877,6 +15882,7 @@ namespace ts { } function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: UnderscoreEscapedMap | undefined, isIntersectionConstituent: boolean): Ternary { + if (relation === identityRelation) { return propertiesIdenticalTo(source, target, excludedProperties); } @@ -15884,34 +15890,58 @@ namespace ts { const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false); if (unmatchedProperty) { if (reportErrors) { - const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false)); let shouldSkipElaboration = false; - if (!headMessage || (headMessage.code !== Diagnostics.Class_0_incorrectly_implements_interface_1.code && - headMessage.code !== Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) { - shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it - } - if (props.length === 1) { - const propName = symbolToString(unmatchedProperty); - reportError(Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, ...getTypeNamesForErrorDisplay(source, target)); - if (length(unmatchedProperty.declarations)) { - associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName)); + let hasReported = false; + if ( + unmatchedProperty.valueDeclaration + && isNamedDeclaration(unmatchedProperty.valueDeclaration) + && isPrivateName(unmatchedProperty.valueDeclaration.name) + && isClassDeclaration(source.symbol.valueDeclaration) + ) { + const privateNameDescription = unmatchedProperty.valueDeclaration.name.escapedText; + const symbolTableKey = getPropertyNameForPrivateNameDescription(source.symbol, privateNameDescription); + if (symbolTableKey && !!getPropertyOfType(source, symbolTableKey)) { + reportError( + Diagnostics.Property_0_is_missing_in_type_1_While_type_1_has_a_private_member_with_the_same_spelling_its_declaration_and_accessibility_are_distinct, + diagnosticName(privateNameDescription), + diagnosticName(source.symbol.valueDeclaration.name || ("(anonymous)" as __String)) + ); + hasReported = true; } if (shouldSkipElaboration && errorInfo) { overrideNextErrorInfo++; } } - else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) { - if (props.length > 5) { // arbitrary cutoff for too-long list form - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); + if (!hasReported) { + const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false)); + let shouldSkipElaboration = false; + if (!headMessage || (headMessage.code !== Diagnostics.Class_0_incorrectly_implements_interface_1.code && + headMessage.code !== Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) { + shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it } - else { - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); + if (props.length === 1) { + const propName = symbolToString(unmatchedProperty); + reportError(Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, ...getTypeNamesForErrorDisplay(source, target)); + if (length(unmatchedProperty.declarations)) { + associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName)); + } + if (shouldSkipElaboration && errorInfo) { + overrideNextErrorInfo++; + } } - if (shouldSkipElaboration && errorInfo) { - overrideNextErrorInfo++; + else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) { + if (props.length > 5) { // arbitrary cutoff for too-long list form + reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); + } + else { + reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); + } + if (shouldSkipElaboration && errorInfo) { + overrideNextErrorInfo++; + } } + // ELSE: No array like or unmatched property error - just issue top level error (errorInfo = undefined) } - // ELSE: No array like or unmatched property error - just issue top level error (errorInfo = undefined) } return Ternary.False; } @@ -23028,6 +23058,48 @@ namespace ts { return isCallOrNewExpression(node.parent) && node.parent.expression === node; } + function getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined { + let classWithShadowedPrivateName; + let container = getContainingClass(right); + while (container) { + const symbolTableKey = getPropertyNameForPrivateNameDescription(container.symbol, right.escapedText); + if (symbolTableKey) { + const prop = getPropertyOfType(apparentType, symbolTableKey); + if (prop) { + if (classWithShadowedPrivateName) { + if (errorNode) { + error( + errorNode, + Diagnostics.This_usage_of_0_refers_to_the_private_member_declared_in_its_enclosing_class_While_type_1_has_a_private_member_with_the_same_spelling_its_declaration_and_accessibility_are_distinct, + diagnosticName(right), + diagnosticName(classWithShadowedPrivateName.name || ("(anonymous)" as __String)) + ); + } + return undefined; + } + return prop; + } + else { + classWithShadowedPrivateName = container; + } + } + container = getContainingClass(container); + } + // If this isn't a case of shadowing, and the lhs has a property with the same + // private name description, then there is a privacy violation + if (leftType.symbol.members) { + const symbolTableKey = getPropertyNameForPrivateNameDescription(leftType.symbol, right.escapedText); + const prop = getPropertyOfType(apparentType, symbolTableKey); + if (prop) { + if (errorNode) { + error(right, Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_name, symbolToString(prop), typeToString(getDeclaringClass(prop)!)); + } + } + } + // not found + return undefined; + } + function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateName) { const parentSymbol = getNodeLinks(left).resolvedSymbol; const assignmentKind = getAssignmentTargetKind(node); @@ -23038,7 +23110,7 @@ namespace ts { } return apparentType; } - const prop = getPropertyOfType(apparentType, right.escapedText); + const prop = isPrivateName(right) ? getPropertyForPrivateName(apparentType, leftType, right, /* errorNode */ right) : getPropertyOfType(apparentType, right.escapedText); if (isIdentifier(left) && parentSymbol && !(prop && isConstEnumOrConstEnumOnlyModule(prop))) { markAliasReferenced(parentSymbol, node); } @@ -26424,6 +26496,9 @@ namespace ts { error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference); return booleanType; } + if (expr.kind === SyntaxKind.PropertyAccessExpression && isPrivateName((expr as PropertyAccessExpression).name)) { + error(expr, Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_private_name); + } const links = getNodeLinks(expr); const symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol); if (symbol && isReadonlySymbol(symbol)) { @@ -35144,6 +35219,9 @@ namespace ts { else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.ParameterPropertyModifier) && (node).dotDotDotToken) { return grammarErrorOnNode(node, Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter); } + else if (isNamedDeclaration(node) && (flags & ModifierFlags.AccessibilityModifier) && node.name.kind === SyntaxKind.PrivateName) { + return grammarErrorOnNode(node, Diagnostics.Accessibility_modifiers_cannot_be_used_with_private_names); + } if (flags & ModifierFlags.Async) { return checkGrammarAsyncModifier(node, lastAsync!); } @@ -35549,6 +35627,10 @@ namespace ts { return grammarErrorOnNode(prop.equalsToken!, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment); } + if (name.kind === SyntaxKind.PrivateName) { + return grammarErrorOnNode(name, Diagnostics.Private_names_are_not_allowed_outside_class_bodies); + } + // Modifiers are never allowed on properties except for 'async' on a method declaration if (prop.modifiers) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 21a6d0fae51ae..53eed06c725cc 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5361,6 +5361,37 @@ "'#!' can only be used at the start of a file.": { "category": "Error", "code": 18008 + }, + "Private names cannot be used as parameters": { + "category": "Error", + "code": 18009 + }, + "Accessibility modifiers cannot be used with private names.": { + "category": "Error", + "code": 18010 + }, + "The operand of a delete operator cannot be a private name.": { + "category": "Error", + "code": 18011 + }, + "'#constructor' is a reserved word.": { + "category": "Error", + "code": 18012 + }, + "Property '{0}' is not accessible outside class '{1}' because it has a private name.": { + "category": "Error", + "code": 18013 + }, + "This usage of '{0}' refers to the private member declared in its enclosing class. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct.": { + "category": "Error", + "code": 18014 + }, + "Property '{0}' is missing in type '{1}'. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct.": { + "category": "Error", + "code": 18015 + }, + "Private names are not allowed outside class bodies.": { + "category": "Error", + "code": 18016 } - } diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index dc9fa61b0e0ba..a695f22e7d308 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -82,7 +82,10 @@ namespace ts { * @param node A PropertyAccessExpression */ function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression { - const literalName = trySubstituteReservedName(cast(node.name, isIdentifier)); + if (isPrivateName(node.name)) { + return node; + } + const literalName = trySubstituteReservedName(node.name); if (literalName) { return setTextRange(createElementAccess(node.expression, literalName), node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d6d68c6482a08..87339929b1bc0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3347,6 +3347,7 @@ namespace ts { getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; + getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined; /* @internal */ getTypeOfPropertyOfType(type: Type, propertyName: string): Type | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c087b1e2eb05d..613d3802bfe81 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1584,6 +1584,10 @@ namespace ts { export function nodeCanBeDecorated(node: ClassElement, parent: Node): boolean; export function nodeCanBeDecorated(node: Node, parent: Node, grandparent: Node): boolean; export function nodeCanBeDecorated(node: Node, parent?: Node, grandparent?: Node): boolean { + // private names cannot be used with decorators yet + if (isNamedDeclaration(node) && isPrivateName(node.name)) { + return false; + } switch (node.kind) { case SyntaxKind.ClassDeclaration: // classes are valid targets @@ -2964,10 +2968,18 @@ namespace ts { } } + export function getPropertyNameForUniqueESSymbol(symbol: Symbol): __String { + return `__@${getSymbolId(symbol)}@${symbol.escapedName}` as __String; + } + export function getPropertyNameForKnownSymbolName(symbolName: string): __String { return "__@" + symbolName as __String; } + export function getPropertyNameForPrivateNameDescription(containingClassSymbol: Symbol, description: __String): __String { + return `__#${getSymbolId(containingClassSymbol)}@${description}` as __String; + } + export function isKnownSymbol(symbol: Symbol): boolean { return startsWith(symbol.escapedName as string, "__@"); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a58f546780f66..545c39107cca4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2009,6 +2009,7 @@ declare namespace ts { getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; + getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 6a52d40623c03..81f0e0bdd25bc 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2009,6 +2009,7 @@ declare namespace ts { getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; + getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline new file mode 100644 index 0000000000000..5fae8ec8c9914 --- /dev/null +++ b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline @@ -0,0 +1,34 @@ +EmitSkipped: false +FileName : ./dist/index.js +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Foo = /** @class */ (function () { + function Foo() { + } + Foo.prototype.methodName = function (propName) { }; + Foo.prototype.otherMethod = function () { + if (Math.random() > 0.5) { + return { x: 42 }; + } + return { y: "yes" }; + }; + return Foo; +}()); +exports.Foo = Foo; +FileName : ./dist/index.d.ts.map +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts +export declare class Foo { + member: string; + methodName(propName: SomeType): void; + otherMethod(): { + x: number; + y?: undefined; + } | { + y: string; + x?: undefined; + }; +} +export interface SomeType { + member: number; +} +//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline new file mode 100644 index 0000000000000..151713a03bd45 --- /dev/null +++ b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline @@ -0,0 +1,35 @@ +EmitSkipped: false +FileName : ./dist/index.js.map +{"version":3,"file":"index.js","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":";;AAAA;IAAA;IASA,CAAC;IAPG,wBAAU,GAAV,UAAW,QAAkB,IAAS,CAAC;IACvC,yBAAW,GAAX;QACI,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,EAAE;YACrB,OAAO,EAAC,CAAC,EAAE,EAAE,EAAC,CAAC;SAClB;QACD,OAAO,EAAC,CAAC,EAAE,KAAK,EAAC,CAAC;IACtB,CAAC;IACL,UAAC;AAAD,CAAC,AATD,IASC;AATY,kBAAG"}FileName : ./dist/index.js +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Foo = /** @class */ (function () { + function Foo() { + } + Foo.prototype.methodName = function (propName) { }; + Foo.prototype.otherMethod = function () { + if (Math.random() > 0.5) { + return { x: 42 }; + } + return { y: "yes" }; + }; + return Foo; +}()); +exports.Foo = Foo; +//# sourceMappingURL=index.js.mapFileName : ./dist/index.d.ts.map +{"version":3,"file":"index.d.ts","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts +export declare class Foo { + member: string; + methodName(propName: SomeType): void; + otherMethod(): { + x: number; + y?: undefined; + } | { + y: string; + x?: undefined; + }; +} +export interface SomeType { + member: number; +} +//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline new file mode 100644 index 0000000000000..f05cbbd4c351b --- /dev/null +++ b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline @@ -0,0 +1,34 @@ +EmitSkipped: false +FileName : ./dist/index.js +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Foo = /** @class */ (function () { + function Foo() { + } + Foo.prototype.methodName = function (propName) { }; + Foo.prototype.otherMethod = function () { + if (Math.random() > 0.5) { + return { x: 42 }; + } + return { y: "yes" }; + }; + return Foo; +}()); +exports.Foo = Foo; +FileName : ./dist/index.d.ts.map +{"version":3,"file":"index.d.ts","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts +export declare class Foo { + member: string; + methodName(propName: SomeType): void; + otherMethod(): { + x: number; + y?: undefined; + } | { + y: string; + x?: undefined; + }; +} +export interface SomeType { + member: number; +} +//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline new file mode 100644 index 0000000000000..ad51be6ddc0f5 --- /dev/null +++ b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline @@ -0,0 +1,34 @@ +EmitSkipped: false +FileName : ./dist/index.js +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Foo = /** @class */ (function () { + function Foo() { + } + Foo.prototype.methodName = function (propName) { }; + Foo.prototype.otherMethod = function () { + if (Math.random() > 0.5) { + return { x: 42 }; + } + return { y: "yes" }; + }; + return Foo; +}()); +exports.Foo = Foo; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0cy9jYXNlcy9mb3Vyc2xhc2gvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtJQUFBO0lBU0EsQ0FBQztJQVBHLHdCQUFVLEdBQVYsVUFBVyxRQUFrQixJQUFTLENBQUM7SUFDdkMseUJBQVcsR0FBWDtRQUNJLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsRUFBRTtZQUNyQixPQUFPLEVBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBQyxDQUFDO1NBQ2xCO1FBQ0QsT0FBTyxFQUFDLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN0QixDQUFDO0lBQ0wsVUFBQztBQUFELENBQUMsQUFURCxJQVNDO0FBVFksa0JBQUcifQ==FileName : ./dist/index.d.ts.map +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts +export declare class Foo { + member: string; + methodName(propName: SomeType): void; + otherMethod(): { + x: number; + y?: undefined; + } | { + y: string; + x?: undefined; + }; +} +export interface SomeType { + member: number; +} +//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline new file mode 100644 index 0000000000000..8f6440b29dc78 --- /dev/null +++ b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline @@ -0,0 +1,34 @@ +EmitSkipped: false +FileName : ./dist/index.js +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Foo = /** @class */ (function () { + function Foo() { + } + Foo.prototype.methodName = function (propName) { }; + Foo.prototype.otherMethod = function () { + if (Math.random() > 0.5) { + return { x: 42 }; + } + return { y: "yes" }; + }; + return Foo; +}()); +exports.Foo = Foo; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0cy9jYXNlcy9mb3Vyc2xhc2gvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtJQUFBO0lBU0EsQ0FBQztJQVBHLHdCQUFVLEdBQVYsVUFBVyxRQUFrQixJQUFTLENBQUM7SUFDdkMseUJBQVcsR0FBWDtRQUNJLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsRUFBRTtZQUNyQixPQUFPLEVBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBQyxDQUFDO1NBQ2xCO1FBQ0QsT0FBTyxFQUFDLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN0QixDQUFDO0lBQ0wsVUFBQztBQUFELENBQUMsQUFURCxJQVNDO0FBVFksa0JBQUciLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgRm9vIHtcbiAgICBtZW1iZXI6IHN0cmluZztcbiAgICBtZXRob2ROYW1lKHByb3BOYW1lOiBTb21lVHlwZSk6IHZvaWQge31cbiAgICBvdGhlck1ldGhvZCgpIHtcbiAgICAgICAgaWYgKE1hdGgucmFuZG9tKCkgPiAwLjUpIHtcbiAgICAgICAgICAgIHJldHVybiB7eDogNDJ9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7eTogXCJ5ZXNcIn07XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvbWVUeXBlIHtcbiAgICBtZW1iZXI6IG51bWJlcjtcbn0iXX0=FileName : ./dist/index.d.ts.map +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts +export declare class Foo { + member: string; + methodName(propName: SomeType): void; + otherMethod(): { + x: number; + y?: undefined; + } | { + y: string; + x?: undefined; + }; +} +export interface SomeType { + member: number; +} +//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/privateNameAndIndexSignature.errors.txt b/tests/baselines/reference/privateNameAndIndexSignature.errors.txt new file mode 100644 index 0000000000000..cbe22ffb7c156 --- /dev/null +++ b/tests/baselines/reference/privateNameAndIndexSignature.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts(6,14): error TS2339: Property '#f' does not exist on type 'A'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts (1 errors) ==== + // @target es6 + + class A { + [k: string]: any; + constructor(message: string) { + this.#f = 3 // Error Property '#f' does not exist on type 'A'. + ~~ +!!! error TS2339: Property '#f' does not exist on type 'A'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameAndIndexSignature.js b/tests/baselines/reference/privateNameAndIndexSignature.js index d1271acca8ce9..472406958ec72 100644 --- a/tests/baselines/reference/privateNameAndIndexSignature.js +++ b/tests/baselines/reference/privateNameAndIndexSignature.js @@ -1,4 +1,6 @@ //// [privateNameAndIndexSignature.ts] +// @target es6 + class A { [k: string]: any; constructor(message: string) { @@ -7,10 +9,18 @@ class A { } -//// [privateNameAndIndexSignature.js] -var A = /** @class */ (function () { - function A(message) { - this.#f = 3; // Error Property '#f' does not exist on type 'A'. - } - return A; -}()); +tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.js(5,15): error TS1003: Identifier expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.js (1 errors) ==== + "use strict"; + // @target es6 + var A = /** @class */ (function () { + function A(message) { + this. = 3; // Error Property '#f' does not exist on type 'A'. + ~ +!!! error TS1003: Identifier expected. + } + return A; + }()); + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameAndIndexSignature.symbols b/tests/baselines/reference/privateNameAndIndexSignature.symbols index d8a153c04270e..609eb3a491779 100644 --- a/tests/baselines/reference/privateNameAndIndexSignature.symbols +++ b/tests/baselines/reference/privateNameAndIndexSignature.symbols @@ -1,12 +1,14 @@ === tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts === +// @target es6 + class A { >A : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) [k: string]: any; ->k : Symbol(k, Decl(privateNameAndIndexSignature.ts, 1, 5)) +>k : Symbol(k, Decl(privateNameAndIndexSignature.ts, 3, 5)) constructor(message: string) { ->message : Symbol(message, Decl(privateNameAndIndexSignature.ts, 2, 16)) +>message : Symbol(message, Decl(privateNameAndIndexSignature.ts, 4, 16)) this.#f = 3 // Error Property '#f' does not exist on type 'A'. >this : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) diff --git a/tests/baselines/reference/privateNameAndIndexSignature.types b/tests/baselines/reference/privateNameAndIndexSignature.types index 450cfdef6b3bd..47015a920bb28 100644 --- a/tests/baselines/reference/privateNameAndIndexSignature.types +++ b/tests/baselines/reference/privateNameAndIndexSignature.types @@ -1,4 +1,6 @@ === tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts === +// @target es6 + class A { >A : A @@ -12,7 +14,6 @@ class A { >this.#f = 3 : 3 >this.#f : any >this : this ->#f : any >3 : 3 } } diff --git a/tests/baselines/reference/privateNameConstructorReserved.errors.txt b/tests/baselines/reference/privateNameConstructorReserved.errors.txt new file mode 100644 index 0000000000000..a387876bce30e --- /dev/null +++ b/tests/baselines/reference/privateNameConstructorReserved.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts(4,5): error TS18012: '#constructor' is a reserved word. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts (1 errors) ==== + // @target es6 + + class A { + #constructor() {} // Error: `#constructor` is a reserved word. + ~~~~~~~~~~~~ +!!! error TS18012: '#constructor' is a reserved word. + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameConstructorReserved.js b/tests/baselines/reference/privateNameConstructorReserved.js new file mode 100644 index 0000000000000..cab7f6b3e729e --- /dev/null +++ b/tests/baselines/reference/privateNameConstructorReserved.js @@ -0,0 +1,16 @@ +//// [privateNameConstructorReserved.ts] +// @target es6 + +class A { + #constructor() {} // Error: `#constructor` is a reserved word. +} + + +//// [privateNameConstructorReserved.js] +// @target es6 +var A = /** @class */ (function () { + function A() { + } + A.prototype[] = function () { }; // Error: `#constructor` is a reserved word. + return A; +}()); diff --git a/tests/baselines/reference/privateNameConstructorReserved.symbols b/tests/baselines/reference/privateNameConstructorReserved.symbols new file mode 100644 index 0000000000000..3f3cbc722039f --- /dev/null +++ b/tests/baselines/reference/privateNameConstructorReserved.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNameConstructorReserved.ts, 0, 0)) + + #constructor() {} // Error: `#constructor` is a reserved word. +>#constructor : Symbol(A.#constructor, Decl(privateNameConstructorReserved.ts, 2, 9)) +} + diff --git a/tests/baselines/reference/privateNameConstructorReserved.types b/tests/baselines/reference/privateNameConstructorReserved.types new file mode 100644 index 0000000000000..2b75281b7a02e --- /dev/null +++ b/tests/baselines/reference/privateNameConstructorReserved.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts === +// @target es6 + +class A { +>A : A + + #constructor() {} // Error: `#constructor` is a reserved word. +>#constructor : () => void +} + diff --git a/tests/baselines/reference/privateNameDuplicateField.errors.txt b/tests/baselines/reference/privateNameDuplicateField.errors.txt new file mode 100644 index 0000000000000..4a8428c6102c2 --- /dev/null +++ b/tests/baselines/reference/privateNameDuplicateField.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts(5,5): error TS2300: Duplicate identifier '#foo'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts (1 errors) ==== + // @target es6 + + class A { + #foo = "foo"; + #foo = "foo"; + ~~~~ +!!! error TS2300: Duplicate identifier '#foo'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameDuplicateField.js b/tests/baselines/reference/privateNameDuplicateField.js new file mode 100644 index 0000000000000..66b668a69b531 --- /dev/null +++ b/tests/baselines/reference/privateNameDuplicateField.js @@ -0,0 +1,19 @@ +//// [privateNameDuplicateField.ts] +// @target es6 + +class A { + #foo = "foo"; + #foo = "foo"; +} + + +//// [privateNameDuplicateField.js] +"use strict"; +// @target es6 +var A = /** @class */ (function () { + function A() { + this[] = "foo"; + this[] = "foo"; + } + return A; +}()); diff --git a/tests/baselines/reference/privateNameDuplicateField.symbols b/tests/baselines/reference/privateNameDuplicateField.symbols new file mode 100644 index 0000000000000..0da02e645ada3 --- /dev/null +++ b/tests/baselines/reference/privateNameDuplicateField.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNameDuplicateField.ts, 0, 0)) + + #foo = "foo"; +>#foo : Symbol(A.#foo, Decl(privateNameDuplicateField.ts, 2, 9), Decl(privateNameDuplicateField.ts, 3, 17)) + + #foo = "foo"; +>#foo : Symbol(A.#foo, Decl(privateNameDuplicateField.ts, 2, 9), Decl(privateNameDuplicateField.ts, 3, 17)) +} + diff --git a/tests/baselines/reference/privateNameDuplicateField.types b/tests/baselines/reference/privateNameDuplicateField.types new file mode 100644 index 0000000000000..e73152ebd4455 --- /dev/null +++ b/tests/baselines/reference/privateNameDuplicateField.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts === +// @target es6 + +class A { +>A : A + + #foo = "foo"; +>#foo : string +>"foo" : "foo" + + #foo = "foo"; +>#foo : string +>"foo" : "foo" +} + diff --git a/tests/baselines/reference/privateNameField.errors.txt b/tests/baselines/reference/privateNameField.errors.txt deleted file mode 100644 index a4539bf375f5f..0000000000000 --- a/tests/baselines/reference/privateNameField.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -tests/cases/conformance/classes/members/privateNames/privateNameField.ts(4,14): error TS2339: Property '#name' does not exist on type 'A'. - - -==== tests/cases/conformance/classes/members/privateNames/privateNameField.ts (1 errors) ==== - class A { - #name: string; - constructor(name: string) { - this.#name = name; - ~~~~~ -!!! error TS2339: Property '#name' does not exist on type 'A'. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameField.js b/tests/baselines/reference/privateNameField.js index f432be2b3d336..0ca8b2a817cd9 100644 --- a/tests/baselines/reference/privateNameField.js +++ b/tests/baselines/reference/privateNameField.js @@ -1,4 +1,6 @@ //// [privateNameField.ts] +// @target es6 + class A { #name: string; constructor(name: string) { @@ -6,10 +8,18 @@ class A { } } -//// [privateNameField.js] -var A = /** @class */ (function () { - function A(name) { - this.#name = name; - } - return A; -}()); +tests/cases/conformance/classes/members/privateNames/privateNameField.js(5,15): error TS1003: Identifier expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameField.js (1 errors) ==== + "use strict"; + // @target es6 + var A = /** @class */ (function () { + function A(name) { + this. = name; + ~ +!!! error TS1003: Identifier expected. + } + return A; + }()); + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameField.symbols b/tests/baselines/reference/privateNameField.symbols index 1eb98dbdb030c..c37ded65bd1a7 100644 --- a/tests/baselines/reference/privateNameField.symbols +++ b/tests/baselines/reference/privateNameField.symbols @@ -1,15 +1,18 @@ === tests/cases/conformance/classes/members/privateNames/privateNameField.ts === +// @target es6 + class A { >A : Symbol(A, Decl(privateNameField.ts, 0, 0)) #name: string; ->#name : Symbol(A[#name], Decl(privateNameField.ts, 0, 9)) +>#name : Symbol(A.#name, Decl(privateNameField.ts, 2, 9)) constructor(name: string) { ->name : Symbol(name, Decl(privateNameField.ts, 2, 16)) +>name : Symbol(name, Decl(privateNameField.ts, 4, 16)) this.#name = name; +>this.#name : Symbol(A.#name, Decl(privateNameField.ts, 2, 9)) >this : Symbol(A, Decl(privateNameField.ts, 0, 0)) ->name : Symbol(name, Decl(privateNameField.ts, 2, 16)) +>name : Symbol(name, Decl(privateNameField.ts, 4, 16)) } } diff --git a/tests/baselines/reference/privateNameField.types b/tests/baselines/reference/privateNameField.types index e99da97e1e562..db7dba04475e8 100644 --- a/tests/baselines/reference/privateNameField.types +++ b/tests/baselines/reference/privateNameField.types @@ -1,4 +1,6 @@ === tests/cases/conformance/classes/members/privateNames/privateNameField.ts === +// @target es6 + class A { >A : A @@ -10,9 +12,8 @@ class A { this.#name = name; >this.#name = name : string ->this.#name : any +>this.#name : string >this : this ->#name : any >name : string } } diff --git a/tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt b/tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt new file mode 100644 index 0000000000000..bdfe78ee02a78 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts(2,5): error TS18016: Private names are not allowed outside class bodies. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts (1 errors) ==== + const obj = { + #foo: 1 + ~~~~ +!!! error TS18016: Private names are not allowed outside class bodies. + }; + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameInObjectLiteral-1.js b/tests/baselines/reference/privateNameInObjectLiteral-1.js new file mode 100644 index 0000000000000..d9739f151e124 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-1.js @@ -0,0 +1,10 @@ +//// [privateNameInObjectLiteral-1.ts] +const obj = { + #foo: 1 +}; + + +//// [privateNameInObjectLiteral-1.js] +var obj = { + : 1 +}; diff --git a/tests/baselines/reference/privateNameInObjectLiteral-1.symbols b/tests/baselines/reference/privateNameInObjectLiteral-1.symbols new file mode 100644 index 0000000000000..c675ee7cc758c --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-1.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts === +const obj = { +>obj : Symbol(obj, Decl(privateNameInObjectLiteral-1.ts, 0, 5)) + + #foo: 1 +>#foo : Symbol(#foo, Decl(privateNameInObjectLiteral-1.ts, 0, 13)) + +}; + diff --git a/tests/baselines/reference/privateNameInObjectLiteral-1.types b/tests/baselines/reference/privateNameInObjectLiteral-1.types new file mode 100644 index 0000000000000..48de261be2900 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-1.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts === +const obj = { +>obj : {} +>{ #foo: 1} : {} + + #foo: 1 +>#foo : number +>1 : 1 + +}; + diff --git a/tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt b/tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt new file mode 100644 index 0000000000000..a75b09041d830 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts(2,5): error TS18016: Private names are not allowed outside class bodies. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts (1 errors) ==== + const obj = { + #foo() { + ~~~~ +!!! error TS18016: Private names are not allowed outside class bodies. + + } + }; + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameInObjectLiteral-2.js b/tests/baselines/reference/privateNameInObjectLiteral-2.js new file mode 100644 index 0000000000000..2dcbef0323613 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-2.js @@ -0,0 +1,13 @@ +//// [privateNameInObjectLiteral-2.ts] +const obj = { + #foo() { + + } +}; + + +//// [privateNameInObjectLiteral-2.js] +var obj = { + : function () { + } +}; diff --git a/tests/baselines/reference/privateNameInObjectLiteral-2.symbols b/tests/baselines/reference/privateNameInObjectLiteral-2.symbols new file mode 100644 index 0000000000000..b9a25ac870963 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-2.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts === +const obj = { +>obj : Symbol(obj, Decl(privateNameInObjectLiteral-2.ts, 0, 5)) + + #foo() { +>#foo : Symbol(#foo, Decl(privateNameInObjectLiteral-2.ts, 0, 13)) + + } +}; + diff --git a/tests/baselines/reference/privateNameInObjectLiteral-2.types b/tests/baselines/reference/privateNameInObjectLiteral-2.types new file mode 100644 index 0000000000000..a1e36e82380b1 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral-2.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts === +const obj = { +>obj : {} +>{ #foo() { }} : {} + + #foo() { +>#foo : () => void + + } +}; + diff --git a/tests/baselines/reference/privateNameInObjectLiteral.errors.txt b/tests/baselines/reference/privateNameInObjectLiteral.errors.txt new file mode 100644 index 0000000000000..2f5101ec98646 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts(2,5): error TS18010: Private names are not allowed outside class bodies. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts (1 errors) ==== + const obj = { + #foo: "#foo", + ~~~~ +!!! error TS18010: Private names are not allowed outside class bodies. + #bar: () => true, + #baz() { + return true; + } + }; + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameInObjectLiteral.js b/tests/baselines/reference/privateNameInObjectLiteral.js new file mode 100644 index 0000000000000..a95d80d4add5f --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral.js @@ -0,0 +1,18 @@ +//// [privateNameInObjectLiteral.ts] +const obj = { + #foo: "#foo", + #bar: () => true, + #baz() { + return true; + } +}; + + +//// [privateNameInObjectLiteral.js] +var obj = { + #foo: "#foo", + #bar: function () { return true; }, + #baz: function () { + return true; + } +}; diff --git a/tests/baselines/reference/privateNameInObjectLiteral.symbols b/tests/baselines/reference/privateNameInObjectLiteral.symbols new file mode 100644 index 0000000000000..f5592c7384305 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts === +const obj = { +>obj : Symbol(obj, Decl(privateNameInObjectLiteral.ts, 0, 5)) + + #foo: "#foo", +>#foo : Symbol(#foo, Decl(privateNameInObjectLiteral.ts, 0, 13)) + + #bar: () => true, +>#bar : Symbol(#bar, Decl(privateNameInObjectLiteral.ts, 1, 17)) + + #baz() { +>#baz : Symbol(#baz, Decl(privateNameInObjectLiteral.ts, 2, 21)) + + return true; + } +}; + diff --git a/tests/baselines/reference/privateNameInObjectLiteral.types b/tests/baselines/reference/privateNameInObjectLiteral.types new file mode 100644 index 0000000000000..372dc87bae5c3 --- /dev/null +++ b/tests/baselines/reference/privateNameInObjectLiteral.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts === +const obj = { +>obj : {} +>{ #foo: "#foo", #bar: () => true, #baz() { return true; }} : {} + + #foo: "#foo", +>#foo : string +>"#foo" : "#foo" + + #bar: () => true, +>#bar : () => boolean +>() => true : () => boolean +>true : true + + #baz() { +>#baz : () => boolean + + return true; +>true : true + } +}; + diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt new file mode 100644 index 0000000000000..5b4b1c66695e3 --- /dev/null +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt @@ -0,0 +1,17 @@ +tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts(7,9): error TS2339: Property '#foo' does not exist on type 'A'. +tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts(7,9): error TS18013: Property '#foo' is not accessible outside class 'A' because it has a private name. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts (2 errors) ==== + // @target es6 + + class A { + #foo: number = 3; + } + + new A().#foo = 4; // Error + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'A'. + ~~~~ +!!! error TS18013: Property '#foo' is not accessible outside class 'A' because it has a private name. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js new file mode 100644 index 0000000000000..355f1676c2377 --- /dev/null +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js @@ -0,0 +1,20 @@ +//// [privateNameNotAccessibleOutsideDefiningClass.ts] +// @target es6 + +class A { + #foo: number = 3; +} + +new A().#foo = 4; // Error + + +//// [privateNameNotAccessibleOutsideDefiningClass.js] +"use strict"; +// @target es6 +var A = /** @class */ (function () { + function A() { + this[] = 3; + } + return A; +}()); +new A(). = 4; // Error diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols new file mode 100644 index 0000000000000..8d9427fc6d603 --- /dev/null +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNameNotAccessibleOutsideDefiningClass.ts, 0, 0)) + + #foo: number = 3; +>#foo : Symbol(A.#foo, Decl(privateNameNotAccessibleOutsideDefiningClass.ts, 2, 9)) +} + +new A().#foo = 4; // Error +>A : Symbol(A, Decl(privateNameNotAccessibleOutsideDefiningClass.ts, 0, 0)) + diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types new file mode 100644 index 0000000000000..e6a0f5ac8f55b --- /dev/null +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts === +// @target es6 + +class A { +>A : A + + #foo: number = 3; +>#foo : number +>3 : 3 +} + +new A().#foo = 4; // Error +>new A().#foo = 4 : 4 +>new A().#foo : any +>new A() : A +>A : typeof A +>4 : 4 + diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt b/tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt new file mode 100644 index 0000000000000..2e72fffc7ba78 --- /dev/null +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(3,7): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(3,12): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(3,14): error TS1134: Variable declaration expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts (3 errors) ==== + // @target es6 + + const #foo = 3; + ~~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. \ No newline at end of file diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.js b/tests/baselines/reference/privateNameNotAllowedOutsideClass.js new file mode 100644 index 0000000000000..ff2b64b910ca1 --- /dev/null +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.js @@ -0,0 +1,10 @@ +//// [privateNameNotAllowedOutsideClass.ts] +// @target es6 + +const #foo = 3; + +//// [privateNameNotAllowedOutsideClass.js] +"use strict"; +// @target es6 +var ; +3; diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols b/tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols new file mode 100644 index 0000000000000..6d6883e7fdf59 --- /dev/null +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts === +// @target es6 +No type information for this code. +No type information for this code.const #foo = 3; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.types b/tests/baselines/reference/privateNameNotAllowedOutsideClass.types new file mode 100644 index 0000000000000..534e5b042580f --- /dev/null +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts === +// @target es6 + +const #foo = 3; +>3 : 3 + diff --git a/tests/baselines/reference/privateNameSneakyRuntimeException.js b/tests/baselines/reference/privateNameSneakyRuntimeException.js new file mode 100644 index 0000000000000..3a5b3a971f311 --- /dev/null +++ b/tests/baselines/reference/privateNameSneakyRuntimeException.js @@ -0,0 +1,47 @@ +//// [privateNameSneakyRuntimeException.ts] +// @target es6 + +function createClass () { + return class { + #foo = 3; + equals(other: any) { + return this.#foo = other.#foo; + } + }; +} + +const a = new (createClass())(); +const b = new (createClass())(); + +console.log(a.equals(b)); // OK at compile time but will be a runtime error + + +tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js(6,18): error TS1011: An element access expression should take an argument. +tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js(9,26): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js(9,34): error TS1003: Identifier expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js (3 errors) ==== + "use strict"; + // @target es6 + function createClass() { + return /** @class */ (function () { + function class_1() { + this[] = 3; + +!!! error TS1011: An element access expression should take an argument. + } + class_1.prototype.equals = function (other) { + return this. = other.; + ~ +!!! error TS1003: Identifier expected. + ~ +!!! error TS1003: Identifier expected. + }; + return class_1; + }()); + } + var a = new (createClass())(); + var b = new (createClass())(); + console.log(a.equals(b)); // OK at compile time but will be a runtime error + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameSneakyRuntimeException.symbols b/tests/baselines/reference/privateNameSneakyRuntimeException.symbols new file mode 100644 index 0000000000000..585bdbf782c43 --- /dev/null +++ b/tests/baselines/reference/privateNameSneakyRuntimeException.symbols @@ -0,0 +1,39 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts === +// @target es6 + +function createClass () { +>createClass : Symbol(createClass, Decl(privateNameSneakyRuntimeException.ts, 0, 0)) + + return class { + #foo = 3; +>#foo : Symbol((Anonymous class).#foo, Decl(privateNameSneakyRuntimeException.ts, 3, 18)) + + equals(other: any) { +>equals : Symbol((Anonymous class).equals, Decl(privateNameSneakyRuntimeException.ts, 4, 17)) +>other : Symbol(other, Decl(privateNameSneakyRuntimeException.ts, 5, 15)) + + return this.#foo = other.#foo; +>this.#foo : Symbol((Anonymous class).#foo, Decl(privateNameSneakyRuntimeException.ts, 3, 18)) +>this : Symbol((Anonymous class), Decl(privateNameSneakyRuntimeException.ts, 3, 10)) +>other : Symbol(other, Decl(privateNameSneakyRuntimeException.ts, 5, 15)) + } + }; +} + +const a = new (createClass())(); +>a : Symbol(a, Decl(privateNameSneakyRuntimeException.ts, 11, 5)) +>createClass : Symbol(createClass, Decl(privateNameSneakyRuntimeException.ts, 0, 0)) + +const b = new (createClass())(); +>b : Symbol(b, Decl(privateNameSneakyRuntimeException.ts, 12, 5)) +>createClass : Symbol(createClass, Decl(privateNameSneakyRuntimeException.ts, 0, 0)) + +console.log(a.equals(b)); // OK at compile time but will be a runtime error +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>a.equals : Symbol((Anonymous class).equals, Decl(privateNameSneakyRuntimeException.ts, 4, 17)) +>a : Symbol(a, Decl(privateNameSneakyRuntimeException.ts, 11, 5)) +>equals : Symbol((Anonymous class).equals, Decl(privateNameSneakyRuntimeException.ts, 4, 17)) +>b : Symbol(b, Decl(privateNameSneakyRuntimeException.ts, 12, 5)) + diff --git a/tests/baselines/reference/privateNameSneakyRuntimeException.types b/tests/baselines/reference/privateNameSneakyRuntimeException.types new file mode 100644 index 0000000000000..6f080bb585fca --- /dev/null +++ b/tests/baselines/reference/privateNameSneakyRuntimeException.types @@ -0,0 +1,52 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts === +// @target es6 + +function createClass () { +>createClass : () => typeof (Anonymous class) + + return class { +>class { #foo = 3; equals(other: any) { return this.#foo = other.#foo; } } : typeof (Anonymous class) + + #foo = 3; +>#foo : number +>3 : 3 + + equals(other: any) { +>equals : (other: any) => any +>other : any + + return this.#foo = other.#foo; +>this.#foo = other.#foo : any +>this.#foo : number +>this : this +>other.#foo : any +>other : any + } + }; +} + +const a = new (createClass())(); +>a : (Anonymous class) +>new (createClass())() : (Anonymous class) +>(createClass()) : typeof (Anonymous class) +>createClass() : typeof (Anonymous class) +>createClass : () => typeof (Anonymous class) + +const b = new (createClass())(); +>b : (Anonymous class) +>new (createClass())() : (Anonymous class) +>(createClass()) : typeof (Anonymous class) +>createClass() : typeof (Anonymous class) +>createClass : () => typeof (Anonymous class) + +console.log(a.equals(b)); // OK at compile time but will be a runtime error +>console.log(a.equals(b)) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>a.equals(b) : any +>a.equals : (other: any) => any +>a : (Anonymous class) +>equals : (other: any) => any +>b : (Anonymous class) + diff --git a/tests/baselines/reference/privateNamesAndDecorators.errors.txt b/tests/baselines/reference/privateNamesAndDecorators.errors.txt new file mode 100644 index 0000000000000..a17770c1cb2a7 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndDecorators.errors.txt @@ -0,0 +1,18 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts(4,5): error TS1206: Decorators are not valid here. +tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts(6,5): error TS1206: Decorators are not valid here. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts (2 errors) ==== + declare function dec(target: T): T; + + class A { + @dec // Error + ~ +!!! error TS1206: Decorators are not valid here. + #foo = 1; + @dec // Error + ~ +!!! error TS1206: Decorators are not valid here. + #bar(): void { } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndDecorators.js b/tests/baselines/reference/privateNamesAndDecorators.js new file mode 100644 index 0000000000000..3c50944ab04dc --- /dev/null +++ b/tests/baselines/reference/privateNamesAndDecorators.js @@ -0,0 +1,19 @@ +//// [privateNamesAndDecorators.ts] +declare function dec(target: T): T; + +class A { + @dec // Error + #foo = 1; + @dec // Error + #bar(): void { } +} + + +//// [privateNamesAndDecorators.js] +var A = /** @class */ (function () { + function A() { + this[] = 1; + } + A.prototype[] = function () { }; + return A; +}()); diff --git a/tests/baselines/reference/privateNamesAndDecorators.symbols b/tests/baselines/reference/privateNamesAndDecorators.symbols new file mode 100644 index 0000000000000..97463512cd910 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndDecorators.symbols @@ -0,0 +1,24 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts === +declare function dec(target: T): T; +>dec : Symbol(dec, Decl(privateNamesAndDecorators.ts, 0, 0)) +>T : Symbol(T, Decl(privateNamesAndDecorators.ts, 0, 21)) +>target : Symbol(target, Decl(privateNamesAndDecorators.ts, 0, 24)) +>T : Symbol(T, Decl(privateNamesAndDecorators.ts, 0, 21)) +>T : Symbol(T, Decl(privateNamesAndDecorators.ts, 0, 21)) + +class A { +>A : Symbol(A, Decl(privateNamesAndDecorators.ts, 0, 38)) + + @dec // Error +>dec : Symbol(dec, Decl(privateNamesAndDecorators.ts, 0, 0)) + + #foo = 1; +>#foo : Symbol(A.#foo, Decl(privateNamesAndDecorators.ts, 2, 9)) + + @dec // Error +>dec : Symbol(dec, Decl(privateNamesAndDecorators.ts, 0, 0)) + + #bar(): void { } +>#bar : Symbol(A.#bar, Decl(privateNamesAndDecorators.ts, 4, 13)) +} + diff --git a/tests/baselines/reference/privateNamesAndDecorators.types b/tests/baselines/reference/privateNamesAndDecorators.types new file mode 100644 index 0000000000000..828516f38999b --- /dev/null +++ b/tests/baselines/reference/privateNamesAndDecorators.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>target : T + +class A { +>A : A + + @dec // Error +>dec : (target: T) => T + + #foo = 1; +>#foo : number +>1 : 1 + + @dec // Error +>dec : (target: T) => T + + #bar(): void { } +>#bar : () => void +} + diff --git a/tests/baselines/reference/privateNamesAndFields.js b/tests/baselines/reference/privateNamesAndFields.js new file mode 100644 index 0000000000000..06aaa64003b63 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndFields.js @@ -0,0 +1,59 @@ +//// [privateNamesAndFields.ts] +// @target es6 + +class A { + #foo: number; + constructor () { + this.#foo = 3; + } +} + +class B extends A { + #foo: string; + constructor () { + super(); + this.#foo = "some string"; + } +} + + +tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.js(18,15): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.js(26,16): error TS1003: Identifier expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.js (2 errors) ==== + "use strict"; + // @target es6 + var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + })(); + var A = /** @class */ (function () { + function A() { + this. = 3; + ~ +!!! error TS1003: Identifier expected. + } + return A; + }()); + var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + var _this = _super.call(this) || this; + _this. = "some string"; + ~ +!!! error TS1003: Identifier expected. + return _this; + } + return B; + }(A)); + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndFields.symbols b/tests/baselines/reference/privateNamesAndFields.symbols new file mode 100644 index 0000000000000..5300cd0427ff0 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndFields.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) + + #foo: number; +>#foo : Symbol(A.#foo, Decl(privateNamesAndFields.ts, 2, 9)) + + constructor () { + this.#foo = 3; +>this.#foo : Symbol(A.#foo, Decl(privateNamesAndFields.ts, 2, 9)) +>this : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) + } +} + +class B extends A { +>B : Symbol(B, Decl(privateNamesAndFields.ts, 7, 1)) +>A : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) + + #foo: string; +>#foo : Symbol(B.#foo, Decl(privateNamesAndFields.ts, 9, 19)) + + constructor () { + super(); +>super : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) + + this.#foo = "some string"; +>this.#foo : Symbol(B.#foo, Decl(privateNamesAndFields.ts, 9, 19)) +>this : Symbol(B, Decl(privateNamesAndFields.ts, 7, 1)) + } +} + diff --git a/tests/baselines/reference/privateNamesAndFields.types b/tests/baselines/reference/privateNamesAndFields.types new file mode 100644 index 0000000000000..88a48ecd81298 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndFields.types @@ -0,0 +1,38 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts === +// @target es6 + +class A { +>A : A + + #foo: number; +>#foo : number + + constructor () { + this.#foo = 3; +>this.#foo = 3 : 3 +>this.#foo : number +>this : this +>3 : 3 + } +} + +class B extends A { +>B : B +>A : A + + #foo: string; +>#foo : string + + constructor () { + super(); +>super() : void +>super : typeof A + + this.#foo = "some string"; +>this.#foo = "some string" : "some string" +>this.#foo : string +>this : this +>"some string" : "some string" + } +} + diff --git a/tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt b/tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt new file mode 100644 index 0000000000000..58e321374b8c1 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt @@ -0,0 +1,46 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(24,3): error TS2339: Property '#foo' does not exist on type 'C'. +tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(24,3): error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. +tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(25,1): error TS2322: Type 'C' is not assignable to type 'C'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(26,1): error TS2322: Type 'C' is not assignable to type 'C'. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts (4 errors) ==== + class C { + #foo: T; + #bar(): T { + return this.#foo; + } + constructor(t: T) { + this.#foo = t; + t = this.#bar(); + } + set baz(t: T) { + this.#foo = t; + + } + get baz(): T { + return this.#foo; + } + } + + let a = new C(3); + let b = new C("hello"); + + a.baz = 5 // OK + const x: number = a.baz // OK + a.#foo; // Error + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'C'. + ~~~~ +!!! error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. + a = b; // Error + ~ +!!! error TS2322: Type 'C' is not assignable to type 'C'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + b = a; // Error + ~ +!!! error TS2322: Type 'C' is not assignable to type 'C'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndGenericClasses-2.js b/tests/baselines/reference/privateNamesAndGenericClasses-2.js new file mode 100644 index 0000000000000..fb344944965a7 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndGenericClasses-2.js @@ -0,0 +1,53 @@ +//// [privateNamesAndGenericClasses-2.ts] +class C { + #foo: T; + #bar(): T { + return this.#foo; + } + constructor(t: T) { + this.#foo = t; + t = this.#bar(); + } + set baz(t: T) { + this.#foo = t; + + } + get baz(): T { + return this.#foo; + } +} + +let a = new C(3); +let b = new C("hello"); + +a.baz = 5 // OK +const x: number = a.baz // OK +a.#foo; // Error +a = b; // Error +b = a; // Error + + +//// [privateNamesAndGenericClasses-2.js] +"use strict"; +class C { + constructor(t) { + this. = t; + t = this.(); + } + () { + return this.; + } + set baz(t) { + this. = t; + } + get baz() { + return this.; + } +} +let a = new C(3); +let b = new C("hello"); +a.baz = 5; // OK +const x = a.baz; // OK +a.; // Error +a = b; // Error +b = a; // Error diff --git a/tests/baselines/reference/privateNamesAndGenericClasses-2.symbols b/tests/baselines/reference/privateNamesAndGenericClasses-2.symbols new file mode 100644 index 0000000000000..0f84af4a027f0 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndGenericClasses-2.symbols @@ -0,0 +1,82 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts === +class C { +>C : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) +>T : Symbol(T, Decl(privateNamesAndGenericClasses-2.ts, 0, 8)) + + #foo: T; +>#foo : Symbol(C.#foo, Decl(privateNamesAndGenericClasses-2.ts, 0, 12)) +>T : Symbol(T, Decl(privateNamesAndGenericClasses-2.ts, 0, 8)) + + #bar(): T { +>#bar : Symbol(C.#bar, Decl(privateNamesAndGenericClasses-2.ts, 1, 12)) +>T : Symbol(T, Decl(privateNamesAndGenericClasses-2.ts, 0, 8)) + + return this.#foo; +>this.#foo : Symbol(C.#foo, Decl(privateNamesAndGenericClasses-2.ts, 0, 12)) +>this : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) + } + constructor(t: T) { +>t : Symbol(t, Decl(privateNamesAndGenericClasses-2.ts, 5, 16)) +>T : Symbol(T, Decl(privateNamesAndGenericClasses-2.ts, 0, 8)) + + this.#foo = t; +>this.#foo : Symbol(C.#foo, Decl(privateNamesAndGenericClasses-2.ts, 0, 12)) +>this : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) +>t : Symbol(t, Decl(privateNamesAndGenericClasses-2.ts, 5, 16)) + + t = this.#bar(); +>t : Symbol(t, Decl(privateNamesAndGenericClasses-2.ts, 5, 16)) +>this.#bar : Symbol(C.#bar, Decl(privateNamesAndGenericClasses-2.ts, 1, 12)) +>this : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) + } + set baz(t: T) { +>baz : Symbol(C.baz, Decl(privateNamesAndGenericClasses-2.ts, 8, 5), Decl(privateNamesAndGenericClasses-2.ts, 12, 5)) +>t : Symbol(t, Decl(privateNamesAndGenericClasses-2.ts, 9, 12)) +>T : Symbol(T, Decl(privateNamesAndGenericClasses-2.ts, 0, 8)) + + this.#foo = t; +>this.#foo : Symbol(C.#foo, Decl(privateNamesAndGenericClasses-2.ts, 0, 12)) +>this : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) +>t : Symbol(t, Decl(privateNamesAndGenericClasses-2.ts, 9, 12)) + + } + get baz(): T { +>baz : Symbol(C.baz, Decl(privateNamesAndGenericClasses-2.ts, 8, 5), Decl(privateNamesAndGenericClasses-2.ts, 12, 5)) +>T : Symbol(T, Decl(privateNamesAndGenericClasses-2.ts, 0, 8)) + + return this.#foo; +>this.#foo : Symbol(C.#foo, Decl(privateNamesAndGenericClasses-2.ts, 0, 12)) +>this : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) + } +} + +let a = new C(3); +>a : Symbol(a, Decl(privateNamesAndGenericClasses-2.ts, 18, 3)) +>C : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) + +let b = new C("hello"); +>b : Symbol(b, Decl(privateNamesAndGenericClasses-2.ts, 19, 3)) +>C : Symbol(C, Decl(privateNamesAndGenericClasses-2.ts, 0, 0)) + +a.baz = 5 // OK +>a.baz : Symbol(C.baz, Decl(privateNamesAndGenericClasses-2.ts, 8, 5), Decl(privateNamesAndGenericClasses-2.ts, 12, 5)) +>a : Symbol(a, Decl(privateNamesAndGenericClasses-2.ts, 18, 3)) +>baz : Symbol(C.baz, Decl(privateNamesAndGenericClasses-2.ts, 8, 5), Decl(privateNamesAndGenericClasses-2.ts, 12, 5)) + +const x: number = a.baz // OK +>x : Symbol(x, Decl(privateNamesAndGenericClasses-2.ts, 22, 5)) +>a.baz : Symbol(C.baz, Decl(privateNamesAndGenericClasses-2.ts, 8, 5), Decl(privateNamesAndGenericClasses-2.ts, 12, 5)) +>a : Symbol(a, Decl(privateNamesAndGenericClasses-2.ts, 18, 3)) +>baz : Symbol(C.baz, Decl(privateNamesAndGenericClasses-2.ts, 8, 5), Decl(privateNamesAndGenericClasses-2.ts, 12, 5)) + +a.#foo; // Error +>a : Symbol(a, Decl(privateNamesAndGenericClasses-2.ts, 18, 3)) + +a = b; // Error +>a : Symbol(a, Decl(privateNamesAndGenericClasses-2.ts, 18, 3)) +>b : Symbol(b, Decl(privateNamesAndGenericClasses-2.ts, 19, 3)) + +b = a; // Error +>b : Symbol(b, Decl(privateNamesAndGenericClasses-2.ts, 19, 3)) +>a : Symbol(a, Decl(privateNamesAndGenericClasses-2.ts, 18, 3)) + diff --git a/tests/baselines/reference/privateNamesAndGenericClasses-2.types b/tests/baselines/reference/privateNamesAndGenericClasses-2.types new file mode 100644 index 0000000000000..42f5b237d06fa --- /dev/null +++ b/tests/baselines/reference/privateNamesAndGenericClasses-2.types @@ -0,0 +1,89 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts === +class C { +>C : C + + #foo: T; +>#foo : T + + #bar(): T { +>#bar : () => T + + return this.#foo; +>this.#foo : T +>this : this + } + constructor(t: T) { +>t : T + + this.#foo = t; +>this.#foo = t : T +>this.#foo : T +>this : this +>t : T + + t = this.#bar(); +>t = this.#bar() : T +>t : T +>this.#bar() : T +>this.#bar : () => T +>this : this + } + set baz(t: T) { +>baz : T +>t : T + + this.#foo = t; +>this.#foo = t : T +>this.#foo : T +>this : this +>t : T + + } + get baz(): T { +>baz : T + + return this.#foo; +>this.#foo : T +>this : this + } +} + +let a = new C(3); +>a : C +>new C(3) : C +>C : typeof C +>3 : 3 + +let b = new C("hello"); +>b : C +>new C("hello") : C +>C : typeof C +>"hello" : "hello" + +a.baz = 5 // OK +>a.baz = 5 : 5 +>a.baz : number +>a : C +>baz : number +>5 : 5 + +const x: number = a.baz // OK +>x : number +>a.baz : number +>a : C +>baz : number + +a.#foo; // Error +>a.#foo : any +>a : C + +a = b; // Error +>a = b : C +>a : C +>b : C + +b = a; // Error +>b = a : C +>b : C +>a : C + diff --git a/tests/baselines/reference/privateNamesAndIndexedAccess.errors.txt b/tests/baselines/reference/privateNamesAndIndexedAccess.errors.txt new file mode 100644 index 0000000000000..e7927d6c752b5 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndIndexedAccess.errors.txt @@ -0,0 +1,41 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(7,28): error TS1005: ']' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(7,28): error TS2300: Duplicate identifier '#bar'. +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(7,28): error TS2717: Subsequent property declarations must have the same type. Property '#bar' must be of type 'number', but here has type 'any'. +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(7,32): error TS1005: ';' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(7,34): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(7,36): error TS7008: Member '3' implicitly has an 'any' type. +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(9,28): error TS2339: Property '#bar' does not exist on type 'C'. +tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts(11,1): error TS1128: Declaration or statement expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts (8 errors) ==== + class C { + foo = 3; + #bar = 3; + constructor () { + const ok: C["foo"] = 3; + // not supported yet, could support in future: + const badForNow: C[#bar] = 3; // Error + ~~~~ +!!! error TS1005: ']' expected. +!!! related TS1007 tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts:4:20: The parser expected to find a '}' to match the '{' token here. + ~~~~ +!!! error TS2300: Duplicate identifier '#bar'. + ~~~~ +!!! error TS2717: Subsequent property declarations must have the same type. Property '#bar' must be of type 'number', but here has type 'any'. +!!! related TS6203 tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts:3:5: '#bar' was also declared here. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. + ~ +!!! error TS7008: Member '3' implicitly has an 'any' type. + // will never use this syntax, already taken: + const badAlways: C["#bar"] = 3; // Error + ~~~~~~ +!!! error TS2339: Property '#bar' does not exist on type 'C'. + } + } + ~ +!!! error TS1128: Declaration or statement expected. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndIndexedAccess.js b/tests/baselines/reference/privateNamesAndIndexedAccess.js new file mode 100644 index 0000000000000..805c31f9ff3b1 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndIndexedAccess.js @@ -0,0 +1,27 @@ +//// [privateNamesAndIndexedAccess.ts] +class C { + foo = 3; + #bar = 3; + constructor () { + const ok: C["foo"] = 3; + // not supported yet, could support in future: + const badForNow: C[#bar] = 3; // Error + // will never use this syntax, already taken: + const badAlways: C["#bar"] = 3; // Error + } +} + + +//// [privateNamesAndIndexedAccess.js] +"use strict"; +class C { + constructor() { + this.foo = 3; + this[] = 3; + // will never use this syntax, already taken: + this.badAlways = 3; // Error + const ok = 3; + // not supported yet, could support in future: + const badForNow; + } +} diff --git a/tests/baselines/reference/privateNamesAndIndexedAccess.symbols b/tests/baselines/reference/privateNamesAndIndexedAccess.symbols new file mode 100644 index 0000000000000..43a743810dca6 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndIndexedAccess.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts === +class C { +>C : Symbol(C, Decl(privateNamesAndIndexedAccess.ts, 0, 0)) + + foo = 3; +>foo : Symbol(C.foo, Decl(privateNamesAndIndexedAccess.ts, 0, 9)) + + #bar = 3; +>#bar : Symbol(C.#bar, Decl(privateNamesAndIndexedAccess.ts, 1, 12), Decl(privateNamesAndIndexedAccess.ts, 6, 27)) + + constructor () { + const ok: C["foo"] = 3; +>ok : Symbol(ok, Decl(privateNamesAndIndexedAccess.ts, 4, 13)) +>C : Symbol(C, Decl(privateNamesAndIndexedAccess.ts, 0, 0)) + + // not supported yet, could support in future: + const badForNow: C[#bar] = 3; // Error +>badForNow : Symbol(badForNow, Decl(privateNamesAndIndexedAccess.ts, 6, 13)) +>C : Symbol(C, Decl(privateNamesAndIndexedAccess.ts, 0, 0)) +>#bar : Symbol(C.#bar, Decl(privateNamesAndIndexedAccess.ts, 1, 12), Decl(privateNamesAndIndexedAccess.ts, 6, 27)) +>3 : Symbol(C[3], Decl(privateNamesAndIndexedAccess.ts, 6, 34)) + + // will never use this syntax, already taken: + const badAlways: C["#bar"] = 3; // Error +>badAlways : Symbol(C.badAlways, Decl(privateNamesAndIndexedAccess.ts, 6, 37)) +>C : Symbol(C, Decl(privateNamesAndIndexedAccess.ts, 0, 0)) + } +} + diff --git a/tests/baselines/reference/privateNamesAndIndexedAccess.types b/tests/baselines/reference/privateNamesAndIndexedAccess.types new file mode 100644 index 0000000000000..84ac9d43ffed9 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndIndexedAccess.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts === +class C { +>C : C + + foo = 3; +>foo : number +>3 : 3 + + #bar = 3; +>#bar : number +>3 : 3 + + constructor () { + const ok: C["foo"] = 3; +>ok : number +>3 : 3 + + // not supported yet, could support in future: + const badForNow: C[#bar] = 3; // Error +>badForNow : C[] +>#bar : number +>3 : any + + // will never use this syntax, already taken: + const badAlways: C["#bar"] = 3; // Error +>badAlways : any +>3 : 3 + } +} + diff --git a/tests/baselines/reference/privateNamesAndMethods.js b/tests/baselines/reference/privateNamesAndMethods.js new file mode 100644 index 0000000000000..4df5f690afa0f --- /dev/null +++ b/tests/baselines/reference/privateNamesAndMethods.js @@ -0,0 +1,123 @@ +//// [privateNamesAndMethods.ts] +class A { + #foo(a: number) {} + async #bar(a: number) {} + async *#baz(a: number) { + return 3; + } + #_quux: number; + get #quux (): number { + return this.#_quux; + } + set #quux (val: number) { + this.#_quux = val; + } + constructor () { + this.#foo(30); + this.#bar(30); + this.#bar(30); + this.#quux = this.#quux + 1; + this.#quux++; + } +} + +class B extends A { + #foo(a: string) {} + constructor () { + super(); + this.#foo("str"); + } +} + + +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(3,14): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(4,14): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(5,14): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(6,15): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(6,23): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(7,14): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(9,5): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(9,9): error TS1005: '=>' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(10,15): error TS1005: '=>' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(11,16): error TS1005: ';' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(14,12): error TS1005: ';' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(15,21): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(17,15): error TS1005: ';' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(18,15): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(20,1): error TS1128: Declaration or statement expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(22,5): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(22,9): error TS1005: '=>' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(23,19): error TS1005: ';' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(25,14): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(27,1): error TS1128: Declaration or statement expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js (20 errors) ==== + class A { + constructor() { + this.(30); + ~ +!!! error TS1003: Identifier expected. + this.(30); + ~ +!!! error TS1003: Identifier expected. + this.(30); + ~ +!!! error TS1003: Identifier expected. + this. = this. + 1; + ~ +!!! error TS1003: Identifier expected. + ~ +!!! error TS1003: Identifier expected. + this.++; + ~~ +!!! error TS1003: Identifier expected. + } + (a) { } + ~ +!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. + ~ +!!! error TS1005: '=>' expected. + async (a) { } + ~ +!!! error TS1005: '=>' expected. + async *(a) { + ~ +!!! error TS1005: ';' expected. + return 3; + } + get () { + ~ +!!! error TS1005: ';' expected. + return this.; + ~ +!!! error TS1003: Identifier expected. + } + set (val) { + ~ +!!! error TS1005: ';' expected. + this. = val; + ~ +!!! error TS1003: Identifier expected. + } + } + ~ +!!! error TS1128: Declaration or statement expected. + class B extends A { + (a) { } + ~ +!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. + ~ +!!! error TS1005: '=>' expected. + constructor() { + ~ +!!! error TS1005: ';' expected. + super(); + this.("str"); + ~ +!!! error TS1003: Identifier expected. + } + } + ~ +!!! error TS1128: Declaration or statement expected. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndMethods.symbols b/tests/baselines/reference/privateNamesAndMethods.symbols new file mode 100644 index 0000000000000..817f1dcd31112 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndMethods.symbols @@ -0,0 +1,80 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts === +class A { +>A : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + + #foo(a: number) {} +>#foo : Symbol(A.#foo, Decl(privateNamesAndMethods.ts, 0, 9)) +>a : Symbol(a, Decl(privateNamesAndMethods.ts, 1, 9)) + + async #bar(a: number) {} +>#bar : Symbol(A.#bar, Decl(privateNamesAndMethods.ts, 1, 22)) +>a : Symbol(a, Decl(privateNamesAndMethods.ts, 2, 15)) + + async *#baz(a: number) { +>#baz : Symbol(A.#baz, Decl(privateNamesAndMethods.ts, 2, 28)) +>a : Symbol(a, Decl(privateNamesAndMethods.ts, 3, 16)) + + return 3; + } + #_quux: number; +>#_quux : Symbol(A.#_quux, Decl(privateNamesAndMethods.ts, 5, 5)) + + get #quux (): number { +>#quux : Symbol(A.#quux, Decl(privateNamesAndMethods.ts, 6, 19), Decl(privateNamesAndMethods.ts, 9, 5)) + + return this.#_quux; +>this.#_quux : Symbol(A.#_quux, Decl(privateNamesAndMethods.ts, 5, 5)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + } + set #quux (val: number) { +>#quux : Symbol(A.#quux, Decl(privateNamesAndMethods.ts, 6, 19), Decl(privateNamesAndMethods.ts, 9, 5)) +>val : Symbol(val, Decl(privateNamesAndMethods.ts, 10, 15)) + + this.#_quux = val; +>this.#_quux : Symbol(A.#_quux, Decl(privateNamesAndMethods.ts, 5, 5)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) +>val : Symbol(val, Decl(privateNamesAndMethods.ts, 10, 15)) + } + constructor () { + this.#foo(30); +>this.#foo : Symbol(A.#foo, Decl(privateNamesAndMethods.ts, 0, 9)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + + this.#bar(30); +>this.#bar : Symbol(A.#bar, Decl(privateNamesAndMethods.ts, 1, 22)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + + this.#bar(30); +>this.#bar : Symbol(A.#bar, Decl(privateNamesAndMethods.ts, 1, 22)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + + this.#quux = this.#quux + 1; +>this.#quux : Symbol(A.#quux, Decl(privateNamesAndMethods.ts, 6, 19), Decl(privateNamesAndMethods.ts, 9, 5)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) +>this.#quux : Symbol(A.#quux, Decl(privateNamesAndMethods.ts, 6, 19), Decl(privateNamesAndMethods.ts, 9, 5)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + + this.#quux++; +>this.#quux : Symbol(A.#quux, Decl(privateNamesAndMethods.ts, 6, 19), Decl(privateNamesAndMethods.ts, 9, 5)) +>this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + } +} + +class B extends A { +>B : Symbol(B, Decl(privateNamesAndMethods.ts, 20, 1)) +>A : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + + #foo(a: string) {} +>#foo : Symbol(B.#foo, Decl(privateNamesAndMethods.ts, 22, 19)) +>a : Symbol(a, Decl(privateNamesAndMethods.ts, 23, 9)) + + constructor () { + super(); +>super : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) + + this.#foo("str"); +>this.#foo : Symbol(B.#foo, Decl(privateNamesAndMethods.ts, 22, 19)) +>this : Symbol(B, Decl(privateNamesAndMethods.ts, 20, 1)) + } +} + diff --git a/tests/baselines/reference/privateNamesAndMethods.types b/tests/baselines/reference/privateNamesAndMethods.types new file mode 100644 index 0000000000000..9f8fa569f1719 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndMethods.types @@ -0,0 +1,95 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts === +class A { +>A : A + + #foo(a: number) {} +>#foo : (a: number) => void +>a : number + + async #bar(a: number) {} +>#bar : (a: number) => Promise +>a : number + + async *#baz(a: number) { +>#baz : (a: number) => AsyncGenerator +>a : number + + return 3; +>3 : 3 + } + #_quux: number; +>#_quux : number + + get #quux (): number { +>#quux : number + + return this.#_quux; +>this.#_quux : number +>this : this + } + set #quux (val: number) { +>#quux : number +>val : number + + this.#_quux = val; +>this.#_quux = val : number +>this.#_quux : number +>this : this +>val : number + } + constructor () { + this.#foo(30); +>this.#foo(30) : void +>this.#foo : (a: number) => void +>this : this +>30 : 30 + + this.#bar(30); +>this.#bar(30) : Promise +>this.#bar : (a: number) => Promise +>this : this +>30 : 30 + + this.#bar(30); +>this.#bar(30) : Promise +>this.#bar : (a: number) => Promise +>this : this +>30 : 30 + + this.#quux = this.#quux + 1; +>this.#quux = this.#quux + 1 : number +>this.#quux : number +>this : this +>this.#quux + 1 : number +>this.#quux : number +>this : this +>1 : 1 + + this.#quux++; +>this.#quux++ : number +>this.#quux : number +>this : this + } +} + +class B extends A { +>B : B +>A : A + + #foo(a: string) {} +>#foo : (a: string) => void +>a : string + + constructor () { + super(); +>super() : void +>super : typeof A + + this.#foo("str"); +>this.#foo("str") : void +>this.#foo : (a: string) => void +>this : this +>"str" : "str" + } +} + diff --git a/tests/baselines/reference/privateNamesAndStaticFields.js b/tests/baselines/reference/privateNamesAndStaticFields.js new file mode 100644 index 0000000000000..cd9bead54c5b1 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticFields.js @@ -0,0 +1,59 @@ +//// [privateNamesAndStaticFields.ts] +// @target es6 + +class A { + static #foo: number; + constructor () { + A.#foo = 3; + } +} + +class B extends A { + static #foo: string; + constructor () { + super(); + B.#foo = "some string"; + } +} + + +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.js(18,12): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.js(26,12): error TS1003: Identifier expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.js (2 errors) ==== + "use strict"; + // @target es6 + var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + })(); + var A = /** @class */ (function () { + function A() { + A. = 3; + ~ +!!! error TS1003: Identifier expected. + } + return A; + }()); + var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + var _this = _super.call(this) || this; + B. = "some string"; + ~ +!!! error TS1003: Identifier expected. + return _this; + } + return B; + }(A)); + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndStaticFields.symbols b/tests/baselines/reference/privateNamesAndStaticFields.symbols new file mode 100644 index 0000000000000..5898928bfb741 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticFields.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) + + static #foo: number; +>#foo : Symbol(A.#foo, Decl(privateNamesAndStaticFields.ts, 2, 9)) + + constructor () { + A.#foo = 3; +>A.#foo : Symbol(A.#foo, Decl(privateNamesAndStaticFields.ts, 2, 9)) +>A : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) + } +} + +class B extends A { +>B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 7, 1)) +>A : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) + + static #foo: string; +>#foo : Symbol(B.#foo, Decl(privateNamesAndStaticFields.ts, 9, 19)) + + constructor () { + super(); +>super : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) + + B.#foo = "some string"; +>B.#foo : Symbol(B.#foo, Decl(privateNamesAndStaticFields.ts, 9, 19)) +>B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 7, 1)) + } +} + diff --git a/tests/baselines/reference/privateNamesAndStaticFields.types b/tests/baselines/reference/privateNamesAndStaticFields.types new file mode 100644 index 0000000000000..ba630cbcf7709 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticFields.types @@ -0,0 +1,38 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts === +// @target es6 + +class A { +>A : A + + static #foo: number; +>#foo : number + + constructor () { + A.#foo = 3; +>A.#foo = 3 : 3 +>A.#foo : number +>A : typeof A +>3 : 3 + } +} + +class B extends A { +>B : B +>A : A + + static #foo: string; +>#foo : string + + constructor () { + super(); +>super() : void +>super : typeof A + + B.#foo = "some string"; +>B.#foo = "some string" : "some string" +>B.#foo : string +>B : typeof B +>"some string" : "some string" + } +} + diff --git a/tests/baselines/reference/privateNamesAndStaticMethods.js b/tests/baselines/reference/privateNamesAndStaticMethods.js new file mode 100644 index 0000000000000..9bb578ef6ccd6 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticMethods.js @@ -0,0 +1,94 @@ +//// [privateNamesAndStaticMethods.ts] +class A { + static #foo(a: number) {} + static async #bar(a: number) {} + static async *#baz(a: number) { + return 3; + } + static #_quux: number; + static get #quux (): number { + return this.#_quux; + } + static set #quux (val: number) { + this.#_quux = val; + } + constructor () { + A.#foo(30); + A.#bar(30); + A.#bar(30); + A.#quux = A.#quux + 1; + A.#quux++; + } +} + +class B extends A { + static #foo(a: string) {} + constructor () { + super(); + B.#foo("str"); + } +} + + +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(4,11): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(5,11): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(6,11): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(7,12): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(7,17): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(8,11): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(12,19): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(16,21): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(19,15): error TS1003: Identifier expected. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(26,11): error TS1003: Identifier expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js (10 errors) ==== + "use strict"; + class A { + constructor() { + A.(30); + ~ +!!! error TS1003: Identifier expected. + A.(30); + ~ +!!! error TS1003: Identifier expected. + A.(30); + ~ +!!! error TS1003: Identifier expected. + A. = A. + 1; + ~ +!!! error TS1003: Identifier expected. + ~ +!!! error TS1003: Identifier expected. + A.++; + ~~ +!!! error TS1003: Identifier expected. + } + static (a) { } + static async (a) { } + static async *(a) { + ~ +!!! error TS1003: Identifier expected. + return 3; + } + static get () { + return this.; + ~ +!!! error TS1003: Identifier expected. + } + static set (val) { + this. = val; + ~ +!!! error TS1003: Identifier expected. + } + } + class B extends A { + static (a) { } + constructor() { + super(); + B.("str"); + ~ +!!! error TS1003: Identifier expected. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndStaticMethods.symbols b/tests/baselines/reference/privateNamesAndStaticMethods.symbols new file mode 100644 index 0000000000000..57d684a70696d --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticMethods.symbols @@ -0,0 +1,80 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts === +class A { +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + + static #foo(a: number) {} +>#foo : Symbol(A.#foo, Decl(privateNamesAndStaticMethods.ts, 0, 9)) +>a : Symbol(a, Decl(privateNamesAndStaticMethods.ts, 1, 16)) + + static async #bar(a: number) {} +>#bar : Symbol(A.#bar, Decl(privateNamesAndStaticMethods.ts, 1, 29)) +>a : Symbol(a, Decl(privateNamesAndStaticMethods.ts, 2, 22)) + + static async *#baz(a: number) { +>#baz : Symbol(A.#baz, Decl(privateNamesAndStaticMethods.ts, 2, 35)) +>a : Symbol(a, Decl(privateNamesAndStaticMethods.ts, 3, 23)) + + return 3; + } + static #_quux: number; +>#_quux : Symbol(A.#_quux, Decl(privateNamesAndStaticMethods.ts, 5, 5)) + + static get #quux (): number { +>#quux : Symbol(A.#quux, Decl(privateNamesAndStaticMethods.ts, 6, 26), Decl(privateNamesAndStaticMethods.ts, 9, 5)) + + return this.#_quux; +>this.#_quux : Symbol(A.#_quux, Decl(privateNamesAndStaticMethods.ts, 5, 5)) +>this : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + } + static set #quux (val: number) { +>#quux : Symbol(A.#quux, Decl(privateNamesAndStaticMethods.ts, 6, 26), Decl(privateNamesAndStaticMethods.ts, 9, 5)) +>val : Symbol(val, Decl(privateNamesAndStaticMethods.ts, 10, 22)) + + this.#_quux = val; +>this.#_quux : Symbol(A.#_quux, Decl(privateNamesAndStaticMethods.ts, 5, 5)) +>this : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) +>val : Symbol(val, Decl(privateNamesAndStaticMethods.ts, 10, 22)) + } + constructor () { + A.#foo(30); +>A.#foo : Symbol(A.#foo, Decl(privateNamesAndStaticMethods.ts, 0, 9)) +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + + A.#bar(30); +>A.#bar : Symbol(A.#bar, Decl(privateNamesAndStaticMethods.ts, 1, 29)) +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + + A.#bar(30); +>A.#bar : Symbol(A.#bar, Decl(privateNamesAndStaticMethods.ts, 1, 29)) +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + + A.#quux = A.#quux + 1; +>A.#quux : Symbol(A.#quux, Decl(privateNamesAndStaticMethods.ts, 6, 26), Decl(privateNamesAndStaticMethods.ts, 9, 5)) +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) +>A.#quux : Symbol(A.#quux, Decl(privateNamesAndStaticMethods.ts, 6, 26), Decl(privateNamesAndStaticMethods.ts, 9, 5)) +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + + A.#quux++; +>A.#quux : Symbol(A.#quux, Decl(privateNamesAndStaticMethods.ts, 6, 26), Decl(privateNamesAndStaticMethods.ts, 9, 5)) +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + } +} + +class B extends A { +>B : Symbol(B, Decl(privateNamesAndStaticMethods.ts, 20, 1)) +>A : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + + static #foo(a: string) {} +>#foo : Symbol(B.#foo, Decl(privateNamesAndStaticMethods.ts, 22, 19)) +>a : Symbol(a, Decl(privateNamesAndStaticMethods.ts, 23, 16)) + + constructor () { + super(); +>super : Symbol(A, Decl(privateNamesAndStaticMethods.ts, 0, 0)) + + B.#foo("str"); +>B.#foo : Symbol(B.#foo, Decl(privateNamesAndStaticMethods.ts, 22, 19)) +>B : Symbol(B, Decl(privateNamesAndStaticMethods.ts, 20, 1)) + } +} + diff --git a/tests/baselines/reference/privateNamesAndStaticMethods.types b/tests/baselines/reference/privateNamesAndStaticMethods.types new file mode 100644 index 0000000000000..706d630f5f9fb --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticMethods.types @@ -0,0 +1,95 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts === +class A { +>A : A + + static #foo(a: number) {} +>#foo : (a: number) => void +>a : number + + static async #bar(a: number) {} +>#bar : (a: number) => Promise +>a : number + + static async *#baz(a: number) { +>#baz : (a: number) => AsyncGenerator +>a : number + + return 3; +>3 : 3 + } + static #_quux: number; +>#_quux : number + + static get #quux (): number { +>#quux : number + + return this.#_quux; +>this.#_quux : number +>this : typeof A + } + static set #quux (val: number) { +>#quux : number +>val : number + + this.#_quux = val; +>this.#_quux = val : number +>this.#_quux : number +>this : typeof A +>val : number + } + constructor () { + A.#foo(30); +>A.#foo(30) : void +>A.#foo : (a: number) => void +>A : typeof A +>30 : 30 + + A.#bar(30); +>A.#bar(30) : Promise +>A.#bar : (a: number) => Promise +>A : typeof A +>30 : 30 + + A.#bar(30); +>A.#bar(30) : Promise +>A.#bar : (a: number) => Promise +>A : typeof A +>30 : 30 + + A.#quux = A.#quux + 1; +>A.#quux = A.#quux + 1 : number +>A.#quux : number +>A : typeof A +>A.#quux + 1 : number +>A.#quux : number +>A : typeof A +>1 : 1 + + A.#quux++; +>A.#quux++ : number +>A.#quux : number +>A : typeof A + } +} + +class B extends A { +>B : B +>A : A + + static #foo(a: string) {} +>#foo : (a: string) => void +>a : string + + constructor () { + super(); +>super() : void +>super : typeof A + + B.#foo("str"); +>B.#foo("str") : void +>B.#foo : (a: string) => void +>B : typeof B +>"str" : "str" + } +} + diff --git a/tests/baselines/reference/privateNamesAndkeyof.js b/tests/baselines/reference/privateNamesAndkeyof.js new file mode 100644 index 0000000000000..d73251c6a530e --- /dev/null +++ b/tests/baselines/reference/privateNamesAndkeyof.js @@ -0,0 +1,29 @@ +//// [privateNamesAndkeyof.ts] +// @target es6 + +class A { + #foo = 3; + bar = 3; + baz = 3; +} + +type T = keyof A // should not include '#foo' + + +tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.js(5,14): error TS1011: An element access expression should take an argument. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.js (1 errors) ==== + "use strict"; + // @target es6 + var A = /** @class */ (function () { + function A() { + this[] = 3; + +!!! error TS1011: An element access expression should take an argument. + this.bar = 3; + this.baz = 3; + } + return A; + }()); + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndkeyof.symbols b/tests/baselines/reference/privateNamesAndkeyof.symbols new file mode 100644 index 0000000000000..3b633505522a1 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndkeyof.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesAndkeyof.ts, 0, 0)) + + #foo = 3; +>#foo : Symbol(A.#foo, Decl(privateNamesAndkeyof.ts, 2, 9)) + + bar = 3; +>bar : Symbol(A.bar, Decl(privateNamesAndkeyof.ts, 3, 13)) + + baz = 3; +>baz : Symbol(A.baz, Decl(privateNamesAndkeyof.ts, 4, 12)) +} + +type T = keyof A // should not include '#foo' +>T : Symbol(T, Decl(privateNamesAndkeyof.ts, 6, 1)) +>A : Symbol(A, Decl(privateNamesAndkeyof.ts, 0, 0)) + diff --git a/tests/baselines/reference/privateNamesAndkeyof.types b/tests/baselines/reference/privateNamesAndkeyof.types new file mode 100644 index 0000000000000..f8d3d99de7369 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndkeyof.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts === +// @target es6 + +class A { +>A : A + + #foo = 3; +>#foo : number +>3 : 3 + + bar = 3; +>bar : number +>3 : 3 + + baz = 3; +>baz : number +>3 : 3 +} + +type T = keyof A // should not include '#foo' +>T : "bar" | "baz" + diff --git a/tests/baselines/reference/privateNamesInGenericClasses.errors.txt b/tests/baselines/reference/privateNamesInGenericClasses.errors.txt new file mode 100644 index 0000000000000..f47a95f00b276 --- /dev/null +++ b/tests/baselines/reference/privateNamesInGenericClasses.errors.txt @@ -0,0 +1,32 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(10,3): error TS2339: Property '#foo' does not exist on type 'C'. +tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(10,3): error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. +tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(11,1): error TS2322: Type 'C' is not assignable to type 'C'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(12,1): error TS2322: Type 'C' is not assignable to type 'C'. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts (4 errors) ==== + class C { + #foo: T; + bar(x: C) { return x.#foo; } // OK + baz(x: C) { return x.#foo; } // OK + quux(x: C) { return x.#foo; } // OK + } + + declare let a: C; + declare let b: C; + a.#foo; // Error + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'C'. + ~~~~ +!!! error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. + a = b; // Error + ~ +!!! error TS2322: Type 'C' is not assignable to type 'C'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + b = a; // Error + ~ +!!! error TS2322: Type 'C' is not assignable to type 'C'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesInGenericClasses.js b/tests/baselines/reference/privateNamesInGenericClasses.js new file mode 100644 index 0000000000000..59772b09fa1de --- /dev/null +++ b/tests/baselines/reference/privateNamesInGenericClasses.js @@ -0,0 +1,25 @@ +//// [privateNamesInGenericClasses.ts] +class C { + #foo: T; + bar(x: C) { return x.#foo; } // OK + baz(x: C) { return x.#foo; } // OK + quux(x: C) { return x.#foo; } // OK +} + +declare let a: C; +declare let b: C; +a.#foo; // Error +a = b; // Error +b = a; // Error + + +//// [privateNamesInGenericClasses.js] +"use strict"; +class C { + bar(x) { return x.; } // OK + baz(x) { return x.; } // OK + quux(x) { return x.; } // OK +} +a.; // Error +a = b; // Error +b = a; // Error diff --git a/tests/baselines/reference/privateNamesInGenericClasses.symbols b/tests/baselines/reference/privateNamesInGenericClasses.symbols new file mode 100644 index 0000000000000..c697c06390869 --- /dev/null +++ b/tests/baselines/reference/privateNamesInGenericClasses.symbols @@ -0,0 +1,51 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts === +class C { +>C : Symbol(C, Decl(privateNamesInGenericClasses.ts, 0, 0)) +>T : Symbol(T, Decl(privateNamesInGenericClasses.ts, 0, 8)) + + #foo: T; +>#foo : Symbol(C.#foo, Decl(privateNamesInGenericClasses.ts, 0, 12)) +>T : Symbol(T, Decl(privateNamesInGenericClasses.ts, 0, 8)) + + bar(x: C) { return x.#foo; } // OK +>bar : Symbol(C.bar, Decl(privateNamesInGenericClasses.ts, 1, 12)) +>x : Symbol(x, Decl(privateNamesInGenericClasses.ts, 2, 8)) +>C : Symbol(C, Decl(privateNamesInGenericClasses.ts, 0, 0)) +>T : Symbol(T, Decl(privateNamesInGenericClasses.ts, 0, 8)) +>x.#foo : Symbol(C.#foo, Decl(privateNamesInGenericClasses.ts, 0, 12)) +>x : Symbol(x, Decl(privateNamesInGenericClasses.ts, 2, 8)) + + baz(x: C) { return x.#foo; } // OK +>baz : Symbol(C.baz, Decl(privateNamesInGenericClasses.ts, 2, 35)) +>x : Symbol(x, Decl(privateNamesInGenericClasses.ts, 3, 8)) +>C : Symbol(C, Decl(privateNamesInGenericClasses.ts, 0, 0)) +>x.#foo : Symbol(C.#foo, Decl(privateNamesInGenericClasses.ts, 0, 12)) +>x : Symbol(x, Decl(privateNamesInGenericClasses.ts, 3, 8)) + + quux(x: C) { return x.#foo; } // OK +>quux : Symbol(C.quux, Decl(privateNamesInGenericClasses.ts, 3, 40)) +>x : Symbol(x, Decl(privateNamesInGenericClasses.ts, 4, 9)) +>C : Symbol(C, Decl(privateNamesInGenericClasses.ts, 0, 0)) +>x.#foo : Symbol(C.#foo, Decl(privateNamesInGenericClasses.ts, 0, 12)) +>x : Symbol(x, Decl(privateNamesInGenericClasses.ts, 4, 9)) +} + +declare let a: C; +>a : Symbol(a, Decl(privateNamesInGenericClasses.ts, 7, 11)) +>C : Symbol(C, Decl(privateNamesInGenericClasses.ts, 0, 0)) + +declare let b: C; +>b : Symbol(b, Decl(privateNamesInGenericClasses.ts, 8, 11)) +>C : Symbol(C, Decl(privateNamesInGenericClasses.ts, 0, 0)) + +a.#foo; // Error +>a : Symbol(a, Decl(privateNamesInGenericClasses.ts, 7, 11)) + +a = b; // Error +>a : Symbol(a, Decl(privateNamesInGenericClasses.ts, 7, 11)) +>b : Symbol(b, Decl(privateNamesInGenericClasses.ts, 8, 11)) + +b = a; // Error +>b : Symbol(b, Decl(privateNamesInGenericClasses.ts, 8, 11)) +>a : Symbol(a, Decl(privateNamesInGenericClasses.ts, 7, 11)) + diff --git a/tests/baselines/reference/privateNamesInGenericClasses.types b/tests/baselines/reference/privateNamesInGenericClasses.types new file mode 100644 index 0000000000000..e0a29a45492c1 --- /dev/null +++ b/tests/baselines/reference/privateNamesInGenericClasses.types @@ -0,0 +1,46 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts === +class C { +>C : C + + #foo: T; +>#foo : T + + bar(x: C) { return x.#foo; } // OK +>bar : (x: C) => T +>x : C +>x.#foo : T +>x : C + + baz(x: C) { return x.#foo; } // OK +>baz : (x: C) => number +>x : C +>x.#foo : number +>x : C + + quux(x: C) { return x.#foo; } // OK +>quux : (x: C) => string +>x : C +>x.#foo : string +>x : C +} + +declare let a: C; +>a : C + +declare let b: C; +>b : C + +a.#foo; // Error +>a.#foo : any +>a : C + +a = b; // Error +>a = b : C +>a : C +>b : C + +b = a; // Error +>b = a : C +>b : C +>a : C + diff --git a/tests/baselines/reference/privateNamesInNestedClasses.errors.txt b/tests/baselines/reference/privateNamesInNestedClasses.errors.txt new file mode 100644 index 0000000000000..86aa021ad0326 --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts(13,18): error TS2339: Property '#foo' does not exist on type 'A'. +tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts(13,18): error TS18014: This usage of '#foo' refers to the private member declared in its enclosing class. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts (2 errors) ==== + // @target es6 + + class A { + #foo = "A's #foo"; + #bar = "A's #bar"; + method () { + class B { + #foo = "B's #foo"; + bar (a: any) { + a.#foo; // OK, no compile-time error, don't know what `a` is + } + baz (a: A) { + a.#foo; // compile-time error, shadowed + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'A'. + ~~~~ +!!! error TS18014: This usage of '#foo' refers to the private member declared in its enclosing class. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. + } + quux (b: B) { + b.#foo; // OK + } + } + const a = new A(); + new B().bar(a); + new B().baz(a); + const b = new B(); + new B().quux(b); + } + } + + new A().method(); \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesInNestedClasses.js b/tests/baselines/reference/privateNamesInNestedClasses.js new file mode 100644 index 0000000000000..40d45516ddd1a --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses.js @@ -0,0 +1,62 @@ +//// [privateNamesInNestedClasses.ts] +// @target es6 + +class A { + #foo = "A's #foo"; + #bar = "A's #bar"; + method () { + class B { + #foo = "B's #foo"; + bar (a: any) { + a.#foo; // OK, no compile-time error, don't know what `a` is + } + baz (a: A) { + a.#foo; // compile-time error, shadowed + } + quux (b: B) { + b.#foo; // OK + } + } + const a = new A(); + new B().bar(a); + new B().baz(a); + const b = new B(); + new B().quux(b); + } +} + +new A().method(); + +//// [privateNamesInNestedClasses.js] +"use strict"; +// @target es6 +var A = /** @class */ (function () { + function A() { + this[] = "A's #foo"; + this[] = "A's #bar"; + } + A.prototype.method = function () { + var B = /** @class */ (function () { + function B() { + this[] = "B's #foo"; + } + B.prototype.bar = function (a) { + a.; // OK, no compile-time error, don't know what `a` is + }; + B.prototype.baz = function (a) { + a.; // compile-time error, shadowed + }; + B.prototype.quux = function (b) { + b.; // OK + }; + return B; + }()); + var a = new A(); + new B().bar(a); + new B().baz(a); + var b = new B(); + new B().quux(b); + }; + return A; +}()); +new A().method(); diff --git a/tests/baselines/reference/privateNamesInNestedClasses.symbols b/tests/baselines/reference/privateNamesInNestedClasses.symbols new file mode 100644 index 0000000000000..14eaae87aa402 --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses.symbols @@ -0,0 +1,79 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) + + #foo = "A's #foo"; +>#foo : Symbol(A.#foo, Decl(privateNamesInNestedClasses.ts, 2, 9)) + + #bar = "A's #bar"; +>#bar : Symbol(A.#bar, Decl(privateNamesInNestedClasses.ts, 3, 21)) + + method () { +>method : Symbol(A.method, Decl(privateNamesInNestedClasses.ts, 4, 21)) + + class B { +>B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) + + #foo = "B's #foo"; +>#foo : Symbol(B.#foo, Decl(privateNamesInNestedClasses.ts, 6, 16)) + + bar (a: any) { +>bar : Symbol(B.bar, Decl(privateNamesInNestedClasses.ts, 7, 29)) +>a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 8, 16)) + + a.#foo; // OK, no compile-time error, don't know what `a` is +>a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 8, 16)) + } + baz (a: A) { +>baz : Symbol(B.baz, Decl(privateNamesInNestedClasses.ts, 10, 12)) +>a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 11, 16)) +>A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) + + a.#foo; // compile-time error, shadowed +>a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 11, 16)) + } + quux (b: B) { +>quux : Symbol(B.quux, Decl(privateNamesInNestedClasses.ts, 13, 12)) +>b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 14, 17)) +>B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) + + b.#foo; // OK +>b.#foo : Symbol(B.#foo, Decl(privateNamesInNestedClasses.ts, 6, 16)) +>b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 14, 17)) + } + } + const a = new A(); +>a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 18, 12)) +>A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) + + new B().bar(a); +>new B().bar : Symbol(B.bar, Decl(privateNamesInNestedClasses.ts, 7, 29)) +>B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) +>bar : Symbol(B.bar, Decl(privateNamesInNestedClasses.ts, 7, 29)) +>a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 18, 12)) + + new B().baz(a); +>new B().baz : Symbol(B.baz, Decl(privateNamesInNestedClasses.ts, 10, 12)) +>B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) +>baz : Symbol(B.baz, Decl(privateNamesInNestedClasses.ts, 10, 12)) +>a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 18, 12)) + + const b = new B(); +>b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 21, 12)) +>B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) + + new B().quux(b); +>new B().quux : Symbol(B.quux, Decl(privateNamesInNestedClasses.ts, 13, 12)) +>B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) +>quux : Symbol(B.quux, Decl(privateNamesInNestedClasses.ts, 13, 12)) +>b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 21, 12)) + } +} + +new A().method(); +>new A().method : Symbol(A.method, Decl(privateNamesInNestedClasses.ts, 4, 21)) +>A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) +>method : Symbol(A.method, Decl(privateNamesInNestedClasses.ts, 4, 21)) + diff --git a/tests/baselines/reference/privateNamesInNestedClasses.types b/tests/baselines/reference/privateNamesInNestedClasses.types new file mode 100644 index 0000000000000..12986429358da --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses.types @@ -0,0 +1,92 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts === +// @target es6 + +class A { +>A : A + + #foo = "A's #foo"; +>#foo : string +>"A's #foo" : "A's #foo" + + #bar = "A's #bar"; +>#bar : string +>"A's #bar" : "A's #bar" + + method () { +>method : () => void + + class B { +>B : B + + #foo = "B's #foo"; +>#foo : string +>"B's #foo" : "B's #foo" + + bar (a: any) { +>bar : (a: any) => void +>a : any + + a.#foo; // OK, no compile-time error, don't know what `a` is +>a.#foo : any +>a : any + } + baz (a: A) { +>baz : (a: A) => void +>a : A + + a.#foo; // compile-time error, shadowed +>a.#foo : any +>a : A + } + quux (b: B) { +>quux : (b: B) => void +>b : B + + b.#foo; // OK +>b.#foo : string +>b : B + } + } + const a = new A(); +>a : A +>new A() : A +>A : typeof A + + new B().bar(a); +>new B().bar(a) : void +>new B().bar : (a: any) => void +>new B() : B +>B : typeof B +>bar : (a: any) => void +>a : A + + new B().baz(a); +>new B().baz(a) : void +>new B().baz : (a: A) => void +>new B() : B +>B : typeof B +>baz : (a: A) => void +>a : A + + const b = new B(); +>b : B +>new B() : B +>B : typeof B + + new B().quux(b); +>new B().quux(b) : void +>new B().quux : (b: B) => void +>new B() : B +>B : typeof B +>quux : (b: B) => void +>b : B + } +} + +new A().method(); +>new A().method() : void +>new A().method : () => void +>new A() : A +>A : typeof A +>method : () => void + diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt new file mode 100644 index 0000000000000..079f4940d4ef5 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts(4,12): error TS18010: Accessibility modifiers cannot be used with private names. +tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts(5,13): error TS18010: Accessibility modifiers cannot be used with private names. +tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts(6,15): error TS18010: Accessibility modifiers cannot be used with private names. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts (3 errors) ==== + // @target es6 + + class A { + public #foo = 3; // Error + ~~~~ +!!! error TS18010: Accessibility modifiers cannot be used with private names. + private #bar = 3; // Error + ~~~~ +!!! error TS18010: Accessibility modifiers cannot be used with private names. + protected #baz = 3; // Error + ~~~~ +!!! error TS18010: Accessibility modifiers cannot be used with private names. + readonly #qux = 3; // OK + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.js b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.js new file mode 100644 index 0000000000000..3c3acaf9f4672 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.js @@ -0,0 +1,23 @@ +//// [privateNamesNoAccessibilityModifiers.ts] +// @target es6 + +class A { + public #foo = 3; // Error + private #bar = 3; // Error + protected #baz = 3; // Error + readonly #qux = 3; // OK +} + + +//// [privateNamesNoAccessibilityModifiers.js] +"use strict"; +// @target es6 +var A = /** @class */ (function () { + function A() { + this[] = 3; // Error + this[] = 3; // Error + this[] = 3; // Error + this[] = 3; // OK + } + return A; +}()); diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols new file mode 100644 index 0000000000000..49bd89a39842a --- /dev/null +++ b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesNoAccessibilityModifiers.ts, 0, 0)) + + public #foo = 3; // Error +>#foo : Symbol(A.#foo, Decl(privateNamesNoAccessibilityModifiers.ts, 2, 9)) + + private #bar = 3; // Error +>#bar : Symbol(A.#bar, Decl(privateNamesNoAccessibilityModifiers.ts, 3, 20)) + + protected #baz = 3; // Error +>#baz : Symbol(A.#baz, Decl(privateNamesNoAccessibilityModifiers.ts, 4, 21)) + + readonly #qux = 3; // OK +>#qux : Symbol(A.#qux, Decl(privateNamesNoAccessibilityModifiers.ts, 5, 23)) +} + diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.types b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.types new file mode 100644 index 0000000000000..d727c9a2f2dc3 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts === +// @target es6 + +class A { +>A : A + + public #foo = 3; // Error +>#foo : number +>3 : 3 + + private #bar = 3; // Error +>#bar : number +>3 : 3 + + protected #baz = 3; // Error +>#baz : number +>3 : 3 + + readonly #qux = 3; // OK +>#qux : 3 +>3 : 3 +} + diff --git a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.js b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.js new file mode 100644 index 0000000000000..e25509c4c843a --- /dev/null +++ b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.js @@ -0,0 +1,43 @@ +//// [privateNamesNoConflictWhenInheriting.ts] +// @target es6 + +class A { + #foo: number; +} + +class B extends A { + #foo: string; // OK: private names are unique to each class +} + +const b: A = new B() // OK + + +//// [privateNamesNoConflictWhenInheriting.js] +"use strict"; +// @target es6 +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + return B; +}(A)); +var b = new B(); // OK diff --git a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols new file mode 100644 index 0000000000000..d1442d5750cd5 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesNoConflictWhenInheriting.ts, 0, 0)) + + #foo: number; +>#foo : Symbol(A.#foo, Decl(privateNamesNoConflictWhenInheriting.ts, 2, 9)) +} + +class B extends A { +>B : Symbol(B, Decl(privateNamesNoConflictWhenInheriting.ts, 4, 1)) +>A : Symbol(A, Decl(privateNamesNoConflictWhenInheriting.ts, 0, 0)) + + #foo: string; // OK: private names are unique to each class +>#foo : Symbol(B.#foo, Decl(privateNamesNoConflictWhenInheriting.ts, 6, 19)) +} + +const b: A = new B() // OK +>b : Symbol(b, Decl(privateNamesNoConflictWhenInheriting.ts, 10, 5)) +>A : Symbol(A, Decl(privateNamesNoConflictWhenInheriting.ts, 0, 0)) +>B : Symbol(B, Decl(privateNamesNoConflictWhenInheriting.ts, 4, 1)) + diff --git a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.types b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.types new file mode 100644 index 0000000000000..fd88a20816e15 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts === +// @target es6 + +class A { +>A : A + + #foo: number; +>#foo : number +} + +class B extends A { +>B : B +>A : A + + #foo: string; // OK: private names are unique to each class +>#foo : string +} + +const b: A = new B() // OK +>b : A +>new B() : B +>B : typeof B + diff --git a/tests/baselines/reference/privateNamesNoDelete.errors.txt b/tests/baselines/reference/privateNamesNoDelete.errors.txt new file mode 100644 index 0000000000000..27c1ba93a77f4 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoDelete.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts(6,16): error TS18011: The operand of a delete operator cannot be a private name. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts (1 errors) ==== + // @target es6 + + class A { + #v = 1; + constructor() { + delete this.#v; // Error: The operand of a delete operator cannot be a private name. + ~~~~~~~ +!!! error TS18011: The operand of a delete operator cannot be a private name. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNoDelete.js b/tests/baselines/reference/privateNamesNoDelete.js new file mode 100644 index 0000000000000..1b1f285d4c7c6 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoDelete.js @@ -0,0 +1,21 @@ +//// [privateNamesNoDelete.ts] +// @target es6 + +class A { + #v = 1; + constructor() { + delete this.#v; // Error: The operand of a delete operator cannot be a private name. + } +} + + +//// [privateNamesNoDelete.js] +"use strict"; +// @target es6 +var A = /** @class */ (function () { + function A() { + this[] = 1; + delete this.; // Error: The operand of a delete operator cannot be a private name. + } + return A; +}()); diff --git a/tests/baselines/reference/privateNamesNoDelete.symbols b/tests/baselines/reference/privateNamesNoDelete.symbols new file mode 100644 index 0000000000000..50e2542c07877 --- /dev/null +++ b/tests/baselines/reference/privateNamesNoDelete.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesNoDelete.ts, 0, 0)) + + #v = 1; +>#v : Symbol(A.#v, Decl(privateNamesNoDelete.ts, 2, 9)) + + constructor() { + delete this.#v; // Error: The operand of a delete operator cannot be a private name. +>this.#v : Symbol(A.#v, Decl(privateNamesNoDelete.ts, 2, 9)) +>this : Symbol(A, Decl(privateNamesNoDelete.ts, 0, 0)) + } +} + diff --git a/tests/baselines/reference/privateNamesNoDelete.types b/tests/baselines/reference/privateNamesNoDelete.types new file mode 100644 index 0000000000000..681651a4f770a --- /dev/null +++ b/tests/baselines/reference/privateNamesNoDelete.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts === +// @target es6 + +class A { +>A : A + + #v = 1; +>#v : number +>1 : 1 + + constructor() { + delete this.#v; // Error: The operand of a delete operator cannot be a private name. +>delete this.#v : boolean +>this.#v : number +>this : this + } +} + diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt b/tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt new file mode 100644 index 0000000000000..942bea1e251a8 --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(4,12): error TS1138: Parameter declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(4,24): error TS1005: ';' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(4,26): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(5,1): error TS1128: Declaration or statement expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts (4 errors) ==== + // @target es6 + + class A { + setFoo(#foo: string) {} + ~~~~ +!!! error TS1138: Parameter declaration expected. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. + } + ~ +!!! error TS1128: Declaration or statement expected. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.js b/tests/baselines/reference/privateNamesNotAllowedAsParameters.js new file mode 100644 index 0000000000000..8c3a394e1ac03 --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.js @@ -0,0 +1,17 @@ +//// [privateNamesNotAllowedAsParameters.ts] +// @target es6 + +class A { + setFoo(#foo: string) {} +} + + +//// [privateNamesNotAllowedAsParameters.js] +// @target es6 +var A = /** @class */ (function () { + function A() { + } + A.prototype.setFoo = function () { }; + return A; +}()); +{ } diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols b/tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols new file mode 100644 index 0000000000000..b7ea0b4850fb9 --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesNotAllowedAsParameters.ts, 0, 0)) + + setFoo(#foo: string) {} +>setFoo : Symbol(A.setFoo, Decl(privateNamesNotAllowedAsParameters.ts, 2, 9)) +>#foo : Symbol(A.#foo, Decl(privateNamesNotAllowedAsParameters.ts, 3, 11)) +} + diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.types b/tests/baselines/reference/privateNamesNotAllowedAsParameters.types new file mode 100644 index 0000000000000..effe8726a9470 --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts === +// @target es6 + +class A { +>A : A + + setFoo(#foo: string) {} +>setFoo : () => any +>#foo : string +} + diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt new file mode 100644 index 0000000000000..5d79de2754392 --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(3,7): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(3,12): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(3,14): error TS1134: Variable declaration expected. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts (3 errors) ==== + // @target es6 + + const #foo = 3; + ~~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js new file mode 100644 index 0000000000000..3a5f19724d38e --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js @@ -0,0 +1,10 @@ +//// [privateNamesNotAllowedInVariableDeclarations.ts] +// @target es6 + +const #foo = 3; + +//// [privateNamesNotAllowedInVariableDeclarations.js] +"use strict"; +// @target es6 +var ; +3; diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols new file mode 100644 index 0000000000000..8a90d43a114c9 --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts === +// @target es6 +No type information for this code. +No type information for this code.const #foo = 3; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types new file mode 100644 index 0000000000000..1def5f332d291 --- /dev/null +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts === +// @target es6 + +const #foo = 3; +>3 : 3 + diff --git a/tests/baselines/reference/privateNamesUnique.errors.txt b/tests/baselines/reference/privateNamesUnique.errors.txt new file mode 100644 index 0000000000000..0c3b1ef188c17 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts(11,7): error TS2322: Type 'B' is not assignable to type 'A'. + Property '#foo' is missing in type 'B'. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts (1 errors) ==== + // @target es6 + + class A { + #foo: number; + } + + class B { + #foo: number; + } + + const b: A = new B(); // Error: Property #foo is missing + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property '#foo' is missing in type 'B'. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesUnique.js b/tests/baselines/reference/privateNamesUnique.js new file mode 100644 index 0000000000000..52c8a3bc69799 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique.js @@ -0,0 +1,28 @@ +//// [privateNamesUnique.ts] +// @target es6 + +class A { + #foo: number; +} + +class B { + #foo: number; +} + +const b: A = new B(); // Error: Property #foo is missing + + +//// [privateNamesUnique.js] +"use strict"; +// @target es6 +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +var b = new B(); // Error: Property #foo is missing diff --git a/tests/baselines/reference/privateNamesUnique.symbols b/tests/baselines/reference/privateNamesUnique.symbols new file mode 100644 index 0000000000000..5266e47918187 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique.symbols @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts === +// @target es6 + +class A { +>A : Symbol(A, Decl(privateNamesUnique.ts, 0, 0)) + + #foo: number; +>#foo : Symbol(A.#foo, Decl(privateNamesUnique.ts, 2, 9)) +} + +class B { +>B : Symbol(B, Decl(privateNamesUnique.ts, 4, 1)) + + #foo: number; +>#foo : Symbol(B.#foo, Decl(privateNamesUnique.ts, 6, 9)) +} + +const b: A = new B(); // Error: Property #foo is missing +>b : Symbol(b, Decl(privateNamesUnique.ts, 10, 5)) +>A : Symbol(A, Decl(privateNamesUnique.ts, 0, 0)) +>B : Symbol(B, Decl(privateNamesUnique.ts, 4, 1)) + diff --git a/tests/baselines/reference/privateNamesUnique.types b/tests/baselines/reference/privateNamesUnique.types new file mode 100644 index 0000000000000..a9d738ee0ca5b --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts === +// @target es6 + +class A { +>A : A + + #foo: number; +>#foo : number +} + +class B { +>B : B + + #foo: number; +>#foo : number +} + +const b: A = new B(); // Error: Property #foo is missing +>b : A +>new B() : B +>B : typeof B + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts b/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts index d4c0b8ad46efb..1f5da9ab9171e 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts @@ -1,6 +1,9 @@ -class A { - [k: string]: any; - constructor(message: string) { - this.#f = 3 // Error Property '#f' does not exist on type 'A'. - } -} +// @strict: true +// @target es6 + +class A { + [k: string]: any; + constructor(message: string) { + this.#f = 3 // Error Property '#f' does not exist on type 'A'. + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts b/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts new file mode 100644 index 0000000000000..1421db99944d8 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts @@ -0,0 +1,5 @@ +// @target es6 + +class A { + #constructor() {} // Error: `#constructor` is a reserved word. +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts b/tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts new file mode 100644 index 0000000000000..ba8160cb122ab --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts @@ -0,0 +1,7 @@ +// @strict: true +// @target es6 + +class A { + #foo = "foo"; + #foo = "foo"; +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameField.ts b/tests/cases/conformance/classes/members/privateNames/privateNameField.ts index 02e449fb3e002..d4b823c49da63 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameField.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameField.ts @@ -1,6 +1,9 @@ -class A { - #name: string; - constructor(name: string) { - this.#name = name; - } +// @strict: true +// @target es6 + +class A { + #name: string; + constructor(name: string) { + this.#name = name; + } } \ No newline at end of file diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts b/tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts new file mode 100644 index 0000000000000..04c75fda5f841 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts @@ -0,0 +1,3 @@ +const obj = { + #foo: 1 +}; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts b/tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts new file mode 100644 index 0000000000000..3356e7a957b1f --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts @@ -0,0 +1,5 @@ +const obj = { + #foo() { + + } +}; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts b/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts new file mode 100644 index 0000000000000..6f14d0ec8d72e --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target es6 + +class A { + #foo: number = 3; +} + +new A().#foo = 4; // Error diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts b/tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts new file mode 100644 index 0000000000000..26aacc421a19a --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts @@ -0,0 +1,4 @@ +// @strict: true +// @target es6 + +const #foo = 3; \ No newline at end of file diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts b/tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts new file mode 100644 index 0000000000000..f4450f031ab75 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts @@ -0,0 +1,16 @@ +// @strict: true +// @target es6 + +function createClass () { + return class { + #foo = 3; + equals(other: any) { + return this.#foo = other.#foo; + } + }; +} + +const a = new (createClass())(); +const b = new (createClass())(); + +console.log(a.equals(b)); // OK at compile time but will be a runtime error diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts new file mode 100644 index 0000000000000..d82e05ef9735e --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts @@ -0,0 +1,8 @@ +declare function dec(target: T): T; + +class A { + @dec // Error + #foo = 1; + @dec // Error + #bar(): void { } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts new file mode 100644 index 0000000000000..ebf44118093aa --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts @@ -0,0 +1,17 @@ +// @strict: true +// @target es6 + +class A { + #foo: number; + constructor () { + this.#foo = 3; + } +} + +class B extends A { + #foo: string; + constructor () { + super(); + this.#foo = "some string"; + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts new file mode 100644 index 0000000000000..fb515e4bb023a --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts @@ -0,0 +1,29 @@ +// @strict: true +// @target: es6 + +class C { + #foo: T; + #bar(): T { + return this.#foo; + } + constructor(t: T) { + this.#foo = t; + t = this.#bar(); + } + set baz(t: T) { + this.#foo = t; + + } + get baz(): T { + return this.#foo; + } +} + +let a = new C(3); +let b = new C("hello"); + +a.baz = 5 // OK +const x: number = a.baz // OK +a.#foo; // Error +a = b; // Error +b = a; // Error diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts new file mode 100644 index 0000000000000..0673430ce272c --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndIndexedAccess.ts @@ -0,0 +1,14 @@ +// @strict: true +// @target: es6 + +class C { + foo = 3; + #bar = 3; + constructor () { + const ok: C["foo"] = 3; + // not supported yet, could support in future: + const badForNow: C[#bar] = 3; // Error + // will never use this syntax, already taken: + const badAlways: C["#bar"] = 3; // Error + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts new file mode 100644 index 0000000000000..d564860b56e97 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts @@ -0,0 +1,32 @@ +// @target: esnext +// @lib: esnext + +class A { + #foo(a: number) {} + async #bar(a: number) {} + async *#baz(a: number) { + return 3; + } + #_quux: number; + get #quux (): number { + return this.#_quux; + } + set #quux (val: number) { + this.#_quux = val; + } + constructor () { + this.#foo(30); + this.#bar(30); + this.#bar(30); + this.#quux = this.#quux + 1; + this.#quux++; + } +} + +class B extends A { + #foo(a: string) {} + constructor () { + super(); + this.#foo("str"); + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts new file mode 100644 index 0000000000000..ec9906a8ef00d --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts @@ -0,0 +1,17 @@ +// @strict: true +// @target es6 + +class A { + static #foo: number; + constructor () { + A.#foo = 3; + } +} + +class B extends A { + static #foo: string; + constructor () { + super(); + B.#foo = "some string"; + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts new file mode 100644 index 0000000000000..7cbf9f8f9992b --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts @@ -0,0 +1,33 @@ +// @strict: true +// @target: esnext +// @lib: esnext + +class A { + static #foo(a: number) {} + static async #bar(a: number) {} + static async *#baz(a: number) { + return 3; + } + static #_quux: number; + static get #quux (): number { + return this.#_quux; + } + static set #quux (val: number) { + this.#_quux = val; + } + constructor () { + A.#foo(30); + A.#bar(30); + A.#bar(30); + A.#quux = A.#quux + 1; + A.#quux++; + } +} + +class B extends A { + static #foo(a: string) {} + constructor () { + super(); + B.#foo("str"); + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts new file mode 100644 index 0000000000000..1e178092c7e8d --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts @@ -0,0 +1,10 @@ +// @strict: true +// @target es6 + +class A { + #foo = 3; + bar = 3; + baz = 3; +} + +type T = keyof A // should not include '#foo' diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts new file mode 100644 index 0000000000000..fbf667d82f921 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts @@ -0,0 +1,15 @@ +// @strict: true +// @target: es6 + +class C { + #foo: T; + bar(x: C) { return x.#foo; } // OK + baz(x: C) { return x.#foo; } // OK + quux(x: C) { return x.#foo; } // OK +} + +declare let a: C; +declare let b: C; +a.#foo; // Error +a = b; // Error +b = a; // Error diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts new file mode 100644 index 0000000000000..dc6076ffbe096 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts @@ -0,0 +1,28 @@ +// @strict: true +// @target es6 + +class A { + #foo = "A's #foo"; + #bar = "A's #bar"; + method () { + class B { + #foo = "B's #foo"; + bar (a: any) { + a.#foo; // OK, no compile-time error, don't know what `a` is + } + baz (a: A) { + a.#foo; // compile-time error, shadowed + } + quux (b: B) { + b.#foo; // OK + } + } + const a = new A(); + new B().bar(a); + new B().baz(a); + const b = new B(); + new B().quux(b); + } +} + +new A().method(); \ No newline at end of file diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts new file mode 100644 index 0000000000000..a70c8acd143ac --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts @@ -0,0 +1,9 @@ +// @strict: true +// @target es6 + +class A { + public #foo = 3; // Error + private #bar = 3; // Error + protected #baz = 3; // Error + readonly #qux = 3; // OK +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts new file mode 100644 index 0000000000000..937ed9c4c3cfa --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts @@ -0,0 +1,12 @@ +// @strict: true +// @target es6 + +class A { + #foo: number; +} + +class B extends A { + #foo: string; // OK: private names are unique to each class +} + +const b: A = new B() // OK diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts new file mode 100644 index 0000000000000..70b099a0e5397 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts @@ -0,0 +1,9 @@ +// @strict: true +// @target es6 + +class A { + #v = 1; + constructor() { + delete this.#v; // Error: The operand of a delete operator cannot be a private name. + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts new file mode 100644 index 0000000000000..5a71fc00803c2 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts @@ -0,0 +1,5 @@ +// @target es6 + +class A { + setFoo(#foo: string) {} +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts new file mode 100644 index 0000000000000..26aacc421a19a --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts @@ -0,0 +1,4 @@ +// @strict: true +// @target es6 + +const #foo = 3; \ No newline at end of file diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts new file mode 100644 index 0000000000000..1e9891095512d --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts @@ -0,0 +1,12 @@ +// @strict: true +// @target es6 + +class A { + #foo: number; +} + +class B { + #foo: number; +} + +const b: A = new B(); // Error: Property #foo is missing From 49633996a6092c7e8ef432a848400276a318674d Mon Sep 17 00:00:00 2001 From: Joey Watts Date: Wed, 27 Mar 2019 16:09:29 -0400 Subject: [PATCH 07/16] Add private instance field transformation, pr feedback Implements private instance fields on top of the class properties refactor. This commit also includes incorporation of PR feedback on the checker, parser, and transformer in order to make the rebase manageable. Co-Authored-By: Max Heiber Co-Authored-By: Ron Buckton Signed-off-by: Joey Watts Signed-off-by: Max Heiber Incorporate PR feedback Fix checker crash with new block scoped bindings Add classExpressionInLoop test Update baselines for private name errors Apply suggestions from code review Fix privateNameFieldCallExpression test Remove unnecessary comment Fix PropertyAccessEntityNameExpression type Remove PrivateName from PropertyNameLiteral Add createPrivateName Remove PrivateName type from textSourceNode Add Debug asserts for invalid syntax kinds Don't output private name syntax when undeclared Make PrivateName extend Node Update baselines for public API Fix completions in language server Fix fourslash test crash intern private name descriptions undo expensive node.name.parent assignment Back the way things were on `master`: only assign node.name.parent when we need to Add tests for private names and JSDoc Patch hoverOverPrivateName fourslash test Fix goToDefinition for private-named fields remove Debug.fail for private name outside class Remove Debug.fail in binder.ts::`getDeclarationName`. It turns out this code path *does* get hit (intentionally). For best error messages, return `undefined` and rely on the parser generating a good error message "Private names are not allowed outside class bodies" Add rbuckton test cases for private names These test cases specifically exercise where we needed to use name-mangling. They are cases where private names have the same description. - private names no conflict when inheriting - private names distinct even when the two classes have the same name check dup instance+static private identifiers class A { #foo; static #foo; } not allowed because static and private names share the same lexical scope https://tc39.es/proposal-class-fields/#prod-ClassBody refactor getPropertyForPrivateName, rel spans refactor getPropertyForPrivateName so it is easier to read (use findAncestor instead of loop). Fix bugs in getPropertyForPrivateName: - make it work with deeply-nested classes with and without shadowing - make it catch shadowing when the conflict is between static and instance private name descriptions (these can actually clash) And add related spans to diagnostics for getPropertyForPrivateName catch conflicts between static and instance private identifiers: - cannot have an instance and static private identifier with the same spelling, as there is only one namespace for private names rename 'PrivateName' to 'PrivateIdentifier' to match the change of wording in the spec prposal: https://tc39.es/proposal-class-fields/#sec-syntax The rename in the spec was to avoid confusion between the AST Node PrivateIdentifier and the internal spec type PrivateName. So one uses the [[Description]] of a PrivateIdentifier to look up the PrivateName for a given scope. This corresponds closely to our implementation in the binder and checker: - we mangle PrivateIdentifier.escapedText to get a `key` which we use to get the symbol for a property f getLiteralTypeFromProperty-check privateIdentifier rename and simplify privateNameAndAny test case make it clearer that all this test is showing is that we allow accessing arbitrary private identifiers on `any`. Note: we could have something more sound here by checking that there is a private-named field declaration in a class scope above the property access. Discussion: https://github.com/microsoft/TypeScript/pull/30829/files#r302760015 Fix typo in checker s/identifer/identifier remove accidental change patch fourslash test broken by isPrivateIdentifier just needed to add a check to see if the symbol .name is defined extract reportUnmatchedProperty per @nsandersn feedback propertiesRelatedTo was getting to long pull out the unmatchedProperty reporting into a seprate function fix typo in private names test Fix type soundness with private names Remove PrivateIdentifier from emit with Expr hint Fixup helpers and set function name for privates remove accidentally-committed baselines These baselines somehow ended up in this pr, though they have nothing to do with the changes Revert "getLiteralTypeFromProperty-check privateIdentifier" This reverts commit bd1155c300bc3517a0543580f4790268f86e473f. reason: the check for isIdentifier in getLiteralTypeFromProperty is superfluous because we do this check in getLiteralTypeFromPropertyName Update comment in private name uniqueness test 3 I think the comments were not accurate and that we export the error on `this.#x = child.#x` because: - private names are lexically scoped: the code in question is not in a lexical scope under the definition of Child's #x. - private names are private to their containing class: never inherited This expected behavior matches that of Chrome Canary and my understanding of the spec test private names use before def, circular ref test private names use before def, circular ref update diagnosticMessages s/delete/'delete' per @DanielRosenwasser and @sandersn guidance, use this style in diagnostic messages: "operand of a 'delete' operator" (single quotes) rather than old style: "operand of a delete operator" (single quotes) This is for consistency, as we use the new style in the privateIdentifiers error messages and it is consistent with our messages about other operators incorporate private names early exit feedback and code style change to use a ternary instead of if so we can 'const' require private-named fields to be declared in JS All fields must be declared in TS files. In JS files, we typically do not have this requirement. So special-case private fields, which must always be declared (even in JS files, per spec) update debug failure for es2015 private identifier Co-Authored-By: Ron Buckton fix checker handling of private name in subclasse update checker and tests to account for the following ts features: - private names do not participate in the prototype chain, but *are* assigned in the parent class' constructor. So parent can access its *own* private fields on instances of the subclass Add more tests for private-named fields in JS add test to hit symbolToExpression w private names symbolToExpression knows about private names add a test to exercise this code path ban private-named static methods (not supported yet) ban private-named methods (not supported yet) ban private-named accessors (not supported yet) fix privateIdentifier fourslash test change assertion throw to return Co-Authored-By: Ron Buckton Update comment in checker.ts re reserved members Remove case for privateIdentifier in EntityNameExpr Remove case for privateIdentifier in EntityNameExpr. That code path is never hit, and privateIdnetifiers cannot be entity names. remove unnecessary parentheses Ban private identifier in enum As the new test, 'privateNameEnumNoEmit', shows, the checker now correctly makes a diagnostic for private identifiers in enums. However, when noEmit is false we hit this assertion in the transformer. This assertion will have to be removed so that we have a diagnostic here instead of an assertion error. When the assertion is removed, the 'privateNameEnum' baseline will have to be updated Fix destructuring assignment, use createCallBinding, remove unneeded helper Add class private field helpers to external helpers Remove private identifier enum assertion, use missing identifiers Fix hash map inefficiency by only using get Update baselines with empty identifier change Add privateNameEnum test baselines Fix private identifier destructuring (array assignment defaults, unique names) Use createPrivateIdentifierAssignment in destructuring transform Fix lint error Separate destructuring target visitor from regular visitor Fix destructuring assignment with this bindings Fix destructuring assignment with this bindings Fix syntax error with destructuring assignment output Disallow private identifiers in property signatures remove duplicate test baselines Add tests for undeclarated private identifiers remove unnecessary cast Nicer error message for mis-placed hashbang Workaround v8 bug with destructured assignments Optimize private identifier stack lookup Avoid the cost of performing an array lookup to look at the top of the private identifier environment stack. Change function name to be more specific Changes "getOperatorForCompoundAssignment" to "getNonAssignmentOperatorForCompoundAssignment" now that this function is accessible to the entire compiler. Improve test case for private name assignment Adds a compound assignment test case for a class with private names being declared on the left-hand-side of the assignment expression. Remove extra non-private-field test Remove isPrivateIdentifierAssignmentExpression helper Don't transform private names in ESNext target Preserve private fields initialized to functions Move function expressions to outer scope for efficiency Add WeakMap collision check Modify potential WeakMap collision condition Fix this property assignment binding with private names Add correct error message for WeakMap collision Add error for statements before super with private identifiers Refactor getPropertyForPrivateIdentifier Add test for private identifier fields initialized to class exprs Fix shebang errors Fix private errors on index signatures Add codefix for missing private property Update error messages for unsupported private features Fix inheritance-related errors Fixes inheritance-related errors with private identifiers by resolving properties from base classes. Private identifiers do not show up as properties on a union type, so those do not type-check. Add test for interface extending class with private access Remove debugging log Remove name assignment from private named functions Rename to getPrivateIdentifierPropertyOfType Fix index signature test comment Fix test target syntax error Change error messages patch private identifiers outside class bodies Add test for private identifier with ooo super Add test for a class with a private identifier with a non-preambly (for example, not a comment) statement before 'super': should error, saying 'super' must come first Fix nits incorporate PR feedback Incorporate checker feedback - reorganize if statements in checkFunctionOrConstructorSymbol - remove overload for getPrivateIdentifierPropertyOfType reorganize if statements in checkFunctionOrConstructorSymbol test for private names with JSX use getPropertyOftype in getPropertyForPrivateIdentifier getPrivateIdentifierPropertyOfType error on synthetic make getPrivateIdentifierPropertyOfType error if given a node that is not from the parse tree Simplify checkPrivateIdentifierPropertyAccess use getPropertiesOfType instead of rehashing that logic test for private identifiers w decl merging fix test target for privateNameDeclarationMerging update baselines Fix private identifier ++/-- numeric coercion Remove 'downleveled' from super error Fix bad comments in helper call emit Error on private identifiers in JSX tag names Add more private identifier tests Add es2015 target for private name destructured binding test Add privateNameConstructorSignature test Add test for navigation bar w private identifier Remove spurious line from test // in js file class A { exports.#foo = 3; // should error } The above line failed to produce an error when run using the test harness. When using tsc or the language server, we got the expected error message. Removing the troublesome line, as it seems to say more about the test runner than about the code it is testing. Fix inefficient constructor generation dts: don't emit type for private-identified field Do not emit types for private-identified fields when generating declaration files. // example.ts export class A { #foo: number; } // example.d.ts export declare class A { #foo; } **This is not ideal!** The following would be better: // example.d.ts export declare unique class A { #foo; } See discussion: https://github.com/microsoft/TypeScript/pull/33038#issuecomment-530321165 notice when private-identified field unused Notice when private-identified fields are unused, and implement the same behavior as for unused private-modified fields. This is used in the language server to make things grayed out. This case generates an error when --noUnusedLocals flag is passed to tsc: - " is declared but never used" accept baselines Revert "dts: don't emit type for private-identified field" This reverts commit e50305df5fb88121486291abad14478f5339a455. Instead of just excluding the type from private identifier emit, only emit a single private identifier per class. This accomplishes nominality while hiding implementation detail that is irrelevant to .d.ts consumers only emit a single private identifier in dts In dts emit, emit at most one private identifier, and rename it to `#private`. refactor getPrivateIdentifierPropertyOfType - safer check for wehther is parse tree node - return undefined when not found (instead of a Debug.fail) Incorporate PR feedback Don't rely on parent pointers in transform Passes context about whether the postfix unary expression value is discarded down the tree into the visitPostfixUnaryExpression function. Remove orphaned test baseline files remove unreachable if Check `any`-typed private identified fields Update private identifier incompatible modifier checks - disallow 'abstract' with private identifiers - s/private-named-property/private identifier Add additional call expression test cases Fix disallow 'abstract' with private identifier Static private identifiers not inherited Including this in the PR for private instance fields even though static private identifiers are banned. Reason: this change improves quality of error messages, see test case. Thanks Ron! Simplifiy private identifier 'any' type handling Error on private identifier declarations for ES5/ES3 Bind `this` for private identifier property tagged template literals Fix target for jsdocPrivateName1 test Update getPrivateIdentifierPropertyOfType API Make it easier to use by accepting a string and location, rather than a PrivateIdentifier. Thanks Ron! remove orphaned tests rename test remove duplicate tests Remove unrelated error from test update diagnostic message 'private identifier' The nodes for hash private fields are now called 'private identifier'. Update one last diagnostic message to use the new terminology. refine solution for static private identifier fields - use `continue` instead of `filter` for perf - better naming - make it clear the current solution will need to be altered when we lift the ban on static private identifier fields, including a test case that should change in the future Fix display of private identifiers in lang server Fix bug where private identifiers in completion tooltips in the playground were showing up as the symbol table entries (with underscores and such). https://github.com/microsoft/TypeScript/pull/30829#issuecomment-534157560 Signed-off-by: Max Heiber --- src/compiler/binder.ts | 39 +- src/compiler/checker.ts | 576 +++++++++++------ src/compiler/diagnosticMessages.json | 60 +- src/compiler/emitter.ts | 12 +- src/compiler/factory.ts | 21 +- src/compiler/factoryPublic.ts | 17 +- src/compiler/parser.ts | 55 +- src/compiler/scanner.ts | 2 +- src/compiler/transformers/classFields.ts | 601 +++++++++++++++++- src/compiler/transformers/declarations.ts | 33 +- src/compiler/transformers/es2015.ts | 12 +- src/compiler/transformers/es5.ts | 2 +- src/compiler/transformers/generators.ts | 24 +- src/compiler/transformers/ts.ts | 9 +- src/compiler/transformers/utilities.ts | 34 +- src/compiler/types.ts | 31 +- src/compiler/utilities.ts | 39 +- src/compiler/utilitiesPublic.ts | 28 +- src/compiler/visitor.ts | 2 +- src/compiler/visitorPublic.ts | 2 +- src/services/codefixes/fixAddMissingMember.ts | 26 +- src/services/codefixes/inferFromUsage.ts | 2 +- src/services/completions.ts | 8 +- src/services/navigationBar.ts | 2 +- src/services/services.ts | 23 +- src/services/types.ts | 2 +- src/services/utilities.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 29 +- tests/baselines/reference/api/typescript.d.ts | 29 +- .../await_unaryExpression_es2017_1.errors.txt | 8 +- .../await_unaryExpression_es2017_2.errors.txt | 8 +- .../await_unaryExpression_es6_1.errors.txt | 8 +- .../await_unaryExpression_es6_2.errors.txt | 8 +- .../reference/classUpdateTests.errors.txt | 8 +- .../computedPropertyNames3_ES5.errors.txt | 4 +- .../computedPropertyNames3_ES6.errors.txt | 4 +- .../controlFlowDeleteOperator.errors.txt | 4 +- ...ionMapsGeneratedMapsEnableMapping.baseline | 34 - ...onMapsGeneratedMapsEnableMapping2.baseline | 35 - ...onMapsGeneratedMapsEnableMapping3.baseline | 34 - ...neratedMapsEnableMapping_NoInline.baseline | 34 - ...MapsEnableMapping_NoInlineSources.baseline | 34 - .../reference/deleteOperator1.errors.txt | 12 +- .../deleteOperatorInStrictMode.errors.txt | 4 +- ...deleteOperatorInvalidOperations.errors.txt | 12 +- .../deleteOperatorWithAnyOtherType.errors.txt | 88 +-- .../deleteOperatorWithBooleanType.errors.txt | 44 +- .../deleteOperatorWithEnumType.errors.txt | 52 +- .../deleteOperatorWithNumberType.errors.txt | 68 +- .../deleteOperatorWithStringType.errors.txt | 72 +-- .../reference/deleteReadonly.errors.txt | 4 +- ...derivedClassParameterProperties.errors.txt | 16 +- ...onentiationOperatorSyntaxError2.errors.txt | 32 +- ...idSimpleUnaryExpressionOperands.errors.txt | 32 +- ...CompilationBindStrictModeErrors.errors.txt | 4 +- .../reference/jsdocPrivateName1.errors.txt | 11 + .../reference/jsdocPrivateName1.symbols | 9 + .../reference/jsdocPrivateName1.types | 10 + .../reference/jsdocPrivateName2.errors.txt | 14 + .../reference/jsdocPrivateName2.symbols | 10 + .../reference/jsdocPrivateName2.types | 10 + .../reference/parserStrictMode15.errors.txt | 4 +- .../reference/parserStrictMode16.errors.txt | 16 +- .../reference/privateNameAndAny.errors.txt | 14 + .../baselines/reference/privateNameAndAny.js | 30 + .../reference/privateNameAndAny.symbols | 19 + .../reference/privateNameAndAny.types | 22 + .../privateNameAndIndexSignature.errors.txt | 13 +- .../reference/privateNameAndIndexSignature.js | 35 +- .../privateNameAndIndexSignature.symbols | 19 +- .../privateNameAndIndexSignature.types | 23 +- ...privateNameAndPropertySignature.errors.txt | 35 + .../privateNameAndPropertySignature.js | 20 + .../privateNameAndPropertySignature.symbols | 34 + .../privateNameAndPropertySignature.types | 32 + ...NameAndStaticInitializer(target=es2015).js | 19 + ...ndStaticInitializer(target=es2015).symbols | 16 + ...eAndStaticInitializer(target=es2015).types | 19 + ...NameAndStaticInitializer(target=esnext).js | 19 + ...ndStaticInitializer(target=esnext).symbols | 16 + ...eAndStaticInitializer(target=esnext).types | 19 + .../privateNameBadAssignment.errors.txt | 36 ++ .../reference/privateNameBadAssignment.js | 40 ++ .../privateNameBadAssignment.symbols | 29 + .../reference/privateNameBadAssignment.types | 49 ++ .../privateNameBadDeclaration.errors.txt | 25 + .../reference/privateNameBadDeclaration.js | 34 + .../privateNameBadDeclaration.symbols | 31 + .../reference/privateNameBadDeclaration.types | 40 ++ .../reference/privateNameBadSuper.errors.txt | 17 + .../reference/privateNameBadSuper.js | 23 + .../reference/privateNameBadSuper.symbols | 17 + .../reference/privateNameBadSuper.types | 21 + .../privateNameCircularReference.errors.txt | 22 + .../reference/privateNameCircularReference.js | 25 + .../privateNameCircularReference.symbols | 21 + .../privateNameCircularReference.types | 22 + .../privateNameConstructorReserved.errors.txt | 9 +- .../privateNameConstructorReserved.js | 12 +- .../privateNameConstructorReserved.symbols | 4 +- .../privateNameConstructorReserved.types | 2 - .../privateNameConstructorSignature.js | 40 ++ .../privateNameConstructorSignature.symbols | 42 ++ .../privateNameConstructorSignature.types | 44 ++ .../reference/privateNameDeclaration.js | 33 + .../reference/privateNameDeclaration.symbols | 22 + .../reference/privateNameDeclaration.types | 24 + .../privateNameDeclarationMerging.errors.txt | 21 + .../privateNameDeclarationMerging.js | 40 ++ .../privateNameDeclarationMerging.symbols | 37 ++ .../privateNameDeclarationMerging.types | 36 ++ .../privateNameDuplicateField.errors.txt | 4 +- .../reference/privateNameDuplicateField.js | 16 +- .../privateNameDuplicateField.symbols | 6 +- .../reference/privateNameDuplicateField.types | 2 - .../privateNameES5Ban(target=es3).errors.txt | 52 ++ .../privateNameES5Ban(target=es3).js | 39 ++ .../privateNameES5Ban(target=es3).symbols | 33 + .../privateNameES5Ban(target=es3).types | 37 ++ .../privateNameES5Ban(target=es5).errors.txt | 40 ++ .../privateNameES5Ban(target=es5).js | 39 ++ .../privateNameES5Ban(target=es5).symbols | 33 + .../privateNameES5Ban(target=es5).types | 37 ++ .../reference/privateNameEnum.errors.txt | 10 + tests/baselines/reference/privateNameEnum.js | 11 + .../reference/privateNameEnum.symbols | 8 + .../baselines/reference/privateNameEnum.types | 8 + tests/baselines/reference/privateNameField.js | 35 +- .../reference/privateNameField.symbols | 11 +- .../reference/privateNameField.types | 3 +- .../reference/privateNameFieldAccess.js | 24 + .../reference/privateNameFieldAccess.symbols | 17 + .../reference/privateNameFieldAccess.types | 19 + .../reference/privateNameFieldAssignment.js | 88 +++ .../privateNameFieldAssignment.symbols | 146 +++++ .../privateNameFieldAssignment.types | 213 +++++++ .../privateNameFieldCallExpression.js | 50 ++ .../privateNameFieldCallExpression.symbols | 64 ++ .../privateNameFieldCallExpression.types | 96 +++ .../privateNameFieldClassExpression.js | 35 + .../privateNameFieldClassExpression.symbols | 29 + .../privateNameFieldClassExpression.types | 35 + .../privateNameFieldDerivedClasses.errors.txt | 19 + .../privateNameFieldDerivedClasses.js | 37 ++ .../privateNameFieldDerivedClasses.symbols | 38 ++ .../privateNameFieldDerivedClasses.types | 40 ++ ...FieldDestructuredBinding(target=es2015).js | 60 ++ ...DestructuredBinding(target=es2015).symbols | 90 +++ ...ldDestructuredBinding(target=es2015).types | 144 +++++ ...FieldDestructuredBinding(target=esnext).js | 51 ++ ...DestructuredBinding(target=esnext).symbols | 90 +++ ...ldDestructuredBinding(target=esnext).types | 144 +++++ .../reference/privateNameFieldInitializer.js | 16 + .../privateNameFieldInitializer.symbols | 11 + .../privateNameFieldInitializer.types | 12 + .../privateNameFieldUnaryMutation.js | 77 +++ .../privateNameFieldUnaryMutation.symbols | 148 +++++ .../privateNameFieldUnaryMutation.types | 200 ++++++ .../privateNameFieldsESNext.errors.txt | 32 + .../reference/privateNameFieldsESNext.js | 46 ++ .../reference/privateNameFieldsESNext.symbols | 65 ++ .../reference/privateNameFieldsESNext.types | 79 +++ .../privateNameImplicitDeclaration.errors.txt | 14 + .../privateNameImplicitDeclaration.symbols | 12 + .../privateNameImplicitDeclaration.types | 13 + .../privateNameInLhsReceiverExpression.js | 51 ++ ...privateNameInLhsReceiverExpression.symbols | 32 + .../privateNameInLhsReceiverExpression.types | 48 ++ .../privateNameInObjectLiteral-1.errors.txt | 4 +- .../privateNameInObjectLiteral-2.errors.txt | 4 +- .../privateNameInObjectLiteral.errors.txt | 14 - .../reference/privateNameInObjectLiteral.js | 18 - .../privateNameInObjectLiteral.symbols | 17 - .../privateNameInObjectLiteral.types | 22 - .../privateNameJsBadAssignment.errors.txt | 29 + .../privateNameJsBadAssignment.symbols | 30 + .../privateNameJsBadAssignment.types | 43 ++ .../privateNameJsBadDeclaration.errors.txt | 25 + .../privateNameJsBadDeclaration.symbols | 31 + .../privateNameJsBadDeclaration.types | 40 ++ .../reference/privateNameJsx.errors.txt | 14 + tests/baselines/reference/privateNameJsx.js | 22 + .../reference/privateNameJsx.symbols | 16 + .../baselines/reference/privateNameJsx.types | 22 + ...teNameNestedClassFieldShadowing.errors.txt | 23 + .../privateNameNestedClassFieldShadowing.js | 44 ++ ...ivateNameNestedClassFieldShadowing.symbols | 41 ++ ...privateNameNestedClassFieldShadowing.types | 42 ++ .../privateNameNestedClassNameConflict.js | 26 + ...privateNameNestedClassNameConflict.symbols | 17 + .../privateNameNestedClassNameConflict.types | 17 + ...tAccessibleOutsideDefiningClass.errors.txt | 11 +- ...teNameNotAccessibleOutsideDefiningClass.js | 14 +- ...eNotAccessibleOutsideDefiningClass.symbols | 4 +- ...ameNotAccessibleOutsideDefiningClass.types | 2 - ...ivateNameNotAllowedOutsideClass.errors.txt | 11 +- .../privateNameNotAllowedOutsideClass.js | 8 +- .../privateNameNotAllowedOutsideClass.symbols | 3 +- .../privateNameNotAllowedOutsideClass.types | 2 - .../privateNameSneakyRuntimeException.js | 47 -- .../privateNameSneakyRuntimeException.symbols | 39 -- .../privateNameSneakyRuntimeException.types | 52 -- .../reference/privateNameUnused.errors.txt | 14 + .../reference/privateNameUnused.symbols | 20 + .../reference/privateNameUnused.types | 23 + .../privateNameWeakMapCollision.errors.txt | 13 + .../reference/privateNameWeakMapCollision.js | 20 + .../privateNameWeakMapCollision.symbols | 15 + .../privateNameWeakMapCollision.types | 15 + .../privateNamesAndDecorators.errors.txt | 5 +- .../reference/privateNamesAndDecorators.js | 6 +- .../reference/privateNamesAndFields.js | 67 +- .../reference/privateNamesAndFields.symbols | 14 +- .../reference/privateNamesAndFields.types | 2 - ...privateNamesAndGenericClasses-2.errors.txt | 10 +- .../privateNamesAndGenericClasses-2.js | 26 +- .../reference/privateNamesAndIndexedAccess.js | 5 +- .../privateNamesAndMethods.errors.txt | 51 ++ .../reference/privateNamesAndMethods.js | 118 +--- .../reference/privateNamesAndMethods.symbols | 4 +- .../reference/privateNamesAndMethods.types | 6 +- .../privateNamesAndStaticFields.errors.txt | 40 ++ .../reference/privateNamesAndStaticFields.js | 84 +-- .../privateNamesAndStaticFields.symbols | 29 +- .../privateNamesAndStaticFields.types | 20 +- .../privateNamesAndStaticMethods.errors.txt | 54 ++ .../reference/privateNamesAndStaticMethods.js | 88 +-- .../reference/privateNamesAndkeyof.js | 30 +- .../reference/privateNamesAndkeyof.symbols | 10 +- .../reference/privateNamesAndkeyof.types | 2 - .../privateNamesConstructorChain-1.errors.txt | 23 + .../privateNamesConstructorChain-1.js | 43 ++ .../privateNamesConstructorChain-1.symbols | 33 + .../privateNamesConstructorChain-1.types | 39 ++ .../privateNamesConstructorChain-2.errors.txt | 25 + .../privateNamesConstructorChain-2.js | 46 ++ .../privateNamesConstructorChain-2.symbols | 41 ++ .../privateNamesConstructorChain-2.types | 46 ++ .../privateNamesInGenericClasses.errors.txt | 9 +- .../reference/privateNamesInGenericClasses.js | 17 +- .../privateNamesInNestedClasses-1.errors.txt | 34 + .../privateNamesInNestedClasses-1.js | 68 ++ .../privateNamesInNestedClasses-1.symbols | 77 +++ ...es => privateNamesInNestedClasses-1.types} | 4 +- .../privateNamesInNestedClasses-2.errors.txt | 27 + .../privateNamesInNestedClasses-2.js | 45 ++ .../privateNamesInNestedClasses-2.symbols | 28 + .../privateNamesInNestedClasses-2.types | 31 + .../privateNamesInNestedClasses.errors.txt | 36 -- .../reference/privateNamesInNestedClasses.js | 62 -- .../privateNamesInNestedClasses.symbols | 79 --- ...ivateNamesIncompatibleModifiers.errors.txt | 26 + .../privateNamesIncompatibleModifiers.js | 31 + .../privateNamesIncompatibleModifiers.symbols | 24 + ...> privateNamesIncompatibleModifiers.types} | 12 +- ...ateNamesInterfaceExtendingClass.errors.txt | 19 + .../privateNamesInterfaceExtendingClass.js | 36 ++ ...rivateNamesInterfaceExtendingClass.symbols | 31 + .../privateNamesInterfaceExtendingClass.types | 32 + ...teNamesNoAccessibilityModifiers.errors.txt | 21 - .../privateNamesNoAccessibilityModifiers.js | 23 - ...ivateNamesNoAccessibilityModifiers.symbols | 19 - .../privateNamesNoConflictWhenInheriting.js | 43 -- ...ivateNamesNoConflictWhenInheriting.symbols | 23 - ...privateNamesNoConflictWhenInheriting.types | 23 - .../reference/privateNamesNoDelete.errors.txt | 6 +- .../reference/privateNamesNoDelete.js | 22 +- .../reference/privateNamesNoDelete.symbols | 6 +- .../reference/privateNamesNoDelete.types | 2 - ...vateNamesNotAllowedAsParameters.errors.txt | 10 +- .../privateNamesNotAllowedAsParameters.js | 15 +- ...privateNamesNotAllowedAsParameters.symbols | 6 +- .../privateNamesNotAllowedAsParameters.types | 2 - ...otAllowedInVariableDeclarations.errors.txt | 11 +- ...teNamesNotAllowedInVariableDeclarations.js | 8 +- ...esNotAllowedInVariableDeclarations.symbols | 3 +- ...amesNotAllowedInVariableDeclarations.types | 2 - .../reference/privateNamesUnique-1.errors.txt | 18 + .../reference/privateNamesUnique-1.js | 28 + .../reference/privateNamesUnique-1.symbols | 20 + ...nique.types => privateNamesUnique-1.types} | 4 +- .../reference/privateNamesUnique-2.errors.txt | 26 + .../reference/privateNamesUnique-2.js | 55 ++ .../reference/privateNamesUnique-2.symbols | 48 ++ .../reference/privateNamesUnique-2.types | 51 ++ .../reference/privateNamesUnique-3.errors.txt | 29 + .../reference/privateNamesUnique-3.js | 41 ++ .../reference/privateNamesUnique-3.symbols | 30 + .../reference/privateNamesUnique-3.types | 33 + .../reference/privateNamesUnique.errors.txt | 20 - .../baselines/reference/privateNamesUnique.js | 28 - .../reference/privateNamesUnique.symbols | 22 - .../privateNamesUseBeforeDef.errors.txt | 21 + .../reference/privateNamesUseBeforeDef.js | 34 + .../privateNamesUseBeforeDef.symbols | 27 + .../reference/privateNamesUseBeforeDef.types | 28 + .../reference/shebangError.errors.txt | 4 +- .../strictModeInConstructor.errors.txt | 4 +- .../reference/symbolType3.errors.txt | 4 +- ...emplateStringInDeleteExpression.errors.txt | 4 +- ...lateStringInDeleteExpressionES6.errors.txt | 4 +- tests/cases/compiler/privateNameJsx.tsx | 9 + .../compiler/privateNameWeakMapCollision.ts | 8 + .../members/privateNames/privateNameAndAny.ts | 10 + .../privateNameAndIndexSignature.ts | 8 +- .../privateNameAndPropertySignature.ts | 16 + .../privateNameAndStaticInitializer.ts | 8 + .../privateNames/privateNameBadAssignment.ts | 16 + .../privateNames/privateNameBadDeclaration.ts | 13 + .../privateNames/privateNameBadSuper.ts | 9 + .../privateNameCircularReference.ts | 8 + .../privateNameConstructorReserved.ts | 2 +- .../privateNameConstructorSignature.ts | 18 + .../privateNames/privateNameDeclaration.ts | 12 + .../privateNameDeclarationMerging.ts | 16 + .../privateNames/privateNameDuplicateField.ts | 2 +- .../members/privateNames/privateNameES5Ban.ts | 14 + .../members/privateNames/privateNameEnum.ts | 4 + .../members/privateNames/privateNameField.ts | 4 +- .../privateNames/privateNameFieldAccess.ts | 8 + .../privateNameFieldAssignment.ts | 36 ++ .../privateNameFieldCallExpression.ts | 20 + .../privateNameFieldClassExpression.ts | 15 + .../privateNameFieldDerivedClasses.ts | 14 + .../privateNameFieldDestructuredBinding.ts | 25 + .../privateNameFieldInitializer.ts | 6 + .../privateNameFieldUnaryMutation.ts | 30 + .../privateNames/privateNameFieldsESNext.ts | 21 + .../privateNameImplicitDeclaration.ts | 12 + .../privateNameInLhsReceiverExpression.ts | 10 + .../privateNameJsBadAssignment.ts | 19 + .../privateNameJsBadDeclaration.ts | 18 + .../privateNameNestedClassFieldShadowing.ts | 16 + .../privateNameNestedClassNameConflict.ts | 10 + ...teNameNotAccessibleOutsideDefiningClass.ts | 2 +- .../privateNameNotAllowedOutsideClass.ts | 4 +- .../privateNameSneakyRuntimeException.ts | 16 - .../members/privateNames/privateNameUnused.ts | 11 + .../privateNames/privateNamesAndFields.ts | 2 +- .../privateNames/privateNamesAndMethods.ts | 2 +- .../privateNamesAndStaticFields.ts | 9 +- .../privateNames/privateNamesAndkeyof.ts | 2 +- .../privateNamesConstructorChain-1.ts | 15 + .../privateNamesConstructorChain-2.ts | 17 + ...es.ts => privateNamesInNestedClasses-1.ts} | 4 +- .../privateNamesInNestedClasses-2.ts | 18 + ...s => privateNamesIncompatibleModifiers.ts} | 6 +- .../privateNamesInterfaceExtendingClass.ts | 14 + .../privateNamesNoConflictWhenInheriting.ts | 12 - .../privateNames/privateNamesNoDelete.ts | 2 +- .../privateNamesNotAllowedAsParameters.ts | 2 +- ...teNamesNotAllowedInVariableDeclarations.ts | 4 +- ...NamesUnique.ts => privateNamesUnique-1.ts} | 2 +- .../privateNames/privateNamesUnique-2.ts | 21 + .../privateNames/privateNamesUnique-3.ts | 15 + .../privateNames/privateNamesUseBeforeDef.ts | 11 + .../conformance/jsdoc/jsdocPrivateName1.ts | 11 + .../conformance/jsdoc/jsdocPrivateName2.ts | 13 + ...ssingPrivateIdentifierMethodDeclaration.ts | 19 + .../fourslash/goToDefinitionPrivateName.ts | 12 + tests/cases/fourslash/hoverOverPrivateName.ts | 36 +- .../fourslash/navigationBarPrivateName.ts | 91 +++ 362 files changed, 8705 insertions(+), 2002 deletions(-) delete mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline delete mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline delete mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline delete mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline delete mode 100644 tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline create mode 100644 tests/baselines/reference/jsdocPrivateName1.errors.txt create mode 100644 tests/baselines/reference/jsdocPrivateName1.symbols create mode 100644 tests/baselines/reference/jsdocPrivateName1.types create mode 100644 tests/baselines/reference/jsdocPrivateName2.errors.txt create mode 100644 tests/baselines/reference/jsdocPrivateName2.symbols create mode 100644 tests/baselines/reference/jsdocPrivateName2.types create mode 100644 tests/baselines/reference/privateNameAndAny.errors.txt create mode 100644 tests/baselines/reference/privateNameAndAny.js create mode 100644 tests/baselines/reference/privateNameAndAny.symbols create mode 100644 tests/baselines/reference/privateNameAndAny.types create mode 100644 tests/baselines/reference/privateNameAndPropertySignature.errors.txt create mode 100644 tests/baselines/reference/privateNameAndPropertySignature.js create mode 100644 tests/baselines/reference/privateNameAndPropertySignature.symbols create mode 100644 tests/baselines/reference/privateNameAndPropertySignature.types create mode 100644 tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).js create mode 100644 tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).symbols create mode 100644 tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).types create mode 100644 tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).js create mode 100644 tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).symbols create mode 100644 tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).types create mode 100644 tests/baselines/reference/privateNameBadAssignment.errors.txt create mode 100644 tests/baselines/reference/privateNameBadAssignment.js create mode 100644 tests/baselines/reference/privateNameBadAssignment.symbols create mode 100644 tests/baselines/reference/privateNameBadAssignment.types create mode 100644 tests/baselines/reference/privateNameBadDeclaration.errors.txt create mode 100644 tests/baselines/reference/privateNameBadDeclaration.js create mode 100644 tests/baselines/reference/privateNameBadDeclaration.symbols create mode 100644 tests/baselines/reference/privateNameBadDeclaration.types create mode 100644 tests/baselines/reference/privateNameBadSuper.errors.txt create mode 100644 tests/baselines/reference/privateNameBadSuper.js create mode 100644 tests/baselines/reference/privateNameBadSuper.symbols create mode 100644 tests/baselines/reference/privateNameBadSuper.types create mode 100644 tests/baselines/reference/privateNameCircularReference.errors.txt create mode 100644 tests/baselines/reference/privateNameCircularReference.js create mode 100644 tests/baselines/reference/privateNameCircularReference.symbols create mode 100644 tests/baselines/reference/privateNameCircularReference.types create mode 100644 tests/baselines/reference/privateNameConstructorSignature.js create mode 100644 tests/baselines/reference/privateNameConstructorSignature.symbols create mode 100644 tests/baselines/reference/privateNameConstructorSignature.types create mode 100644 tests/baselines/reference/privateNameDeclaration.js create mode 100644 tests/baselines/reference/privateNameDeclaration.symbols create mode 100644 tests/baselines/reference/privateNameDeclaration.types create mode 100644 tests/baselines/reference/privateNameDeclarationMerging.errors.txt create mode 100644 tests/baselines/reference/privateNameDeclarationMerging.js create mode 100644 tests/baselines/reference/privateNameDeclarationMerging.symbols create mode 100644 tests/baselines/reference/privateNameDeclarationMerging.types create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es3).errors.txt create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es3).js create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es3).symbols create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es3).types create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es5).errors.txt create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es5).js create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es5).symbols create mode 100644 tests/baselines/reference/privateNameES5Ban(target=es5).types create mode 100644 tests/baselines/reference/privateNameEnum.errors.txt create mode 100644 tests/baselines/reference/privateNameEnum.js create mode 100644 tests/baselines/reference/privateNameEnum.symbols create mode 100644 tests/baselines/reference/privateNameEnum.types create mode 100644 tests/baselines/reference/privateNameFieldAccess.js create mode 100644 tests/baselines/reference/privateNameFieldAccess.symbols create mode 100644 tests/baselines/reference/privateNameFieldAccess.types create mode 100644 tests/baselines/reference/privateNameFieldAssignment.js create mode 100644 tests/baselines/reference/privateNameFieldAssignment.symbols create mode 100644 tests/baselines/reference/privateNameFieldAssignment.types create mode 100644 tests/baselines/reference/privateNameFieldCallExpression.js create mode 100644 tests/baselines/reference/privateNameFieldCallExpression.symbols create mode 100644 tests/baselines/reference/privateNameFieldCallExpression.types create mode 100644 tests/baselines/reference/privateNameFieldClassExpression.js create mode 100644 tests/baselines/reference/privateNameFieldClassExpression.symbols create mode 100644 tests/baselines/reference/privateNameFieldClassExpression.types create mode 100644 tests/baselines/reference/privateNameFieldDerivedClasses.errors.txt create mode 100644 tests/baselines/reference/privateNameFieldDerivedClasses.js create mode 100644 tests/baselines/reference/privateNameFieldDerivedClasses.symbols create mode 100644 tests/baselines/reference/privateNameFieldDerivedClasses.types create mode 100644 tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).js create mode 100644 tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).symbols create mode 100644 tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).types create mode 100644 tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).js create mode 100644 tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).symbols create mode 100644 tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).types create mode 100644 tests/baselines/reference/privateNameFieldInitializer.js create mode 100644 tests/baselines/reference/privateNameFieldInitializer.symbols create mode 100644 tests/baselines/reference/privateNameFieldInitializer.types create mode 100644 tests/baselines/reference/privateNameFieldUnaryMutation.js create mode 100644 tests/baselines/reference/privateNameFieldUnaryMutation.symbols create mode 100644 tests/baselines/reference/privateNameFieldUnaryMutation.types create mode 100644 tests/baselines/reference/privateNameFieldsESNext.errors.txt create mode 100644 tests/baselines/reference/privateNameFieldsESNext.js create mode 100644 tests/baselines/reference/privateNameFieldsESNext.symbols create mode 100644 tests/baselines/reference/privateNameFieldsESNext.types create mode 100644 tests/baselines/reference/privateNameImplicitDeclaration.errors.txt create mode 100644 tests/baselines/reference/privateNameImplicitDeclaration.symbols create mode 100644 tests/baselines/reference/privateNameImplicitDeclaration.types create mode 100644 tests/baselines/reference/privateNameInLhsReceiverExpression.js create mode 100644 tests/baselines/reference/privateNameInLhsReceiverExpression.symbols create mode 100644 tests/baselines/reference/privateNameInLhsReceiverExpression.types delete mode 100644 tests/baselines/reference/privateNameInObjectLiteral.errors.txt delete mode 100644 tests/baselines/reference/privateNameInObjectLiteral.js delete mode 100644 tests/baselines/reference/privateNameInObjectLiteral.symbols delete mode 100644 tests/baselines/reference/privateNameInObjectLiteral.types create mode 100644 tests/baselines/reference/privateNameJsBadAssignment.errors.txt create mode 100644 tests/baselines/reference/privateNameJsBadAssignment.symbols create mode 100644 tests/baselines/reference/privateNameJsBadAssignment.types create mode 100644 tests/baselines/reference/privateNameJsBadDeclaration.errors.txt create mode 100644 tests/baselines/reference/privateNameJsBadDeclaration.symbols create mode 100644 tests/baselines/reference/privateNameJsBadDeclaration.types create mode 100644 tests/baselines/reference/privateNameJsx.errors.txt create mode 100644 tests/baselines/reference/privateNameJsx.js create mode 100644 tests/baselines/reference/privateNameJsx.symbols create mode 100644 tests/baselines/reference/privateNameJsx.types create mode 100644 tests/baselines/reference/privateNameNestedClassFieldShadowing.errors.txt create mode 100644 tests/baselines/reference/privateNameNestedClassFieldShadowing.js create mode 100644 tests/baselines/reference/privateNameNestedClassFieldShadowing.symbols create mode 100644 tests/baselines/reference/privateNameNestedClassFieldShadowing.types create mode 100644 tests/baselines/reference/privateNameNestedClassNameConflict.js create mode 100644 tests/baselines/reference/privateNameNestedClassNameConflict.symbols create mode 100644 tests/baselines/reference/privateNameNestedClassNameConflict.types delete mode 100644 tests/baselines/reference/privateNameSneakyRuntimeException.js delete mode 100644 tests/baselines/reference/privateNameSneakyRuntimeException.symbols delete mode 100644 tests/baselines/reference/privateNameSneakyRuntimeException.types create mode 100644 tests/baselines/reference/privateNameUnused.errors.txt create mode 100644 tests/baselines/reference/privateNameUnused.symbols create mode 100644 tests/baselines/reference/privateNameUnused.types create mode 100644 tests/baselines/reference/privateNameWeakMapCollision.errors.txt create mode 100644 tests/baselines/reference/privateNameWeakMapCollision.js create mode 100644 tests/baselines/reference/privateNameWeakMapCollision.symbols create mode 100644 tests/baselines/reference/privateNameWeakMapCollision.types create mode 100644 tests/baselines/reference/privateNamesAndMethods.errors.txt create mode 100644 tests/baselines/reference/privateNamesAndStaticFields.errors.txt create mode 100644 tests/baselines/reference/privateNamesAndStaticMethods.errors.txt create mode 100644 tests/baselines/reference/privateNamesConstructorChain-1.errors.txt create mode 100644 tests/baselines/reference/privateNamesConstructorChain-1.js create mode 100644 tests/baselines/reference/privateNamesConstructorChain-1.symbols create mode 100644 tests/baselines/reference/privateNamesConstructorChain-1.types create mode 100644 tests/baselines/reference/privateNamesConstructorChain-2.errors.txt create mode 100644 tests/baselines/reference/privateNamesConstructorChain-2.js create mode 100644 tests/baselines/reference/privateNamesConstructorChain-2.symbols create mode 100644 tests/baselines/reference/privateNamesConstructorChain-2.types create mode 100644 tests/baselines/reference/privateNamesInNestedClasses-1.errors.txt create mode 100644 tests/baselines/reference/privateNamesInNestedClasses-1.js create mode 100644 tests/baselines/reference/privateNamesInNestedClasses-1.symbols rename tests/baselines/reference/{privateNamesInNestedClasses.types => privateNamesInNestedClasses-1.types} (91%) create mode 100644 tests/baselines/reference/privateNamesInNestedClasses-2.errors.txt create mode 100644 tests/baselines/reference/privateNamesInNestedClasses-2.js create mode 100644 tests/baselines/reference/privateNamesInNestedClasses-2.symbols create mode 100644 tests/baselines/reference/privateNamesInNestedClasses-2.types delete mode 100644 tests/baselines/reference/privateNamesInNestedClasses.errors.txt delete mode 100644 tests/baselines/reference/privateNamesInNestedClasses.js delete mode 100644 tests/baselines/reference/privateNamesInNestedClasses.symbols create mode 100644 tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt create mode 100644 tests/baselines/reference/privateNamesIncompatibleModifiers.js create mode 100644 tests/baselines/reference/privateNamesIncompatibleModifiers.symbols rename tests/baselines/reference/{privateNamesNoAccessibilityModifiers.types => privateNamesIncompatibleModifiers.types} (67%) create mode 100644 tests/baselines/reference/privateNamesInterfaceExtendingClass.errors.txt create mode 100644 tests/baselines/reference/privateNamesInterfaceExtendingClass.js create mode 100644 tests/baselines/reference/privateNamesInterfaceExtendingClass.symbols create mode 100644 tests/baselines/reference/privateNamesInterfaceExtendingClass.types delete mode 100644 tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt delete mode 100644 tests/baselines/reference/privateNamesNoAccessibilityModifiers.js delete mode 100644 tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols delete mode 100644 tests/baselines/reference/privateNamesNoConflictWhenInheriting.js delete mode 100644 tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols delete mode 100644 tests/baselines/reference/privateNamesNoConflictWhenInheriting.types create mode 100644 tests/baselines/reference/privateNamesUnique-1.errors.txt create mode 100644 tests/baselines/reference/privateNamesUnique-1.js create mode 100644 tests/baselines/reference/privateNamesUnique-1.symbols rename tests/baselines/reference/{privateNamesUnique.types => privateNamesUnique-1.types} (82%) create mode 100644 tests/baselines/reference/privateNamesUnique-2.errors.txt create mode 100644 tests/baselines/reference/privateNamesUnique-2.js create mode 100644 tests/baselines/reference/privateNamesUnique-2.symbols create mode 100644 tests/baselines/reference/privateNamesUnique-2.types create mode 100644 tests/baselines/reference/privateNamesUnique-3.errors.txt create mode 100644 tests/baselines/reference/privateNamesUnique-3.js create mode 100644 tests/baselines/reference/privateNamesUnique-3.symbols create mode 100644 tests/baselines/reference/privateNamesUnique-3.types delete mode 100644 tests/baselines/reference/privateNamesUnique.errors.txt delete mode 100644 tests/baselines/reference/privateNamesUnique.js delete mode 100644 tests/baselines/reference/privateNamesUnique.symbols create mode 100644 tests/baselines/reference/privateNamesUseBeforeDef.errors.txt create mode 100644 tests/baselines/reference/privateNamesUseBeforeDef.js create mode 100644 tests/baselines/reference/privateNamesUseBeforeDef.symbols create mode 100644 tests/baselines/reference/privateNamesUseBeforeDef.types create mode 100644 tests/cases/compiler/privateNameJsx.tsx create mode 100644 tests/cases/compiler/privateNameWeakMapCollision.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameConstructorSignature.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameDeclaration.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldAccess.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldAssignment.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldCallExpression.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldClassExpression.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldInitializer.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldUnaryMutation.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameInLhsReceiverExpression.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameJsBadDeclaration.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameNestedClassNameConflict.ts delete mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts rename tests/cases/conformance/classes/members/privateNames/{privateNamesInNestedClasses.ts => privateNamesInNestedClasses-1.ts} (89%) create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts rename tests/cases/conformance/classes/members/privateNames/{privateNamesNoAccessibilityModifiers.ts => privateNamesIncompatibleModifiers.ts} (66%) create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts delete mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts rename tests/cases/conformance/classes/members/privateNames/{privateNamesUnique.ts => privateNamesUnique-1.ts} (83%) create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesUnique-2.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocPrivateName1.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocPrivateName2.ts create mode 100644 tests/cases/fourslash/codeFixMissingPrivateIdentifierMethodDeclaration.ts create mode 100644 tests/cases/fourslash/goToDefinitionPrivateName.ts create mode 100644 tests/cases/fourslash/navigationBarPrivateName.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index c315f6567160b..b87e1b4ffc0d1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -359,15 +359,15 @@ namespace ts { if (isWellKnownSymbolSyntactically(name)) { return getPropertyNameForKnownSymbolName(idText(name.name)); } - if (isPrivateName(name)) { + if (isPrivateIdentifier(name)) { // containingClass exists because private names only allowed inside classes - const containingClass = getContainingClass(name.parent); + const containingClass = getContainingClass(node); if (!containingClass) { - // we're in a case where there's a private name outside a class (invalid) + // we can get here in cases where there is already a parse error. return undefined; } const containingClassSymbol = containingClass.symbol; - return getPropertyNameForPrivateNameDescription(containingClassSymbol, name.escapedText); + return getSymbolNameForPrivateIdentifier(containingClassSymbol, name.escapedText); } return isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined; } @@ -425,10 +425,6 @@ namespace ts { const isDefaultExport = hasModifier(node, ModifierFlags.Default); - // need this before getDeclarationName - if (isNamedDeclaration(node)) { - node.name.parent = node; - } // The exported symbol for an export default function/class node is always named "default" const name = isDefaultExport && parent ? InternalSymbolName.Default : getDeclarationName(node); @@ -481,6 +477,10 @@ namespace ts { symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); } else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.Assignment)) { + // Assignment declarations are allowed to merge with variables, no matter what other flags they have. + if (isNamedDeclaration(node)) { + node.name.parent = node; + } // Report errors every position with duplicate declaration // Report errors on previous encountered declarations let message = symbol.flags & SymbolFlags.BlockScopedVariable @@ -2037,7 +2037,7 @@ namespace ts { // The binder visits every node, so this is a good place to check for // the reserved private name (there is only one) - function checkPrivateName(node: PrivateName) { + function checkPrivateIdentifier(node: PrivateIdentifier) { if (node.escapedText === "#constructor") { // Report error only if there are no parse errors in file if (!file.parseDiagnostics.length) { @@ -2319,8 +2319,8 @@ namespace ts { node.flowNode = currentFlow; } return checkStrictModeIdentifier(node); - case SyntaxKind.PrivateName: - return checkPrivateName(node as PrivateName); + case SyntaxKind.PrivateIdentifier: + return checkPrivateIdentifier(node as PrivateIdentifier); case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: const expr = node as PropertyAccessExpression | ElementAccessExpression; @@ -2680,6 +2680,12 @@ namespace ts { function bindThisPropertyAssignment(node: BindablePropertyAssignmentExpression | PropertyAccessExpression | LiteralLikeElementAccessExpression) { Debug.assert(isInJSFile(node)); + // private identifiers *must* be declared (even in JS files) + const hasPrivateIdentifier = (isBinaryExpression(node) && isPropertyAccessExpression(node.left) && isPrivateIdentifier(node.left.name)) + || (isPropertyAccessExpression(node) && isPrivateIdentifier(node.name)); + if (hasPrivateIdentifier) { + return; + } const thisContainer = getThisContainer(node, /*includeArrowFunctions*/ false); switch (thisContainer.kind) { case SyntaxKind.FunctionDeclaration: @@ -2982,7 +2988,12 @@ namespace ts { } else { const s = forEachIdentifierInEntityName(e.expression, parent, action); - return action(getNameOrArgument(e), s && s.exports && s.exports.get(getElementOrPropertyAccessName(e)), s); + const name = getNameOrArgument(e); + // unreachable + if (isPrivateIdentifier(name)) { + Debug.fail("unexpected PrivateIdentifier"); + } + return action(name, s && s.exports && s.exports.get(getElementOrPropertyAccessName(e)), s); } } @@ -4154,6 +4165,10 @@ namespace ts { case SyntaxKind.BreakStatement: transformFlags |= TransformFlags.ContainsHoistedDeclarationOrCompletion; break; + + case SyntaxKind.PrivateIdentifier: + transformFlags |= TransformFlags.ContainsClassFields; + break; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e5e17085a3f6e..d9a23cdc5a672 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,6 +1,7 @@ /* @internal */ namespace ts { const ambientModuleSymbolRegex = /^".+"$/; + const anon = "(anonymous)" as __String & string; let nextSymbolId = 1; let nextNodeId = 1; @@ -365,7 +366,15 @@ namespace ts { getDeclaredTypeOfSymbol, getPropertiesOfType, getPropertyOfType: (type, name) => getPropertyOfType(type, escapeLeadingUnderscores(name)), - getPropertyForPrivateName, + getPrivateIdentifierPropertyOfType: (leftType: Type, name: string, location: Node) => { + const node = getParseTreeNode(location); + if (!node) { + return undefined; + } + const propName = escapeLeadingUnderscores(name); + const lexicallyScopedIdentifier = lookupSymbolForPrivateIdentifierDeclaration(propName, node); + return lexicallyScopedIdentifier ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedIdentifier) : undefined; + }, getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, escapeLeadingUnderscores(name)), getIndexInfoOfType, getSignaturesOfType, @@ -853,6 +862,7 @@ namespace ts { const flowNodeReachable: (boolean | undefined)[] = []; const potentialThisCollisions: Node[] = []; const potentialNewTargetCollisions: Node[] = []; + const potentialWeakMapCollisions: Node[] = []; const awaitedTypeStack: number[] = []; const diagnostics = createDiagnosticCollection(); @@ -1881,8 +1891,8 @@ namespace ts { } } - function diagnosticName(nameArg: __String | Identifier | PrivateName) { - return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier | PrivateName); + function diagnosticName(nameArg: __String | Identifier | PrivateIdentifier) { + return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier); } function isTypeParameterSymbolDeclaredInContainer(symbol: Symbol, container: Node) { @@ -3186,9 +3196,9 @@ namespace ts { } // A reserved member name starts with two underscores, but the third character cannot be an underscore, - // @, or #. A third underscore indicates an escaped form of an identifer that started + // @, or #. A third underscore indicates an escaped form of an identifier that started // with at least two underscores. The @ character indicates that the name is denoted by a well known ES - // Symbol instance and the # indicates that the name is a PrivateName. + // Symbol instance and the # character indicates that the name is a PrivateIdentifier. function isReservedMemberName(name: __String) { return (name as string).charCodeAt(0) === CharacterCodes._ && (name as string).charCodeAt(1) === CharacterCodes._ && @@ -8382,12 +8392,16 @@ namespace ts { function addInheritedMembers(symbols: SymbolTable, baseSymbols: Symbol[]) { for (const s of baseSymbols) { - if (!symbols.has(s.escapedName)) { + if (!symbols.has(s.escapedName) && !isStaticPrivateIdentifierProperty(s)) { symbols.set(s.escapedName, s); } } } + function isStaticPrivateIdentifierProperty(s: Symbol): boolean { + return !!s.valueDeclaration && isPrivateIdentifierPropertyDeclaration(s.valueDeclaration) && hasModifier(s.valueDeclaration, ModifierFlags.Static); + } + function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers { if (!(type).declaredProperties) { const symbol = type.symbol; @@ -8462,7 +8476,7 @@ namespace ts { */ function getPropertyNameFromType(type: StringLiteralType | NumberLiteralType | UniqueESSymbolType): __String { if (type.flags & TypeFlags.UniqueESSymbol) { - return getPropertyNameForUniqueESSymbol(type.symbol); + return (type).escapedName; } if (type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { return escapeLeadingUnderscores("" + (type).value); @@ -10953,7 +10967,7 @@ namespace ts { function checkNoTypeArguments(node: NodeWithTypeArguments, symbol?: Symbol) { if (node.typeArguments) { - error(node, Diagnostics.Type_0_is_not_generic, symbol ? symbolToString(symbol) : (node).typeName ? declarationNameToString((node).typeName) : "(anonymous)"); + error(node, Diagnostics.Type_0_is_not_generic, symbol ? symbolToString(symbol) : (node).typeName ? declarationNameToString((node).typeName) : anon); return false; } return true; @@ -11845,7 +11859,7 @@ namespace ts { } function getLiteralTypeFromPropertyName(name: PropertyName) { - if (isPrivateName(name)) { + if (isPrivateIdentifier(name)) { return neverType; } return isIdentifier(name) ? getLiteralType(unescapeLeadingUnderscores(name.escapedText)) : @@ -11971,7 +11985,7 @@ namespace ts { return false; } - function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | PrivateName | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) { + function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | PrivateIdentifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; return isTypeUsableAsPropertyName(indexType) ? getPropertyNameFromType(indexType) : @@ -11985,7 +11999,7 @@ namespace ts { function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; - const propName = getPropertyNameFromIndex(indexType, accessNode); + const propName = accessNode && isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode); if (propName !== undefined) { const prop = getPropertyOfType(objectType, propName); if (prop) { @@ -15881,6 +15895,58 @@ namespace ts { return related; } + function reportUnmatchedProperty(source: Type, target: Type, unmatchedProperty: Symbol, requireOptionalProperties: boolean) { + let shouldSkipElaboration = false; + // give specific error in case where private names have the same description + if ( + unmatchedProperty.valueDeclaration + && isNamedDeclaration(unmatchedProperty.valueDeclaration) + && isPrivateIdentifier(unmatchedProperty.valueDeclaration.name) + && isClassDeclaration(source.symbol.valueDeclaration) + ) { + const privateIdentifierDescription = unmatchedProperty.valueDeclaration.name.escapedText; + const symbolTableKey = getSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription); + if (symbolTableKey && !!getPropertyOfType(source, symbolTableKey)) { + const sourceName = source.symbol.valueDeclaration.name; + const targetName = isClassDeclaration(target.symbol.valueDeclaration) ? target.symbol.valueDeclaration.name : undefined; + reportError( + Diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, + diagnosticName(privateIdentifierDescription), + diagnosticName(sourceName || anon), + diagnosticName(targetName || anon), + ); + return; + } + } + const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false)); + if (!headMessage || (headMessage.code !== Diagnostics.Class_0_incorrectly_implements_interface_1.code && + headMessage.code !== Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) { + shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it + } + if (props.length === 1) { + const propName = symbolToString(unmatchedProperty); + reportError(Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, ...getTypeNamesForErrorDisplay(source, target)); + if (length(unmatchedProperty.declarations)) { + associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName)); + } + if (shouldSkipElaboration && errorInfo) { + overrideNextErrorInfo++; + } + } + else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) { + if (props.length > 5) { // arbitrary cutoff for too-long list form + reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); + } + else { + reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); + } + if (shouldSkipElaboration && errorInfo) { + overrideNextErrorInfo++; + } + } + // No array like or unmatched property error - just issue top level error (errorInfo = undefined) + } + function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: UnderscoreEscapedMap | undefined, isIntersectionConstituent: boolean): Ternary { if (relation === identityRelation) { @@ -15890,58 +15956,7 @@ namespace ts { const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false); if (unmatchedProperty) { if (reportErrors) { - let shouldSkipElaboration = false; - let hasReported = false; - if ( - unmatchedProperty.valueDeclaration - && isNamedDeclaration(unmatchedProperty.valueDeclaration) - && isPrivateName(unmatchedProperty.valueDeclaration.name) - && isClassDeclaration(source.symbol.valueDeclaration) - ) { - const privateNameDescription = unmatchedProperty.valueDeclaration.name.escapedText; - const symbolTableKey = getPropertyNameForPrivateNameDescription(source.symbol, privateNameDescription); - if (symbolTableKey && !!getPropertyOfType(source, symbolTableKey)) { - reportError( - Diagnostics.Property_0_is_missing_in_type_1_While_type_1_has_a_private_member_with_the_same_spelling_its_declaration_and_accessibility_are_distinct, - diagnosticName(privateNameDescription), - diagnosticName(source.symbol.valueDeclaration.name || ("(anonymous)" as __String)) - ); - hasReported = true; - } - if (shouldSkipElaboration && errorInfo) { - overrideNextErrorInfo++; - } - } - if (!hasReported) { - const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false)); - let shouldSkipElaboration = false; - if (!headMessage || (headMessage.code !== Diagnostics.Class_0_incorrectly_implements_interface_1.code && - headMessage.code !== Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) { - shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it - } - if (props.length === 1) { - const propName = symbolToString(unmatchedProperty); - reportError(Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, ...getTypeNamesForErrorDisplay(source, target)); - if (length(unmatchedProperty.declarations)) { - associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName)); - } - if (shouldSkipElaboration && errorInfo) { - overrideNextErrorInfo++; - } - } - else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) { - if (props.length > 5) { // arbitrary cutoff for too-long list form - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); - } - else { - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); - } - if (shouldSkipElaboration && errorInfo) { - overrideNextErrorInfo++; - } - } - // ELSE: No array like or unmatched property error - just issue top level error (errorInfo = undefined) - } + reportUnmatchedProperty(source, target, unmatchedProperty, requireOptionalProperties); } return Ternary.False; } @@ -17500,6 +17515,10 @@ namespace ts { function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean): IterableIterator { const properties = getPropertiesOfType(target); for (const targetProp of properties) { + // TODO: remove this when we support static private identifier fields and find other solutions to get privateNamesAndStaticFields test to pass + if (isStaticPrivateIdentifierProperty(targetProp)) { + continue; + } if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional || getCheckFlags(targetProp) & CheckFlags.Partial)) { const sourceProp = getPropertyOfType(source, targetProp.escapedName); if (!sourceProp) { @@ -20426,18 +20445,20 @@ namespace ts { if (usedInFunction) { // mark iteration statement as containing block-scoped binding captured in some function let capturesBlockScopeBindingInLoopBody = true; - if (isForStatement(container) && - getAncestor(symbol.valueDeclaration, SyntaxKind.VariableDeclarationList)!.parent === container) { - const part = getPartOfForStatementContainingNode(node.parent, container); - if (part) { - const links = getNodeLinks(part); - links.flags |= NodeCheckFlags.ContainsCapturedBlockScopeBinding; - - const capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []); - pushIfUnique(capturedBindings, symbol); - - if (part === container.initializer) { - capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body + if (isForStatement(container)) { + const varDeclList = getAncestor(symbol.valueDeclaration, SyntaxKind.VariableDeclarationList); + if (varDeclList && varDeclList.parent === container) { + const part = getPartOfForStatementContainingNode(node.parent, container); + if (part) { + const links = getNodeLinks(part); + links.flags |= NodeCheckFlags.ContainsCapturedBlockScopeBinding; + + const capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []); + pushIfUnique(capturedBindings, symbol); + + if (part === container.initializer) { + capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body + } } } } @@ -20448,10 +20469,11 @@ namespace ts { // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement. // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back. - if (container.kind === SyntaxKind.ForStatement && - getAncestor(symbol.valueDeclaration, SyntaxKind.VariableDeclarationList)!.parent === container && - isAssignedInBodyOfForStatement(node, container)) { - getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.NeedsLoopOutParameter; + if (isForStatement(container)) { + const varDeclList = getAncestor(symbol.valueDeclaration, SyntaxKind.VariableDeclarationList); + if (varDeclList && varDeclList.parent === container && isAssignedInBodyOfForStatement(node, container)) { + getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.NeedsLoopOutParameter; + } } // set 'declared inside loop' bit on the block-scoped binding @@ -22911,6 +22933,14 @@ namespace ts { } } + if (isPropertyAccessExpression(node) && isPrivateIdentifier(node.name)) { + if (!getContainingClass(node)) { + error(errorNode, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + return false; + } + return true; + } + // Public properties are otherwise accessible. if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) { return true; @@ -23058,66 +23088,126 @@ namespace ts { return isCallOrNewExpression(node.parent) && node.parent.expression === node; } - function getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined { - let classWithShadowedPrivateName; - let container = getContainingClass(right); - while (container) { - const symbolTableKey = getPropertyNameForPrivateNameDescription(container.symbol, right.escapedText); - if (symbolTableKey) { - const prop = getPropertyOfType(apparentType, symbolTableKey); - if (prop) { - if (classWithShadowedPrivateName) { - if (errorNode) { - error( - errorNode, - Diagnostics.This_usage_of_0_refers_to_the_private_member_declared_in_its_enclosing_class_While_type_1_has_a_private_member_with_the_same_spelling_its_declaration_and_accessibility_are_distinct, - diagnosticName(right), - diagnosticName(classWithShadowedPrivateName.name || ("(anonymous)" as __String)) - ); - } - return undefined; - } - return prop; - } - else { - classWithShadowedPrivateName = container; - } + // Lookup the private identifier lexically. + function lookupSymbolForPrivateIdentifierDeclaration(propName: __String, location: Node): Symbol | undefined { + for (let containingClass = getContainingClass(location); !!containingClass; containingClass = getContainingClass(containingClass)) { + const { symbol } = containingClass; + const name = getSymbolNameForPrivateIdentifier(symbol, propName); + const prop = (symbol.members && symbol.members.get(name)) || (symbol.exports && symbol.exports.get(name)); + if (prop) { + return prop; } - container = getContainingClass(container); } - // If this isn't a case of shadowing, and the lhs has a property with the same - // private name description, then there is a privacy violation - if (leftType.symbol.members) { - const symbolTableKey = getPropertyNameForPrivateNameDescription(leftType.symbol, right.escapedText); - const prop = getPropertyOfType(apparentType, symbolTableKey); - if (prop) { - if (errorNode) { - error(right, Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_name, symbolToString(prop), typeToString(getDeclaringClass(prop)!)); + } + + function getPrivateIdentifierPropertyOfType(leftType: Type, lexicallyScopedIdentifier: Symbol): Symbol | undefined { + return getPropertyOfType(leftType, lexicallyScopedIdentifier.escapedName); + } + + function checkPrivateIdentifierPropertyAccess(leftType: Type, right: PrivateIdentifier, lexicallyScopedIdentifier: Symbol | undefined): boolean { + // Either the identifier could not be looked up in the lexical scope OR the lexically scoped identifier did not exist on the type. + // Find a private identifier with the same description on the type. + let propertyOnType: Symbol | undefined; + const properties = getPropertiesOfType(leftType); + if (properties) { + forEach(properties, (symbol: Symbol) => { + const decl = symbol.valueDeclaration; + if (decl && isNamedDeclaration(decl) && isPrivateIdentifier(decl.name) && decl.name.escapedText === right.escapedText) { + propertyOnType = symbol; + return true; + } + }); + } + const diagName = diagnosticName(right); + if (propertyOnType) { + const typeValueDecl = propertyOnType.valueDeclaration; + const typeClass = getContainingClass(typeValueDecl); + Debug.assert(!!typeClass); + // We found a private identifier property with the same description. + // Either: + // - There is a lexically scoped private identifier AND it shadows the one we found on the type. + // - It is an attempt to access the private identifier outside of the class. + if (lexicallyScopedIdentifier) { + const lexicalValueDecl = lexicallyScopedIdentifier.valueDeclaration; + const lexicalClass = getContainingClass(lexicalValueDecl); + Debug.assert(!!lexicalClass); + if (findAncestor(lexicalClass, n => typeClass === n)) { + const diagnostic = error( + right, + Diagnostics.The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling, + diagName, + typeToString(leftType) + ); + + addRelatedInfo( + diagnostic, + createDiagnosticForNode( + lexicalValueDecl, + Diagnostics.The_shadowing_declaration_of_0_is_defined_here, + diagName + ), + createDiagnosticForNode( + typeValueDecl, + Diagnostics.The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here, + diagName + ) + ); + return true; } } + error( + right, + Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, + diagName, + diagnosticName(typeClass!.name || anon) + ); + return true; } - // not found - return undefined; + return false; } - function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateName) { + function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateIdentifier) { const parentSymbol = getNodeLinks(left).resolvedSymbol; const assignmentKind = getAssignmentTargetKind(node); const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); - if (isTypeAny(apparentType) || apparentType === silentNeverType) { - if (isIdentifier(left) && parentSymbol) { - markAliasReferenced(parentSymbol, node); + if (isPrivateIdentifier(right)) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.ClassPrivateFieldGet); + } + const isAnyLike = isTypeAny(apparentType) || apparentType === silentNeverType; + let prop: Symbol | undefined; + if (isPrivateIdentifier(right)) { + const lexicallyScopedSymbol = lookupSymbolForPrivateIdentifierDeclaration(right.escapedText, right); + if (isAnyLike) { + if (lexicallyScopedSymbol) { + return apparentType; + } + if (!getContainingClass(right)) { + grammarErrorOnNode(right, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + return anyType; + } } - return apparentType; + prop = lexicallyScopedSymbol ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedSymbol) : undefined; + // Check for private-identifier-specific shadowing and lexical-scoping errors. + if (!prop && checkPrivateIdentifierPropertyAccess(leftType, right, lexicallyScopedSymbol)) { + return errorType; + } + } + else { + if (isAnyLike) { + if (isIdentifier(left) && parentSymbol) { + markAliasReferenced(parentSymbol, node); + } + return apparentType; + } + prop = getPropertyOfType(apparentType, right.escapedText); } - const prop = isPrivateName(right) ? getPropertyForPrivateName(apparentType, leftType, right, /* errorNode */ right) : getPropertyOfType(apparentType, right.escapedText); if (isIdentifier(left) && parentSymbol && !(prop && isConstEnumOrConstEnumOnlyModule(prop))) { markAliasReferenced(parentSymbol, node); } let propType: Type; if (!prop) { - const indexInfo = assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined; + const indexInfo = !isPrivateIdentifier(right) && (assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined; if (!(indexInfo && indexInfo.type)) { if (isJSLiteralType(leftType)) { return anyType; @@ -23194,7 +23284,7 @@ namespace ts { return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } - function checkPropertyNotUsedBeforeDeclaration(prop: Symbol, node: PropertyAccessExpression | QualifiedName, right: Identifier | PrivateName): void { + function checkPropertyNotUsedBeforeDeclaration(prop: Symbol, node: PropertyAccessExpression | QualifiedName, right: Identifier | PrivateIdentifier): void { const { valueDeclaration } = prop; if (!valueDeclaration || getSourceFileOfNode(node).isDeclarationFile) { return; @@ -23276,10 +23366,10 @@ namespace ts { return getIntersectionType(x); } - function reportNonexistentProperty(propNode: Identifier | PrivateName, containingType: Type) { + function reportNonexistentProperty(propNode: Identifier | PrivateIdentifier, containingType: Type) { let errorInfo: DiagnosticMessageChain | undefined; let relatedInfo: Diagnostic | undefined; - if (containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) { + if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) { for (const subtype of (containingType as UnionType).types) { if (!getPropertyOfType(subtype, propNode.escapedText) && !getIndexInfoOfType(subtype, IndexKind.String)) { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(subtype)); @@ -23320,11 +23410,11 @@ namespace ts { return prop !== undefined && prop.valueDeclaration && hasModifier(prop.valueDeclaration, ModifierFlags.Static); } - function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateName | string, containingType: Type): Symbol | undefined { + function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined { return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value); } - function getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined { + function getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined { const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType); return suggestion && symbolName(suggestion); } @@ -23407,7 +23497,14 @@ namespace ts { } function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined, isThisAccess: boolean) { - if (!prop || !(prop.flags & SymbolFlags.ClassMember) || !prop.valueDeclaration || !hasModifier(prop.valueDeclaration, ModifierFlags.Private)) { + + const valueDeclaration = prop && (prop.flags & SymbolFlags.ClassMember) && prop.valueDeclaration; + if (!valueDeclaration) { + return; + } + const hasPrivateModifier = hasModifier(valueDeclaration, ModifierFlags.Private); + const hasPrivateIdentifier = isNamedDeclaration(prop.valueDeclaration) && isPrivateIdentifier(prop.valueDeclaration.name); + if (!hasPrivateModifier && !hasPrivateIdentifier) { return; } if (nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor))) { @@ -26496,8 +26593,8 @@ namespace ts { error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference); return booleanType; } - if (expr.kind === SyntaxKind.PropertyAccessExpression && isPrivateName((expr as PropertyAccessExpression).name)) { - error(expr, Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_private_name); + if (expr.kind === SyntaxKind.PropertyAccessExpression && isPrivateIdentifier((expr as PropertyAccessExpression).name)) { + error(expr, Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_private_identifier); } const links = getNodeLinks(expr); const symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol); @@ -26897,6 +26994,9 @@ namespace ts { if (checkReferenceExpression(target, error, optionalError)) { checkTypeAssignableToAndOptionallyElaborate(sourceType, targetType, target, target); } + if (isPrivateIdentifierPropertyAccessExpression(target)) { + checkExternalEmitHelpers(target.parent, ExternalEmitHelpers.ClassPrivateFieldSet); + } return sourceType; } @@ -28215,6 +28315,8 @@ namespace ts { function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) { const instanceNames = createUnderscoreEscapedMap(); const staticNames = createUnderscoreEscapedMap(); + // instance and static private identifiers share the same scope + const privateIdentifiers = createUnderscoreEscapedMap(); for (const member of node.members) { if (member.kind === SyntaxKind.Constructor) { for (const param of (member as ConstructorDeclaration).parameters) { @@ -28225,11 +28327,16 @@ namespace ts { } else { const isStatic = hasModifier(member, ModifierFlags.Static); - const names = isStatic ? staticNames : instanceNames; - const name = member.name; + if (!name) { + return; + } + const names = + isPrivateIdentifier(name) ? privateIdentifiers : + isStatic ? staticNames : + instanceNames; const memberName = name && getPropertyNameForPropertyNameNode(name); - if (name && memberName) { + if (memberName) { switch (member.kind) { case SyntaxKind.GetAccessor: addName(names, name, memberName, DeclarationMeaning.GetAccessor); @@ -28380,12 +28487,30 @@ namespace ts { // Grammar checking if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node)) checkGrammarComputedPropertyName(node.name); checkVariableLikeDeclaration(node); + + // Private class fields transformation relies on WeakMaps. + if (isPrivateIdentifier(node.name) && languageVersion < ScriptTarget.ESNext) { + for (let lexicalScope = getEnclosingBlockScopeContainer(node); !!lexicalScope; lexicalScope = getEnclosingBlockScopeContainer(lexicalScope)) { + getNodeLinks(lexicalScope).flags |= NodeCheckFlags.ContainsClassWithPrivateIdentifiers; + } + } + } + + function checkPropertySignature(node: PropertySignature) { + if (isPrivateIdentifier(node.name)) { + error(node, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + } + return checkPropertyDeclaration(node); } function checkMethodDeclaration(node: MethodDeclaration | MethodSignature) { // Grammar checking if (!checkGrammarMethod(node)) checkGrammarComputedPropertyName(node.name); + if (isPrivateIdentifier(node.name)) { + error(node, Diagnostics.A_method_cannot_be_named_with_a_private_identifier); + } + // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration checkFunctionOrMethodDeclaration(node); @@ -28421,7 +28546,10 @@ namespace ts { return; } - function isInstancePropertyWithInitializer(n: Node): boolean { + function isInstancePropertyWithInitializerOrPrivateIdentifierProperty(n: Node): boolean { + if (isPrivateIdentifierPropertyDeclaration(n)) { + return true; + } return n.kind === SyntaxKind.PropertyDeclaration && !hasModifier(n, ModifierFlags.Static) && !!(n).initializer; @@ -28446,7 +28574,7 @@ namespace ts { // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. const superCallShouldBeFirst = - some((node.parent).members, isInstancePropertyWithInitializer) || + some((node.parent).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) || some(node.parameters, p => hasModifier(p, ModifierFlags.ParameterPropertyModifier)); // Skip past any prologue directives to find the first statement @@ -28465,7 +28593,7 @@ namespace ts { } } if (!superCallStatement) { - error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); + error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_parameter_properties_or_private_identifiers); } } } @@ -28495,6 +28623,9 @@ namespace ts { if (node.name.kind === SyntaxKind.ComputedPropertyName) { checkComputedPropertyName(node.name); } + if (isPrivateIdentifier(node.name)) { + error(node.name, Diagnostics.An_accessor_cannot_be_named_with_a_private_identifier); + } if (!hasNonBindableDynamicName(node)) { // TypeScript 1.0 spec (April 2014): 8.4.3 // Accessors for the same member name must specify the same accessibility. @@ -28835,11 +28966,17 @@ namespace ts { if (subsequentNode && subsequentNode.pos === node.end) { if (subsequentNode.kind === node.kind) { const errorNode: Node = (subsequentNode).name || subsequentNode; - // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!) const subsequentName = (subsequentNode).name; - if (node.name && subsequentName && - (isComputedPropertyName(node.name) && isComputedPropertyName(subsequentName) || - !isComputedPropertyName(node.name) && !isComputedPropertyName(subsequentName) && getEscapedTextOfIdentifierOrLiteral(node.name) === getEscapedTextOfIdentifierOrLiteral(subsequentName))) { + if (node.name && subsequentName && ( + // both are private identifiers + isPrivateIdentifier(node.name) && isPrivateIdentifier(subsequentName) && node.name.escapedText === subsequentName.escapedText || + // Both are computed property names + // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!) + isComputedPropertyName(node.name) && isComputedPropertyName(subsequentName) || + // Both are literal property names that are the same. + isPropertyNameLiteral(node.name) && isPropertyNameLiteral(subsequentName) && + getEscapedTextOfIdentifierOrLiteral(node.name) === getEscapedTextOfIdentifierOrLiteral(subsequentName) + )) { const reportError = (node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) && hasModifier(node, ModifierFlags.Static) !== hasModifier(subsequentNode, ModifierFlags.Static); @@ -28853,7 +28990,7 @@ namespace ts { } return; } - else if (nodeIsPresent((subsequentNode).body)) { + if (nodeIsPresent((subsequentNode).body)) { error(errorNode, Diagnostics.Function_implementation_name_must_be_0, declarationNameToString(node.name)); return; } @@ -29691,9 +29828,9 @@ namespace ts { } } - function getIdentifierFromEntityNameExpression(node: Identifier | PropertyAccessExpression): Identifier | PrivateName; - function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateName | undefined; - function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateName | undefined { + function getIdentifierFromEntityNameExpression(node: Identifier | PropertyAccessExpression): Identifier | PrivateIdentifier; + function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateIdentifier | undefined; + function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateIdentifier | undefined { switch (node.kind) { case SyntaxKind.Identifier: return node as Identifier; @@ -29864,7 +30001,7 @@ namespace ts { break; } const symbol = getSymbolOfNode(member); - if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { + if (!symbol.isReferenced && (hasModifier(member, ModifierFlags.Private) || isNamedDeclaration(member) && isPrivateIdentifier(member.name))) { addDiagnostic(member, UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol))); } break; @@ -30147,6 +30284,13 @@ namespace ts { }); } + function checkWeakMapCollision(node: Node) { + const enclosingBlockScope = getEnclosingBlockScopeContainer(node); + if (getNodeCheckFlags(enclosingBlockScope) & NodeCheckFlags.ContainsClassWithPrivateIdentifiers) { + error(node, Diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, "WeakMap"); + } + } + function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) { // No need to check for require or exports for ES6 modules and later if (moduleKind >= ModuleKind.ES2015 || compilerOptions.noEmit) { @@ -30403,6 +30547,9 @@ namespace ts { } checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); + if (!compilerOptions.noEmit && languageVersion < ScriptTarget.ESNext && needCollisionCheckForIdentifier(node, node.name as Identifier, "WeakMap")) { + potentialWeakMapCollisions.push(node); + } } } @@ -32030,8 +32177,11 @@ namespace ts { if (base.flags & SymbolFlags.Prototype) { continue; } - - const derived = getTargetSymbol(getPropertyOfObjectType(type, base.escapedName)!); // TODO: GH#18217 + const baseSymbol = getPropertyOfObjectType(type, base.escapedName); + if (!baseSymbol) { + continue; + } + const derived = getTargetSymbol(baseSymbol); const baseDeclarationFlags = getDeclarationModifierFlagsFromSymbol(base); Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration."); @@ -32105,7 +32255,7 @@ namespace ts { && !(derived.flags & SymbolFlags.Transient) && !(baseDeclarationFlags & ModifierFlags.Abstract) && !(derivedDeclarationFlags & ModifierFlags.Abstract) - && !derived.declarations.some(d => d.flags & NodeFlags.Ambient)) { + && !derived.declarations.some(d => !!(d.flags & NodeFlags.Ambient))) { const constructor = findConstructorDeclaration(getClassLikeDeclarationOfSymbol(type.symbol)!); const propName = (uninitialized as PropertyDeclaration).name; if ((uninitialized as PropertyDeclaration).exclamationToken @@ -32447,6 +32597,7 @@ namespace ts { checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); checkExportsOnMergedDeclarations(node); + node.members.forEach(checkEnumMember); computeEnumMemberValues(node); @@ -32494,6 +32645,12 @@ namespace ts { } } + function checkEnumMember(node: EnumMember) { + if (isPrivateIdentifier(node.name)) { + error(node, Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); + } + } + function getFirstNonAmbientClassOrFunctionDeclaration(symbol: Symbol): Declaration | undefined { const declarations = symbol.declarations; for (const declaration of declarations) { @@ -32682,7 +32839,7 @@ namespace ts { return node; case SyntaxKind.PropertyAccessExpression: do { - if (isModuleExportsAccessExpression(node.expression)) { + if (isModuleExportsAccessExpression(node.expression) && !isPrivateIdentifier(node.name)) { return node.name; } node = node.expression; @@ -33044,8 +33201,9 @@ namespace ts { case SyntaxKind.Parameter: return checkParameter(node); case SyntaxKind.PropertyDeclaration: + return checkPropertyDeclaration(node); case SyntaxKind.PropertySignature: - return checkPropertyDeclaration(node); + return checkPropertySignature(node); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: @@ -33350,6 +33508,7 @@ namespace ts { clear(potentialThisCollisions); clear(potentialNewTargetCollisions); + clear(potentialWeakMapCollisions); forEach(node.statements, checkSourceElement); checkSourceElement(node.endOfFileToken); @@ -33382,6 +33541,11 @@ namespace ts { clear(potentialNewTargetCollisions); } + if (potentialWeakMapCollisions.length) { + forEach(potentialWeakMapCollisions, checkWeakMapCollision); + clear(potentialWeakMapCollisions); + } + links.flags |= NodeCheckFlags.TypeChecked; } } @@ -33652,57 +33816,59 @@ namespace ts { return undefined; } - function getSymbolOfEntityNameOrPropertyAccessExpression(entityName: EntityName | PropertyAccessExpression): Symbol | undefined { - if (isDeclarationName(entityName)) { - return getSymbolOfNode(entityName.parent); + function getSymbolOfNameOrPropertyAccessExpression(name: EntityName | PrivateIdentifier | PropertyAccessExpression): Symbol | undefined { + if (isDeclarationName(name)) { + return getSymbolOfNode(name.parent); } - if (isInJSFile(entityName) && - entityName.parent.kind === SyntaxKind.PropertyAccessExpression && - entityName.parent === (entityName.parent.parent as BinaryExpression).left) { + if (isInJSFile(name) && + name.parent.kind === SyntaxKind.PropertyAccessExpression && + name.parent === (name.parent.parent as BinaryExpression).left) { // Check if this is a special property assignment - const specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(entityName); - if (specialPropertyAssignmentSymbol) { - return specialPropertyAssignmentSymbol; + if (!isPrivateIdentifier(name)) { + const specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(name); + if (specialPropertyAssignmentSymbol) { + return specialPropertyAssignmentSymbol; + } } } - if (entityName.parent.kind === SyntaxKind.ExportAssignment && isEntityNameExpression(entityName)) { + if (name.parent.kind === SyntaxKind.ExportAssignment && isEntityNameExpression(name)) { // Even an entity name expression that doesn't resolve as an entityname may still typecheck as a property access expression - const success = resolveEntityName(entityName, + const success = resolveEntityName(name, /*all meanings*/ SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*ignoreErrors*/ true); if (success && success !== unknownSymbol) { return success; } } - else if (!isPropertyAccessExpression(entityName) && isInRightSideOfImportOrExportAssignment(entityName)) { + else if (!isPropertyAccessExpression(name) && !isPrivateIdentifier(name) && isInRightSideOfImportOrExportAssignment(name)) { // Since we already checked for ExportAssignment, this really could only be an Import - const importEqualsDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); + const importEqualsDeclaration = getAncestor(name, SyntaxKind.ImportEqualsDeclaration); Debug.assert(importEqualsDeclaration !== undefined); - return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true); + return getSymbolOfPartOfRightHandSideOfImportEquals(name, /*dontResolveAlias*/ true); } - if (!isPropertyAccessExpression(entityName)) { - const possibleImportNode = isImportTypeQualifierPart(entityName); + if (!isPropertyAccessExpression(name) && !isPrivateIdentifier(name)) { + const possibleImportNode = isImportTypeQualifierPart(name); if (possibleImportNode) { getTypeFromTypeNode(possibleImportNode); - const sym = getNodeLinks(entityName).resolvedSymbol; + const sym = getNodeLinks(name).resolvedSymbol; return sym === unknownSymbol ? undefined : sym; } } - while (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { - entityName = entityName.parent; + while (isRightSideOfQualifiedNameOrPropertyAccess(name)) { + name = name.parent; } - if (isHeritageClauseElementIdentifier(entityName)) { + if (isHeritageClauseElementIdentifier(name)) { let meaning = SymbolFlags.None; // In an interface or class, we're definitely interested in a type. - if (entityName.parent.kind === SyntaxKind.ExpressionWithTypeArguments) { + if (name.parent.kind === SyntaxKind.ExpressionWithTypeArguments) { meaning = SymbolFlags.Type; // In a class 'extends' clause we are also looking for a value. - if (isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) { + if (isExpressionWithTypeArgumentsInClassExtendsClause(name.parent)) { meaning |= SymbolFlags.Value; } } @@ -33711,58 +33877,58 @@ namespace ts { } meaning |= SymbolFlags.Alias; - const entityNameSymbol = isEntityNameExpression(entityName) ? resolveEntityName(entityName, meaning) : undefined; + const entityNameSymbol = isEntityNameExpression(name) ? resolveEntityName(name, meaning) : undefined; if (entityNameSymbol) { return entityNameSymbol; } } - if (entityName.parent.kind === SyntaxKind.JSDocParameterTag) { - return getParameterSymbolFromJSDoc(entityName.parent as JSDocParameterTag); + if (name.parent.kind === SyntaxKind.JSDocParameterTag) { + return getParameterSymbolFromJSDoc(name.parent as JSDocParameterTag); } - if (entityName.parent.kind === SyntaxKind.TypeParameter && entityName.parent.parent.kind === SyntaxKind.JSDocTemplateTag) { - Debug.assert(!isInJSFile(entityName)); // Otherwise `isDeclarationName` would have been true. - const typeParameter = getTypeParameterFromJsDoc(entityName.parent as TypeParameterDeclaration & { parent: JSDocTemplateTag }); + if (name.parent.kind === SyntaxKind.TypeParameter && name.parent.parent.kind === SyntaxKind.JSDocTemplateTag) { + Debug.assert(!isInJSFile(name)); // Otherwise `isDeclarationName` would have been true. + const typeParameter = getTypeParameterFromJsDoc(name.parent as TypeParameterDeclaration & { parent: JSDocTemplateTag }); return typeParameter && typeParameter.symbol; } - if (isExpressionNode(entityName)) { - if (nodeIsMissing(entityName)) { + if (isExpressionNode(name)) { + if (nodeIsMissing(name)) { // Missing entity name. return undefined; } - if (entityName.kind === SyntaxKind.Identifier) { - if (isJSXTagName(entityName) && isJsxIntrinsicIdentifier(entityName)) { - const symbol = getIntrinsicTagSymbol(entityName.parent); + if (name.kind === SyntaxKind.Identifier) { + if (isJSXTagName(name) && isJsxIntrinsicIdentifier(name)) { + const symbol = getIntrinsicTagSymbol(name.parent); return symbol === unknownSymbol ? undefined : symbol; } - return resolveEntityName(entityName, SymbolFlags.Value, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); + return resolveEntityName(name, SymbolFlags.Value, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); } - else if (entityName.kind === SyntaxKind.PropertyAccessExpression || entityName.kind === SyntaxKind.QualifiedName) { - const links = getNodeLinks(entityName); + else if (name.kind === SyntaxKind.PropertyAccessExpression || name.kind === SyntaxKind.QualifiedName) { + const links = getNodeLinks(name); if (links.resolvedSymbol) { return links.resolvedSymbol; } - if (entityName.kind === SyntaxKind.PropertyAccessExpression) { - checkPropertyAccessExpression(entityName); + if (name.kind === SyntaxKind.PropertyAccessExpression) { + checkPropertyAccessExpression(name); } else { - checkQualifiedName(entityName); + checkQualifiedName(name); } return links.resolvedSymbol; } } - else if (isTypeReferenceIdentifier(entityName)) { - const meaning = entityName.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; - return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); + else if (isTypeReferenceIdentifier(name)) { + const meaning = name.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; + return resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); } - if (entityName.parent.kind === SyntaxKind.TypePredicate) { - return resolveEntityName(entityName, /*meaning*/ SymbolFlags.FunctionScopedVariable); + if (name.parent.kind === SyntaxKind.TypePredicate) { + return resolveEntityName(name, /*meaning*/ SymbolFlags.FunctionScopedVariable); } // Do we want to return undefined here? @@ -33794,7 +33960,7 @@ namespace ts { if (node.kind === SyntaxKind.Identifier) { if (isInRightSideOfImportOrExportAssignment(node)) { - return getSymbolOfEntityNameOrPropertyAccessExpression(node); + return getSymbolOfNameOrPropertyAccessExpression(node); } else if (parent.kind === SyntaxKind.BindingElement && grandParent.kind === SyntaxKind.ObjectBindingPattern && @@ -33810,9 +33976,10 @@ namespace ts { switch (node.kind) { case SyntaxKind.Identifier: + case SyntaxKind.PrivateIdentifier: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.QualifiedName: - return getSymbolOfEntityNameOrPropertyAccessExpression(node); + return getSymbolOfNameOrPropertyAccessExpression(node); case SyntaxKind.ThisKeyword: const container = getThisContainer(node, /*includeArrowFunctions*/ false); @@ -34979,6 +35146,8 @@ namespace ts { case ExternalEmitHelpers.AsyncValues: return "__asyncValues"; case ExternalEmitHelpers.ExportStar: return "__exportStar"; case ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject"; + case ExternalEmitHelpers.ClassPrivateFieldGet: return "__classPrivateFieldGet"; + case ExternalEmitHelpers.ClassPrivateFieldSet: return "__classPrivateFieldSet"; default: return Debug.fail("Unrecognized helper"); } } @@ -35089,6 +35258,9 @@ namespace ts { else if (flags & ModifierFlags.Abstract) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); } + else if (isPrivateIdentifierPropertyDeclaration(node)) { + return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "static"); + } flags |= ModifierFlags.Static; lastStatic = modifier; break; @@ -35175,6 +35347,9 @@ namespace ts { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract"); } } + if (isNamedDeclaration(node) && node.name.kind === SyntaxKind.PrivateIdentifier) { + return grammarErrorOnNode(node, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract"); + } flags |= ModifierFlags.Abstract; break; @@ -35219,8 +35394,8 @@ namespace ts { else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.ParameterPropertyModifier) && (node).dotDotDotToken) { return grammarErrorOnNode(node, Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter); } - else if (isNamedDeclaration(node) && (flags & ModifierFlags.AccessibilityModifier) && node.name.kind === SyntaxKind.PrivateName) { - return grammarErrorOnNode(node, Diagnostics.Accessibility_modifiers_cannot_be_used_with_private_names); + else if (isNamedDeclaration(node) && (flags & ModifierFlags.AccessibilityModifier) && node.name.kind === SyntaxKind.PrivateIdentifier) { + return grammarErrorOnNode(node, Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); } if (flags & ModifierFlags.Async) { return checkGrammarAsyncModifier(node, lastAsync!); @@ -35627,8 +35802,8 @@ namespace ts { return grammarErrorOnNode(prop.equalsToken!, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment); } - if (name.kind === SyntaxKind.PrivateName) { - return grammarErrorOnNode(name, Diagnostics.Private_names_are_not_allowed_outside_class_bodies); + if (name.kind === SyntaxKind.PrivateIdentifier) { + return grammarErrorOnNode(name, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); } // Modifiers are never allowed on properties except for 'async' on a method declaration @@ -36249,6 +36424,9 @@ namespace ts { if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.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)) { return true; } + if (languageVersion < ScriptTarget.ES2015 && isPrivateIdentifier(node.name)) { + return grammarErrorOnNode(node.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher); + } } else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) { if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 53eed06c725cc..c9627076641d6 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1397,7 +1397,7 @@ "category": "Error", "code": 2375 }, - "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.": { + "A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.": { "category": "Error", "code": 2376 }, @@ -2479,11 +2479,11 @@ "category": "Error", "code": 2702 }, - "The operand of a delete operator must be a property reference.": { + "The operand of a 'delete' operator must be a property reference.": { "category": "Error", "code": 2703 }, - "The operand of a delete operator cannot be a read-only property.": { + "The operand of a 'delete' operator cannot be a read-only property.": { "category": "Error", "code": 2704 }, @@ -5362,15 +5362,15 @@ "category": "Error", "code": 18008 }, - "Private names cannot be used as parameters": { + "Private identifiers cannot be used as parameters": { "category": "Error", "code": 18009 }, - "Accessibility modifiers cannot be used with private names.": { + "An accessibility modifier cannot be used with a private identifier.": { "category": "Error", "code": 18010 }, - "The operand of a delete operator cannot be a private name.": { + "The operand of a 'delete' operator cannot be a private identifier.": { "category": "Error", "code": 18011 }, @@ -5378,20 +5378,60 @@ "category": "Error", "code": 18012 }, - "Property '{0}' is not accessible outside class '{1}' because it has a private name.": { + "Property '{0}' is not accessible outside class '{1}' because it has a private identifier.": { "category": "Error", "code": 18013 }, - "This usage of '{0}' refers to the private member declared in its enclosing class. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct.": { + "The property '{0}' cannot be accessed on type '{1}' within this class because it is shadowed by another private identifier with the same spelling.": { "category": "Error", "code": 18014 }, - "Property '{0}' is missing in type '{1}'. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct.": { + "Property '{0}' in type '{1}' refers to a different member that cannot be accessed from within type '{2}'.": { "category": "Error", "code": 18015 }, - "Private names are not allowed outside class bodies.": { + "Private identifiers are not allowed outside class bodies.": { "category": "Error", "code": 18016 + }, + "The shadowing declaration of '{0}' is defined here": { + "category": "Error", + "code": 18017 + }, + "The declaration of '{0}' that you probably intended to use is defined here": { + "category": "Error", + "code": 18018 + }, + "'{0}' modifier cannot be used with a private identifier": { + "category": "Error", + "code": 18019 + }, + "A method cannot be named with a private identifier.": { + "category": "Error", + "code": 18022 + }, + "An accessor cannot be named with a private identifier.": { + "category": "Error", + "code": 18023 + }, + "An enum member cannot be named with a private identifier.": { + "category": "Error", + "code": 18024 + }, + "'#!' can only be used at the start of a file.": { + "category": "Error", + "code": 18026 + }, + "Compiler reserves name '{0}' when emitting private identifier downlevel.": { + "category": "Error", + "code": 18027 + }, + "Private identifiers are only available when targeting ECMAScript 2015 and higher.": { + "category": "Error", + "code": 18028 + }, + "Private identifiers are not allowed in variable declarations.": { + "category": "Error", + "code": 18029 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 84b0a801f5f7d..48e35cb1e2550 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1253,6 +1253,10 @@ namespace ts { case SyntaxKind.Identifier: return emitIdentifier(node); + // PrivateIdentifiers + case SyntaxKind.PrivateIdentifier: + return emitPrivateIdentifier(node as PrivateIdentifier); + // Parse tree nodes // Names case SyntaxKind.QualifiedName: @@ -1818,6 +1822,12 @@ namespace ts { // Names // + function emitPrivateIdentifier(node: PrivateIdentifier) { + const writeText = node.symbol ? writeSymbol : write; + writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol); + } + + function emitQualifiedName(node: QualifiedName) { emitEntityName(node.left); writePunctuation("."); @@ -4285,7 +4295,7 @@ namespace ts { if (isGeneratedIdentifier(node)) { return generateName(node); } - else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent || !currentSourceFile || (node.parent && currentSourceFile && getSourceFileOfNode(node) !== getOriginalNode(currentSourceFile)))) { + else if ((isIdentifier(node) || isPrivateIdentifier(node)) && (nodeIsSynthesized(node) || !node.parent || !currentSourceFile || (node.parent && currentSourceFile && getSourceFileOfNode(node) !== getOriginalNode(currentSourceFile)))) { return idText(node); } else if (node.kind === SyntaxKind.StringLiteral && (node).textSourceNode) { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 88c53d492296e..64613525939cd 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -37,7 +37,7 @@ namespace ts { } else { const expression = setTextRange( - isIdentifier(memberName) + (isIdentifier(memberName) || isPrivateIdentifier(memberName)) ? createPropertyAccess(target, memberName) : createElementAccess(target, memberName), memberName @@ -501,7 +501,7 @@ namespace ts { } } - export function createExpressionForPropertyName(memberName: PropertyName): Expression { + export function createExpressionForPropertyName(memberName: Exclude): Expression { if (isIdentifier(memberName)) { return createLiteral(memberName); } @@ -514,10 +514,13 @@ namespace ts { } export function createExpressionForObjectLiteralElementLike(node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression | undefined { + if (property.name && isPrivateIdentifier(property.name)) { + Debug.failBadSyntaxKind(property.name, "Private identifiers are not allowed in object literals."); + } switch (property.kind) { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return createExpressionForAccessorDeclaration(node.properties, property, receiver, !!node.multiLine); + return createExpressionForAccessorDeclaration(node.properties, property as typeof property & { name: Exclude; }, receiver, !!node.multiLine); case SyntaxKind.PropertyAssignment: return createExpressionForPropertyAssignment(property, receiver); case SyntaxKind.ShorthandPropertyAssignment: @@ -527,7 +530,7 @@ namespace ts { } } - function createExpressionForAccessorDeclaration(properties: NodeArray, property: AccessorDeclaration, receiver: Expression, multiLine: boolean) { + function createExpressionForAccessorDeclaration(properties: NodeArray, property: AccessorDeclaration & { name: Exclude; }, receiver: Expression, multiLine: boolean) { const { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(properties, property); if (property === firstAccessor) { const properties: ObjectLiteralElementLike[] = []; @@ -1740,13 +1743,13 @@ namespace ts { /** * Gets the property name of a BindingOrAssignmentElement */ - export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { + export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement); Debug.assert(!!propertyName || isSpreadAssignment(bindingElement), "Invalid property name for binding element."); return propertyName; } - export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { + export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { switch (bindingElement.kind) { case SyntaxKind.BindingElement: // `a` in `let { a: b } = ...` @@ -1755,7 +1758,7 @@ namespace ts { // `1` in `let { 1: b } = ...` if (bindingElement.propertyName) { const propertyName = bindingElement.propertyName; - if (isPrivateName(propertyName)) { + if (isPrivateIdentifier(propertyName)) { return Debug.failBadSyntaxKind(propertyName); } return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) @@ -1772,7 +1775,7 @@ namespace ts { // `1` in `({ 1: b } = ...)` if (bindingElement.name) { const propertyName = bindingElement.name; - if (isPrivateName(propertyName)) { + if (isPrivateIdentifier(propertyName)) { return Debug.failBadSyntaxKind(propertyName); } return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) @@ -1784,7 +1787,7 @@ namespace ts { case SyntaxKind.SpreadAssignment: // `a` in `({ ...a } = ...)` - if (bindingElement.name && isPrivateName(bindingElement.name)) { + if (bindingElement.name && isPrivateIdentifier(bindingElement.name)) { return Debug.failBadSyntaxKind(bindingElement.name); } return bindingElement.name; diff --git a/src/compiler/factoryPublic.ts b/src/compiler/factoryPublic.ts index 5512118d73318..0d9adc26d9cbf 100644 --- a/src/compiler/factoryPublic.ts +++ b/src/compiler/factoryPublic.ts @@ -116,7 +116,7 @@ namespace ts { return node; } - function createLiteralFromNode(sourceNode: Exclude): StringLiteral { + function createLiteralFromNode(sourceNode: Exclude): StringLiteral { const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode)); node.textSourceNode = sourceNode; return node; @@ -216,6 +216,13 @@ namespace ts { return name; } + // Private Identifiers + export function createPrivateIdentifier(text: string): PrivateIdentifier { + const node = createSynthesizedNode(SyntaxKind.PrivateIdentifier) as PrivateIdentifier; + node.escapedText = escapeLeadingUnderscores(text); + return node; + } + // Punctuation export function createToken(token: TKind) { @@ -1057,7 +1064,7 @@ namespace ts { : node; } - export function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateName) { + export function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateIdentifier) { const node = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); node.expression = parenthesizeForAccess(expression); node.name = asName(name); @@ -1065,7 +1072,7 @@ namespace ts { return node; } - export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateName) { + export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) { if (isOptionalChain(node) && isIdentifier(node.name) && isIdentifier(name)) { // Not sure why this cast was necessary: the previous line should already establish that node.name is an identifier const theNode = node as (typeof node & { name: Identifier }); @@ -2925,7 +2932,9 @@ namespace ts { templateObjectHelper, generatorHelper, importStarHelper, - importDefaultHelper + importDefaultHelper, + classPrivateFieldGetHelper, + classPrivateFieldSetHelper, ], helper => helper.name)); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9261b97def4f1..d130118534e49 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -11,6 +11,7 @@ namespace ts { let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node { @@ -20,6 +21,9 @@ namespace ts { else if (kind === SyntaxKind.Identifier) { return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end); } + else if (kind === SyntaxKind.PrivateIdentifier) { + return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, pos, end); + } else if (!isNodeKind(kind)) { return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end); } @@ -602,6 +606,7 @@ namespace ts { let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let sourceFile: SourceFile; @@ -612,6 +617,7 @@ namespace ts { let sourceText: string; let nodeCount: number; let identifiers: Map; + let privateIdentifiers: Map; let identifierCount: number; let parsingContext: ParsingContext; @@ -800,6 +806,7 @@ namespace ts { NodeConstructor = objectAllocator.getNodeConstructor(); TokenConstructor = objectAllocator.getTokenConstructor(); IdentifierConstructor = objectAllocator.getIdentifierConstructor(); + PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor(); SourceFileConstructor = objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; @@ -808,6 +815,7 @@ namespace ts { parseDiagnostics = []; parsingContext = 0; identifiers = createMap(); + privateIdentifiers = createMap(); identifierCount = 0; nodeCount = 0; @@ -1321,6 +1329,7 @@ namespace ts { const p = pos! >= 0 ? pos! : scanner.getStartPos(); return isNodeKind(kind) || kind === SyntaxKind.Unknown ? new NodeConstructor(kind, p, p) : kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, p, p) : + kind === SyntaxKind.PrivateIdentifier ? new PrivateIdentifierConstructor(kind, p, p) : new TokenConstructor(kind, p, p); } @@ -1429,17 +1438,6 @@ namespace ts { return createIdentifier(tokenIsIdentifierOrKeyword(token()), diagnosticMessage); } - function createPrivateName(): PrivateName { - const node = createNode(SyntaxKind.PrivateName) as PrivateName; - node.escapedText = escapeLeadingUnderscores(scanner.getTokenText()); - nextToken(); - return finishNode(node); - } - - function parsePrivateName(): PrivateName { - return createPrivateName(); - } - function isLiteralPropertyName(): boolean { return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.StringLiteral || @@ -1455,8 +1453,8 @@ namespace ts { if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) { return parseComputedPropertyName(); } - if (token() === SyntaxKind.PrivateName) { - return parsePrivateName(); + if (token() === SyntaxKind.PrivateIdentifier) { + return parsePrivateIdentifier(); } return parseIdentifierName(); } @@ -1481,6 +1479,21 @@ namespace ts { return finishNode(node); } + function internPrivateIdentifier(text: string): string { + let privateIdentifier = privateIdentifiers.get(text); + if (privateIdentifier === undefined) { + privateIdentifiers.set(text, privateIdentifier = text); + } + return privateIdentifier; + } + + function parsePrivateIdentifier(): PrivateIdentifier { + const node = createNode(SyntaxKind.PrivateIdentifier) as PrivateIdentifier; + node.escapedText = escapeLeadingUnderscores(internPrivateIdentifier(scanner.getTokenText())); + nextToken(); + return finishNode(node); + } + function parseContextualModifier(t: SyntaxKind): boolean { return token() === t && tryParse(nextTokenCanFollowModifier); } @@ -2242,7 +2255,7 @@ namespace ts { break; } dotPos = scanner.getStartPos(); - entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords, /* allowPrivateNames */ false) as Identifier); + entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as Identifier); } return entity; } @@ -2254,7 +2267,7 @@ namespace ts { return finishNode(node); } - function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateNames: boolean): Identifier | PrivateName { + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean): Identifier | PrivateIdentifier { // Technically a keyword is valid here as all identifiers and keywords are identifier names. // However, often we'll encounter this in error situations when the identifier or keyword // is actually starting another valid construct. @@ -2285,8 +2298,9 @@ namespace ts { } } - if (allowPrivateNames && token() === SyntaxKind.PrivateName) { - return parsePrivateName(); + if (token() === SyntaxKind.PrivateIdentifier) { + const node = parsePrivateIdentifier(); + return allowPrivateIdentifiers ? node : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); } return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); @@ -4363,7 +4377,7 @@ namespace ts { node.expression = expression; parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic - node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateNames*/ true); + node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true); return finishNode(node); } @@ -4534,7 +4548,7 @@ namespace ts { while (parseOptional(SyntaxKind.DotToken)) { const propertyAccess: JsxTagNamePropertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); propertyAccess.expression = expression; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateNames*/ true); + propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false); expression = finishNode(propertyAccess); } return expression; @@ -4651,8 +4665,7 @@ namespace ts { const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); propertyAccess.expression = expression; propertyAccess.questionDotToken = questionDotToken; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateNames*/ true); - + propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ !questionDotToken); if (questionDotToken || expression.flags & NodeFlags.OptionalChain) { propertyAccess.flags |= NodeFlags.OptionalChain; } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index fe7df55c916e3..2ccc8ef270d0f 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1907,7 +1907,7 @@ namespace ts { if (ch === CharacterCodes.backslash) { tokenValue += scanIdentifierParts(); } - return token = SyntaxKind.PrivateName; + return token = SyntaxKind.PrivateIdentifier; } error(Diagnostics.Invalid_character); // no `pos++` because already advanced past the '#' diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index da4a5b08a0a4b..c5b64a6fa7c70 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -7,6 +7,23 @@ namespace ts { */ ClassAliases = 1 << 0, } + + const enum PrivateIdentifierPlacement { + InstanceField + } + + type PrivateIdentifierInfo = PrivateIdentifierInstanceField; + + interface PrivateIdentifierInstanceField { + placement: PrivateIdentifierPlacement.InstanceField; + weakMapName: Identifier; + } + + /** + * A mapping of private names to information needed for transformation. + */ + type PrivateIdentifierEnvironment = UnderscoreEscapedMap; + /** * Transforms ECMAScript Class Syntax. * TypeScript parameter property syntax is transformed in the TypeScript transformer. @@ -21,6 +38,10 @@ namespace ts { resumeLexicalEnvironment } = context; const resolver = context.getEmitResolver(); + const compilerOptions = context.getCompilerOptions(); + const languageVersion = getEmitScriptTarget(compilerOptions); + + const shouldTransformPrivateFields = languageVersion < ScriptTarget.ESNext; const previousOnSubstituteNode = context.onSubstituteNode; context.onSubstituteNode = onSubstituteNode; @@ -41,6 +62,9 @@ namespace ts { */ let pendingStatements: Statement[] | undefined; + const privateIdentifierEnvironmentStack: (PrivateIdentifierEnvironment | undefined)[] = []; + let currentPrivateIdentifierEnvironment: PrivateIdentifierEnvironment | undefined; + return chainBundle(transformSourceFile); function transformSourceFile(node: SourceFile) { @@ -59,15 +83,57 @@ namespace ts { switch (node.kind) { case SyntaxKind.ClassExpression: - return visitClassExpression(node as ClassExpression); case SyntaxKind.ClassDeclaration: - return visitClassDeclaration(node as ClassDeclaration); + return visitClassLike(node as ClassLikeDeclaration); + case SyntaxKind.PropertyDeclaration: + return visitPropertyDeclaration(node as PropertyDeclaration); case SyntaxKind.VariableStatement: return visitVariableStatement(node as VariableStatement); + case SyntaxKind.ComputedPropertyName: + return visitComputedPropertyName(node as ComputedPropertyName); + case SyntaxKind.PropertyAccessExpression: + return visitPropertyAccessExpression(node as PropertyAccessExpression); + case SyntaxKind.PrefixUnaryExpression: + return visitPrefixUnaryExpression(node as PrefixUnaryExpression); + case SyntaxKind.PostfixUnaryExpression: + return visitPostfixUnaryExpression(node as PostfixUnaryExpression, /*valueIsDiscarded*/ false); + case SyntaxKind.CallExpression: + return visitCallExpression(node as CallExpression); + case SyntaxKind.BinaryExpression: + return visitBinaryExpression(node as BinaryExpression); + case SyntaxKind.PrivateIdentifier: + return visitPrivateIdentifier(node as PrivateIdentifier); + case SyntaxKind.ExpressionStatement: + return visitExpressionStatement(node as ExpressionStatement); + case SyntaxKind.ForStatement: + return visitForStatement(node as ForStatement); + case SyntaxKind.TaggedTemplateExpression: + return visitTaggedTemplateExpression(node as TaggedTemplateExpression); } return visitEachChild(node, visitor, context); } + function visitorDestructuringTarget(node: Node): VisitResult { + switch (node.kind) { + case SyntaxKind.ObjectLiteralExpression: + case SyntaxKind.ArrayLiteralExpression: + return visitAssignmentPattern(node as AssignmentPattern); + default: + return visitor(node); + } + } + + /** + * If we visit a private name, this means it is an undeclared private name. + * Replace it with an empty identifier to indicate a problem with the code. + */ + function visitPrivateIdentifier(node: PrivateIdentifier) { + if (!shouldTransformPrivateFields) { + return node; + } + return setOriginalNode(createIdentifier(""), node); + } + /** * Visits the members of a class that has fields. * @@ -129,6 +195,18 @@ namespace ts { function visitPropertyDeclaration(node: PropertyDeclaration) { Debug.assert(!some(node.decorators)); + if (!shouldTransformPrivateFields && isPrivateIdentifier(node.name)) { + // Initializer is elided as the field is initialized in transformConstructor. + return updateProperty( + node, + /*decorators*/ undefined, + visitNodes(node.modifiers, visitor, isModifier), + node.name, + /*questionOrExclamationToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ); + } // Create a temporary variable to store a computed property name (if necessary). // If it's not inlineable, then we emit an expression after the class which assigns // the property name to the temporary variable. @@ -139,13 +217,244 @@ namespace ts { return undefined; } - function visitClassDeclaration(node: ClassDeclaration) { - if (!forEach(node.members, isPropertyDeclaration)) { - return visitEachChild(node, visitor, context); + function createPrivateIdentifierAccess(info: PrivateIdentifierInfo, receiver: Expression): Expression { + receiver = visitNode(receiver, visitor, isExpression); + switch (info.placement) { + case PrivateIdentifierPlacement.InstanceField: + return createClassPrivateFieldGetHelper( + context, + nodeIsSynthesized(receiver) ? receiver : getSynthesizedClone(receiver), + info.weakMapName + ); + default: return Debug.fail("Unexpected private identifier placement"); } + } + function visitPropertyAccessExpression(node: PropertyAccessExpression) { + if (shouldTransformPrivateFields && isPrivateIdentifier(node.name)) { + const privateIdentifierInfo = accessPrivateIdentifier(node.name); + if (privateIdentifierInfo) { + return setOriginalNode( + createPrivateIdentifierAccess(privateIdentifierInfo, node.expression), + node + ); + } + } + return visitEachChild(node, visitor, context); + } + + function visitPrefixUnaryExpression(node: PrefixUnaryExpression) { + if (shouldTransformPrivateFields && isPrivateIdentifierPropertyAccessExpression(node.operand)) { + const operator = node.operator === SyntaxKind.PlusPlusToken ? + SyntaxKind.PlusToken : node.operator === SyntaxKind.MinusMinusToken ? + SyntaxKind.MinusToken : undefined; + let info: PrivateIdentifierInfo | undefined; + if (operator && (info = accessPrivateIdentifier(node.operand.name))) { + const receiver = visitNode(node.operand.expression, visitor, isExpression); + const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); + + const existingValue = createPrefix(SyntaxKind.PlusToken, createPrivateIdentifierAccess(info, readExpression)); + + return setOriginalNode( + createPrivateIdentifierAssignment( + info, + initializeExpression || readExpression, + createBinary(existingValue, operator, createLiteral(1)), + SyntaxKind.EqualsToken + ), + node + ); + } + } + return visitEachChild(node, visitor, context); + } + + function visitPostfixUnaryExpression(node: PostfixUnaryExpression, valueIsDiscarded: boolean) { + if (shouldTransformPrivateFields && isPrivateIdentifierPropertyAccessExpression(node.operand)) { + const operator = node.operator === SyntaxKind.PlusPlusToken ? + SyntaxKind.PlusToken : node.operator === SyntaxKind.MinusMinusToken ? + SyntaxKind.MinusToken : undefined; + let info: PrivateIdentifierInfo | undefined; + if (operator && (info = accessPrivateIdentifier(node.operand.name))) { + const receiver = visitNode(node.operand.expression, visitor, isExpression); + const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); + + const existingValue = createPrefix(SyntaxKind.PlusToken, createPrivateIdentifierAccess(info, readExpression)); + + // Create a temporary variable to store the value returned by the expression. + const returnValue = valueIsDiscarded ? undefined : createTempVariable(hoistVariableDeclaration); + + return setOriginalNode( + inlineExpressions(compact([ + createPrivateIdentifierAssignment( + info, + initializeExpression || readExpression, + createBinary( + returnValue ? createAssignment(returnValue, existingValue) : existingValue, + operator, + createLiteral(1) + ), + SyntaxKind.EqualsToken + ), + returnValue + ])), + node + ); + } + } + return visitEachChild(node, visitor, context); + } + + function visitForStatement(node: ForStatement) { + if (node.incrementor && isPostfixUnaryExpression(node.incrementor)) { + return updateFor( + node, + visitNode(node.initializer, visitor, isForInitializer), + visitNode(node.condition, visitor, isExpression), + visitPostfixUnaryExpression(node.incrementor, /*valueIsDiscarded*/ true), + visitNode(node.statement, visitor, isStatement) + ); + } + return visitEachChild(node, visitor, context); + } + + function visitExpressionStatement(node: ExpressionStatement) { + if (isPostfixUnaryExpression(node.expression)) { + return updateExpressionStatement(node, visitPostfixUnaryExpression(node.expression, /*valueIsDiscarded*/ true)); + } + return visitEachChild(node, visitor, context); + } + + function createCopiableReceiverExpr(receiver: Expression): { readExpression: Expression; initializeExpression: Expression | undefined } { + const clone = nodeIsSynthesized(receiver) ? receiver : getSynthesizedClone(receiver); + if (isSimpleInlineableExpression(receiver)) { + return { readExpression: clone, initializeExpression: undefined }; + } + const readExpression = createTempVariable(hoistVariableDeclaration); + const initializeExpression = createAssignment(readExpression, clone); + return { readExpression, initializeExpression }; + } + + function visitCallExpression(node: CallExpression) { + if (shouldTransformPrivateFields && isPrivateIdentifierPropertyAccessExpression(node.expression)) { + // Transform call expressions of private names to properly bind the `this` parameter. + const { thisArg, target } = createCallBinding(node.expression, hoistVariableDeclaration, languageVersion); + return updateCall( + node, + createPropertyAccess(visitNode(target, visitor), "call"), + /*typeArguments*/ undefined, + [visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)] + ); + } + return visitEachChild(node, visitor, context); + } + + function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { + if (shouldTransformPrivateFields && isPrivateIdentifierPropertyAccessExpression(node.tag)) { + // Bind the `this` correctly for tagged template literals when the tag is a private identifier property access. + const { thisArg, target } = createCallBinding(node.tag, hoistVariableDeclaration, languageVersion); + return updateTaggedTemplate( + node, + createCall( + createPropertyAccess(visitNode(target, visitor), "bind"), + /*typeArguments*/ undefined, + [visitNode(thisArg, visitor, isExpression)] + ), + visitNode(node.template, visitor, isTemplateLiteral) + ); + } + return visitEachChild(node, visitor, context); + } + + function visitBinaryExpression(node: BinaryExpression) { + if (shouldTransformPrivateFields) { + if (isDestructuringAssignment(node)) { + const savedPendingExpressions = pendingExpressions; + pendingExpressions = undefined!; + node = updateBinary( + node, + visitNode(node.left, visitorDestructuringTarget), + visitNode(node.right, visitor), + node.operatorToken + ); + const expr = some(pendingExpressions) ? + inlineExpressions(compact([...pendingExpressions!, node])) : + node; + pendingExpressions = savedPendingExpressions; + return expr; + } + if (isAssignmentExpression(node) && isPrivateIdentifierPropertyAccessExpression(node.left)) { + const info = accessPrivateIdentifier(node.left.name); + if (info) { + return setOriginalNode( + createPrivateIdentifierAssignment(info, node.left.expression, node.right, node.operatorToken.kind), + node + ); + } + } + } + return visitEachChild(node, visitor, context); + } + + function createPrivateIdentifierAssignment(info: PrivateIdentifierInfo, receiver: Expression, right: Expression, operator: AssignmentOperator) { + switch (info.placement) { + case PrivateIdentifierPlacement.InstanceField: { + return createPrivateIdentifierInstanceFieldAssignment(info, receiver, right, operator); + } + default: return Debug.fail("Unexpected private identifier placement"); + } + } + + function createPrivateIdentifierInstanceFieldAssignment(info: PrivateIdentifierInstanceField, receiver: Expression, right: Expression, operator: AssignmentOperator) { + receiver = visitNode(receiver, visitor, isExpression); + right = visitNode(right, visitor, isExpression); + if (isCompoundAssignment(operator)) { + const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); + return createClassPrivateFieldSetHelper( + context, + initializeExpression || readExpression, + info.weakMapName, + createBinary( + createClassPrivateFieldGetHelper(context, readExpression, info.weakMapName), + getNonAssignmentOperatorForCompoundAssignment(operator), + right + ) + ); + } + else { + return createClassPrivateFieldSetHelper(context, receiver, info.weakMapName, right); + } + } + + /** + * Set up the environment for a class. + */ + function visitClassLike(node: ClassLikeDeclaration) { const savedPendingExpressions = pendingExpressions; pendingExpressions = undefined; + if (shouldTransformPrivateFields) { + startPrivateIdentifierEnvironment(); + } + + const result = isClassDeclaration(node) ? + visitClassDeclaration(node) : + visitClassExpression(node); + + if (shouldTransformPrivateFields) { + endPrivateIdentifierEnvironment(); + } + pendingExpressions = savedPendingExpressions; + return result; + } + + function doesClassElementNeedTransform(node: ClassElement) { + return isPropertyDeclaration(node) || (shouldTransformPrivateFields && node.name && isPrivateIdentifier(node.name)); + } + + function visitClassDeclaration(node: ClassDeclaration) { + if (!forEach(node.members, doesClassElementNeedTransform)) { + return visitEachChild(node, visitor, context); + } const extendsClauseElement = getEffectiveBaseTypeNode(node); const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword); @@ -167,8 +476,6 @@ namespace ts { statements.push(createExpressionStatement(inlineExpressions(pendingExpressions))); } - pendingExpressions = savedPendingExpressions; - // Emit static property assignment. Because classDeclaration is lexically evaluated, // it is safe to emit static property assignment after classDeclaration // From ES6 specification: @@ -183,11 +490,9 @@ namespace ts { } function visitClassExpression(node: ClassExpression): Expression { - if (!forEach(node.members, isPropertyDeclaration)) { + if (!forEach(node.members, doesClassElementNeedTransform)) { return visitEachChild(node, visitor, context); } - const savedPendingExpressions = pendingExpressions; - pendingExpressions = undefined; // If this class expression is a transformation of a decorated class declaration, // then we want to output the pendingExpressions as statements, not as inlined @@ -219,7 +524,6 @@ namespace ts { if (pendingStatements && pendingExpressions && some(pendingExpressions)) { pendingStatements.push(createExpressionStatement(inlineExpressions(pendingExpressions))); } - pendingExpressions = savedPendingExpressions; if (pendingStatements && some(staticProperties)) { addPropertyStatements(pendingStatements, staticProperties, getInternalName(node)); @@ -247,16 +551,23 @@ namespace ts { addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp)); expressions.push(startOnNewLine(temp)); - pendingExpressions = savedPendingExpressions; return inlineExpressions(expressions); } } - pendingExpressions = savedPendingExpressions; return classExpression; } function transformClassMembers(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) { + if (shouldTransformPrivateFields) { + // Declare private names. + for (const member of node.members) { + if (isPrivateIdentifierPropertyDeclaration(member)) { + addPrivateIdentifierToEnvironment(member.name); + } + } + } + const members: ClassElement[] = []; const constructor = transformConstructor(node, isDerivedClass); if (constructor) { @@ -266,10 +577,22 @@ namespace ts { return setTextRange(createNodeArray(members), /*location*/ node.members); } + function isPropertyDeclarationThatRequiresConstructorStatement(member: ClassElement): member is PropertyDeclaration { + if (!isPropertyDeclaration(member) || hasStaticModifier(member)) { + return false; + } + if (context.getCompilerOptions().useDefineForClassFields) { + // If we are using define semantics and targeting ESNext or higher, + // then we don't need to transform any class properties. + return languageVersion < ScriptTarget.ESNext; + } + return isInitializedProperty(member) || shouldTransformPrivateFields && isPrivateIdentifierPropertyDeclaration(member); + } + function transformConstructor(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) { const constructor = visitNode(getFirstConstructorWithBody(node), visitor, isConstructorDeclaration); - const containsProperty = forEach(node.members, m => isInitializedProperty(m, /*requireInitializer*/ !context.getCompilerOptions().useDefineForClassFields)); - if (!containsProperty) { + const properties = node.members.filter(isPropertyDeclarationThatRequiresConstructorStatement); + if (!some(properties)) { return constructor; } const parameters = visitParameterList(constructor ? constructor.parameters : undefined, visitor, context); @@ -295,7 +618,7 @@ namespace ts { function transformConstructorBody(node: ClassDeclaration | ClassExpression, constructor: ConstructorDeclaration | undefined, isDerivedClass: boolean) { const useDefineForClassFields = context.getCompilerOptions().useDefineForClassFields; - const properties = getProperties(node, /*requireInitializer*/ !useDefineForClassFields, /*isStatic*/ false); + const properties = getProperties(node, /*requireInitializer*/ !useDefineForClassFields, /*isStatic*/ false) // Only generate synthetic constructor when there are property initializers to move. if (!constructor && !some(properties)) { @@ -377,7 +700,11 @@ namespace ts { */ function addPropertyStatements(statements: Statement[], properties: readonly PropertyDeclaration[], receiver: LeftHandSideExpression) { for (const property of properties) { - const statement = createExpressionStatement(transformInitializedProperty(property, receiver)); + const expression = transformProperty(property, receiver); + if (!expression) { + continue; + } + const statement = createExpressionStatement(expression); setSourceMapRange(statement, moveRangePastModifiers(property)); setCommentRange(statement, property); setOriginalNode(statement, property); @@ -394,7 +721,10 @@ namespace ts { function generateInitializedPropertyExpressions(properties: readonly PropertyDeclaration[], receiver: LeftHandSideExpression) { const expressions: Expression[] = []; for (const property of properties) { - const expression = transformInitializedProperty(property, receiver); + const expression = transformProperty(property, receiver); + if (!expression) { + continue; + } startOnNewLine(expression); setSourceMapRange(expression, moveRangePastModifiers(property)); setCommentRange(expression, property); @@ -411,17 +741,36 @@ namespace ts { * @param property The property declaration. * @param receiver The object receiving the property assignment. */ - function transformInitializedProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) { + function transformProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) { // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name) const emitAssignment = !context.getCompilerOptions().useDefineForClassFields; const propertyName = isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression) ? updateComputedPropertyName(property.name, getGeneratedNameForNode(property.name)) : property.name; + if (shouldTransformPrivateFields && isPrivateIdentifier(propertyName)) { + const privateIdentifierInfo = accessPrivateIdentifier(propertyName); + if (privateIdentifierInfo) { + switch (privateIdentifierInfo.placement) { + case PrivateIdentifierPlacement.InstanceField: { + return createPrivateInstanceFieldInitializer( + receiver, + visitNode(property.initializer, visitor, isExpression), + privateIdentifierInfo.weakMapName + ); + } + } + } + else { + Debug.fail("Undeclared private name for property declaration."); + } + } + const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) : hasModifier(getOriginalNode(property), ModifierFlags.ParameterPropertyModifier) && isIdentifier(propertyName) ? propertyName : createVoidZero(); - if (emitAssignment) { + + if (emitAssignment || isPrivateIdentifier(propertyName)) { const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); return createAssignment(memberAccess, initializer); } @@ -517,6 +866,218 @@ namespace ts { return (inlinable || isIdentifier(innerExpression)) ? undefined : expression; } } + + function startPrivateIdentifierEnvironment() { + privateIdentifierEnvironmentStack.push(currentPrivateIdentifierEnvironment); + currentPrivateIdentifierEnvironment = undefined; + } + + function endPrivateIdentifierEnvironment() { + currentPrivateIdentifierEnvironment = privateIdentifierEnvironmentStack.pop(); + } + + function addPrivateIdentifierToEnvironment(name: PrivateIdentifier) { + const text = getTextOfPropertyName(name) as string; + const weakMapName = createOptimisticUniqueName("_" + text.substring(1)); + weakMapName.autoGenerateFlags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + hoistVariableDeclaration(weakMapName); + (currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = createUnderscoreEscapedMap())) + .set(name.escapedText, { placement: PrivateIdentifierPlacement.InstanceField, weakMapName }); + (pendingExpressions || (pendingExpressions = [])).push( + createAssignment( + weakMapName, + createNew( + createIdentifier("WeakMap"), + /*typeArguments*/ undefined, + [] + ) + ) + ); + } + + function accessPrivateIdentifier(name: PrivateIdentifier) { + if (currentPrivateIdentifierEnvironment) { + const info = currentPrivateIdentifierEnvironment.get(name.escapedText); + if (info) { + return info; + } + } + for (let i = privateIdentifierEnvironmentStack.length - 1; i >= 0; --i) { + const env = privateIdentifierEnvironmentStack[i]; + if (!env) { + continue; + } + const info = env.get(name.escapedText); + if (info) { + return info; + } + } + return undefined; + } + + + function wrapPrivateIdentifierForDestructuringTarget(node: PrivateIdentifierPropertyAccessExpression) { + const parameter = getGeneratedNameForNode(node); + const info = accessPrivateIdentifier(node.name); + if (!info) { + return visitEachChild(node, visitor, context); + } + let receiver = node.expression; + // We cannot copy `this` or `super` into the function because they will be bound + // differently inside the function. + if (isThisProperty(node) || isSuperProperty(node) || !isSimpleCopiableExpression(node.expression)) { + receiver = createTempVariable(hoistVariableDeclaration); + (receiver as Identifier).autoGenerateFlags! |= GeneratedIdentifierFlags.ReservedInNestedScopes; + (pendingExpressions || (pendingExpressions = [])).push(createBinary(receiver, SyntaxKind.EqualsToken, node.expression)); + } + return createPropertyAccess( + // Explicit parens required because of v8 regression (https://bugs.chromium.org/p/v8/issues/detail?id=9560) + createParen( + createObjectLiteral([ + createSetAccessor( + /*decorators*/ undefined, + /*modifiers*/ undefined, + "value", + [createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + parameter, + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + )], + createBlock( + [createExpressionStatement( + createPrivateIdentifierAssignment( + info, + receiver, + parameter, + SyntaxKind.EqualsToken + ) + )] + ) + ) + ]) + ), + "value" + ); + } + + function visitArrayAssignmentTarget(node: AssignmentPattern) { + const target = getTargetOfBindingOrAssignmentElement(node); + if (target && isPrivateIdentifierPropertyAccessExpression(target)) { + const wrapped = wrapPrivateIdentifierForDestructuringTarget(target); + if (isAssignmentExpression(node)) { + return updateBinary( + node, + wrapped, + visitNode(node.right, visitor, isExpression), + node.operatorToken + ); + } + else if (isSpreadElement(node)) { + return updateSpread(node, wrapped); + } + else { + return wrapped; + } + } + return visitNode(node, visitorDestructuringTarget); + } + + function visitObjectAssignmentTarget(node: ObjectLiteralElementLike) { + if (isPropertyAssignment(node)) { + const target = getTargetOfBindingOrAssignmentElement(node); + if (target && isPrivateIdentifierPropertyAccessExpression(target)) { + const initializer = getInitializerOfBindingOrAssignmentElement(node); + const wrapped = wrapPrivateIdentifierForDestructuringTarget(target); + return updatePropertyAssignment( + node, + visitNode(node.name, visitor), + initializer ? createAssignment(wrapped, visitNode(initializer, visitor)) : wrapped, + ); + } + return updatePropertyAssignment( + node, + visitNode(node.name, visitor), + visitNode(node.initializer, visitorDestructuringTarget) + ); + } + return visitNode(node, visitor); + } + + + function visitAssignmentPattern(node: AssignmentPattern) { + if (isArrayLiteralExpression(node)) { + // Transforms private names in destructuring assignment array bindings. + // + // Source: + // ([ this.#myProp ] = [ "hello" ]); + // + // Transformation: + // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ]; + return updateArrayLiteral( + node, + visitNodes(node.elements, visitArrayAssignmentTarget, isExpression) + ); + } + else { + // Transforms private names in destructuring assignment object bindings. + // + // Source: + // ({ stringProperty: this.#myProp } = { stringProperty: "hello" }); + // + // Transformation: + // ({ stringProperty: { set value(x) { this.#myProp = x; } }.value }) = { stringProperty: "hello" }; + return updateObjectLiteral( + node, + visitNodes(node.properties, visitObjectAssignmentTarget, isObjectLiteralElementLike) + ); + } + } + } + + function createPrivateInstanceFieldInitializer(receiver: LeftHandSideExpression, initializer: Expression | undefined, weakMapName: Identifier) { + return createCall( + createPropertyAccess(weakMapName, "set"), + /*typeArguments*/ undefined, + [receiver, initializer || createVoidZero()] + ); } + export const classPrivateFieldGetHelper: UnscopedEmitHelper = { + name: "typescript:classPrivateFieldGet", + scoped: false, + text: ` + var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); + };` + }; + + function createClassPrivateFieldGetHelper(context: TransformationContext, receiver: Expression, privateField: Identifier) { + context.requestEmitHelper(classPrivateFieldGetHelper); + return createCall(getUnscopedHelperName("__classPrivateFieldGet"), /* typeArguments */ undefined, [receiver, privateField]); + } + + export const classPrivateFieldSetHelper: UnscopedEmitHelper = { + name: "typescript:classPrivateFieldSet", + scoped: false, + text: ` + var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; + };` + }; + + function createClassPrivateFieldSetHelper(context: TransformationContext, receiver: Expression, privateField: Identifier, value: Expression) { + context.requestEmitHelper(classPrivateFieldSetHelper); + return createCall(getUnscopedHelperName("__classPrivateFieldSet"), /* typeArguments */ undefined, [receiver, privateField, value]); + } } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 460eb64563898..0b81d2bb32043 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -851,6 +851,9 @@ namespace ts { return cleanup(ctor); } case SyntaxKind.MethodDeclaration: { + if (isPrivateIdentifier(input.name)) { + return cleanup(/*returnValue*/ undefined); + } const sig = createSignatureDeclaration( SyntaxKind.MethodSignature, ensureTypeParams(input, input.typeParameters), @@ -863,6 +866,9 @@ namespace ts { return cleanup(sig); } case SyntaxKind.GetAccessor: { + if (isPrivateIdentifier(input.name)) { + return cleanup(/*returnValue*/ undefined); + } const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input)); return cleanup(updateGetAccessor( input, @@ -874,6 +880,9 @@ namespace ts { /*body*/ undefined)); } case SyntaxKind.SetAccessor: { + if (isPrivateIdentifier(input.name)) { + return cleanup(/*returnValue*/ undefined); + } return cleanup(updateSetAccessor( input, /*decorators*/ undefined, @@ -883,6 +892,9 @@ namespace ts { /*body*/ undefined)); } case SyntaxKind.PropertyDeclaration: + if (isPrivateIdentifier(input.name)) { + return cleanup(/*returnValue*/ undefined); + } return cleanup(updateProperty( input, /*decorators*/ undefined, @@ -893,6 +905,9 @@ namespace ts { ensureNoInitializer(input) )); case SyntaxKind.PropertySignature: + if (isPrivateIdentifier(input.name)) { + return cleanup(/*returnValue*/ undefined); + } return cleanup(updatePropertySignature( input, ensureModifiers(input), @@ -902,6 +917,9 @@ namespace ts { ensureNoInitializer(input) )); case SyntaxKind.MethodSignature: { + if (isPrivateIdentifier(input.name)) { + return cleanup(/*returnValue*/ undefined); + } return cleanup(updateMethodSignature( input, ensureTypeParams(input, input.typeParameters), @@ -1283,7 +1301,20 @@ namespace ts { })); getSymbolAccessibilityDiagnostic = oldDiag; } - const members = createNodeArray(concatenate(parameterProperties, visitNodes(input.members, visitDeclarationSubtree))); + + const hasPrivateIdentifier = some(input.members, member => !!member.name && isPrivateIdentifier(member.name)); + const privateIdentifier = hasPrivateIdentifier ? [ + createProperty( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createPrivateIdentifier("#private"), + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ) + ] : undefined; + const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree)); + const members = createNodeArray(memberNodes); const extendsClause = getEffectiveBaseTypeNode(input); if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 2684b1acdd554..28722351b8d50 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1592,16 +1592,16 @@ namespace ts { const commentRange = getCommentRange(member); const sourceMapRange = getSourceMapRange(member); const memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container); + const propertyName = visitNode(member.name, visitor, isPropertyName); let e: Expression; - if (context.getCompilerOptions().useDefineForClassFields) { - const propertyName = visitNode(member.name, visitor, isPropertyName); + if (!isPrivateIdentifier(propertyName) && context.getCompilerOptions().useDefineForClassFields) { const name = isComputedPropertyName(propertyName) ? propertyName.expression : isIdentifier(propertyName) ? createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) : propertyName; e = createObjectDefinePropertyCall(receiver, name, createPropertyDescriptor({ value: memberFunction, enumerable: false, writable: true, configurable: true })); } else { - const memberName = createMemberAccessForPropertyName(receiver, visitNode(member.name, visitor, isPropertyName), /*location*/ member.name); + const memberName = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ member.name); e = createAssignment(memberName, memberFunction); } setEmitFlags(memberFunction, EmitFlags.NoComments); @@ -1647,7 +1647,11 @@ namespace ts { setEmitFlags(target, EmitFlags.NoComments | EmitFlags.NoTrailingSourceMap); setSourceMapRange(target, firstAccessor.name); - const propertyName = createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName)); + const visitedAccessorName = visitNode(firstAccessor.name, visitor, isPropertyName); + if (isPrivateIdentifier(visitedAccessorName)) { + return Debug.failBadSyntaxKind(visitedAccessorName, "Encountered unhandled private identifier while transforming ES2015."); + } + const propertyName = createExpressionForPropertyName(visitedAccessorName); setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoLeadingSourceMap); setSourceMapRange(propertyName, firstAccessor.name); diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index a695f22e7d308..a0a171cc86399 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -82,7 +82,7 @@ namespace ts { * @param node A PropertyAccessExpression */ function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression { - if (isPrivateName(node.name)) { + if (isPrivateIdentifier(node.name)) { return node; } const literalName = trySubstituteReservedName(node.name); diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index cc16aef60093f..b6f40f4adc773 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -667,28 +667,6 @@ namespace ts { } } - function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator { - return kind >= SyntaxKind.FirstCompoundAssignment - && kind <= SyntaxKind.LastCompoundAssignment; - } - - function getOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher { - switch (kind) { - case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken; - case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken; - case SyntaxKind.AsteriskEqualsToken: return SyntaxKind.AsteriskToken; - case SyntaxKind.AsteriskAsteriskEqualsToken: return SyntaxKind.AsteriskAsteriskToken; - case SyntaxKind.SlashEqualsToken: return SyntaxKind.SlashToken; - case SyntaxKind.PercentEqualsToken: return SyntaxKind.PercentToken; - case SyntaxKind.LessThanLessThanEqualsToken: return SyntaxKind.LessThanLessThanToken; - case SyntaxKind.GreaterThanGreaterThanEqualsToken: return SyntaxKind.GreaterThanGreaterThanToken; - case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: return SyntaxKind.GreaterThanGreaterThanGreaterThanToken; - case SyntaxKind.AmpersandEqualsToken: return SyntaxKind.AmpersandToken; - case SyntaxKind.BarEqualsToken: return SyntaxKind.BarToken; - case SyntaxKind.CaretEqualsToken: return SyntaxKind.CaretToken; - } - } - /** * Visits a right-associative binary expression containing `yield`. * @@ -748,7 +726,7 @@ namespace ts { setTextRange( createBinary( cacheExpression(target), - getOperatorForCompoundAssignment(operator), + getNonAssignmentOperatorForCompoundAssignment(operator), visitNode(right, visitor, isExpression) ), node diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index d67e414357aac..3b83356acbfb7 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1784,14 +1784,17 @@ namespace ts { } /** - * Gets an expression that represents a property name. For a computed property, a - * name is generated for the node. + * Gets an expression that represents a property name (for decorated properties or enums). + * For a computed property, a name is generated for the node. * * @param member The member whose name should be converted into an expression. */ function getExpressionForPropertyName(member: ClassElement | EnumMember, generateNameForComputedPropertyName: boolean): Expression { const name = member.name!; - if (isComputedPropertyName(name)) { + if (isPrivateIdentifier(name)) { + return createIdentifier(""); + } + else if (isComputedPropertyName(name)) { return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression) ? getGeneratedNameForNode(name) : name.expression; diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index c47b033014b0b..3cf912dfb4742 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -254,6 +254,28 @@ namespace ts { isWellKnownSymbolSyntactically(expression); } + export function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator { + return kind >= SyntaxKind.FirstCompoundAssignment + && kind <= SyntaxKind.LastCompoundAssignment; + } + + export function getNonAssignmentOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher { + switch (kind) { + case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken; + case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken; + case SyntaxKind.AsteriskEqualsToken: return SyntaxKind.AsteriskToken; + case SyntaxKind.AsteriskAsteriskEqualsToken: return SyntaxKind.AsteriskAsteriskToken; + case SyntaxKind.SlashEqualsToken: return SyntaxKind.SlashToken; + case SyntaxKind.PercentEqualsToken: return SyntaxKind.PercentToken; + case SyntaxKind.LessThanLessThanEqualsToken: return SyntaxKind.LessThanLessThanToken; + case SyntaxKind.GreaterThanGreaterThanEqualsToken: return SyntaxKind.GreaterThanGreaterThanToken; + case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: return SyntaxKind.GreaterThanGreaterThanGreaterThanToken; + case SyntaxKind.AmpersandEqualsToken: return SyntaxKind.AmpersandToken; + case SyntaxKind.BarEqualsToken: return SyntaxKind.BarToken; + case SyntaxKind.CaretEqualsToken: return SyntaxKind.CaretToken; + } + } + /** * Adds super call and preceding prologue directives into the list of statements. * @@ -323,8 +345,14 @@ namespace ts { && hasStaticModifier(member) === isStatic; } - export function isInitializedProperty(member: ClassElement, requireInitializer: boolean): member is PropertyDeclaration { - return isPropertyDeclaration(member) && (!!member.initializer || !requireInitializer); + /** + * Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer. + * + * @param member The class element node. + * @param isStatic A value indicating whether the member should be a static or instance member. + */ + export function isInitializedProperty(member: ClassElement): member is PropertyDeclaration & { initializer: Expression; } { + return member.kind === SyntaxKind.PropertyDeclaration + && (member).initializer !== undefined; } - } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 87339929b1bc0..0550361562a6d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -201,9 +201,9 @@ namespace ts { AmpersandEqualsToken, BarEqualsToken, CaretEqualsToken, - // Identifiers and Private Names + // Identifiers and PrivateIdentifiers Identifier, - PrivateName, + PrivateIdentifier, // Reserved words BreakKeyword, CaseKeyword, @@ -832,11 +832,11 @@ namespace ts { export type EntityName = Identifier | QualifiedName; - export type PropertyName = Identifier | PrivateName | StringLiteral | NumericLiteral | ComputedPropertyName; + export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; export type DeclarationName = | Identifier - | PrivateName + | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName @@ -888,8 +888,8 @@ namespace ts { expression: Expression; } - export interface PrivateName extends PrimaryExpression, Declaration { - kind: SyntaxKind.PrivateName; + export interface PrivateIdentifier extends Node { + kind: SyntaxKind.PrivateIdentifier; // escaping not strictly necessary // avoids gotchas in transforms and utils escapedText: __String; @@ -1009,6 +1009,11 @@ namespace ts { initializer?: Expression; // Optional initializer } + /*@internal*/ + export interface PrivateIdentifierPropertyDeclaration extends PropertyDeclaration { + name: PrivateIdentifier; + } + export interface ObjectLiteralElement extends NamedDeclaration { _objectLiteralBrand: any; name?: PropertyName; @@ -1841,7 +1846,12 @@ namespace ts { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; questionDotToken?: QuestionDotToken; - name: Identifier | PrivateName; + name: Identifier | PrivateIdentifier; + } + + /*@internal*/ + export interface PrivateIdentifierPropertyAccessExpression extends PropertyAccessExpression { + name: PrivateIdentifier; } export interface PropertyAccessChain extends PropertyAccessExpression { @@ -3347,7 +3357,7 @@ namespace ts { getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; - getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined; + getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined; /* @internal */ getTypeOfPropertyOfType(type: Type, propertyName: string): Type | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; @@ -4196,6 +4206,7 @@ namespace ts { AssignmentsMarked = 0x00800000, // Parameter assignments have been marked ClassWithConstructorReference = 0x01000000, // Class that contains a binding to its constructor inside of the class body. ConstructorReferenceInClass = 0x02000000, // Binding to a class constructor inside of the class's body. + ContainsClassWithPrivateIdentifiers = 0x04000000, // Marked on all block-scoped containers containing a class with private identifiers. } /* @internal */ @@ -5778,8 +5789,10 @@ namespace ts { AsyncValues = 1 << 15, // __asyncValues (used by ES2017 for..await..of transformation) ExportStar = 1 << 16, // __exportStar (used by CommonJS/AMD/UMD module transformation) MakeTemplateObject = 1 << 17, // __makeTemplateObject (used for constructing template string array objects) + ClassPrivateFieldGet = 1 << 18, // __classPrivateFieldGet (used by the class private field transformation) + ClassPrivateFieldSet = 1 << 19, // __classPrivateFieldSet (used by the class private field transformation) FirstEmitHelper = Extends, - LastEmitHelper = MakeTemplateObject, + LastEmitHelper = ClassPrivateFieldSet, // Helpers included by ES2015 for..of ForOfIncludes = Values, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 613d3802bfe81..93343650841c7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -840,7 +840,7 @@ namespace ts { export function getTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String { switch (name.kind) { case SyntaxKind.Identifier: - case SyntaxKind.PrivateName: + case SyntaxKind.PrivateIdentifier: return name.escapedText; case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: @@ -868,7 +868,7 @@ namespace ts { return Debug.assertNever(name.name); } default: - throw Debug.assertNever(name); + return Debug.assertNever(name); } } @@ -1585,7 +1585,7 @@ namespace ts { export function nodeCanBeDecorated(node: Node, parent: Node, grandparent: Node): boolean; export function nodeCanBeDecorated(node: Node, parent?: Node, grandparent?: Node): boolean { // private names cannot be used with decorators yet - if (isNamedDeclaration(node) && isPrivateName(node.name)) { + if (isNamedDeclaration(node) && isPrivateIdentifier(node.name)) { return false; } switch (node.kind) { @@ -2005,13 +2005,18 @@ namespace ts { if (isPropertyNameLiteral(name) && isPropertyNameLiteral(initializer)) { return getTextOfIdentifierOrLiteral(name) === getTextOfIdentifierOrLiteral(name); } - if (isIdentifier(name) && (isLiteralLikeAccess(initializer))) { - return (initializer.expression.kind === SyntaxKind.ThisKeyword || + if (isIdentifier(name) && isLiteralLikeAccess(initializer) && + (initializer.expression.kind === SyntaxKind.ThisKeyword || isIdentifier(initializer.expression) && (initializer.expression.escapedText === "window" || initializer.expression.escapedText === "self" || - initializer.expression.escapedText === "global")) && - isSameEntityName(name, getNameOrArgument(initializer)); + initializer.expression.escapedText === "global"))) { + + const nameOrArgument = getNameOrArgument(initializer); + if (isPrivateIdentifier(nameOrArgument)) { + Debug.fail("Unexpected PrivateIdentifier in name expression with literal-like access."); + } + return isSameEntityName(name, nameOrArgument); } if (isLiteralLikeAccess(name) && isLiteralLikeAccess(initializer)) { return getElementOrPropertyAccessName(name) === getElementOrPropertyAccessName(initializer) @@ -2121,7 +2126,7 @@ namespace ts { * throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand) */ /* @internal */ - export function getElementOrPropertyAccessArgumentExpressionOrName(node: AccessExpression): Identifier | PrivateName | StringLiteralLike | NumericLiteral | ElementAccessExpression | undefined { + export function getElementOrPropertyAccessArgumentExpressionOrName(node: AccessExpression): Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ElementAccessExpression | undefined { if (isPropertyAccessExpression(node)) { return node.name; } @@ -2923,7 +2928,7 @@ namespace ts { export function getPropertyNameForPropertyNameNode(name: PropertyName): __String | undefined { switch (name.kind) { case SyntaxKind.Identifier: - case SyntaxKind.PrivateName: + case SyntaxKind.PrivateIdentifier: return name.escapedText; case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: @@ -2942,7 +2947,7 @@ namespace ts { } } - export type PropertyNameLiteral = Identifier | PrivateName | StringLiteralLike | NumericLiteral; + export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; export function isPropertyNameLiteral(node: Node): node is PropertyNameLiteral { switch (node.kind) { case SyntaxKind.Identifier: @@ -2955,17 +2960,11 @@ namespace ts { } } export function getTextOfIdentifierOrLiteral(node: PropertyNameLiteral): string { - return isIdentifierOrPrivateName(node) ? idText(node) : node.text; + return isIdentifierOrPrivateIdentifier(node) ? idText(node) : node.text; } export function getEscapedTextOfIdentifierOrLiteral(node: PropertyNameLiteral): __String { - switch(node.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.PrivateName: - return node.escapedText; - default: - return escapeLeadingUnderscores(node.text); - } + return isIdentifierOrPrivateIdentifier(node) ? node.escapedText : escapeLeadingUnderscores(node.text); } export function getPropertyNameForUniqueESSymbol(symbol: Symbol): __String { @@ -2976,7 +2975,7 @@ namespace ts { return "__@" + symbolName as __String; } - export function getPropertyNameForPrivateNameDescription(containingClassSymbol: Symbol, description: __String): __String { + export function getSymbolNameForPrivateIdentifier(containingClassSymbol: Symbol, description: __String): __String { return `__#${getSymbolId(containingClassSymbol)}@${description}` as __String; } @@ -4938,6 +4937,7 @@ namespace ts { getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token; getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier; + getPrivateIdentifierConstructor(): new (kind: SyntaxKind.PrivateIdentifier, pos?: number, end?: number) => PrivateIdentifier; getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile; getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol; getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; @@ -4992,6 +4992,7 @@ namespace ts { getNodeConstructor: () => Node, getTokenConstructor: () => Node, getIdentifierConstructor: () => Node, + getPrivateIdentifierConstructor: () => Node, getSourceFileConstructor: () => Node, getSymbolConstructor: () => Symbol, getTypeConstructor: () => Type, diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 388d58f598a25..1dc3a87742ebe 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -453,10 +453,13 @@ namespace ts { return id.length >= 3 && id.charCodeAt(0) === CharacterCodes._ && id.charCodeAt(1) === CharacterCodes._ && id.charCodeAt(2) === CharacterCodes._ ? id.substr(1) : id; } - export function idText(identifierOrPrivateName: Identifier | PrivateName): string { + export function idText(identifierOrPrivateName: Identifier | PrivateIdentifier): string { return unescapeLeadingUnderscores(identifierOrPrivateName.escapedText); } export function symbolName(symbol: Symbol): string { + if (symbol.valueDeclaration && isPrivateIdentifierPropertyDeclaration(symbol.valueDeclaration)) { + return idText(symbol.valueDeclaration.name); + } return unescapeLeadingUnderscores(symbol.escapedName); } @@ -465,7 +468,7 @@ namespace ts { * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol * will be merged with) */ - function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag | JSDocEnumTag): Identifier | PrivateName | undefined { + function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag | JSDocEnumTag): Identifier | PrivateIdentifier | undefined { const hostNode = declaration.parent.parent; if (!hostNode) { return undefined; @@ -524,7 +527,7 @@ namespace ts { return false; } - export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateName | undefined { + export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateIdentifier | undefined { return declaration.name || nameForNamelessJSDocTypedef(declaration); } @@ -878,12 +881,12 @@ namespace ts { return node.kind === SyntaxKind.ComputedPropertyName; } - export function isPrivateName(node: Node): node is PrivateName { - return node.kind === SyntaxKind.PrivateName; + export function isPrivateIdentifier(node: Node): node is PrivateIdentifier { + return node.kind === SyntaxKind.PrivateIdentifier; } - export function isIdentifierOrPrivateName(node: Node): node is Identifier | PrivateName { - return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateName; + export function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier { + return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateIdentifier; } // Signature elements @@ -1729,6 +1732,17 @@ namespace ts { return isIdentifier(node) && (node.autoGenerateFlags! & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None; } + // Private Identifiers + /*@internal*/ + export function isPrivateIdentifierPropertyDeclaration(node: Node): node is PrivateIdentifierPropertyDeclaration { + return isPropertyDeclaration(node) && isPrivateIdentifier(node.name); + } + + /*@internal*/ + export function isPrivateIdentifierPropertyAccessExpression(node: Node): node is PrivateIdentifierPropertyAccessExpression { + return isPropertyAccessExpression(node) && isPrivateIdentifier(node.name); + } + // Keywords /* @internal */ diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 54ea4ea060a3f..a7a331d4bffab 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -614,4 +614,4 @@ namespace ts { function aggregateTransformFlagsForChildNodes(transformFlags: TransformFlags, nodes: NodeArray): TransformFlags { return transformFlags | aggregateTransformFlagsForNodeArray(nodes); } -} \ No newline at end of file +} diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 65608e2ffee6f..0a40cd473305e 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -464,7 +464,7 @@ namespace ts { } return updatePropertyAccess(node, visitNode((node).expression, visitor, isExpression), - visitNode((node).name, visitor, isIdentifierOrPrivateName)); + visitNode((node).name, visitor, isIdentifierOrPrivateIdentifier)); case SyntaxKind.ElementAccessExpression: if (node.flags & NodeFlags.OptionalChain) { diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 2e24fd2253dd2..c57565531514c 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -65,7 +65,7 @@ namespace ts.codefix { const { parentDeclaration, declSourceFile, inJs, makeStatic, token, call } = info; // Always prefer to add a method declaration if possible. - if (call) { + if (call && !isPrivateIdentifier(token)) { addMethodDeclaration(context, changes, declSourceFile, parentDeclaration, token, call, makeStatic, inJs, preferences); } else { @@ -104,7 +104,7 @@ namespace ts.codefix { } interface ClassOrInterfaceInfo { readonly kind: InfoKind.ClassOrInterface; - readonly token: Identifier; + readonly token: Identifier | PrivateIdentifier; readonly parentDeclaration: ClassOrInterface; readonly makeStatic: boolean; readonly declSourceFile: SourceFile; @@ -118,7 +118,7 @@ namespace ts.codefix { // this.missing = 1; // ^^^^^^^ const token = getTokenAtPosition(tokenSourceFile, tokenPos); - if (!isIdentifier(token)) { + if (!isIdentifier(token) && !isPrivateIdentifier(token)) { return undefined; } @@ -129,17 +129,25 @@ namespace ts.codefix { const { symbol } = leftExpressionType; if (!symbol || !symbol.declarations) return undefined; + const isClass = find(symbol.declarations, isClassLike); + // Don't suggest adding private identifiers to anything other than a class. + if (!isClass && isPrivateIdentifier(token)) { + return undefined; + } + // Prefer to change the class instead of the interface if they are merged - const classOrInterface = find(symbol.declarations, isClassLike) || find(symbol.declarations, isInterfaceDeclaration); + const classOrInterface = isClass || find(symbol.declarations, isInterfaceDeclaration); if (classOrInterface && !program.isSourceFileFromExternalLibrary(classOrInterface.getSourceFile())) { const makeStatic = ((leftExpressionType as TypeReference).target || leftExpressionType) !== checker.getDeclaredTypeOfSymbol(symbol); + // Static private identifier properties are not supported yet. + if (makeStatic && isPrivateIdentifier(token)) { return undefined; } const declSourceFile = classOrInterface.getSourceFile(); const inJs = isSourceFileJS(declSourceFile); const call = tryCast(parent.parent, isCallExpression); return { kind: InfoKind.ClassOrInterface, token, parentDeclaration: classOrInterface, makeStatic, declSourceFile, inJs, call }; } const enumDeclaration = find(symbol.declarations, isEnumDeclaration); - if (enumDeclaration && !program.isSourceFileFromExternalLibrary(enumDeclaration.getSourceFile())) { + if (enumDeclaration && !isPrivateIdentifier(token) && !program.isSourceFileFromExternalLibrary(enumDeclaration.getSourceFile())) { return { kind: InfoKind.Enum, token, parentDeclaration: enumDeclaration }; } return undefined; @@ -174,10 +182,10 @@ namespace ts.codefix { return createStatement(createAssignment(createPropertyAccess(obj, propertyName), createIdentifier("undefined"))); } - function getActionsForAddMissingMemberInTypeScriptFile(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, token: Identifier, makeStatic: boolean): CodeFixAction[] | undefined { + function getActionsForAddMissingMemberInTypeScriptFile(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, token: Identifier | PrivateIdentifier, makeStatic: boolean): CodeFixAction[] | undefined { const typeNode = getTypeNode(context.program.getTypeChecker(), classDeclaration, token); const addProp = createAddPropertyDeclarationAction(context, declSourceFile, classDeclaration, makeStatic, token.text, typeNode); - return makeStatic ? [addProp] : [addProp, createAddIndexSignatureAction(context, declSourceFile, classDeclaration, token.text, typeNode)]; + return makeStatic || isPrivateIdentifier(token) ? [addProp] : [addProp, createAddIndexSignatureAction(context, declSourceFile, classDeclaration, token.text, typeNode)]; } function getTypeNode(checker: TypeChecker, classDeclaration: ClassOrInterface, token: Node) { @@ -254,12 +262,14 @@ namespace ts.codefix { context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, - token: Identifier, + token: Identifier | PrivateIdentifier, callExpression: CallExpression, makeStatic: boolean, inJs: boolean, preferences: UserPreferences, ): CodeFixAction | undefined { + // Private methods are not implemented yet. + if (isPrivateIdentifier(token)) { return undefined; } const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(context, t, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences)); return createCodeFixAction(fixName, changes, [makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0, token.text], fixId, Diagnostics.Add_all_missing_members); } diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index df77e281cf0a4..5718f592cb82a 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -403,7 +403,7 @@ namespace ts.codefix { entry.kind !== FindAllReferences.EntryKind.Span ? tryCast(entry.node, isIdentifier) : undefined); } - function inferTypeForVariableFromUsage(token: Identifier | PrivateName, program: Program, cancellationToken: CancellationToken): Type { + function inferTypeForVariableFromUsage(token: Identifier | PrivateIdentifier, program: Program, cancellationToken: CancellationToken): Type { const references = getReferences(token, program, cancellationToken); return inferTypeFromReferences(program, references, cancellationToken).single(); } diff --git a/src/services/completions.ts b/src/services/completions.ts index d64692f2dce56..2326acd27ae24 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -2396,8 +2396,10 @@ namespace ts.Completions { return undefined; } - const validIdentifierResult: CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess: false }; - if (isIdentifierText(name, target)) return validIdentifierResult; + const validNameResult: CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess: false }; + if (isIdentifierText(name, target) || symbol.valueDeclaration && isPrivateIdentifierPropertyDeclaration(symbol.valueDeclaration)) { + return validNameResult; + } switch (kind) { case CompletionKind.MemberLike: return undefined; @@ -2410,7 +2412,7 @@ namespace ts.Completions { return name.charCodeAt(0) === CharacterCodes.space ? undefined : { name, needsConvertPropertyAccess: true }; case CompletionKind.None: case CompletionKind.String: - return validIdentifierResult; + return validNameResult; default: Debug.assertNever(kind); } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index ba369f975fbe5..650496bfbc1e6 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -141,7 +141,7 @@ namespace ts.NavigationBar { const name = getNameOrArgument(entityName); const nameText = getElementOrPropertyAccessName(entityName); entityName = entityName.expression; - if (nameText === "prototype") continue; + if (nameText === "prototype" || isPrivateIdentifier(name)) continue; names.push(name); } names.push(entityName); diff --git a/src/services/services.ts b/src/services/services.ts index 71159e71973fc..1a3eae675e62c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2,10 +2,11 @@ namespace ts { /** The version of the language service API */ export const servicesVersion = "0.8"; - function createNode(kind: TKind, pos: number, end: number, parent: Node): NodeObject | TokenObject | IdentifierObject { + function createNode(kind: TKind, pos: number, end: number, parent: Node): NodeObject | TokenObject | IdentifierObject | PrivateIdentifierObject { const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) : kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : - new TokenObject(kind, pos, end); + kind === SyntaxKind.PrivateIdentifier ? new PrivateIdentifierObject(SyntaxKind.PrivateIdentifier, pos, end) : + new TokenObject(kind, pos, end); node.parent = parent; node.flags = parent.flags & NodeFlags.ContextFlags; return node; @@ -368,6 +369,19 @@ namespace ts { } } IdentifierObject.prototype.kind = SyntaxKind.Identifier; + class PrivateIdentifierObject extends TokenOrIdentifierObject implements PrivateIdentifier { + public kind!: SyntaxKind.PrivateIdentifier; + public escapedText!: __String; + public symbol!: Symbol; + constructor(_kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) { + super(pos, end); + } + + get text(): string { + return idText(this); + } + } + PrivateIdentifierObject.prototype.kind = SyntaxKind.PrivateIdentifier; class TypeObject implements Type { checker: TypeChecker; @@ -814,6 +828,7 @@ namespace ts { getTokenConstructor: () => TokenObject, getIdentifierConstructor: () => IdentifierObject, + getPrivateIdentifierConstructor: () => PrivateIdentifierObject, getSourceFileConstructor: () => SourceFileObject, getSymbolConstructor: () => SymbolObject, getTypeConstructor: () => TypeObject, @@ -2235,6 +2250,10 @@ namespace ts { const text = getEscapedTextOfIdentifierOrLiteral(node); nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); } + else if (isPrivateIdentifier(node)) { + const text = node.escapedText; + nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); + } forEachChild(node, walk); if (hasJSDocNodes(node)) { diff --git a/src/services/types.ts b/src/services/types.ts index 4d82fbbe00587..3a1627c247fe2 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -30,7 +30,7 @@ namespace ts { readonly text: string; } - export interface PrivateName { + export interface PrivateIdentifier { readonly text: string; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index bb10faa8179ab..39ce286486b7a 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1335,7 +1335,7 @@ namespace ts { return name.kind === SyntaxKind.ComputedPropertyName // treat computed property names where expression is string/numeric literal as just string/numeric literal ? isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined - : getTextOfIdentifierOrLiteral(name); + : isPrivateIdentifier(name) ? idText(name) : getTextOfIdentifierOrLiteral(name); } export function programContainsEs6Modules(program: Program): boolean { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 545c39107cca4..0ac0f4c227ee4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -151,7 +151,7 @@ declare namespace ts { BarEqualsToken = 73, CaretEqualsToken = 74, Identifier = 75, - PrivateName = 76, + PrivateIdentifier = 76, BreakKeyword = 77, CaseKeyword = 78, CatchKeyword = 79, @@ -553,8 +553,8 @@ declare namespace ts { right: Identifier; } export type EntityName = Identifier | QualifiedName; - export type PropertyName = Identifier | PrivateName | StringLiteral | NumericLiteral | ComputedPropertyName; - export type DeclarationName = Identifier | PrivateName | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; + export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; + export type DeclarationName = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; export interface Declaration extends Node { _declarationBrand: any; } @@ -569,8 +569,8 @@ declare namespace ts { kind: SyntaxKind.ComputedPropertyName; expression: Expression; } - export interface PrivateName extends PrimaryExpression, Declaration { - kind: SyntaxKind.PrivateName; + export interface PrivateIdentifier extends Node { + kind: SyntaxKind.PrivateIdentifier; escapedText: __String; } export interface Decorator extends Node { @@ -1098,7 +1098,7 @@ declare namespace ts { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; questionDotToken?: QuestionDotToken; - name: Identifier | PrivateName; + name: Identifier | PrivateIdentifier; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; @@ -2009,7 +2009,7 @@ declare namespace ts { getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; - getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined; + getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; @@ -3448,9 +3448,9 @@ declare namespace ts { * @returns The unescaped identifier text. */ function unescapeLeadingUnderscores(identifier: __String): string; - function idText(identifierOrPrivateName: Identifier | PrivateName): string; + function idText(identifierOrPrivateName: Identifier | PrivateIdentifier): string; function symbolName(symbol: Symbol): string; - function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateName | undefined; + function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateIdentifier | undefined; function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** * Gets the JSDoc parameter tags for the node if present. @@ -3546,8 +3546,8 @@ declare namespace ts { function isIdentifier(node: Node): node is Identifier; function isQualifiedName(node: Node): node is QualifiedName; function isComputedPropertyName(node: Node): node is ComputedPropertyName; - function isPrivateName(node: Node): node is PrivateName; - function isIdentifierOrPrivateName(node: Node): node is Identifier | PrivateName; + function isPrivateIdentifier(node: Node): node is PrivateIdentifier; + function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier; function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration; function isParameter(node: Node): node is ParameterDeclaration; function isDecorator(node: Node): node is Decorator; @@ -3947,6 +3947,7 @@ declare namespace ts { function createFileLevelUniqueName(text: string): Identifier; /** Create a unique name generated for a node. */ function getGeneratedNameForNode(node: Node | undefined): Identifier; + function createPrivateIdentifier(text: string): PrivateIdentifier; function createToken(token: TKind): Token; function createSuper(): SuperExpression; function createThis(): ThisExpression & Token; @@ -4041,8 +4042,8 @@ declare namespace ts { function updateArrayLiteral(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; function createObjectLiteral(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; - function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateName): PropertyAccessExpression; - function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateName): PropertyAccessExpression; + function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression; + function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression; function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain; function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain; function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; @@ -4952,7 +4953,7 @@ declare namespace ts { interface Identifier { readonly text: string; } - interface PrivateName { + interface PrivateIdentifier { readonly text: string; } interface Symbol { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 81f0e0bdd25bc..42432eac6e783 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -151,7 +151,7 @@ declare namespace ts { BarEqualsToken = 73, CaretEqualsToken = 74, Identifier = 75, - PrivateName = 76, + PrivateIdentifier = 76, BreakKeyword = 77, CaseKeyword = 78, CatchKeyword = 79, @@ -553,8 +553,8 @@ declare namespace ts { right: Identifier; } export type EntityName = Identifier | QualifiedName; - export type PropertyName = Identifier | PrivateName | StringLiteral | NumericLiteral | ComputedPropertyName; - export type DeclarationName = Identifier | PrivateName | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; + export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; + export type DeclarationName = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; export interface Declaration extends Node { _declarationBrand: any; } @@ -569,8 +569,8 @@ declare namespace ts { kind: SyntaxKind.ComputedPropertyName; expression: Expression; } - export interface PrivateName extends PrimaryExpression, Declaration { - kind: SyntaxKind.PrivateName; + export interface PrivateIdentifier extends Node { + kind: SyntaxKind.PrivateIdentifier; escapedText: __String; } export interface Decorator extends Node { @@ -1098,7 +1098,7 @@ declare namespace ts { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; questionDotToken?: QuestionDotToken; - name: Identifier | PrivateName; + name: Identifier | PrivateIdentifier; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; @@ -2009,7 +2009,7 @@ declare namespace ts { getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; - getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined; + getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; @@ -3448,9 +3448,9 @@ declare namespace ts { * @returns The unescaped identifier text. */ function unescapeLeadingUnderscores(identifier: __String): string; - function idText(identifierOrPrivateName: Identifier | PrivateName): string; + function idText(identifierOrPrivateName: Identifier | PrivateIdentifier): string; function symbolName(symbol: Symbol): string; - function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateName | undefined; + function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateIdentifier | undefined; function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** * Gets the JSDoc parameter tags for the node if present. @@ -3546,8 +3546,8 @@ declare namespace ts { function isIdentifier(node: Node): node is Identifier; function isQualifiedName(node: Node): node is QualifiedName; function isComputedPropertyName(node: Node): node is ComputedPropertyName; - function isPrivateName(node: Node): node is PrivateName; - function isIdentifierOrPrivateName(node: Node): node is Identifier | PrivateName; + function isPrivateIdentifier(node: Node): node is PrivateIdentifier; + function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier; function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration; function isParameter(node: Node): node is ParameterDeclaration; function isDecorator(node: Node): node is Decorator; @@ -3947,6 +3947,7 @@ declare namespace ts { function createFileLevelUniqueName(text: string): Identifier; /** Create a unique name generated for a node. */ function getGeneratedNameForNode(node: Node | undefined): Identifier; + function createPrivateIdentifier(text: string): PrivateIdentifier; function createToken(token: TKind): Token; function createSuper(): SuperExpression; function createThis(): ThisExpression & Token; @@ -4041,8 +4042,8 @@ declare namespace ts { function updateArrayLiteral(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; function createObjectLiteral(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; - function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateName): PropertyAccessExpression; - function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateName): PropertyAccessExpression; + function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression; + function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression; function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain; function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain; function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; @@ -4952,7 +4953,7 @@ declare namespace ts { interface Identifier { readonly text: string; } - interface PrivateName { + interface PrivateIdentifier { readonly text: string; } interface Symbol { diff --git a/tests/baselines/reference/await_unaryExpression_es2017_1.errors.txt b/tests/baselines/reference/await_unaryExpression_es2017_1.errors.txt index 06970ab285678..304487da24e8a 100644 --- a/tests/baselines/reference/await_unaryExpression_es2017_1.errors.txt +++ b/tests/baselines/reference/await_unaryExpression_es2017_1.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts(6,12): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts(10,12): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts(6,12): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts(10,12): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts (2 errors) ==== @@ -10,13 +10,13 @@ tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts(10,12): e async function bar1() { delete await 42; // OK ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar2() { delete await 42; // OK ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar3() { diff --git a/tests/baselines/reference/await_unaryExpression_es2017_2.errors.txt b/tests/baselines/reference/await_unaryExpression_es2017_2.errors.txt index e561ceaf79b99..b42186810fb1b 100644 --- a/tests/baselines/reference/await_unaryExpression_es2017_2.errors.txt +++ b/tests/baselines/reference/await_unaryExpression_es2017_2.errors.txt @@ -1,18 +1,18 @@ -tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts(2,12): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts(6,12): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts(2,12): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts(6,12): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts (2 errors) ==== async function bar1() { delete await 42; ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar2() { delete await 42; ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar3() { diff --git a/tests/baselines/reference/await_unaryExpression_es6_1.errors.txt b/tests/baselines/reference/await_unaryExpression_es6_1.errors.txt index 9e9d05bf2ab6a..9bbf96f64d7fa 100644 --- a/tests/baselines/reference/await_unaryExpression_es6_1.errors.txt +++ b/tests/baselines/reference/await_unaryExpression_es6_1.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts(6,12): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts(10,12): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts(6,12): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts(10,12): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts (2 errors) ==== @@ -10,13 +10,13 @@ tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts(10,12): error T async function bar1() { delete await 42; // OK ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar2() { delete await 42; // OK ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar3() { diff --git a/tests/baselines/reference/await_unaryExpression_es6_2.errors.txt b/tests/baselines/reference/await_unaryExpression_es6_2.errors.txt index 1c440e84af79c..7960c2f5a62b8 100644 --- a/tests/baselines/reference/await_unaryExpression_es6_2.errors.txt +++ b/tests/baselines/reference/await_unaryExpression_es6_2.errors.txt @@ -1,18 +1,18 @@ -tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts(2,12): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts(6,12): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts(2,12): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts(6,12): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts (2 errors) ==== async function bar1() { delete await 42; ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar2() { delete await 42; ~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } async function bar3() { diff --git a/tests/baselines/reference/classUpdateTests.errors.txt b/tests/baselines/reference/classUpdateTests.errors.txt index 59e9bc9ced182..1d6e767aad589 100644 --- a/tests/baselines/reference/classUpdateTests.errors.txt +++ b/tests/baselines/reference/classUpdateTests.errors.txt @@ -1,11 +1,11 @@ tests/cases/compiler/classUpdateTests.ts(34,2): error TS2377: Constructors for derived classes must contain a 'super' call. tests/cases/compiler/classUpdateTests.ts(43,18): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/compiler/classUpdateTests.ts(57,2): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +tests/cases/compiler/classUpdateTests.ts(57,2): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. tests/cases/compiler/classUpdateTests.ts(63,7): error TS2415: Class 'L' incorrectly extends base class 'G'. Property 'p1' is private in type 'L' but not in type 'G'. tests/cases/compiler/classUpdateTests.ts(69,7): error TS2415: Class 'M' incorrectly extends base class 'G'. Property 'p1' is private in type 'M' but not in type 'G'. -tests/cases/compiler/classUpdateTests.ts(70,2): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +tests/cases/compiler/classUpdateTests.ts(70,2): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. tests/cases/compiler/classUpdateTests.ts(93,3): error TS1128: Declaration or statement expected. tests/cases/compiler/classUpdateTests.ts(95,1): error TS1128: Declaration or statement expected. tests/cases/compiler/classUpdateTests.ts(99,3): error TS1128: Declaration or statement expected. @@ -87,7 +87,7 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st ~~~~~~~~~~ } ~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. } class L extends G { @@ -111,7 +111,7 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st ~~~~~~~~~~ } ~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. } // diff --git a/tests/baselines/reference/computedPropertyNames3_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames3_ES5.errors.txt index 7caab39885ec7..ad4f1851bbccc 100644 --- a/tests/baselines/reference/computedPropertyNames3_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames3_ES5.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(4,1 tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(5,9): error TS2378: A 'get' accessor must return a value. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(5,9): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(5,17): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(5,17): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(5,17): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(6,9): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(7,16): error TS2378: A 'get' accessor must return a value. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(7,16): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. @@ -23,7 +23,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES5.ts(7,1 ~~ !!! error TS1102: 'delete' cannot be called on an identifier in strict mode. ~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. set [[0, 1]](v) { } ~~~~~~~~ !!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. diff --git a/tests/baselines/reference/computedPropertyNames3_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames3_ES6.errors.txt index 9db937313e301..0960bf6cc9fb3 100644 --- a/tests/baselines/reference/computedPropertyNames3_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames3_ES6.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(4,1 tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(5,9): error TS2378: A 'get' accessor must return a value. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(5,9): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(5,17): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(5,17): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(5,17): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(6,9): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(7,16): error TS2378: A 'get' accessor must return a value. tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(7,16): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. @@ -23,7 +23,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames3_ES6.ts(7,1 ~~ !!! error TS1102: 'delete' cannot be called on an identifier in strict mode. ~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. set [[0, 1]](v) { } ~~~~~~~~ !!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. diff --git a/tests/baselines/reference/controlFlowDeleteOperator.errors.txt b/tests/baselines/reference/controlFlowDeleteOperator.errors.txt index 757f3629975f1..91ec2aa0de8db 100644 --- a/tests/baselines/reference/controlFlowDeleteOperator.errors.txt +++ b/tests/baselines/reference/controlFlowDeleteOperator.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/controlFlow/controlFlowDeleteOperator.ts(14,12): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/controlFlow/controlFlowDeleteOperator.ts(14,12): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/controlFlow/controlFlowDeleteOperator.ts (1 errors) ==== @@ -17,6 +17,6 @@ tests/cases/conformance/controlFlow/controlFlowDeleteOperator.ts(14,12): error T x; delete x; // No effect ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. x; } \ No newline at end of file diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline deleted file mode 100644 index 5fae8ec8c9914..0000000000000 --- a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping.baseline +++ /dev/null @@ -1,34 +0,0 @@ -EmitSkipped: false -FileName : ./dist/index.js -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Foo = /** @class */ (function () { - function Foo() { - } - Foo.prototype.methodName = function (propName) { }; - Foo.prototype.otherMethod = function () { - if (Math.random() > 0.5) { - return { x: 42 }; - } - return { y: "yes" }; - }; - return Foo; -}()); -exports.Foo = Foo; -FileName : ./dist/index.d.ts.map -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts -export declare class Foo { - member: string; - methodName(propName: SomeType): void; - otherMethod(): { - x: number; - y?: undefined; - } | { - y: string; - x?: undefined; - }; -} -export interface SomeType { - member: number; -} -//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline deleted file mode 100644 index 151713a03bd45..0000000000000 --- a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping2.baseline +++ /dev/null @@ -1,35 +0,0 @@ -EmitSkipped: false -FileName : ./dist/index.js.map -{"version":3,"file":"index.js","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":";;AAAA;IAAA;IASA,CAAC;IAPG,wBAAU,GAAV,UAAW,QAAkB,IAAS,CAAC;IACvC,yBAAW,GAAX;QACI,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,EAAE;YACrB,OAAO,EAAC,CAAC,EAAE,EAAE,EAAC,CAAC;SAClB;QACD,OAAO,EAAC,CAAC,EAAE,KAAK,EAAC,CAAC;IACtB,CAAC;IACL,UAAC;AAAD,CAAC,AATD,IASC;AATY,kBAAG"}FileName : ./dist/index.js -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Foo = /** @class */ (function () { - function Foo() { - } - Foo.prototype.methodName = function (propName) { }; - Foo.prototype.otherMethod = function () { - if (Math.random() > 0.5) { - return { x: 42 }; - } - return { y: "yes" }; - }; - return Foo; -}()); -exports.Foo = Foo; -//# sourceMappingURL=index.js.mapFileName : ./dist/index.d.ts.map -{"version":3,"file":"index.d.ts","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts -export declare class Foo { - member: string; - methodName(propName: SomeType): void; - otherMethod(): { - x: number; - y?: undefined; - } | { - y: string; - x?: undefined; - }; -} -export interface SomeType { - member: number; -} -//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline deleted file mode 100644 index f05cbbd4c351b..0000000000000 --- a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping3.baseline +++ /dev/null @@ -1,34 +0,0 @@ -EmitSkipped: false -FileName : ./dist/index.js -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Foo = /** @class */ (function () { - function Foo() { - } - Foo.prototype.methodName = function (propName) { }; - Foo.prototype.otherMethod = function () { - if (Math.random() > 0.5) { - return { x: 42 }; - } - return { y: "yes" }; - }; - return Foo; -}()); -exports.Foo = Foo; -FileName : ./dist/index.d.ts.map -{"version":3,"file":"index.d.ts","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts -export declare class Foo { - member: string; - methodName(propName: SomeType): void; - otherMethod(): { - x: number; - y?: undefined; - } | { - y: string; - x?: undefined; - }; -} -export interface SomeType { - member: number; -} -//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline deleted file mode 100644 index ad51be6ddc0f5..0000000000000 --- a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInline.baseline +++ /dev/null @@ -1,34 +0,0 @@ -EmitSkipped: false -FileName : ./dist/index.js -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Foo = /** @class */ (function () { - function Foo() { - } - Foo.prototype.methodName = function (propName) { }; - Foo.prototype.otherMethod = function () { - if (Math.random() > 0.5) { - return { x: 42 }; - } - return { y: "yes" }; - }; - return Foo; -}()); -exports.Foo = Foo; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0cy9jYXNlcy9mb3Vyc2xhc2gvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtJQUFBO0lBU0EsQ0FBQztJQVBHLHdCQUFVLEdBQVYsVUFBVyxRQUFrQixJQUFTLENBQUM7SUFDdkMseUJBQVcsR0FBWDtRQUNJLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsRUFBRTtZQUNyQixPQUFPLEVBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBQyxDQUFDO1NBQ2xCO1FBQ0QsT0FBTyxFQUFDLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN0QixDQUFDO0lBQ0wsVUFBQztBQUFELENBQUMsQUFURCxJQVNDO0FBVFksa0JBQUcifQ==FileName : ./dist/index.d.ts.map -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts -export declare class Foo { - member: string; - methodName(propName: SomeType): void; - otherMethod(): { - x: number; - y?: undefined; - } | { - y: string; - x?: undefined; - }; -} -export interface SomeType { - member: number; -} -//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline b/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline deleted file mode 100644 index 8f6440b29dc78..0000000000000 --- a/tests/baselines/reference/declarationMapsGeneratedMapsEnableMapping_NoInlineSources.baseline +++ /dev/null @@ -1,34 +0,0 @@ -EmitSkipped: false -FileName : ./dist/index.js -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Foo = /** @class */ (function () { - function Foo() { - } - Foo.prototype.methodName = function (propName) { }; - Foo.prototype.otherMethod = function () { - if (Math.random() > 0.5) { - return { x: 42 }; - } - return { y: "yes" }; - }; - return Foo; -}()); -exports.Foo = Foo; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0cy9jYXNlcy9mb3Vyc2xhc2gvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtJQUFBO0lBU0EsQ0FBQztJQVBHLHdCQUFVLEdBQVYsVUFBVyxRQUFrQixJQUFTLENBQUM7SUFDdkMseUJBQVcsR0FBWDtRQUNJLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsRUFBRTtZQUNyQixPQUFPLEVBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBQyxDQUFDO1NBQ2xCO1FBQ0QsT0FBTyxFQUFDLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN0QixDQUFDO0lBQ0wsVUFBQztBQUFELENBQUMsQUFURCxJQVNDO0FBVFksa0JBQUciLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgRm9vIHtcbiAgICBtZW1iZXI6IHN0cmluZztcbiAgICBtZXRob2ROYW1lKHByb3BOYW1lOiBTb21lVHlwZSk6IHZvaWQge31cbiAgICBvdGhlck1ldGhvZCgpIHtcbiAgICAgICAgaWYgKE1hdGgucmFuZG9tKCkgPiAwLjUpIHtcbiAgICAgICAgICAgIHJldHVybiB7eDogNDJ9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7eTogXCJ5ZXNcIn07XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvbWVUeXBlIHtcbiAgICBtZW1iZXI6IG51bWJlcjtcbn0iXX0=FileName : ./dist/index.d.ts.map -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts -export declare class Foo { - member: string; - methodName(propName: SomeType): void; - otherMethod(): { - x: number; - y?: undefined; - } | { - y: string; - x?: undefined; - }; -} -export interface SomeType { - member: number; -} -//# sourceMappingURL=index.d.ts.map diff --git a/tests/baselines/reference/deleteOperator1.errors.txt b/tests/baselines/reference/deleteOperator1.errors.txt index c316a6e06a983..a2fdeba5722de 100644 --- a/tests/baselines/reference/deleteOperator1.errors.txt +++ b/tests/baselines/reference/deleteOperator1.errors.txt @@ -1,19 +1,19 @@ -tests/cases/compiler/deleteOperator1.ts(2,25): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/compiler/deleteOperator1.ts(3,21): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/compiler/deleteOperator1.ts(2,25): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/compiler/deleteOperator1.ts(3,21): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/compiler/deleteOperator1.ts(4,5): error TS2322: Type 'boolean' is not assignable to type 'number'. -tests/cases/compiler/deleteOperator1.ts(4,24): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/compiler/deleteOperator1.ts(4,24): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/compiler/deleteOperator1.ts (4 errors) ==== var a; var x: boolean = delete a; ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var y: any = delete a; ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var z: number = delete a; ~ !!! error TS2322: Type 'boolean' is not assignable to type 'number'. ~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/baselines/reference/deleteOperatorInStrictMode.errors.txt b/tests/baselines/reference/deleteOperatorInStrictMode.errors.txt index 754406dbc6c49..b9bba470590b5 100644 --- a/tests/baselines/reference/deleteOperatorInStrictMode.errors.txt +++ b/tests/baselines/reference/deleteOperatorInStrictMode.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/deleteOperatorInStrictMode.ts(3,8): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/compiler/deleteOperatorInStrictMode.ts(3,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/compiler/deleteOperatorInStrictMode.ts(3,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/compiler/deleteOperatorInStrictMode.ts (2 errors) ==== @@ -9,4 +9,4 @@ tests/cases/compiler/deleteOperatorInStrictMode.ts(3,8): error TS2703: The opera ~ !!! error TS1102: 'delete' cannot be called on an identifier in strict mode. ~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt b/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt index 3994654c5235a..fa907cb0ef21e 100644 --- a/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt +++ b/tests/baselines/reference/deleteOperatorInvalidOperations.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(5,20): error TS1005: ',' expected. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(5,26): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(5,26): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(5,27): error TS1109: Expression expected. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(8,22): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(8,22): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(8,23): error TS1109: Expression expected. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(13,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(13,16): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts(13,16): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorInvalidOperations.ts (7 errors) ==== @@ -16,14 +16,14 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator ~~~~~~ !!! error TS1005: ',' expected. -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~ !!! error TS1109: Expression expected. // miss an operand var BOOLEAN2 = delete ; -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~ !!! error TS1109: Expression expected. @@ -34,6 +34,6 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator ~ !!! error TS1102: 'delete' cannot be called on an identifier in strict mode. ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. } } \ No newline at end of file diff --git a/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt index 5ea3f6135c16c..62b5475ee3e7f 100644 --- a/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt @@ -1,28 +1,28 @@ -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(25,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(26,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(27,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(28,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(29,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(30,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(33,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(34,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(42,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(43,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(44,33): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(25,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(26,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(27,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(28,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(29,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(30,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(33,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(34,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(42,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(43,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(44,33): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(45,33): error TS2365: Operator '+' cannot be applied to types 'null' and 'undefined'. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(45,33): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(45,33): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(46,33): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(46,33): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(46,33): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(47,33): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(47,33): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(50,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(50,39): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(51,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(51,39): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(51,47): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(54,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(55,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(57,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(47,33): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(50,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(50,39): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(51,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(51,39): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(51,47): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(54,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(55,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(57,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts (25 errors) ==== @@ -52,30 +52,30 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator // any type var var ResultIsBoolean1 = delete ANY1; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean2 = delete ANY2; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean3 = delete A; ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean4 = delete M; ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean5 = delete obj; ~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean6 = delete obj1; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // any type literal var ResultIsBoolean7 = delete undefined; ~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean8 = delete null; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // any type expressions var ResultIsBoolean9 = delete ANY2[0]; @@ -85,54 +85,54 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator var ResultIsBoolean13 = delete M.n; var ResultIsBoolean14 = delete foo(); ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean15 = delete A.foo(); ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean16 = delete (ANY + ANY1); ~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean17 = delete (null + undefined); ~~~~~~~~~~~~~~~~ !!! error TS2365: Operator '+' cannot be applied to types 'null' and 'undefined'. ~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean18 = delete (null + null); ~~~~~~~~~~~ !!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. ~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean19 = delete (undefined + undefined); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // multiple delete operators var ResultIsBoolean20 = delete delete ANY; ~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean21 = delete delete delete (ANY + ANY1); ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // miss assignment operators delete ANY; ~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete ANY1; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete ANY2[0]; delete ANY, ANY1; ~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete obj1.x; delete obj1.y; delete objA.a; diff --git a/tests/baselines/reference/deleteOperatorWithBooleanType.errors.txt b/tests/baselines/reference/deleteOperatorWithBooleanType.errors.txt index 3dfc6672997c9..730693a7fa38c 100644 --- a/tests/baselines/reference/deleteOperatorWithBooleanType.errors.txt +++ b/tests/baselines/reference/deleteOperatorWithBooleanType.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(17,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(20,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(21,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(26,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(27,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(30,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(30,38): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(33,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(34,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(35,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(36,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(17,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(20,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(21,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(26,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(27,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(30,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(30,38): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(33,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(34,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(35,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts(36,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithBooleanType.ts (11 errors) ==== @@ -30,45 +30,45 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator // boolean type var var ResultIsBoolean1 = delete BOOLEAN; ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // boolean type literal var ResultIsBoolean2 = delete true; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean3 = delete { x: true, y: false }; ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // boolean type expressions var ResultIsBoolean4 = delete objA.a; var ResultIsBoolean5 = delete M.n; var ResultIsBoolean6 = delete foo(); ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean7 = delete A.foo(); ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // multiple delete operator var ResultIsBoolean8 = delete delete BOOLEAN; ~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // miss assignment operators delete true; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete BOOLEAN; ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete foo(); ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete true, false; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete objA.a; delete M.n; \ No newline at end of file diff --git a/tests/baselines/reference/deleteOperatorWithEnumType.errors.txt b/tests/baselines/reference/deleteOperatorWithEnumType.errors.txt index e952ce0fdc9a4..dbfacfc7b0189 100644 --- a/tests/baselines/reference/deleteOperatorWithEnumType.errors.txt +++ b/tests/baselines/reference/deleteOperatorWithEnumType.errors.txt @@ -1,16 +1,16 @@ -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(7,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(8,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(11,31): error TS2704: The operand of a delete operator cannot be a read-only property. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(12,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(15,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(15,38): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(16,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(16,38): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(16,46): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(19,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(20,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(21,8): error TS2704: The operand of a delete operator cannot be a read-only property. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(22,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(7,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(8,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(11,31): error TS2704: The operand of a 'delete' operator cannot be a read-only property. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(12,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(15,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(15,38): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(16,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(16,38): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(16,46): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(19,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(20,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(21,8): error TS2704: The operand of a 'delete' operator cannot be a read-only property. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts(22,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithEnumType.ts (13 errors) ==== @@ -22,43 +22,43 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator // enum type var var ResultIsBoolean1 = delete ENUM; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean2 = delete ENUM1; ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // enum type expressions var ResultIsBoolean3 = delete ENUM1["A"]; ~~~~~~~~~~ -!!! error TS2704: The operand of a delete operator cannot be a read-only property. +!!! error TS2704: The operand of a 'delete' operator cannot be a read-only property. var ResultIsBoolean4 = delete (ENUM[0] + ENUM1["B"]); ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // multiple delete operators var ResultIsBoolean5 = delete delete ENUM; ~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean6 = delete delete delete (ENUM[0] + ENUM1["B"]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // miss assignment operators delete ENUM; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete ENUM1; ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete ENUM1.B; ~~~~~~~ -!!! error TS2704: The operand of a delete operator cannot be a read-only property. +!!! error TS2704: The operand of a 'delete' operator cannot be a read-only property. delete ENUM, ENUM1; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/baselines/reference/deleteOperatorWithNumberType.errors.txt b/tests/baselines/reference/deleteOperatorWithNumberType.errors.txt index 0f4a783d98311..dec35a2c96a13 100644 --- a/tests/baselines/reference/deleteOperatorWithNumberType.errors.txt +++ b/tests/baselines/reference/deleteOperatorWithNumberType.errors.txt @@ -1,20 +1,20 @@ -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(18,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(19,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(22,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(23,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(24,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(30,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(31,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(32,33): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(35,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(35,39): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(36,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(36,39): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(36,47): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(39,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(40,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(41,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(42,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(18,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(19,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(22,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(23,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(24,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(30,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(31,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(32,33): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(35,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(35,39): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(36,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(36,39): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(36,47): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(39,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(40,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(41,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts(42,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithNumberType.ts (17 errors) ==== @@ -37,21 +37,21 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator // number type var var ResultIsBoolean1 = delete NUMBER; ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean2 = delete NUMBER1; ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // number type literal var ResultIsBoolean3 = delete 1; ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean4 = delete { x: 1, y: 2}; ~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean5 = delete { x: 1, y: (n: number) => { return n; } }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // number type expressions var ResultIsBoolean6 = delete objA.a; @@ -59,41 +59,41 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator var ResultIsBoolean8 = delete NUMBER1[0]; var ResultIsBoolean9 = delete foo(); ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean10 = delete A.foo(); ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean11 = delete (NUMBER + NUMBER); ~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // multiple delete operator var ResultIsBoolean12 = delete delete NUMBER; ~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean13 = delete delete delete (NUMBER + NUMBER); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // miss assignment operators delete 1; ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete NUMBER; ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete NUMBER1; ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete foo(); ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete objA.a; delete M.n; delete objA.a, M.n; \ No newline at end of file diff --git a/tests/baselines/reference/deleteOperatorWithStringType.errors.txt b/tests/baselines/reference/deleteOperatorWithStringType.errors.txt index fd46679d81a41..7adf3439c1600 100644 --- a/tests/baselines/reference/deleteOperatorWithStringType.errors.txt +++ b/tests/baselines/reference/deleteOperatorWithStringType.errors.txt @@ -1,21 +1,21 @@ -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(18,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(19,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(22,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(23,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(24,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(30,31): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(31,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(32,33): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(33,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(36,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(36,39): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(37,32): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(37,39): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(37,47): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(40,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(41,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(42,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(43,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(18,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(19,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(22,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(23,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(24,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(30,31): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(31,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(32,33): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(33,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(36,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(36,39): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(37,32): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(37,39): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(37,47): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(40,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(41,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(42,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts(43,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithStringType.ts (18 errors) ==== @@ -38,21 +38,21 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator // string type var var ResultIsBoolean1 = delete STRING; ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean2 = delete STRING1; ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // string type literal var ResultIsBoolean3 = delete ""; ~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean4 = delete { x: "", y: "" }; ~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean5 = delete { x: "", y: (s: string) => { return s; } }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // string type expressions var ResultIsBoolean6 = delete objA.a; @@ -60,42 +60,42 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator var ResultIsBoolean8 = delete STRING1[0]; var ResultIsBoolean9 = delete foo(); ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean10 = delete A.foo(); ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean11 = delete (STRING + STRING); ~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean12 = delete STRING.charAt(0); ~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // multiple delete operator var ResultIsBoolean13 = delete delete STRING; ~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. var ResultIsBoolean14 = delete delete delete (STRING + STRING); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. ~~~~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. // miss assignment operators delete ""; ~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete STRING; ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete STRING1; ~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete foo(); ~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete objA.a,M.n; \ No newline at end of file diff --git a/tests/baselines/reference/deleteReadonly.errors.txt b/tests/baselines/reference/deleteReadonly.errors.txt index fbcfbc3bbc974..a91148c2b88f0 100644 --- a/tests/baselines/reference/deleteReadonly.errors.txt +++ b/tests/baselines/reference/deleteReadonly.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/deleteReadonly.ts(8,8): error TS2704: The operand of a delete operator cannot be a read-only property. +tests/cases/compiler/deleteReadonly.ts(8,8): error TS2704: The operand of a 'delete' operator cannot be a read-only property. tests/cases/compiler/deleteReadonly.ts(18,8): error TS2542: Index signature in type 'B' only permits reading. tests/cases/compiler/deleteReadonly.ts(20,12): error TS2542: Index signature in type 'B' only permits reading. @@ -13,7 +13,7 @@ tests/cases/compiler/deleteReadonly.ts(20,12): error TS2542: Index signature in delete a.b; ~~~ -!!! error TS2704: The operand of a delete operator cannot be a read-only property. +!!! error TS2704: The operand of a 'delete' operator cannot be a read-only property. interface B { readonly [k: string]: string diff --git a/tests/baselines/reference/derivedClassParameterProperties.errors.txt b/tests/baselines/reference/derivedClassParameterProperties.errors.txt index 27bb9af63a1a6..a29632acafa90 100644 --- a/tests/baselines/reference/derivedClassParameterProperties.errors.txt +++ b/tests/baselines/reference/derivedClassParameterProperties.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(15,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. -tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(30,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(15,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. +tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(30,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(47,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. -tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(56,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(56,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(57,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(58,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. -tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(79,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(79,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(80,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(81,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. @@ -32,7 +32,7 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~~~~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. } class Derived3 extends Base { @@ -52,7 +52,7 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~~~~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. } class Derived5 extends Base { @@ -91,7 +91,7 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~~~~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. } class Derived8 extends Base { @@ -124,7 +124,7 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP ~~~~~~~~~~~~~~~~~~~~~~~~~ } ~~~~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. } class Derived10 extends Base2 { diff --git a/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt b/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt index 5070f0ad9d27e..c4ad23635cb8f 100644 --- a/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt +++ b/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt @@ -1,27 +1,27 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(4,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(4,1): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(4,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(4,8): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(5,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(5,1): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(5,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(5,8): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(6,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(6,1): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(6,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(6,8): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(7,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(7,1): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(7,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(7,8): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(10,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(10,6): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(10,13): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(10,13): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(11,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(11,6): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(11,13): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(11,13): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(12,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(12,6): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(12,13): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(12,13): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(13,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(13,6): error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(13,13): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(13,13): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(15,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(15,1): error TS17006: An unary expression with the 'typeof' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(16,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. @@ -109,28 +109,28 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxE ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete ++temp ** 3; ~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete temp-- ** 3; ~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete temp++ ** 3; ~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** delete --temp ** 3; @@ -139,28 +139,28 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxE ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** delete ++temp ** 3; ~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** delete temp-- ** 3; ~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** delete temp++ ** 3; ~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'delete' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. typeof --temp ** 3; ~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.errors.txt b/tests/baselines/reference/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.errors.txt index 67cad463c4fff..44bf57340d5be 100644 --- a/tests/baselines/reference/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.errors.txt +++ b/tests/baselines/reference/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.errors.txt @@ -19,21 +19,21 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInv tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(25,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(26,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(28,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(28,9): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(28,9): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(29,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(29,9): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(29,9): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(30,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(30,9): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(30,9): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(31,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(31,9): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(31,9): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(33,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(33,14): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(33,14): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(34,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(34,14): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(34,14): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(35,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(35,14): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(35,14): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(36,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(36,14): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts(36,14): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInvalidSimpleUnaryExpressionOperands.ts (36 errors) ==== @@ -108,40 +108,40 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithInv ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. (delete ++temp) ** 3; ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. (delete temp--) ** 3; ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. (delete temp++) ** 3; ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** (delete --temp) ** 3; ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** (delete ++temp) ** 3; ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** (delete temp--) ** 3; ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. 1 ** (delete temp++) ** 3; ~~~~~~~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationBindStrictModeErrors.errors.txt b/tests/baselines/reference/jsFileCompilationBindStrictModeErrors.errors.txt index ed19b5c4a9b89..f2d68282c67fd 100644 --- a/tests/baselines/reference/jsFileCompilationBindStrictModeErrors.errors.txt +++ b/tests/baselines/reference/jsFileCompilationBindStrictModeErrors.errors.txt @@ -2,7 +2,7 @@ tests/cases/compiler/a.js(5,5): error TS1117: An object literal cannot have mult tests/cases/compiler/a.js(5,5): error TS2300: Duplicate identifier 'a'. tests/cases/compiler/a.js(7,5): error TS1212: Identifier expected. 'let' is a reserved word in strict mode. tests/cases/compiler/a.js(8,8): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/compiler/a.js(8,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/compiler/a.js(8,8): error TS2703: The operand of a 'delete' operator must be a property reference. tests/cases/compiler/a.js(10,10): error TS1100: Invalid use of 'eval' in strict mode. tests/cases/compiler/a.js(12,10): error TS1100: Invalid use of 'arguments' in strict mode. tests/cases/compiler/a.js(15,1): error TS1101: 'with' statements are not allowed in strict mode. @@ -33,7 +33,7 @@ tests/cases/compiler/d.js(2,11): error TS1005: ',' expected. ~ !!! error TS1102: 'delete' cannot be called on an identifier in strict mode. ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. try { } catch (eval) { // error ~~~~ diff --git a/tests/baselines/reference/jsdocPrivateName1.errors.txt b/tests/baselines/reference/jsdocPrivateName1.errors.txt new file mode 100644 index 0000000000000..503b1fdb3d6f4 --- /dev/null +++ b/tests/baselines/reference/jsdocPrivateName1.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/jsdoc/jsdocPrivateName1.js(3,5): error TS2322: Type '3' is not assignable to type 'boolean'. + + +==== tests/cases/conformance/jsdoc/jsdocPrivateName1.js (1 errors) ==== + class A { + /** @type {boolean} some number value */ + #foo = 3 // Error because not assignable to boolean + ~~~~ +!!! error TS2322: Type '3' is not assignable to type 'boolean'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocPrivateName1.symbols b/tests/baselines/reference/jsdocPrivateName1.symbols new file mode 100644 index 0000000000000..376b5f6375fb8 --- /dev/null +++ b/tests/baselines/reference/jsdocPrivateName1.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/jsdocPrivateName1.js === +class A { +>A : Symbol(A, Decl(jsdocPrivateName1.js, 0, 0)) + + /** @type {boolean} some number value */ + #foo = 3 // Error because not assignable to boolean +>#foo : Symbol(A.#foo, Decl(jsdocPrivateName1.js, 0, 9)) +} + diff --git a/tests/baselines/reference/jsdocPrivateName1.types b/tests/baselines/reference/jsdocPrivateName1.types new file mode 100644 index 0000000000000..41ada9660d5e0 --- /dev/null +++ b/tests/baselines/reference/jsdocPrivateName1.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/jsdoc/jsdocPrivateName1.js === +class A { +>A : A + + /** @type {boolean} some number value */ + #foo = 3 // Error because not assignable to boolean +>#foo : boolean +>3 : 3 +} + diff --git a/tests/baselines/reference/jsdocPrivateName2.errors.txt b/tests/baselines/reference/jsdocPrivateName2.errors.txt new file mode 100644 index 0000000000000..84f90a2e8251a --- /dev/null +++ b/tests/baselines/reference/jsdocPrivateName2.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/jsdoc/jsdocPrivateName1.js(6,23): error TS1003: Identifier expected. + + +==== tests/cases/conformance/jsdoc/jsdocPrivateName1.js (1 errors) ==== + // Expecting parse error for private field + + /** + * @typedef A + * @type {object} + * @property {string} #id + +!!! error TS1003: Identifier expected. + */ + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocPrivateName2.symbols b/tests/baselines/reference/jsdocPrivateName2.symbols new file mode 100644 index 0000000000000..756c4657c6f5c --- /dev/null +++ b/tests/baselines/reference/jsdocPrivateName2.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/jsdoc/jsdocPrivateName1.js === +// Expecting parse error for private field +No type information for this code. +No type information for this code./** +No type information for this code. * @typedef A +No type information for this code. * @type {object} +No type information for this code. * @property {string} #id +No type information for this code. */ +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/jsdocPrivateName2.types b/tests/baselines/reference/jsdocPrivateName2.types new file mode 100644 index 0000000000000..756c4657c6f5c --- /dev/null +++ b/tests/baselines/reference/jsdocPrivateName2.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/jsdoc/jsdocPrivateName1.js === +// Expecting parse error for private field +No type information for this code. +No type information for this code./** +No type information for this code. * @typedef A +No type information for this code. * @type {object} +No type information for this code. * @property {string} #id +No type information for this code. */ +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/parserStrictMode15.errors.txt b/tests/baselines/reference/parserStrictMode15.errors.txt index e3d381761308d..f610086d80651 100644 --- a/tests/baselines/reference/parserStrictMode15.errors.txt +++ b/tests/baselines/reference/parserStrictMode15.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode15.ts(2,8): error TS1102: 'delete' cannot be called on an identifier in strict mode. tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode15.ts(2,8): error TS2304: Cannot find name 'a'. -tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode15.ts(2,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode15.ts(2,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode15.ts (3 errors) ==== @@ -11,4 +11,4 @@ tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode15.ts(2,8) ~ !!! error TS2304: Cannot find name 'a'. ~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/baselines/reference/parserStrictMode16.errors.txt b/tests/baselines/reference/parserStrictMode16.errors.txt index 4761f0a94b43e..989e3614ce7ea 100644 --- a/tests/baselines/reference/parserStrictMode16.errors.txt +++ b/tests/baselines/reference/parserStrictMode16.errors.txt @@ -1,20 +1,20 @@ -tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(2,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(3,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(4,8): error TS2703: The operand of a delete operator must be a property reference. -tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(5,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(2,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(3,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(4,8): error TS2703: The operand of a 'delete' operator must be a property reference. +tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts(5,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode16.ts (4 errors) ==== "use strict"; delete this; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete 1; ~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete null; ~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. +!!! error TS2703: The operand of a 'delete' operator must be a property reference. delete "a"; ~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/baselines/reference/privateNameAndAny.errors.txt b/tests/baselines/reference/privateNameAndAny.errors.txt new file mode 100644 index 0000000000000..95130d6af41f5 --- /dev/null +++ b/tests/baselines/reference/privateNameAndAny.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts(5,15): error TS2339: Property '#bar' does not exist on type 'any'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts (1 errors) ==== + class A { + #foo = true; + method(thing: any) { + thing.#foo; // OK + thing.#bar; // Error + ~~~~ +!!! error TS2339: Property '#bar' does not exist on type 'any'. + } + }; + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameAndAny.js b/tests/baselines/reference/privateNameAndAny.js new file mode 100644 index 0000000000000..83399f4aa4c8c --- /dev/null +++ b/tests/baselines/reference/privateNameAndAny.js @@ -0,0 +1,30 @@ +//// [privateNameAndAny.ts] +class A { + #foo = true; + method(thing: any) { + thing.#foo; // OK + thing.#bar; // Error + } +}; + + +//// [privateNameAndAny.js] +"use strict"; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo; +class A { + constructor() { + _foo.set(this, true); + } + method(thing) { + __classPrivateFieldGet(thing, _foo); // OK + thing.; // Error + } +} +_foo = new WeakMap(); +; diff --git a/tests/baselines/reference/privateNameAndAny.symbols b/tests/baselines/reference/privateNameAndAny.symbols new file mode 100644 index 0000000000000..070938340cbe1 --- /dev/null +++ b/tests/baselines/reference/privateNameAndAny.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts === +class A { +>A : Symbol(A, Decl(privateNameAndAny.ts, 0, 0)) + + #foo = true; +>#foo : Symbol(A.#foo, Decl(privateNameAndAny.ts, 0, 9)) + + method(thing: any) { +>method : Symbol(A.method, Decl(privateNameAndAny.ts, 1, 16)) +>thing : Symbol(thing, Decl(privateNameAndAny.ts, 2, 11)) + + thing.#foo; // OK +>thing : Symbol(thing, Decl(privateNameAndAny.ts, 2, 11)) + + thing.#bar; // Error +>thing : Symbol(thing, Decl(privateNameAndAny.ts, 2, 11)) + } +}; + diff --git a/tests/baselines/reference/privateNameAndAny.types b/tests/baselines/reference/privateNameAndAny.types new file mode 100644 index 0000000000000..89eed87858d61 --- /dev/null +++ b/tests/baselines/reference/privateNameAndAny.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts === +class A { +>A : A + + #foo = true; +>#foo : boolean +>true : true + + method(thing: any) { +>method : (thing: any) => void +>thing : any + + thing.#foo; // OK +>thing.#foo : any +>thing : any + + thing.#bar; // Error +>thing.#bar : any +>thing : any + } +}; + diff --git a/tests/baselines/reference/privateNameAndIndexSignature.errors.txt b/tests/baselines/reference/privateNameAndIndexSignature.errors.txt index cbe22ffb7c156..9270239b27231 100644 --- a/tests/baselines/reference/privateNameAndIndexSignature.errors.txt +++ b/tests/baselines/reference/privateNameAndIndexSignature.errors.txt @@ -1,15 +1,20 @@ +tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts(4,5): error TS7022: '["#bar"]' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts(6,14): error TS2339: Property '#f' does not exist on type 'A'. -==== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts (1 errors) ==== - // @target es6 - +==== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts (2 errors) ==== class A { [k: string]: any; + #foo = 3; + ["#bar"] = this["#bar"] // Error (private identifiers should not prevent circularity checking for computeds) + ~~~~~~~~ +!!! error TS7022: '["#bar"]' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. constructor(message: string) { - this.#f = 3 // Error Property '#f' does not exist on type 'A'. + this.#f = 3 // Error (index signatures do not implicitly declare private names) ~~ !!! error TS2339: Property '#f' does not exist on type 'A'. + this["#foo"] = 3; // Okay (type has index signature and "#foo" does not collide with private identifier #foo) + } } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameAndIndexSignature.js b/tests/baselines/reference/privateNameAndIndexSignature.js index 472406958ec72..693c3900e954f 100644 --- a/tests/baselines/reference/privateNameAndIndexSignature.js +++ b/tests/baselines/reference/privateNameAndIndexSignature.js @@ -1,26 +1,25 @@ //// [privateNameAndIndexSignature.ts] -// @target es6 - class A { [k: string]: any; + #foo = 3; + ["#bar"] = this["#bar"] // Error (private identifiers should not prevent circularity checking for computeds) constructor(message: string) { - this.#f = 3 // Error Property '#f' does not exist on type 'A'. + this.#f = 3 // Error (index signatures do not implicitly declare private names) + this["#foo"] = 3; // Okay (type has index signature and "#foo" does not collide with private identifier #foo) + } } -tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.js(5,15): error TS1003: Identifier expected. - - -==== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.js (1 errors) ==== - "use strict"; - // @target es6 - var A = /** @class */ (function () { - function A(message) { - this. = 3; // Error Property '#f' does not exist on type 'A'. - ~ -!!! error TS1003: Identifier expected. - } - return A; - }()); - \ No newline at end of file +//// [privateNameAndIndexSignature.js] +"use strict"; +var _foo; +class A { + constructor(message) { + _foo.set(this, 3); + this["#bar"] = this["#bar"]; // Error (private identifiers should not prevent circularity checking for computeds) + this. = 3; // Error (index signatures do not implicitly declare private names) + this["#foo"] = 3; // Okay (type has index signature and "#foo" does not collide with private identifier #foo) + } +} +_foo = new WeakMap(); diff --git a/tests/baselines/reference/privateNameAndIndexSignature.symbols b/tests/baselines/reference/privateNameAndIndexSignature.symbols index 609eb3a491779..c1677a01d5dd8 100644 --- a/tests/baselines/reference/privateNameAndIndexSignature.symbols +++ b/tests/baselines/reference/privateNameAndIndexSignature.symbols @@ -1,17 +1,28 @@ === tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) [k: string]: any; ->k : Symbol(k, Decl(privateNameAndIndexSignature.ts, 3, 5)) +>k : Symbol(k, Decl(privateNameAndIndexSignature.ts, 1, 5)) + + #foo = 3; +>#foo : Symbol(A.#foo, Decl(privateNameAndIndexSignature.ts, 1, 21)) + + ["#bar"] = this["#bar"] // Error (private identifiers should not prevent circularity checking for computeds) +>["#bar"] : Symbol(A["#bar"], Decl(privateNameAndIndexSignature.ts, 2, 13)) +>"#bar" : Symbol(A["#bar"], Decl(privateNameAndIndexSignature.ts, 2, 13)) +>this : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) +>"#bar" : Symbol(A["#bar"], Decl(privateNameAndIndexSignature.ts, 2, 13)) constructor(message: string) { >message : Symbol(message, Decl(privateNameAndIndexSignature.ts, 4, 16)) - this.#f = 3 // Error Property '#f' does not exist on type 'A'. + this.#f = 3 // Error (index signatures do not implicitly declare private names) >this : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) + + this["#foo"] = 3; // Okay (type has index signature and "#foo" does not collide with private identifier #foo) +>this : Symbol(A, Decl(privateNameAndIndexSignature.ts, 0, 0)) + } } diff --git a/tests/baselines/reference/privateNameAndIndexSignature.types b/tests/baselines/reference/privateNameAndIndexSignature.types index 47015a920bb28..984139aea38a2 100644 --- a/tests/baselines/reference/privateNameAndIndexSignature.types +++ b/tests/baselines/reference/privateNameAndIndexSignature.types @@ -1,20 +1,37 @@ === tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts === -// @target es6 - class A { >A : A [k: string]: any; >k : string + #foo = 3; +>#foo : number +>3 : 3 + + ["#bar"] = this["#bar"] // Error (private identifiers should not prevent circularity checking for computeds) +>["#bar"] : any +>"#bar" : "#bar" +>this["#bar"] : any +>this : this +>"#bar" : "#bar" + constructor(message: string) { >message : string - this.#f = 3 // Error Property '#f' does not exist on type 'A'. + this.#f = 3 // Error (index signatures do not implicitly declare private names) >this.#f = 3 : 3 >this.#f : any >this : this >3 : 3 + + this["#foo"] = 3; // Okay (type has index signature and "#foo" does not collide with private identifier #foo) +>this["#foo"] = 3 : 3 +>this["#foo"] : any +>this : this +>"#foo" : "#foo" +>3 : 3 + } } diff --git a/tests/baselines/reference/privateNameAndPropertySignature.errors.txt b/tests/baselines/reference/privateNameAndPropertySignature.errors.txt new file mode 100644 index 0000000000000..ef7a8276fdc2a --- /dev/null +++ b/tests/baselines/reference/privateNameAndPropertySignature.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts(2,5): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts(6,5): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts(10,5): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts(12,9): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts(16,28): error TS18016: Private identifiers are not allowed outside class bodies. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts (5 errors) ==== + type A = { + #foo: string + ~~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + } + + interface B { + #foo: string; + ~~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + } + + declare const x: { + #foo: number; + ~~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + bar: { + #baz: string; + ~~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + } + }; + + declare const y: [{ qux: { #quux: 3 } }]; + ~~~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameAndPropertySignature.js b/tests/baselines/reference/privateNameAndPropertySignature.js new file mode 100644 index 0000000000000..602e1159171a5 --- /dev/null +++ b/tests/baselines/reference/privateNameAndPropertySignature.js @@ -0,0 +1,20 @@ +//// [privateNameAndPropertySignature.ts] +type A = { + #foo: string +} + +interface B { + #foo: string; +} + +declare const x: { + #foo: number; + bar: { + #baz: string; + } +}; + +declare const y: [{ qux: { #quux: 3 } }]; + + +//// [privateNameAndPropertySignature.js] diff --git a/tests/baselines/reference/privateNameAndPropertySignature.symbols b/tests/baselines/reference/privateNameAndPropertySignature.symbols new file mode 100644 index 0000000000000..da68133a97edf --- /dev/null +++ b/tests/baselines/reference/privateNameAndPropertySignature.symbols @@ -0,0 +1,34 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts === +type A = { +>A : Symbol(A, Decl(privateNameAndPropertySignature.ts, 0, 0)) + + #foo: string +>#foo : Symbol(#foo, Decl(privateNameAndPropertySignature.ts, 0, 10)) +} + +interface B { +>B : Symbol(B, Decl(privateNameAndPropertySignature.ts, 2, 1)) + + #foo: string; +>#foo : Symbol(B.#foo, Decl(privateNameAndPropertySignature.ts, 4, 13)) +} + +declare const x: { +>x : Symbol(x, Decl(privateNameAndPropertySignature.ts, 8, 13)) + + #foo: number; +>#foo : Symbol(#foo, Decl(privateNameAndPropertySignature.ts, 8, 18)) + + bar: { +>bar : Symbol(bar, Decl(privateNameAndPropertySignature.ts, 9, 17)) + + #baz: string; +>#baz : Symbol(#baz, Decl(privateNameAndPropertySignature.ts, 10, 10)) + } +}; + +declare const y: [{ qux: { #quux: 3 } }]; +>y : Symbol(y, Decl(privateNameAndPropertySignature.ts, 15, 13)) +>qux : Symbol(qux, Decl(privateNameAndPropertySignature.ts, 15, 19)) +>#quux : Symbol(#quux, Decl(privateNameAndPropertySignature.ts, 15, 26)) + diff --git a/tests/baselines/reference/privateNameAndPropertySignature.types b/tests/baselines/reference/privateNameAndPropertySignature.types new file mode 100644 index 0000000000000..d33639a86ceaf --- /dev/null +++ b/tests/baselines/reference/privateNameAndPropertySignature.types @@ -0,0 +1,32 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts === +type A = { +>A : A + + #foo: string +>#foo : string +} + +interface B { + #foo: string; +>#foo : string +} + +declare const x: { +>x : { bar: {}; } + + #foo: number; +>#foo : number + + bar: { +>bar : {} + + #baz: string; +>#baz : string + } +}; + +declare const y: [{ qux: { #quux: 3 } }]; +>y : [{ qux: {}; }] +>qux : {} +>#quux : 3 + diff --git a/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).js b/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).js new file mode 100644 index 0000000000000..caeb43d15a3e9 --- /dev/null +++ b/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).js @@ -0,0 +1,19 @@ +//// [privateNameAndStaticInitializer.ts] +class A { + #foo = 1; + static inst = new A(); + #prop = 2; +} + + + +//// [privateNameAndStaticInitializer.js] +var _foo, _prop; +class A { + constructor() { + _foo.set(this, 1); + _prop.set(this, 2); + } +} +_foo = new WeakMap(), _prop = new WeakMap(); +A.inst = new A(); diff --git a/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).symbols b/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).symbols new file mode 100644 index 0000000000000..2c6f3a53aeae5 --- /dev/null +++ b/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts === +class A { +>A : Symbol(A, Decl(privateNameAndStaticInitializer.ts, 0, 0)) + + #foo = 1; +>#foo : Symbol(A.#foo, Decl(privateNameAndStaticInitializer.ts, 0, 9)) + + static inst = new A(); +>inst : Symbol(A.inst, Decl(privateNameAndStaticInitializer.ts, 1, 11)) +>A : Symbol(A, Decl(privateNameAndStaticInitializer.ts, 0, 0)) + + #prop = 2; +>#prop : Symbol(A.#prop, Decl(privateNameAndStaticInitializer.ts, 2, 24)) +} + + diff --git a/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).types b/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).types new file mode 100644 index 0000000000000..1c6267617ac9d --- /dev/null +++ b/tests/baselines/reference/privateNameAndStaticInitializer(target=es2015).types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts === +class A { +>A : A + + #foo = 1; +>#foo : number +>1 : 1 + + static inst = new A(); +>inst : A +>new A() : A +>A : typeof A + + #prop = 2; +>#prop : number +>2 : 2 +} + + diff --git a/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).js b/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).js new file mode 100644 index 0000000000000..3387d0b4d1a52 --- /dev/null +++ b/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).js @@ -0,0 +1,19 @@ +//// [privateNameAndStaticInitializer.ts] +class A { + #foo = 1; + static inst = new A(); + #prop = 2; +} + + + +//// [privateNameAndStaticInitializer.js] +class A { + constructor() { + this.#foo = 1; + this.#prop = 2; + } + #foo; + #prop; +} +A.inst = new A(); diff --git a/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).symbols b/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).symbols new file mode 100644 index 0000000000000..2c6f3a53aeae5 --- /dev/null +++ b/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts === +class A { +>A : Symbol(A, Decl(privateNameAndStaticInitializer.ts, 0, 0)) + + #foo = 1; +>#foo : Symbol(A.#foo, Decl(privateNameAndStaticInitializer.ts, 0, 9)) + + static inst = new A(); +>inst : Symbol(A.inst, Decl(privateNameAndStaticInitializer.ts, 1, 11)) +>A : Symbol(A, Decl(privateNameAndStaticInitializer.ts, 0, 0)) + + #prop = 2; +>#prop : Symbol(A.#prop, Decl(privateNameAndStaticInitializer.ts, 2, 24)) +} + + diff --git a/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).types b/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).types new file mode 100644 index 0000000000000..1c6267617ac9d --- /dev/null +++ b/tests/baselines/reference/privateNameAndStaticInitializer(target=esnext).types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts === +class A { +>A : A + + #foo = 1; +>#foo : number +>1 : 1 + + static inst = new A(); +>inst : A +>new A() : A +>A : typeof A + + #prop = 2; +>#prop : number +>2 : 2 +} + + diff --git a/tests/baselines/reference/privateNameBadAssignment.errors.txt b/tests/baselines/reference/privateNameBadAssignment.errors.txt new file mode 100644 index 0000000000000..c88e936af9818 --- /dev/null +++ b/tests/baselines/reference/privateNameBadAssignment.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts(1,1): error TS2304: Cannot find name 'exports'. +tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts(1,9): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts(3,13): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts(6,3): error TS2339: Property '#foo' does not exist on type 'typeof B'. +tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts(11,9): error TS2304: Cannot find name 'exports'. +tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts(12,14): error TS2339: Property '#foo' does not exist on type 'C'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts (6 errors) ==== + exports.#nope = 1; // Error (outside class body) + ~~~~~~~ +!!! error TS2304: Cannot find name 'exports'. + ~~~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + function A() { } + A.prototype.#no = 2; // Error (outside class body) + ~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + + class B {} + B.#foo = 3; // Error (outside class body) + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'typeof B'. + + class C { + #bar = 6; + constructor () { + exports.#bar = 6; // Error + ~~~~~~~ +!!! error TS2304: Cannot find name 'exports'. + this.#foo = 3; // Error (undeclared) + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'C'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameBadAssignment.js b/tests/baselines/reference/privateNameBadAssignment.js new file mode 100644 index 0000000000000..a3f937396b0f6 --- /dev/null +++ b/tests/baselines/reference/privateNameBadAssignment.js @@ -0,0 +1,40 @@ +//// [privateNameBadAssignment.ts] +exports.#nope = 1; // Error (outside class body) +function A() { } +A.prototype.#no = 2; // Error (outside class body) + +class B {} +B.#foo = 3; // Error (outside class body) + +class C { + #bar = 6; + constructor () { + exports.#bar = 6; // Error + this.#foo = 3; // Error (undeclared) + } +} + + +//// [privateNameBadAssignment.js] +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var _bar; +exports. = 1; // Error (outside class body) +function A() { } +A.prototype. = 2; // Error (outside class body) +class B { +} +B. = 3; // Error (outside class body) +class C { + constructor() { + _bar.set(this, 6); + __classPrivateFieldSet(exports, _bar, 6); // Error + this. = 3; // Error (undeclared) + } +} +_bar = new WeakMap(); diff --git a/tests/baselines/reference/privateNameBadAssignment.symbols b/tests/baselines/reference/privateNameBadAssignment.symbols new file mode 100644 index 0000000000000..414484f702ee1 --- /dev/null +++ b/tests/baselines/reference/privateNameBadAssignment.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts === +exports.#nope = 1; // Error (outside class body) +function A() { } +>A : Symbol(A, Decl(privateNameBadAssignment.ts, 0, 18)) + +A.prototype.#no = 2; // Error (outside class body) +>A.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>A : Symbol(A, Decl(privateNameBadAssignment.ts, 0, 18)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) + +class B {} +>B : Symbol(B, Decl(privateNameBadAssignment.ts, 2, 20)) + +B.#foo = 3; // Error (outside class body) +>B : Symbol(B, Decl(privateNameBadAssignment.ts, 2, 20)) + +class C { +>C : Symbol(C, Decl(privateNameBadAssignment.ts, 5, 11)) + + #bar = 6; +>#bar : Symbol(C.#bar, Decl(privateNameBadAssignment.ts, 7, 9)) + + constructor () { + exports.#bar = 6; // Error + this.#foo = 3; // Error (undeclared) +>this : Symbol(C, Decl(privateNameBadAssignment.ts, 5, 11)) + } +} + diff --git a/tests/baselines/reference/privateNameBadAssignment.types b/tests/baselines/reference/privateNameBadAssignment.types new file mode 100644 index 0000000000000..3562dab3f4799 --- /dev/null +++ b/tests/baselines/reference/privateNameBadAssignment.types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts === +exports.#nope = 1; // Error (outside class body) +>exports.#nope = 1 : 1 +>exports.#nope : any +>exports : any +>1 : 1 + +function A() { } +>A : () => void + +A.prototype.#no = 2; // Error (outside class body) +>A.prototype.#no = 2 : 2 +>A.prototype.#no : any +>A.prototype : any +>A : () => void +>prototype : any +>2 : 2 + +class B {} +>B : B + +B.#foo = 3; // Error (outside class body) +>B.#foo = 3 : 3 +>B.#foo : any +>B : typeof B +>3 : 3 + +class C { +>C : C + + #bar = 6; +>#bar : number +>6 : 6 + + constructor () { + exports.#bar = 6; // Error +>exports.#bar = 6 : 6 +>exports.#bar : any +>exports : any +>6 : 6 + + this.#foo = 3; // Error (undeclared) +>this.#foo = 3 : 3 +>this.#foo : any +>this : this +>3 : 3 + } +} + diff --git a/tests/baselines/reference/privateNameBadDeclaration.errors.txt b/tests/baselines/reference/privateNameBadDeclaration.errors.txt new file mode 100644 index 0000000000000..71cf3f2089a2a --- /dev/null +++ b/tests/baselines/reference/privateNameBadDeclaration.errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts(3,3): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts(7,3): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts(11,10): error TS2339: Property '#z' does not exist on type 'C'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts (3 errors) ==== + function A() { } + A.prototype = { + #x: 1 // Error + ~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + } + class B { } + B.prototype = { + #y: 2 // Error + ~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + } + class C { + constructor() { + this.#z = 3; + ~~ +!!! error TS2339: Property '#z' does not exist on type 'C'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameBadDeclaration.js b/tests/baselines/reference/privateNameBadDeclaration.js new file mode 100644 index 0000000000000..068720a03a8cf --- /dev/null +++ b/tests/baselines/reference/privateNameBadDeclaration.js @@ -0,0 +1,34 @@ +//// [privateNameBadDeclaration.ts] +function A() { } +A.prototype = { + #x: 1 // Error +} +class B { } +B.prototype = { + #y: 2 // Error +} +class C { + constructor() { + this.#z = 3; + } +} + +//// [privateNameBadDeclaration.js] +function A() { } +A.prototype = { + : 1 // Error +}; +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +B.prototype = { + : 2 // Error +}; +var C = /** @class */ (function () { + function C() { + this. = 3; + } + return C; +}()); diff --git a/tests/baselines/reference/privateNameBadDeclaration.symbols b/tests/baselines/reference/privateNameBadDeclaration.symbols new file mode 100644 index 0000000000000..d689169f7115f --- /dev/null +++ b/tests/baselines/reference/privateNameBadDeclaration.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts === +function A() { } +>A : Symbol(A, Decl(privateNameBadDeclaration.ts, 0, 0)) + +A.prototype = { +>A.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>A : Symbol(A, Decl(privateNameBadDeclaration.ts, 0, 0)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) + + #x: 1 // Error +>#x : Symbol(#x, Decl(privateNameBadDeclaration.ts, 1, 15)) +} +class B { } +>B : Symbol(B, Decl(privateNameBadDeclaration.ts, 3, 1)) + +B.prototype = { +>B.prototype : Symbol(B.prototype) +>B : Symbol(B, Decl(privateNameBadDeclaration.ts, 3, 1)) +>prototype : Symbol(B.prototype) + + #y: 2 // Error +>#y : Symbol(#y, Decl(privateNameBadDeclaration.ts, 5, 15)) +} +class C { +>C : Symbol(C, Decl(privateNameBadDeclaration.ts, 7, 1)) + + constructor() { + this.#z = 3; +>this : Symbol(C, Decl(privateNameBadDeclaration.ts, 7, 1)) + } +} diff --git a/tests/baselines/reference/privateNameBadDeclaration.types b/tests/baselines/reference/privateNameBadDeclaration.types new file mode 100644 index 0000000000000..a84048bde966c --- /dev/null +++ b/tests/baselines/reference/privateNameBadDeclaration.types @@ -0,0 +1,40 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts === +function A() { } +>A : () => void + +A.prototype = { +>A.prototype = { #x: 1 // Error} : {} +>A.prototype : any +>A : () => void +>prototype : any +>{ #x: 1 // Error} : {} + + #x: 1 // Error +>#x : number +>1 : 1 +} +class B { } +>B : B + +B.prototype = { +>B.prototype = { #y: 2 // Error} : {} +>B.prototype : B +>B : typeof B +>prototype : B +>{ #y: 2 // Error} : {} + + #y: 2 // Error +>#y : number +>2 : 2 +} +class C { +>C : C + + constructor() { + this.#z = 3; +>this.#z = 3 : 3 +>this.#z : any +>this : this +>3 : 3 + } +} diff --git a/tests/baselines/reference/privateNameBadSuper.errors.txt b/tests/baselines/reference/privateNameBadSuper.errors.txt new file mode 100644 index 0000000000000..ece66a5e95cd2 --- /dev/null +++ b/tests/baselines/reference/privateNameBadSuper.errors.txt @@ -0,0 +1,17 @@ +tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts(4,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts (1 errors) ==== + class B {}; + class A extends B { + #x; + constructor() { + ~~~~~~~~~~~~~~~ + void 0; // Error: 'super' call must come first + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + super(); + ~~~~~~~~~~~~~~~~ + } + ~~~~~ +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. + } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameBadSuper.js b/tests/baselines/reference/privateNameBadSuper.js new file mode 100644 index 0000000000000..be1b0e6ea619a --- /dev/null +++ b/tests/baselines/reference/privateNameBadSuper.js @@ -0,0 +1,23 @@ +//// [privateNameBadSuper.ts] +class B {}; +class A extends B { + #x; + constructor() { + void 0; // Error: 'super' call must come first + super(); + } +} + +//// [privateNameBadSuper.js] +var _x; +class B { +} +; +class A extends B { + constructor() { + _x.set(this, void 0); + void 0; // Error: 'super' call must come first + super(); + } +} +_x = new WeakMap(); diff --git a/tests/baselines/reference/privateNameBadSuper.symbols b/tests/baselines/reference/privateNameBadSuper.symbols new file mode 100644 index 0000000000000..4af1f8feb9c29 --- /dev/null +++ b/tests/baselines/reference/privateNameBadSuper.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts === +class B {}; +>B : Symbol(B, Decl(privateNameBadSuper.ts, 0, 0)) + +class A extends B { +>A : Symbol(A, Decl(privateNameBadSuper.ts, 0, 11)) +>B : Symbol(B, Decl(privateNameBadSuper.ts, 0, 0)) + + #x; +>#x : Symbol(A.#x, Decl(privateNameBadSuper.ts, 1, 19)) + + constructor() { + void 0; // Error: 'super' call must come first + super(); +>super : Symbol(B, Decl(privateNameBadSuper.ts, 0, 0)) + } +} diff --git a/tests/baselines/reference/privateNameBadSuper.types b/tests/baselines/reference/privateNameBadSuper.types new file mode 100644 index 0000000000000..5029155262fab --- /dev/null +++ b/tests/baselines/reference/privateNameBadSuper.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts === +class B {}; +>B : B + +class A extends B { +>A : A +>B : B + + #x; +>#x : any + + constructor() { + void 0; // Error: 'super' call must come first +>void 0 : undefined +>0 : 0 + + super(); +>super() : void +>super : typeof B + } +} diff --git a/tests/baselines/reference/privateNameCircularReference.errors.txt b/tests/baselines/reference/privateNameCircularReference.errors.txt new file mode 100644 index 0000000000000..a4200829485ef --- /dev/null +++ b/tests/baselines/reference/privateNameCircularReference.errors.txt @@ -0,0 +1,22 @@ +tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts(2,5): error TS7022: '#foo' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts(2,17): error TS2729: Property '#bar' is used before its initialization. +tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts(3,5): error TS7022: '#bar' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts(4,5): error TS7022: '["#baz"]' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts (4 errors) ==== + class A { + #foo = this.#bar; + ~~~~ +!!! error TS7022: '#foo' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + ~~~~ +!!! error TS2729: Property '#bar' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts:3:5: '#bar' is declared here. + #bar = this.#foo; + ~~~~ +!!! error TS7022: '#bar' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + ["#baz"] = this["#baz"]; // Error (should *not* be private name error) + ~~~~~~~~ +!!! error TS7022: '["#baz"]' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameCircularReference.js b/tests/baselines/reference/privateNameCircularReference.js new file mode 100644 index 0000000000000..7d3ef6d1d022d --- /dev/null +++ b/tests/baselines/reference/privateNameCircularReference.js @@ -0,0 +1,25 @@ +//// [privateNameCircularReference.ts] +class A { + #foo = this.#bar; + #bar = this.#foo; + ["#baz"] = this["#baz"]; // Error (should *not* be private name error) +} + + +//// [privateNameCircularReference.js] +"use strict"; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo, _bar; +class A { + constructor() { + _foo.set(this, __classPrivateFieldGet(this, _bar)); + _bar.set(this, __classPrivateFieldGet(this, _foo)); + this["#baz"] = this["#baz"]; // Error (should *not* be private name error) + } +} +_foo = new WeakMap(), _bar = new WeakMap(); diff --git a/tests/baselines/reference/privateNameCircularReference.symbols b/tests/baselines/reference/privateNameCircularReference.symbols new file mode 100644 index 0000000000000..30506ba5b5148 --- /dev/null +++ b/tests/baselines/reference/privateNameCircularReference.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts === +class A { +>A : Symbol(A, Decl(privateNameCircularReference.ts, 0, 0)) + + #foo = this.#bar; +>#foo : Symbol(A.#foo, Decl(privateNameCircularReference.ts, 0, 9)) +>this.#bar : Symbol(A.#bar, Decl(privateNameCircularReference.ts, 1, 21)) +>this : Symbol(A, Decl(privateNameCircularReference.ts, 0, 0)) + + #bar = this.#foo; +>#bar : Symbol(A.#bar, Decl(privateNameCircularReference.ts, 1, 21)) +>this.#foo : Symbol(A.#foo, Decl(privateNameCircularReference.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameCircularReference.ts, 0, 0)) + + ["#baz"] = this["#baz"]; // Error (should *not* be private name error) +>["#baz"] : Symbol(A["#baz"], Decl(privateNameCircularReference.ts, 2, 21)) +>"#baz" : Symbol(A["#baz"], Decl(privateNameCircularReference.ts, 2, 21)) +>this : Symbol(A, Decl(privateNameCircularReference.ts, 0, 0)) +>"#baz" : Symbol(A["#baz"], Decl(privateNameCircularReference.ts, 2, 21)) +} + diff --git a/tests/baselines/reference/privateNameCircularReference.types b/tests/baselines/reference/privateNameCircularReference.types new file mode 100644 index 0000000000000..678786d7fd492 --- /dev/null +++ b/tests/baselines/reference/privateNameCircularReference.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts === +class A { +>A : A + + #foo = this.#bar; +>#foo : any +>this.#bar : any +>this : this + + #bar = this.#foo; +>#bar : any +>this.#foo : any +>this : this + + ["#baz"] = this["#baz"]; // Error (should *not* be private name error) +>["#baz"] : any +>"#baz" : "#baz" +>this["#baz"] : any +>this : this +>"#baz" : "#baz" +} + diff --git a/tests/baselines/reference/privateNameConstructorReserved.errors.txt b/tests/baselines/reference/privateNameConstructorReserved.errors.txt index a387876bce30e..4cc4131338f00 100644 --- a/tests/baselines/reference/privateNameConstructorReserved.errors.txt +++ b/tests/baselines/reference/privateNameConstructorReserved.errors.txt @@ -1,12 +1,13 @@ -tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts(4,5): error TS18012: '#constructor' is a reserved word. +tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts(2,5): error TS18012: '#constructor' is a reserved word. +tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts(2,5): error TS18022: A method cannot be named with a private identifier. -==== tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts (1 errors) ==== - // @target es6 - +==== tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts (2 errors) ==== class A { #constructor() {} // Error: `#constructor` is a reserved word. ~~~~~~~~~~~~ !!! error TS18012: '#constructor' is a reserved word. + ~~~~~~~~~~~~ +!!! error TS18022: A method cannot be named with a private identifier. } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameConstructorReserved.js b/tests/baselines/reference/privateNameConstructorReserved.js index cab7f6b3e729e..54cae241f51da 100644 --- a/tests/baselines/reference/privateNameConstructorReserved.js +++ b/tests/baselines/reference/privateNameConstructorReserved.js @@ -1,16 +1,10 @@ //// [privateNameConstructorReserved.ts] -// @target es6 - class A { #constructor() {} // Error: `#constructor` is a reserved word. } //// [privateNameConstructorReserved.js] -// @target es6 -var A = /** @class */ (function () { - function A() { - } - A.prototype[] = function () { }; // Error: `#constructor` is a reserved word. - return A; -}()); +class A { + () { } // Error: `#constructor` is a reserved word. +} diff --git a/tests/baselines/reference/privateNameConstructorReserved.symbols b/tests/baselines/reference/privateNameConstructorReserved.symbols index 3f3cbc722039f..f2fa74c1f703e 100644 --- a/tests/baselines/reference/privateNameConstructorReserved.symbols +++ b/tests/baselines/reference/privateNameConstructorReserved.symbols @@ -1,10 +1,8 @@ === tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNameConstructorReserved.ts, 0, 0)) #constructor() {} // Error: `#constructor` is a reserved word. ->#constructor : Symbol(A.#constructor, Decl(privateNameConstructorReserved.ts, 2, 9)) +>#constructor : Symbol(A.#constructor, Decl(privateNameConstructorReserved.ts, 0, 9)) } diff --git a/tests/baselines/reference/privateNameConstructorReserved.types b/tests/baselines/reference/privateNameConstructorReserved.types index 2b75281b7a02e..f5e646b9a2190 100644 --- a/tests/baselines/reference/privateNameConstructorReserved.types +++ b/tests/baselines/reference/privateNameConstructorReserved.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts === -// @target es6 - class A { >A : A diff --git a/tests/baselines/reference/privateNameConstructorSignature.js b/tests/baselines/reference/privateNameConstructorSignature.js new file mode 100644 index 0000000000000..d468fc32d31a5 --- /dev/null +++ b/tests/baselines/reference/privateNameConstructorSignature.js @@ -0,0 +1,40 @@ +//// [privateNameConstructorSignature.ts] +interface D { + x: number; +} +class C { + #x; + static test() { + new C().#x = 10; + const y = new C(); + const z = new y(); + z.x = 123; + } +} +interface C { + new (): D; +} + + + +//// [privateNameConstructorSignature.js] +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var _x; +class C { + constructor() { + _x.set(this, void 0); + } + static test() { + __classPrivateFieldSet(new C(), _x, 10); + const y = new C(); + const z = new y(); + z.x = 123; + } +} +_x = new WeakMap(); diff --git a/tests/baselines/reference/privateNameConstructorSignature.symbols b/tests/baselines/reference/privateNameConstructorSignature.symbols new file mode 100644 index 0000000000000..7c0afa25b1ad4 --- /dev/null +++ b/tests/baselines/reference/privateNameConstructorSignature.symbols @@ -0,0 +1,42 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameConstructorSignature.ts === +interface D { +>D : Symbol(D, Decl(privateNameConstructorSignature.ts, 0, 0)) + + x: number; +>x : Symbol(D.x, Decl(privateNameConstructorSignature.ts, 0, 13)) +} +class C { +>C : Symbol(C, Decl(privateNameConstructorSignature.ts, 2, 1), Decl(privateNameConstructorSignature.ts, 11, 1)) + + #x; +>#x : Symbol(C.#x, Decl(privateNameConstructorSignature.ts, 3, 9)) + + static test() { +>test : Symbol(C.test, Decl(privateNameConstructorSignature.ts, 4, 7)) + + new C().#x = 10; +>new C().#x : Symbol(C.#x, Decl(privateNameConstructorSignature.ts, 3, 9)) +>C : Symbol(C, Decl(privateNameConstructorSignature.ts, 2, 1), Decl(privateNameConstructorSignature.ts, 11, 1)) + + const y = new C(); +>y : Symbol(y, Decl(privateNameConstructorSignature.ts, 7, 13)) +>C : Symbol(C, Decl(privateNameConstructorSignature.ts, 2, 1), Decl(privateNameConstructorSignature.ts, 11, 1)) + + const z = new y(); +>z : Symbol(z, Decl(privateNameConstructorSignature.ts, 8, 13)) +>y : Symbol(y, Decl(privateNameConstructorSignature.ts, 7, 13)) + + z.x = 123; +>z.x : Symbol(D.x, Decl(privateNameConstructorSignature.ts, 0, 13)) +>z : Symbol(z, Decl(privateNameConstructorSignature.ts, 8, 13)) +>x : Symbol(D.x, Decl(privateNameConstructorSignature.ts, 0, 13)) + } +} +interface C { +>C : Symbol(C, Decl(privateNameConstructorSignature.ts, 2, 1), Decl(privateNameConstructorSignature.ts, 11, 1)) + + new (): D; +>D : Symbol(D, Decl(privateNameConstructorSignature.ts, 0, 0)) +} + + diff --git a/tests/baselines/reference/privateNameConstructorSignature.types b/tests/baselines/reference/privateNameConstructorSignature.types new file mode 100644 index 0000000000000..df87063a52707 --- /dev/null +++ b/tests/baselines/reference/privateNameConstructorSignature.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameConstructorSignature.ts === +interface D { + x: number; +>x : number +} +class C { +>C : C + + #x; +>#x : any + + static test() { +>test : () => void + + new C().#x = 10; +>new C().#x = 10 : 10 +>new C().#x : any +>new C() : C +>C : typeof C +>10 : 10 + + const y = new C(); +>y : C +>new C() : C +>C : typeof C + + const z = new y(); +>z : D +>new y() : D +>y : C + + z.x = 123; +>z.x = 123 : 123 +>z.x : number +>z : D +>x : number +>123 : 123 + } +} +interface C { + new (): D; +} + + diff --git a/tests/baselines/reference/privateNameDeclaration.js b/tests/baselines/reference/privateNameDeclaration.js new file mode 100644 index 0000000000000..f8d5f0a017ec3 --- /dev/null +++ b/tests/baselines/reference/privateNameDeclaration.js @@ -0,0 +1,33 @@ +//// [privateNameDeclaration.ts] +class A { + #foo: string; + #bar = 6; + baz: string; + qux = 6; + quux(): void { + + } +} + + +//// [privateNameDeclaration.js] +var _foo, _bar; +class A { + constructor() { + _foo.set(this, void 0); + _bar.set(this, 6); + this.qux = 6; + } + quux() { + } +} +_foo = new WeakMap(), _bar = new WeakMap(); + + +//// [privateNameDeclaration.d.ts] +declare class A { + #private; + baz: string; + qux: number; + quux(): void; +} diff --git a/tests/baselines/reference/privateNameDeclaration.symbols b/tests/baselines/reference/privateNameDeclaration.symbols new file mode 100644 index 0000000000000..a58a3224aa191 --- /dev/null +++ b/tests/baselines/reference/privateNameDeclaration.symbols @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameDeclaration.ts === +class A { +>A : Symbol(A, Decl(privateNameDeclaration.ts, 0, 0)) + + #foo: string; +>#foo : Symbol(A.#foo, Decl(privateNameDeclaration.ts, 0, 9)) + + #bar = 6; +>#bar : Symbol(A.#bar, Decl(privateNameDeclaration.ts, 1, 17)) + + baz: string; +>baz : Symbol(A.baz, Decl(privateNameDeclaration.ts, 2, 13)) + + qux = 6; +>qux : Symbol(A.qux, Decl(privateNameDeclaration.ts, 3, 16)) + + quux(): void { +>quux : Symbol(A.quux, Decl(privateNameDeclaration.ts, 4, 12)) + + } +} + diff --git a/tests/baselines/reference/privateNameDeclaration.types b/tests/baselines/reference/privateNameDeclaration.types new file mode 100644 index 0000000000000..73c2e27d41635 --- /dev/null +++ b/tests/baselines/reference/privateNameDeclaration.types @@ -0,0 +1,24 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameDeclaration.ts === +class A { +>A : A + + #foo: string; +>#foo : string + + #bar = 6; +>#bar : number +>6 : 6 + + baz: string; +>baz : string + + qux = 6; +>qux : number +>6 : 6 + + quux(): void { +>quux : () => void + + } +} + diff --git a/tests/baselines/reference/privateNameDeclarationMerging.errors.txt b/tests/baselines/reference/privateNameDeclarationMerging.errors.txt new file mode 100644 index 0000000000000..b5baea3c74ee3 --- /dev/null +++ b/tests/baselines/reference/privateNameDeclarationMerging.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts(9,11): error TS2339: Property '#x' does not exist on type 'D'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts (1 errors) ==== + class D {}; + + class C { + #x; + foo () { + const c = new C(); + c.#x; // OK + const d: D = new C(); + d.#x; // Error + ~~ +!!! error TS2339: Property '#x' does not exist on type 'D'. + } + } + interface C { + new (): D; + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameDeclarationMerging.js b/tests/baselines/reference/privateNameDeclarationMerging.js new file mode 100644 index 0000000000000..1d278bfed2954 --- /dev/null +++ b/tests/baselines/reference/privateNameDeclarationMerging.js @@ -0,0 +1,40 @@ +//// [privateNameDeclarationMerging.ts] +class D {}; + +class C { + #x; + foo () { + const c = new C(); + c.#x; // OK + const d: D = new C(); + d.#x; // Error + } +} +interface C { + new (): D; +} + + +//// [privateNameDeclarationMerging.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _x; +class D { +} +; +class C { + constructor() { + _x.set(this, void 0); + } + foo() { + const c = new C(); + __classPrivateFieldGet(c, _x); // OK + const d = new C(); + __classPrivateFieldGet(d, _x); // Error + } +} +_x = new WeakMap(); diff --git a/tests/baselines/reference/privateNameDeclarationMerging.symbols b/tests/baselines/reference/privateNameDeclarationMerging.symbols new file mode 100644 index 0000000000000..5a81160c24e53 --- /dev/null +++ b/tests/baselines/reference/privateNameDeclarationMerging.symbols @@ -0,0 +1,37 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts === +class D {}; +>D : Symbol(D, Decl(privateNameDeclarationMerging.ts, 0, 0)) + +class C { +>C : Symbol(C, Decl(privateNameDeclarationMerging.ts, 0, 11), Decl(privateNameDeclarationMerging.ts, 10, 1)) + + #x; +>#x : Symbol(C.#x, Decl(privateNameDeclarationMerging.ts, 2, 9)) + + foo () { +>foo : Symbol(C.foo, Decl(privateNameDeclarationMerging.ts, 3, 7)) + + const c = new C(); +>c : Symbol(c, Decl(privateNameDeclarationMerging.ts, 5, 13)) +>C : Symbol(C, Decl(privateNameDeclarationMerging.ts, 0, 11), Decl(privateNameDeclarationMerging.ts, 10, 1)) + + c.#x; // OK +>c.#x : Symbol(C.#x, Decl(privateNameDeclarationMerging.ts, 2, 9)) +>c : Symbol(c, Decl(privateNameDeclarationMerging.ts, 5, 13)) + + const d: D = new C(); +>d : Symbol(d, Decl(privateNameDeclarationMerging.ts, 7, 13)) +>D : Symbol(D, Decl(privateNameDeclarationMerging.ts, 0, 0)) +>C : Symbol(C, Decl(privateNameDeclarationMerging.ts, 0, 11), Decl(privateNameDeclarationMerging.ts, 10, 1)) + + d.#x; // Error +>d : Symbol(d, Decl(privateNameDeclarationMerging.ts, 7, 13)) + } +} +interface C { +>C : Symbol(C, Decl(privateNameDeclarationMerging.ts, 0, 11), Decl(privateNameDeclarationMerging.ts, 10, 1)) + + new (): D; +>D : Symbol(D, Decl(privateNameDeclarationMerging.ts, 0, 0)) +} + diff --git a/tests/baselines/reference/privateNameDeclarationMerging.types b/tests/baselines/reference/privateNameDeclarationMerging.types new file mode 100644 index 0000000000000..b1e5d6e59caf5 --- /dev/null +++ b/tests/baselines/reference/privateNameDeclarationMerging.types @@ -0,0 +1,36 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts === +class D {}; +>D : D + +class C { +>C : C + + #x; +>#x : any + + foo () { +>foo : () => void + + const c = new C(); +>c : C +>new C() : C +>C : typeof C + + c.#x; // OK +>c.#x : any +>c : C + + const d: D = new C(); +>d : D +>new C() : C +>C : typeof C + + d.#x; // Error +>d.#x : any +>d : D + } +} +interface C { + new (): D; +} + diff --git a/tests/baselines/reference/privateNameDuplicateField.errors.txt b/tests/baselines/reference/privateNameDuplicateField.errors.txt index 4a8428c6102c2..b818eec73b47a 100644 --- a/tests/baselines/reference/privateNameDuplicateField.errors.txt +++ b/tests/baselines/reference/privateNameDuplicateField.errors.txt @@ -1,9 +1,7 @@ -tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts(5,5): error TS2300: Duplicate identifier '#foo'. +tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts(3,5): error TS2300: Duplicate identifier '#foo'. ==== tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts (1 errors) ==== - // @target es6 - class A { #foo = "foo"; #foo = "foo"; diff --git a/tests/baselines/reference/privateNameDuplicateField.js b/tests/baselines/reference/privateNameDuplicateField.js index 66b668a69b531..30b96d7c48b74 100644 --- a/tests/baselines/reference/privateNameDuplicateField.js +++ b/tests/baselines/reference/privateNameDuplicateField.js @@ -1,6 +1,4 @@ //// [privateNameDuplicateField.ts] -// @target es6 - class A { #foo = "foo"; #foo = "foo"; @@ -9,11 +7,11 @@ class A { //// [privateNameDuplicateField.js] "use strict"; -// @target es6 -var A = /** @class */ (function () { - function A() { - this[] = "foo"; - this[] = "foo"; +var _foo, _foo_1; +class A { + constructor() { + _foo_1.set(this, "foo"); + _foo_1.set(this, "foo"); } - return A; -}()); +} +_foo = new WeakMap(), _foo_1 = new WeakMap(); diff --git a/tests/baselines/reference/privateNameDuplicateField.symbols b/tests/baselines/reference/privateNameDuplicateField.symbols index 0da02e645ada3..af627ed139dfe 100644 --- a/tests/baselines/reference/privateNameDuplicateField.symbols +++ b/tests/baselines/reference/privateNameDuplicateField.symbols @@ -1,13 +1,11 @@ === tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNameDuplicateField.ts, 0, 0)) #foo = "foo"; ->#foo : Symbol(A.#foo, Decl(privateNameDuplicateField.ts, 2, 9), Decl(privateNameDuplicateField.ts, 3, 17)) +>#foo : Symbol(A.#foo, Decl(privateNameDuplicateField.ts, 0, 9), Decl(privateNameDuplicateField.ts, 1, 17)) #foo = "foo"; ->#foo : Symbol(A.#foo, Decl(privateNameDuplicateField.ts, 2, 9), Decl(privateNameDuplicateField.ts, 3, 17)) +>#foo : Symbol(A.#foo, Decl(privateNameDuplicateField.ts, 0, 9), Decl(privateNameDuplicateField.ts, 1, 17)) } diff --git a/tests/baselines/reference/privateNameDuplicateField.types b/tests/baselines/reference/privateNameDuplicateField.types index e73152ebd4455..0f67eac2456aa 100644 --- a/tests/baselines/reference/privateNameDuplicateField.types +++ b/tests/baselines/reference/privateNameDuplicateField.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts === -// @target es6 - class A { >A : A diff --git a/tests/baselines/reference/privateNameES5Ban(target=es3).errors.txt b/tests/baselines/reference/privateNameES5Ban(target=es3).errors.txt new file mode 100644 index 0000000000000..2faa86696394d --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es3).errors.txt @@ -0,0 +1,52 @@ +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(3,5): error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(4,5): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(5,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(6,12): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(7,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(7,9): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(8,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(8,9): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(9,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(9,16): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(10,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(10,16): error TS18023: An accessor cannot be named with a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts (12 errors) ==== + class A { + constructor() {} + #field = 123; + ~~~~~~ +!!! error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher. + #method() {} + ~~~~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + static #sField = "hello world"; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + static #sMethod() {} + ~~~~~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + get #acc() { return ""; } + ~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + ~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + set #acc(x: string) {} + ~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + ~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + static get #sAcc() { return 0; } + ~~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + static set #sAcc(x: number) {} + ~~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + } + + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameES5Ban(target=es3).js b/tests/baselines/reference/privateNameES5Ban(target=es3).js new file mode 100644 index 0000000000000..0f273d9e7fc45 --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es3).js @@ -0,0 +1,39 @@ +//// [privateNameES5Ban.ts] +class A { + constructor() {} + #field = 123; + #method() {} + static #sField = "hello world"; + static #sMethod() {} + get #acc() { return ""; } + set #acc(x: string) {} + static get #sAcc() { return 0; } + static set #sAcc(x: number) {} +} + + + +//// [privateNameES5Ban.js] +var A = /** @class */ (function () { + function A() { + _field.set(this, 123); + } + A.prototype. = function () { }; + A. = function () { }; + Object.defineProperty(A.prototype, "", { + get: function () { return ""; }, + set: function (x) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(A, "", { + get: function () { return 0; }, + set: function (x) { }, + enumerable: true, + configurable: true + }); + var _field, _sField; + _field = new WeakMap(), _sField = new WeakMap(); + _sField.set(A, "hello world"); + return A; +}()); diff --git a/tests/baselines/reference/privateNameES5Ban(target=es3).symbols b/tests/baselines/reference/privateNameES5Ban(target=es3).symbols new file mode 100644 index 0000000000000..f332af7cd5b95 --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es3).symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts === +class A { +>A : Symbol(A, Decl(privateNameES5Ban.ts, 0, 0)) + + constructor() {} + #field = 123; +>#field : Symbol(A.#field, Decl(privateNameES5Ban.ts, 1, 20)) + + #method() {} +>#method : Symbol(A.#method, Decl(privateNameES5Ban.ts, 2, 17)) + + static #sField = "hello world"; +>#sField : Symbol(A.#sField, Decl(privateNameES5Ban.ts, 3, 16)) + + static #sMethod() {} +>#sMethod : Symbol(A.#sMethod, Decl(privateNameES5Ban.ts, 4, 35)) + + get #acc() { return ""; } +>#acc : Symbol(A.#acc, Decl(privateNameES5Ban.ts, 5, 24), Decl(privateNameES5Ban.ts, 6, 29)) + + set #acc(x: string) {} +>#acc : Symbol(A.#acc, Decl(privateNameES5Ban.ts, 5, 24), Decl(privateNameES5Ban.ts, 6, 29)) +>x : Symbol(x, Decl(privateNameES5Ban.ts, 7, 13)) + + static get #sAcc() { return 0; } +>#sAcc : Symbol(A.#sAcc, Decl(privateNameES5Ban.ts, 7, 26), Decl(privateNameES5Ban.ts, 8, 36)) + + static set #sAcc(x: number) {} +>#sAcc : Symbol(A.#sAcc, Decl(privateNameES5Ban.ts, 7, 26), Decl(privateNameES5Ban.ts, 8, 36)) +>x : Symbol(x, Decl(privateNameES5Ban.ts, 9, 21)) +} + + diff --git a/tests/baselines/reference/privateNameES5Ban(target=es3).types b/tests/baselines/reference/privateNameES5Ban(target=es3).types new file mode 100644 index 0000000000000..e5b5ee65d4d7b --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es3).types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts === +class A { +>A : A + + constructor() {} + #field = 123; +>#field : number +>123 : 123 + + #method() {} +>#method : () => void + + static #sField = "hello world"; +>#sField : string +>"hello world" : "hello world" + + static #sMethod() {} +>#sMethod : () => void + + get #acc() { return ""; } +>#acc : string +>"" : "" + + set #acc(x: string) {} +>#acc : string +>x : string + + static get #sAcc() { return 0; } +>#sAcc : number +>0 : 0 + + static set #sAcc(x: number) {} +>#sAcc : number +>x : number +} + + diff --git a/tests/baselines/reference/privateNameES5Ban(target=es5).errors.txt b/tests/baselines/reference/privateNameES5Ban(target=es5).errors.txt new file mode 100644 index 0000000000000..9f596efe43b8e --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es5).errors.txt @@ -0,0 +1,40 @@ +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(3,5): error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(4,5): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(5,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(6,12): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(7,9): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(8,9): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(9,16): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts(10,16): error TS18023: An accessor cannot be named with a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts (8 errors) ==== + class A { + constructor() {} + #field = 123; + ~~~~~~ +!!! error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher. + #method() {} + ~~~~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + static #sField = "hello world"; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + static #sMethod() {} + ~~~~~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + get #acc() { return ""; } + ~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + set #acc(x: string) {} + ~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + static get #sAcc() { return 0; } + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + static set #sAcc(x: number) {} + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + } + + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameES5Ban(target=es5).js b/tests/baselines/reference/privateNameES5Ban(target=es5).js new file mode 100644 index 0000000000000..0f273d9e7fc45 --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es5).js @@ -0,0 +1,39 @@ +//// [privateNameES5Ban.ts] +class A { + constructor() {} + #field = 123; + #method() {} + static #sField = "hello world"; + static #sMethod() {} + get #acc() { return ""; } + set #acc(x: string) {} + static get #sAcc() { return 0; } + static set #sAcc(x: number) {} +} + + + +//// [privateNameES5Ban.js] +var A = /** @class */ (function () { + function A() { + _field.set(this, 123); + } + A.prototype. = function () { }; + A. = function () { }; + Object.defineProperty(A.prototype, "", { + get: function () { return ""; }, + set: function (x) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(A, "", { + get: function () { return 0; }, + set: function (x) { }, + enumerable: true, + configurable: true + }); + var _field, _sField; + _field = new WeakMap(), _sField = new WeakMap(); + _sField.set(A, "hello world"); + return A; +}()); diff --git a/tests/baselines/reference/privateNameES5Ban(target=es5).symbols b/tests/baselines/reference/privateNameES5Ban(target=es5).symbols new file mode 100644 index 0000000000000..f332af7cd5b95 --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es5).symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts === +class A { +>A : Symbol(A, Decl(privateNameES5Ban.ts, 0, 0)) + + constructor() {} + #field = 123; +>#field : Symbol(A.#field, Decl(privateNameES5Ban.ts, 1, 20)) + + #method() {} +>#method : Symbol(A.#method, Decl(privateNameES5Ban.ts, 2, 17)) + + static #sField = "hello world"; +>#sField : Symbol(A.#sField, Decl(privateNameES5Ban.ts, 3, 16)) + + static #sMethod() {} +>#sMethod : Symbol(A.#sMethod, Decl(privateNameES5Ban.ts, 4, 35)) + + get #acc() { return ""; } +>#acc : Symbol(A.#acc, Decl(privateNameES5Ban.ts, 5, 24), Decl(privateNameES5Ban.ts, 6, 29)) + + set #acc(x: string) {} +>#acc : Symbol(A.#acc, Decl(privateNameES5Ban.ts, 5, 24), Decl(privateNameES5Ban.ts, 6, 29)) +>x : Symbol(x, Decl(privateNameES5Ban.ts, 7, 13)) + + static get #sAcc() { return 0; } +>#sAcc : Symbol(A.#sAcc, Decl(privateNameES5Ban.ts, 7, 26), Decl(privateNameES5Ban.ts, 8, 36)) + + static set #sAcc(x: number) {} +>#sAcc : Symbol(A.#sAcc, Decl(privateNameES5Ban.ts, 7, 26), Decl(privateNameES5Ban.ts, 8, 36)) +>x : Symbol(x, Decl(privateNameES5Ban.ts, 9, 21)) +} + + diff --git a/tests/baselines/reference/privateNameES5Ban(target=es5).types b/tests/baselines/reference/privateNameES5Ban(target=es5).types new file mode 100644 index 0000000000000..e5b5ee65d4d7b --- /dev/null +++ b/tests/baselines/reference/privateNameES5Ban(target=es5).types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts === +class A { +>A : A + + constructor() {} + #field = 123; +>#field : number +>123 : 123 + + #method() {} +>#method : () => void + + static #sField = "hello world"; +>#sField : string +>"hello world" : "hello world" + + static #sMethod() {} +>#sMethod : () => void + + get #acc() { return ""; } +>#acc : string +>"" : "" + + set #acc(x: string) {} +>#acc : string +>x : string + + static get #sAcc() { return 0; } +>#sAcc : number +>0 : 0 + + static set #sAcc(x: number) {} +>#sAcc : number +>x : number +} + + diff --git a/tests/baselines/reference/privateNameEnum.errors.txt b/tests/baselines/reference/privateNameEnum.errors.txt new file mode 100644 index 0000000000000..52141111ff216 --- /dev/null +++ b/tests/baselines/reference/privateNameEnum.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts(2,5): error TS18024: An enum member cannot be named with a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts (1 errors) ==== + enum E { + #x + ~~ +!!! error TS18024: An enum member cannot be named with a private identifier. + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameEnum.js b/tests/baselines/reference/privateNameEnum.js new file mode 100644 index 0000000000000..2cd562f67eb47 --- /dev/null +++ b/tests/baselines/reference/privateNameEnum.js @@ -0,0 +1,11 @@ +//// [privateNameEnum.ts] +enum E { + #x +} + + +//// [privateNameEnum.js] +var E; +(function (E) { + E[E[] = 0] = ; +})(E || (E = {})); diff --git a/tests/baselines/reference/privateNameEnum.symbols b/tests/baselines/reference/privateNameEnum.symbols new file mode 100644 index 0000000000000..15a7b36f8aed2 --- /dev/null +++ b/tests/baselines/reference/privateNameEnum.symbols @@ -0,0 +1,8 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts === +enum E { +>E : Symbol(E, Decl(privateNameEnum.ts, 0, 0)) + + #x +>#x : Symbol(E.#x, Decl(privateNameEnum.ts, 0, 8)) +} + diff --git a/tests/baselines/reference/privateNameEnum.types b/tests/baselines/reference/privateNameEnum.types new file mode 100644 index 0000000000000..5c85a7058d780 --- /dev/null +++ b/tests/baselines/reference/privateNameEnum.types @@ -0,0 +1,8 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts === +enum E { +>E : E + + #x +>#x : E.__missing +} + diff --git a/tests/baselines/reference/privateNameField.js b/tests/baselines/reference/privateNameField.js index 0ca8b2a817cd9..8803d856771ae 100644 --- a/tests/baselines/reference/privateNameField.js +++ b/tests/baselines/reference/privateNameField.js @@ -1,25 +1,26 @@ //// [privateNameField.ts] -// @target es6 - class A { #name: string; constructor(name: string) { this.#name = name; } -} - -tests/cases/conformance/classes/members/privateNames/privateNameField.js(5,15): error TS1003: Identifier expected. +} -==== tests/cases/conformance/classes/members/privateNames/privateNameField.js (1 errors) ==== - "use strict"; - // @target es6 - var A = /** @class */ (function () { - function A(name) { - this. = name; - ~ -!!! error TS1003: Identifier expected. - } - return A; - }()); - \ No newline at end of file +//// [privateNameField.js] +"use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var _name; +class A { + constructor(name) { + _name.set(this, void 0); + __classPrivateFieldSet(this, _name, name); + } +} +_name = new WeakMap(); diff --git a/tests/baselines/reference/privateNameField.symbols b/tests/baselines/reference/privateNameField.symbols index c37ded65bd1a7..32d4972d162d0 100644 --- a/tests/baselines/reference/privateNameField.symbols +++ b/tests/baselines/reference/privateNameField.symbols @@ -1,18 +1,17 @@ === tests/cases/conformance/classes/members/privateNames/privateNameField.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNameField.ts, 0, 0)) #name: string; ->#name : Symbol(A.#name, Decl(privateNameField.ts, 2, 9)) +>#name : Symbol(A.#name, Decl(privateNameField.ts, 0, 9)) constructor(name: string) { ->name : Symbol(name, Decl(privateNameField.ts, 4, 16)) +>name : Symbol(name, Decl(privateNameField.ts, 2, 16)) this.#name = name; ->this.#name : Symbol(A.#name, Decl(privateNameField.ts, 2, 9)) +>this.#name : Symbol(A.#name, Decl(privateNameField.ts, 0, 9)) >this : Symbol(A, Decl(privateNameField.ts, 0, 0)) ->name : Symbol(name, Decl(privateNameField.ts, 4, 16)) +>name : Symbol(name, Decl(privateNameField.ts, 2, 16)) } } + diff --git a/tests/baselines/reference/privateNameField.types b/tests/baselines/reference/privateNameField.types index db7dba04475e8..2609548a6e02c 100644 --- a/tests/baselines/reference/privateNameField.types +++ b/tests/baselines/reference/privateNameField.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNameField.ts === -// @target es6 - class A { >A : A @@ -17,3 +15,4 @@ class A { >name : string } } + diff --git a/tests/baselines/reference/privateNameFieldAccess.js b/tests/baselines/reference/privateNameFieldAccess.js new file mode 100644 index 0000000000000..35f418690881c --- /dev/null +++ b/tests/baselines/reference/privateNameFieldAccess.js @@ -0,0 +1,24 @@ +//// [privateNameFieldAccess.ts] +class A { + #myField = "hello world"; + constructor() { + console.log(this.#myField); + } +} + + +//// [privateNameFieldAccess.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _myField; +class A { + constructor() { + _myField.set(this, "hello world"); + console.log(__classPrivateFieldGet(this, _myField)); + } +} +_myField = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldAccess.symbols b/tests/baselines/reference/privateNameFieldAccess.symbols new file mode 100644 index 0000000000000..d69eacd7131f9 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldAccess.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldAccess.ts === +class A { +>A : Symbol(A, Decl(privateNameFieldAccess.ts, 0, 0)) + + #myField = "hello world"; +>#myField : Symbol(A.#myField, Decl(privateNameFieldAccess.ts, 0, 9)) + + constructor() { + console.log(this.#myField); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this.#myField : Symbol(A.#myField, Decl(privateNameFieldAccess.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAccess.ts, 0, 0)) + } +} + diff --git a/tests/baselines/reference/privateNameFieldAccess.types b/tests/baselines/reference/privateNameFieldAccess.types new file mode 100644 index 0000000000000..17568587e311d --- /dev/null +++ b/tests/baselines/reference/privateNameFieldAccess.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldAccess.ts === +class A { +>A : A + + #myField = "hello world"; +>#myField : string +>"hello world" : "hello world" + + constructor() { + console.log(this.#myField); +>console.log(this.#myField) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this.#myField : string +>this : this + } +} + diff --git a/tests/baselines/reference/privateNameFieldAssignment.js b/tests/baselines/reference/privateNameFieldAssignment.js new file mode 100644 index 0000000000000..3442958b508ec --- /dev/null +++ b/tests/baselines/reference/privateNameFieldAssignment.js @@ -0,0 +1,88 @@ +//// [privateNameFieldAssignment.ts] +class A { + #field = 0; + constructor() { + this.#field = 1; + this.#field += 2; + this.#field -= 3; + this.#field /= 4; + this.#field *= 5; + this.#field **= 6; + this.#field %= 7; + this.#field <<= 8; + this.#field >>= 9; + this.#field >>>= 10; + this.#field &= 11; + this.#field |= 12; + this.#field ^= 13; + A.getInstance().#field = 1; + A.getInstance().#field += 2; + A.getInstance().#field -= 3; + A.getInstance().#field /= 4; + A.getInstance().#field *= 5; + A.getInstance().#field **= 6; + A.getInstance().#field %= 7; + A.getInstance().#field <<= 8; + A.getInstance().#field >>= 9; + A.getInstance().#field >>>= 10; + A.getInstance().#field &= 11; + A.getInstance().#field |= 12; + A.getInstance().#field ^= 13; + } + static getInstance() { + return new A(); + } +} + + +//// [privateNameFieldAssignment.js] +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _field; +class A { + constructor() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; + _field.set(this, 0); + __classPrivateFieldSet(this, _field, 1); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) + 2); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) - 3); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) / 4); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) * 5); + __classPrivateFieldSet(this, _field, Math.pow(__classPrivateFieldGet(this, _field), 6)); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) % 7); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) << 8); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) >> 9); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) >>> 10); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) & 11); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) | 12); + __classPrivateFieldSet(this, _field, __classPrivateFieldGet(this, _field) ^ 13); + __classPrivateFieldSet(A.getInstance(), _field, 1); + __classPrivateFieldSet(_a = A.getInstance(), _field, __classPrivateFieldGet(_a, _field) + 2); + __classPrivateFieldSet(_b = A.getInstance(), _field, __classPrivateFieldGet(_b, _field) - 3); + __classPrivateFieldSet(_c = A.getInstance(), _field, __classPrivateFieldGet(_c, _field) / 4); + __classPrivateFieldSet(_d = A.getInstance(), _field, __classPrivateFieldGet(_d, _field) * 5); + __classPrivateFieldSet(_e = A.getInstance(), _field, Math.pow(__classPrivateFieldGet(_e, _field), 6)); + __classPrivateFieldSet(_f = A.getInstance(), _field, __classPrivateFieldGet(_f, _field) % 7); + __classPrivateFieldSet(_g = A.getInstance(), _field, __classPrivateFieldGet(_g, _field) << 8); + __classPrivateFieldSet(_h = A.getInstance(), _field, __classPrivateFieldGet(_h, _field) >> 9); + __classPrivateFieldSet(_j = A.getInstance(), _field, __classPrivateFieldGet(_j, _field) >>> 10); + __classPrivateFieldSet(_k = A.getInstance(), _field, __classPrivateFieldGet(_k, _field) & 11); + __classPrivateFieldSet(_l = A.getInstance(), _field, __classPrivateFieldGet(_l, _field) | 12); + __classPrivateFieldSet(_m = A.getInstance(), _field, __classPrivateFieldGet(_m, _field) ^ 13); + } + static getInstance() { + return new A(); + } +} +_field = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldAssignment.symbols b/tests/baselines/reference/privateNameFieldAssignment.symbols new file mode 100644 index 0000000000000..3f08ea141f07f --- /dev/null +++ b/tests/baselines/reference/privateNameFieldAssignment.symbols @@ -0,0 +1,146 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldAssignment.ts === +class A { +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + #field = 0; +>#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) + + constructor() { + this.#field = 1; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field += 2; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field -= 3; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field /= 4; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field *= 5; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field **= 6; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field %= 7; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field <<= 8; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field >>= 9; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field >>>= 10; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field &= 11; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field |= 12; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + this.#field ^= 13; +>this.#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + + A.getInstance().#field = 1; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field += 2; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field -= 3; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field /= 4; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field *= 5; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field **= 6; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field %= 7; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field <<= 8; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field >>= 9; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field >>>= 10; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field &= 11; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field |= 12; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + A.getInstance().#field ^= 13; +>A.getInstance().#field : Symbol(A.#field, Decl(privateNameFieldAssignment.ts, 0, 9)) +>A.getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + } + static getInstance() { +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldAssignment.ts, 29, 5)) + + return new A(); +>A : Symbol(A, Decl(privateNameFieldAssignment.ts, 0, 0)) + } +} + diff --git a/tests/baselines/reference/privateNameFieldAssignment.types b/tests/baselines/reference/privateNameFieldAssignment.types new file mode 100644 index 0000000000000..8a3c507c393f0 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldAssignment.types @@ -0,0 +1,213 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldAssignment.ts === +class A { +>A : A + + #field = 0; +>#field : number +>0 : 0 + + constructor() { + this.#field = 1; +>this.#field = 1 : 1 +>this.#field : number +>this : this +>1 : 1 + + this.#field += 2; +>this.#field += 2 : number +>this.#field : number +>this : this +>2 : 2 + + this.#field -= 3; +>this.#field -= 3 : number +>this.#field : number +>this : this +>3 : 3 + + this.#field /= 4; +>this.#field /= 4 : number +>this.#field : number +>this : this +>4 : 4 + + this.#field *= 5; +>this.#field *= 5 : number +>this.#field : number +>this : this +>5 : 5 + + this.#field **= 6; +>this.#field **= 6 : number +>this.#field : number +>this : this +>6 : 6 + + this.#field %= 7; +>this.#field %= 7 : number +>this.#field : number +>this : this +>7 : 7 + + this.#field <<= 8; +>this.#field <<= 8 : number +>this.#field : number +>this : this +>8 : 8 + + this.#field >>= 9; +>this.#field >>= 9 : number +>this.#field : number +>this : this +>9 : 9 + + this.#field >>>= 10; +>this.#field >>>= 10 : number +>this.#field : number +>this : this +>10 : 10 + + this.#field &= 11; +>this.#field &= 11 : number +>this.#field : number +>this : this +>11 : 11 + + this.#field |= 12; +>this.#field |= 12 : number +>this.#field : number +>this : this +>12 : 12 + + this.#field ^= 13; +>this.#field ^= 13 : number +>this.#field : number +>this : this +>13 : 13 + + A.getInstance().#field = 1; +>A.getInstance().#field = 1 : 1 +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>1 : 1 + + A.getInstance().#field += 2; +>A.getInstance().#field += 2 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>2 : 2 + + A.getInstance().#field -= 3; +>A.getInstance().#field -= 3 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>3 : 3 + + A.getInstance().#field /= 4; +>A.getInstance().#field /= 4 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>4 : 4 + + A.getInstance().#field *= 5; +>A.getInstance().#field *= 5 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>5 : 5 + + A.getInstance().#field **= 6; +>A.getInstance().#field **= 6 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>6 : 6 + + A.getInstance().#field %= 7; +>A.getInstance().#field %= 7 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>7 : 7 + + A.getInstance().#field <<= 8; +>A.getInstance().#field <<= 8 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>8 : 8 + + A.getInstance().#field >>= 9; +>A.getInstance().#field >>= 9 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>9 : 9 + + A.getInstance().#field >>>= 10; +>A.getInstance().#field >>>= 10 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>10 : 10 + + A.getInstance().#field &= 11; +>A.getInstance().#field &= 11 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>11 : 11 + + A.getInstance().#field |= 12; +>A.getInstance().#field |= 12 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>12 : 12 + + A.getInstance().#field ^= 13; +>A.getInstance().#field ^= 13 : number +>A.getInstance().#field : number +>A.getInstance() : A +>A.getInstance : () => A +>A : typeof A +>getInstance : () => A +>13 : 13 + } + static getInstance() { +>getInstance : () => A + + return new A(); +>new A() : A +>A : typeof A + } +} + diff --git a/tests/baselines/reference/privateNameFieldCallExpression.js b/tests/baselines/reference/privateNameFieldCallExpression.js new file mode 100644 index 0000000000000..37692c12290f3 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldCallExpression.js @@ -0,0 +1,50 @@ +//// [privateNameFieldCallExpression.ts] +class A { + #fieldFunc = function() { this.x = 10; }; + #fieldFunc2 = function(a, ...b) {}; + x = 1; + test() { + this.#fieldFunc(); + const func = this.#fieldFunc; + func(); + new this.#fieldFunc(); + + const arr = [ 1, 2 ]; + this.#fieldFunc2(0, ...arr, 3); + const b = new this.#fieldFunc2(0, ...arr, 3); + const str = this.#fieldFunc2`head${1}middle${2}tail`; + this.getInstance().#fieldFunc2`test${1}and${2}`; + } + getInstance() { return new A(); } +} + + +//// [privateNameFieldCallExpression.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _fieldFunc, _fieldFunc2; +class A { + constructor() { + _fieldFunc.set(this, function () { this.x = 10; }); + _fieldFunc2.set(this, function (a, ...b) { }); + this.x = 1; + } + test() { + var _a; + __classPrivateFieldGet(this, _fieldFunc).call(this); + const func = __classPrivateFieldGet(this, _fieldFunc); + func(); + new (__classPrivateFieldGet(this, _fieldFunc))(); + const arr = [1, 2]; + __classPrivateFieldGet(this, _fieldFunc2).call(this, 0, ...arr, 3); + const b = new (__classPrivateFieldGet(this, _fieldFunc2))(0, ...arr, 3); + const str = __classPrivateFieldGet(this, _fieldFunc2).bind(this) `head${1}middle${2}tail`; + __classPrivateFieldGet((_a = this.getInstance()), _fieldFunc2).bind(_a) `test${1}and${2}`; + } + getInstance() { return new A(); } +} +_fieldFunc = new WeakMap(), _fieldFunc2 = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldCallExpression.symbols b/tests/baselines/reference/privateNameFieldCallExpression.symbols new file mode 100644 index 0000000000000..3fe98ce7002f7 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldCallExpression.symbols @@ -0,0 +1,64 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldCallExpression.ts === +class A { +>A : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) + + #fieldFunc = function() { this.x = 10; }; +>#fieldFunc : Symbol(A.#fieldFunc, Decl(privateNameFieldCallExpression.ts, 0, 9)) + + #fieldFunc2 = function(a, ...b) {}; +>#fieldFunc2 : Symbol(A.#fieldFunc2, Decl(privateNameFieldCallExpression.ts, 1, 45)) +>a : Symbol(a, Decl(privateNameFieldCallExpression.ts, 2, 27)) +>b : Symbol(b, Decl(privateNameFieldCallExpression.ts, 2, 29)) + + x = 1; +>x : Symbol(A.x, Decl(privateNameFieldCallExpression.ts, 2, 39)) + + test() { +>test : Symbol(A.test, Decl(privateNameFieldCallExpression.ts, 3, 10)) + + this.#fieldFunc(); +>this.#fieldFunc : Symbol(A.#fieldFunc, Decl(privateNameFieldCallExpression.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) + + const func = this.#fieldFunc; +>func : Symbol(func, Decl(privateNameFieldCallExpression.ts, 6, 13)) +>this.#fieldFunc : Symbol(A.#fieldFunc, Decl(privateNameFieldCallExpression.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) + + func(); +>func : Symbol(func, Decl(privateNameFieldCallExpression.ts, 6, 13)) + + new this.#fieldFunc(); +>this.#fieldFunc : Symbol(A.#fieldFunc, Decl(privateNameFieldCallExpression.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) + + const arr = [ 1, 2 ]; +>arr : Symbol(arr, Decl(privateNameFieldCallExpression.ts, 10, 13)) + + this.#fieldFunc2(0, ...arr, 3); +>this.#fieldFunc2 : Symbol(A.#fieldFunc2, Decl(privateNameFieldCallExpression.ts, 1, 45)) +>this : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) +>arr : Symbol(arr, Decl(privateNameFieldCallExpression.ts, 10, 13)) + + const b = new this.#fieldFunc2(0, ...arr, 3); +>b : Symbol(b, Decl(privateNameFieldCallExpression.ts, 12, 13)) +>this.#fieldFunc2 : Symbol(A.#fieldFunc2, Decl(privateNameFieldCallExpression.ts, 1, 45)) +>this : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) +>arr : Symbol(arr, Decl(privateNameFieldCallExpression.ts, 10, 13)) + + const str = this.#fieldFunc2`head${1}middle${2}tail`; +>str : Symbol(str, Decl(privateNameFieldCallExpression.ts, 13, 13)) +>this.#fieldFunc2 : Symbol(A.#fieldFunc2, Decl(privateNameFieldCallExpression.ts, 1, 45)) +>this : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) + + this.getInstance().#fieldFunc2`test${1}and${2}`; +>this.getInstance().#fieldFunc2 : Symbol(A.#fieldFunc2, Decl(privateNameFieldCallExpression.ts, 1, 45)) +>this.getInstance : Symbol(A.getInstance, Decl(privateNameFieldCallExpression.ts, 15, 5)) +>this : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldCallExpression.ts, 15, 5)) + } + getInstance() { return new A(); } +>getInstance : Symbol(A.getInstance, Decl(privateNameFieldCallExpression.ts, 15, 5)) +>A : Symbol(A, Decl(privateNameFieldCallExpression.ts, 0, 0)) +} + diff --git a/tests/baselines/reference/privateNameFieldCallExpression.types b/tests/baselines/reference/privateNameFieldCallExpression.types new file mode 100644 index 0000000000000..a103c2230b4d6 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldCallExpression.types @@ -0,0 +1,96 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldCallExpression.ts === +class A { +>A : A + + #fieldFunc = function() { this.x = 10; }; +>#fieldFunc : () => void +>function() { this.x = 10; } : () => void +>this.x = 10 : 10 +>this.x : any +>this : any +>x : any +>10 : 10 + + #fieldFunc2 = function(a, ...b) {}; +>#fieldFunc2 : (a: any, ...b: any[]) => void +>function(a, ...b) {} : (a: any, ...b: any[]) => void +>a : any +>b : any[] + + x = 1; +>x : number +>1 : 1 + + test() { +>test : () => void + + this.#fieldFunc(); +>this.#fieldFunc() : void +>this.#fieldFunc : () => void +>this : this + + const func = this.#fieldFunc; +>func : () => void +>this.#fieldFunc : () => void +>this : this + + func(); +>func() : void +>func : () => void + + new this.#fieldFunc(); +>new this.#fieldFunc() : any +>this.#fieldFunc : () => void +>this : this + + const arr = [ 1, 2 ]; +>arr : number[] +>[ 1, 2 ] : number[] +>1 : 1 +>2 : 2 + + this.#fieldFunc2(0, ...arr, 3); +>this.#fieldFunc2(0, ...arr, 3) : void +>this.#fieldFunc2 : (a: any, ...b: any[]) => void +>this : this +>0 : 0 +>...arr : number +>arr : number[] +>3 : 3 + + const b = new this.#fieldFunc2(0, ...arr, 3); +>b : any +>new this.#fieldFunc2(0, ...arr, 3) : any +>this.#fieldFunc2 : (a: any, ...b: any[]) => void +>this : this +>0 : 0 +>...arr : number +>arr : number[] +>3 : 3 + + const str = this.#fieldFunc2`head${1}middle${2}tail`; +>str : void +>this.#fieldFunc2`head${1}middle${2}tail` : void +>this.#fieldFunc2 : (a: any, ...b: any[]) => void +>this : this +>`head${1}middle${2}tail` : string +>1 : 1 +>2 : 2 + + this.getInstance().#fieldFunc2`test${1}and${2}`; +>this.getInstance().#fieldFunc2`test${1}and${2}` : void +>this.getInstance().#fieldFunc2 : (a: any, ...b: any[]) => void +>this.getInstance() : A +>this.getInstance : () => A +>this : this +>getInstance : () => A +>`test${1}and${2}` : string +>1 : 1 +>2 : 2 + } + getInstance() { return new A(); } +>getInstance : () => A +>new A() : A +>A : typeof A +} + diff --git a/tests/baselines/reference/privateNameFieldClassExpression.js b/tests/baselines/reference/privateNameFieldClassExpression.js new file mode 100644 index 0000000000000..2d1641da71244 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldClassExpression.js @@ -0,0 +1,35 @@ +//// [privateNameFieldClassExpression.ts] +class B { + #foo = class { + constructor() { + console.log("hello"); + } + static test = 123; + }; + #foo2 = class Foo { + static otherClass = 123; + }; +} + + + + +//// [privateNameFieldClassExpression.js] +var _foo, _foo2; +class B { + constructor() { + var _a, _b; + _foo.set(this, (_a = class { + constructor() { + console.log("hello"); + } + }, + _a.test = 123, + _a)); + _foo2.set(this, (_b = class Foo { + }, + _b.otherClass = 123, + _b)); + } +} +_foo = new WeakMap(), _foo2 = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldClassExpression.symbols b/tests/baselines/reference/privateNameFieldClassExpression.symbols new file mode 100644 index 0000000000000..190ee14ca9bf2 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldClassExpression.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldClassExpression.ts === +class B { +>B : Symbol(B, Decl(privateNameFieldClassExpression.ts, 0, 0)) + + #foo = class { +>#foo : Symbol(B.#foo, Decl(privateNameFieldClassExpression.ts, 0, 9)) + + constructor() { + console.log("hello"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } + static test = 123; +>test : Symbol((Anonymous class).test, Decl(privateNameFieldClassExpression.ts, 4, 9)) + + }; + #foo2 = class Foo { +>#foo2 : Symbol(B.#foo2, Decl(privateNameFieldClassExpression.ts, 6, 6)) +>Foo : Symbol(Foo, Decl(privateNameFieldClassExpression.ts, 7, 11)) + + static otherClass = 123; +>otherClass : Symbol(Foo.otherClass, Decl(privateNameFieldClassExpression.ts, 7, 23)) + + }; +} + + + diff --git a/tests/baselines/reference/privateNameFieldClassExpression.types b/tests/baselines/reference/privateNameFieldClassExpression.types new file mode 100644 index 0000000000000..0226002eefac5 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldClassExpression.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldClassExpression.ts === +class B { +>B : B + + #foo = class { +>#foo : typeof (Anonymous class) +>class { constructor() { console.log("hello"); } static test = 123; } : typeof (Anonymous class) + + constructor() { + console.log("hello"); +>console.log("hello") : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>"hello" : "hello" + } + static test = 123; +>test : number +>123 : 123 + + }; + #foo2 = class Foo { +>#foo2 : typeof Foo +>class Foo { static otherClass = 123; } : typeof Foo +>Foo : typeof Foo + + static otherClass = 123; +>otherClass : number +>123 : 123 + + }; +} + + + diff --git a/tests/baselines/reference/privateNameFieldDerivedClasses.errors.txt b/tests/baselines/reference/privateNameFieldDerivedClasses.errors.txt new file mode 100644 index 0000000000000..658371865dc47 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDerivedClasses.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts(9,23): error TS18013: Property '#prop' is not accessible outside class 'Base' because it has a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts (1 errors) ==== + class Base { + #prop: number = 123; + static method(x: Derived) { + console.log(x.#prop); + } + } + class Derived extends Base { + static method(x: Derived) { + console.log(x.#prop); + ~~~~~ +!!! error TS18013: Property '#prop' is not accessible outside class 'Base' because it has a private identifier. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameFieldDerivedClasses.js b/tests/baselines/reference/privateNameFieldDerivedClasses.js new file mode 100644 index 0000000000000..f38db5914e9ba --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDerivedClasses.js @@ -0,0 +1,37 @@ +//// [privateNameFieldDerivedClasses.ts] +class Base { + #prop: number = 123; + static method(x: Derived) { + console.log(x.#prop); + } +} +class Derived extends Base { + static method(x: Derived) { + console.log(x.#prop); + } +} + + + +//// [privateNameFieldDerivedClasses.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _prop; +class Base { + constructor() { + _prop.set(this, 123); + } + static method(x) { + console.log(__classPrivateFieldGet(x, _prop)); + } +} +_prop = new WeakMap(); +class Derived extends Base { + static method(x) { + console.log(x.); + } +} diff --git a/tests/baselines/reference/privateNameFieldDerivedClasses.symbols b/tests/baselines/reference/privateNameFieldDerivedClasses.symbols new file mode 100644 index 0000000000000..3d7cee1b1d11d --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDerivedClasses.symbols @@ -0,0 +1,38 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts === +class Base { +>Base : Symbol(Base, Decl(privateNameFieldDerivedClasses.ts, 0, 0)) + + #prop: number = 123; +>#prop : Symbol(Base.#prop, Decl(privateNameFieldDerivedClasses.ts, 0, 12)) + + static method(x: Derived) { +>method : Symbol(Base.method, Decl(privateNameFieldDerivedClasses.ts, 1, 24)) +>x : Symbol(x, Decl(privateNameFieldDerivedClasses.ts, 2, 18)) +>Derived : Symbol(Derived, Decl(privateNameFieldDerivedClasses.ts, 5, 1)) + + console.log(x.#prop); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x.#prop : Symbol(Base.#prop, Decl(privateNameFieldDerivedClasses.ts, 0, 12)) +>x : Symbol(x, Decl(privateNameFieldDerivedClasses.ts, 2, 18)) + } +} +class Derived extends Base { +>Derived : Symbol(Derived, Decl(privateNameFieldDerivedClasses.ts, 5, 1)) +>Base : Symbol(Base, Decl(privateNameFieldDerivedClasses.ts, 0, 0)) + + static method(x: Derived) { +>method : Symbol(Derived.method, Decl(privateNameFieldDerivedClasses.ts, 6, 28)) +>x : Symbol(x, Decl(privateNameFieldDerivedClasses.ts, 7, 18)) +>Derived : Symbol(Derived, Decl(privateNameFieldDerivedClasses.ts, 5, 1)) + + console.log(x.#prop); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(privateNameFieldDerivedClasses.ts, 7, 18)) + } +} + + diff --git a/tests/baselines/reference/privateNameFieldDerivedClasses.types b/tests/baselines/reference/privateNameFieldDerivedClasses.types new file mode 100644 index 0000000000000..a82c6f014b1b6 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDerivedClasses.types @@ -0,0 +1,40 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts === +class Base { +>Base : Base + + #prop: number = 123; +>#prop : number +>123 : 123 + + static method(x: Derived) { +>method : (x: Derived) => void +>x : Derived + + console.log(x.#prop); +>console.log(x.#prop) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>x.#prop : number +>x : Derived + } +} +class Derived extends Base { +>Derived : Derived +>Base : Base + + static method(x: Derived) { +>method : (x: Derived) => void +>x : Derived + + console.log(x.#prop); +>console.log(x.#prop) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>x.#prop : any +>x : Derived + } +} + + diff --git a/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).js b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).js new file mode 100644 index 0000000000000..b45ccaedfe481 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).js @@ -0,0 +1,60 @@ +//// [privateNameFieldDestructuredBinding.ts] +class A { + #field = 1; + otherObject = new A(); + testObject() { + return { x: 10, y: 6 }; + } + testArray() { + return [10, 11]; + } + constructor() { + let y: number; + ({ x: this.#field, y } = this.testObject()); + ([this.#field, y] = this.testArray()); + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); + [this.#field, [this.#field]] = [1, [2]]; + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); + [this.#field = 2] = []; + [this.otherObject.#field = 2] = []; + } + static test(_a: A) { + [_a.#field] = [2]; + } +} + + +//// [privateNameFieldDestructuredBinding.js] +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var _field; +class A { + constructor() { + var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; + _field.set(this, 1); + this.otherObject = new A(); + let y; + (_b = this, { x: ({ set value(_m) { __classPrivateFieldSet(_b, _field, _m); } }).value, y } = this.testObject()); + (_c = this, [({ set value(_m) { __classPrivateFieldSet(_c, _field, _m); } }).value, y] = this.testArray()); + (_d = this, _e = this, { a: ({ set value(_m) { __classPrivateFieldSet(_d, _field, _m); } }).value, b: [({ set value(_m) { __classPrivateFieldSet(_e, _field, _m); } }).value] } = { a: 1, b: [2] }); + _f = this, _g = this, [({ set value(_m) { __classPrivateFieldSet(_f, _field, _m); } }).value, [({ set value(_m) { __classPrivateFieldSet(_g, _field, _m); } }).value]] = [1, [2]]; + (_h = this, _j = this, { a: ({ set value(_m) { __classPrivateFieldSet(_h, _field, _m); } }).value = 1, b: [({ set value(_m) { __classPrivateFieldSet(_j, _field, _m); } }).value = 1] } = { b: [] }); + _k = this, [({ set value(_m) { __classPrivateFieldSet(_k, _field, _m); } }).value = 2] = []; + _l = this.otherObject, [({ set value(_m) { __classPrivateFieldSet(_l, _field, _m); } }).value = 2] = []; + } + testObject() { + return { x: 10, y: 6 }; + } + testArray() { + return [10, 11]; + } + static test(_a) { + [({ set value(_b) { __classPrivateFieldSet(_a, _field, _b); } }).value] = [2]; + } +} +_field = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).symbols b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).symbols new file mode 100644 index 0000000000000..670e8b8c7d018 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).symbols @@ -0,0 +1,90 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts === +class A { +>A : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + #field = 1; +>#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) + + otherObject = new A(); +>otherObject : Symbol(A.otherObject, Decl(privateNameFieldDestructuredBinding.ts, 1, 15)) +>A : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + testObject() { +>testObject : Symbol(A.testObject, Decl(privateNameFieldDestructuredBinding.ts, 2, 26)) + + return { x: 10, y: 6 }; +>x : Symbol(x, Decl(privateNameFieldDestructuredBinding.ts, 4, 16)) +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 4, 23)) + } + testArray() { +>testArray : Symbol(A.testArray, Decl(privateNameFieldDestructuredBinding.ts, 5, 5)) + + return [10, 11]; + } + constructor() { + let y: number; +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 10, 11)) + + ({ x: this.#field, y } = this.testObject()); +>x : Symbol(x, Decl(privateNameFieldDestructuredBinding.ts, 11, 10)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 11, 26)) +>this.testObject : Symbol(A.testObject, Decl(privateNameFieldDestructuredBinding.ts, 2, 26)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>testObject : Symbol(A.testObject, Decl(privateNameFieldDestructuredBinding.ts, 2, 26)) + + ([this.#field, y] = this.testArray()); +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 10, 11)) +>this.testArray : Symbol(A.testArray, Decl(privateNameFieldDestructuredBinding.ts, 5, 5)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>testArray : Symbol(A.testArray, Decl(privateNameFieldDestructuredBinding.ts, 5, 5)) + + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); +>a : Symbol(a, Decl(privateNameFieldDestructuredBinding.ts, 13, 10)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 13, 26)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>a : Symbol(a, Decl(privateNameFieldDestructuredBinding.ts, 13, 49)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 13, 55)) + + [this.#field, [this.#field]] = [1, [2]]; +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); +>a : Symbol(a, Decl(privateNameFieldDestructuredBinding.ts, 15, 10)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 15, 30)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 15, 57)) + + [this.#field = 2] = []; +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + [this.otherObject.#field = 2] = []; +>this.otherObject.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this.otherObject : Symbol(A.otherObject, Decl(privateNameFieldDestructuredBinding.ts, 1, 15)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>otherObject : Symbol(A.otherObject, Decl(privateNameFieldDestructuredBinding.ts, 1, 15)) + } + static test(_a: A) { +>test : Symbol(A.test, Decl(privateNameFieldDestructuredBinding.ts, 18, 5)) +>_a : Symbol(_a, Decl(privateNameFieldDestructuredBinding.ts, 19, 16)) +>A : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + [_a.#field] = [2]; +>_a.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>_a : Symbol(_a, Decl(privateNameFieldDestructuredBinding.ts, 19, 16)) + } +} + diff --git a/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).types b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).types new file mode 100644 index 0000000000000..d361e73d3829d --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=es2015).types @@ -0,0 +1,144 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts === +class A { +>A : A + + #field = 1; +>#field : number +>1 : 1 + + otherObject = new A(); +>otherObject : A +>new A() : A +>A : typeof A + + testObject() { +>testObject : () => { x: number; y: number; } + + return { x: 10, y: 6 }; +>{ x: 10, y: 6 } : { x: number; y: number; } +>x : number +>10 : 10 +>y : number +>6 : 6 + } + testArray() { +>testArray : () => number[] + + return [10, 11]; +>[10, 11] : number[] +>10 : 10 +>11 : 11 + } + constructor() { + let y: number; +>y : number + + ({ x: this.#field, y } = this.testObject()); +>({ x: this.#field, y } = this.testObject()) : { x: number; y: number; } +>{ x: this.#field, y } = this.testObject() : { x: number; y: number; } +>{ x: this.#field, y } : { x: number; y: number; } +>x : number +>this.#field : number +>this : this +>y : number +>this.testObject() : { x: number; y: number; } +>this.testObject : () => { x: number; y: number; } +>this : this +>testObject : () => { x: number; y: number; } + + ([this.#field, y] = this.testArray()); +>([this.#field, y] = this.testArray()) : number[] +>[this.#field, y] = this.testArray() : number[] +>[this.#field, y] : [number, number] +>this.#field : number +>this : this +>y : number +>this.testArray() : number[] +>this.testArray : () => number[] +>this : this +>testArray : () => number[] + + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); +>({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }) : { a: number; b: [number]; } +>{ a: this.#field, b: [this.#field] } = { a: 1, b: [2] } : { a: number; b: [number]; } +>{ a: this.#field, b: [this.#field] } : { a: number; b: [number]; } +>a : number +>this.#field : number +>this : this +>b : [number] +>[this.#field] : [number] +>this.#field : number +>this : this +>{ a: 1, b: [2] } : { a: number; b: [number]; } +>a : number +>1 : 1 +>b : [number] +>[2] : [number] +>2 : 2 + + [this.#field, [this.#field]] = [1, [2]]; +>[this.#field, [this.#field]] = [1, [2]] : [number, [number]] +>[this.#field, [this.#field]] : [number, [number]] +>this.#field : number +>this : this +>[this.#field] : [number] +>this.#field : number +>this : this +>[1, [2]] : [number, [number]] +>1 : 1 +>[2] : [number] +>2 : 2 + + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); +>({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }) : { b: []; a?: number; } +>{ a: this.#field = 1, b: [this.#field = 1] } = { b: [] } : { b: []; a?: number; } +>{ a: this.#field = 1, b: [this.#field = 1] } : { a?: number; b: [number]; } +>a : number +>this.#field = 1 : 1 +>this.#field : number +>this : this +>1 : 1 +>b : [number] +>[this.#field = 1] : [number] +>this.#field = 1 : 1 +>this.#field : number +>this : this +>1 : 1 +>{ b: [] } : { b: []; a?: number; } +>b : [] +>[] : [] + + [this.#field = 2] = []; +>[this.#field = 2] = [] : [] +>[this.#field = 2] : [number] +>this.#field = 2 : 2 +>this.#field : number +>this : this +>2 : 2 +>[] : [] + + [this.otherObject.#field = 2] = []; +>[this.otherObject.#field = 2] = [] : [] +>[this.otherObject.#field = 2] : [number] +>this.otherObject.#field = 2 : 2 +>this.otherObject.#field : number +>this.otherObject : A +>this : this +>otherObject : A +>2 : 2 +>[] : [] + } + static test(_a: A) { +>test : (_a: A) => void +>_a : A + + [_a.#field] = [2]; +>[_a.#field] = [2] : [number] +>[_a.#field] : [number] +>_a.#field : number +>_a : A +>[2] : [number] +>2 : 2 + } +} + diff --git a/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).js b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).js new file mode 100644 index 0000000000000..74ecfe9afb49d --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).js @@ -0,0 +1,51 @@ +//// [privateNameFieldDestructuredBinding.ts] +class A { + #field = 1; + otherObject = new A(); + testObject() { + return { x: 10, y: 6 }; + } + testArray() { + return [10, 11]; + } + constructor() { + let y: number; + ({ x: this.#field, y } = this.testObject()); + ([this.#field, y] = this.testArray()); + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); + [this.#field, [this.#field]] = [1, [2]]; + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); + [this.#field = 2] = []; + [this.otherObject.#field = 2] = []; + } + static test(_a: A) { + [_a.#field] = [2]; + } +} + + +//// [privateNameFieldDestructuredBinding.js] +class A { + constructor() { + this.#field = 1; + this.otherObject = new A(); + let y; + ({ x: this.#field, y } = this.testObject()); + ([this.#field, y] = this.testArray()); + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); + [this.#field, [this.#field]] = [1, [2]]; + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); + [this.#field = 2] = []; + [this.otherObject.#field = 2] = []; + } + #field; + testObject() { + return { x: 10, y: 6 }; + } + testArray() { + return [10, 11]; + } + static test(_a) { + [_a.#field] = [2]; + } +} diff --git a/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).symbols b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).symbols new file mode 100644 index 0000000000000..670e8b8c7d018 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).symbols @@ -0,0 +1,90 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts === +class A { +>A : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + #field = 1; +>#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) + + otherObject = new A(); +>otherObject : Symbol(A.otherObject, Decl(privateNameFieldDestructuredBinding.ts, 1, 15)) +>A : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + testObject() { +>testObject : Symbol(A.testObject, Decl(privateNameFieldDestructuredBinding.ts, 2, 26)) + + return { x: 10, y: 6 }; +>x : Symbol(x, Decl(privateNameFieldDestructuredBinding.ts, 4, 16)) +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 4, 23)) + } + testArray() { +>testArray : Symbol(A.testArray, Decl(privateNameFieldDestructuredBinding.ts, 5, 5)) + + return [10, 11]; + } + constructor() { + let y: number; +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 10, 11)) + + ({ x: this.#field, y } = this.testObject()); +>x : Symbol(x, Decl(privateNameFieldDestructuredBinding.ts, 11, 10)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 11, 26)) +>this.testObject : Symbol(A.testObject, Decl(privateNameFieldDestructuredBinding.ts, 2, 26)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>testObject : Symbol(A.testObject, Decl(privateNameFieldDestructuredBinding.ts, 2, 26)) + + ([this.#field, y] = this.testArray()); +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>y : Symbol(y, Decl(privateNameFieldDestructuredBinding.ts, 10, 11)) +>this.testArray : Symbol(A.testArray, Decl(privateNameFieldDestructuredBinding.ts, 5, 5)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>testArray : Symbol(A.testArray, Decl(privateNameFieldDestructuredBinding.ts, 5, 5)) + + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); +>a : Symbol(a, Decl(privateNameFieldDestructuredBinding.ts, 13, 10)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 13, 26)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>a : Symbol(a, Decl(privateNameFieldDestructuredBinding.ts, 13, 49)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 13, 55)) + + [this.#field, [this.#field]] = [1, [2]]; +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); +>a : Symbol(a, Decl(privateNameFieldDestructuredBinding.ts, 15, 10)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 15, 30)) +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>b : Symbol(b, Decl(privateNameFieldDestructuredBinding.ts, 15, 57)) + + [this.#field = 2] = []; +>this.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + [this.otherObject.#field = 2] = []; +>this.otherObject.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>this.otherObject : Symbol(A.otherObject, Decl(privateNameFieldDestructuredBinding.ts, 1, 15)) +>this : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) +>otherObject : Symbol(A.otherObject, Decl(privateNameFieldDestructuredBinding.ts, 1, 15)) + } + static test(_a: A) { +>test : Symbol(A.test, Decl(privateNameFieldDestructuredBinding.ts, 18, 5)) +>_a : Symbol(_a, Decl(privateNameFieldDestructuredBinding.ts, 19, 16)) +>A : Symbol(A, Decl(privateNameFieldDestructuredBinding.ts, 0, 0)) + + [_a.#field] = [2]; +>_a.#field : Symbol(A.#field, Decl(privateNameFieldDestructuredBinding.ts, 0, 9)) +>_a : Symbol(_a, Decl(privateNameFieldDestructuredBinding.ts, 19, 16)) + } +} + diff --git a/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).types b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).types new file mode 100644 index 0000000000000..d361e73d3829d --- /dev/null +++ b/tests/baselines/reference/privateNameFieldDestructuredBinding(target=esnext).types @@ -0,0 +1,144 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts === +class A { +>A : A + + #field = 1; +>#field : number +>1 : 1 + + otherObject = new A(); +>otherObject : A +>new A() : A +>A : typeof A + + testObject() { +>testObject : () => { x: number; y: number; } + + return { x: 10, y: 6 }; +>{ x: 10, y: 6 } : { x: number; y: number; } +>x : number +>10 : 10 +>y : number +>6 : 6 + } + testArray() { +>testArray : () => number[] + + return [10, 11]; +>[10, 11] : number[] +>10 : 10 +>11 : 11 + } + constructor() { + let y: number; +>y : number + + ({ x: this.#field, y } = this.testObject()); +>({ x: this.#field, y } = this.testObject()) : { x: number; y: number; } +>{ x: this.#field, y } = this.testObject() : { x: number; y: number; } +>{ x: this.#field, y } : { x: number; y: number; } +>x : number +>this.#field : number +>this : this +>y : number +>this.testObject() : { x: number; y: number; } +>this.testObject : () => { x: number; y: number; } +>this : this +>testObject : () => { x: number; y: number; } + + ([this.#field, y] = this.testArray()); +>([this.#field, y] = this.testArray()) : number[] +>[this.#field, y] = this.testArray() : number[] +>[this.#field, y] : [number, number] +>this.#field : number +>this : this +>y : number +>this.testArray() : number[] +>this.testArray : () => number[] +>this : this +>testArray : () => number[] + + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); +>({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }) : { a: number; b: [number]; } +>{ a: this.#field, b: [this.#field] } = { a: 1, b: [2] } : { a: number; b: [number]; } +>{ a: this.#field, b: [this.#field] } : { a: number; b: [number]; } +>a : number +>this.#field : number +>this : this +>b : [number] +>[this.#field] : [number] +>this.#field : number +>this : this +>{ a: 1, b: [2] } : { a: number; b: [number]; } +>a : number +>1 : 1 +>b : [number] +>[2] : [number] +>2 : 2 + + [this.#field, [this.#field]] = [1, [2]]; +>[this.#field, [this.#field]] = [1, [2]] : [number, [number]] +>[this.#field, [this.#field]] : [number, [number]] +>this.#field : number +>this : this +>[this.#field] : [number] +>this.#field : number +>this : this +>[1, [2]] : [number, [number]] +>1 : 1 +>[2] : [number] +>2 : 2 + + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); +>({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }) : { b: []; a?: number; } +>{ a: this.#field = 1, b: [this.#field = 1] } = { b: [] } : { b: []; a?: number; } +>{ a: this.#field = 1, b: [this.#field = 1] } : { a?: number; b: [number]; } +>a : number +>this.#field = 1 : 1 +>this.#field : number +>this : this +>1 : 1 +>b : [number] +>[this.#field = 1] : [number] +>this.#field = 1 : 1 +>this.#field : number +>this : this +>1 : 1 +>{ b: [] } : { b: []; a?: number; } +>b : [] +>[] : [] + + [this.#field = 2] = []; +>[this.#field = 2] = [] : [] +>[this.#field = 2] : [number] +>this.#field = 2 : 2 +>this.#field : number +>this : this +>2 : 2 +>[] : [] + + [this.otherObject.#field = 2] = []; +>[this.otherObject.#field = 2] = [] : [] +>[this.otherObject.#field = 2] : [number] +>this.otherObject.#field = 2 : 2 +>this.otherObject.#field : number +>this.otherObject : A +>this : this +>otherObject : A +>2 : 2 +>[] : [] + } + static test(_a: A) { +>test : (_a: A) => void +>_a : A + + [_a.#field] = [2]; +>[_a.#field] = [2] : [number] +>[_a.#field] : [number] +>_a.#field : number +>_a : A +>[2] : [number] +>2 : 2 + } +} + diff --git a/tests/baselines/reference/privateNameFieldInitializer.js b/tests/baselines/reference/privateNameFieldInitializer.js new file mode 100644 index 0000000000000..36aaae4851217 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldInitializer.js @@ -0,0 +1,16 @@ +//// [privateNameFieldInitializer.ts] +class A { + #field = 10; + #uninitialized; +} + + +//// [privateNameFieldInitializer.js] +var _field, _uninitialized; +class A { + constructor() { + _field.set(this, 10); + _uninitialized.set(this, void 0); + } +} +_field = new WeakMap(), _uninitialized = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldInitializer.symbols b/tests/baselines/reference/privateNameFieldInitializer.symbols new file mode 100644 index 0000000000000..015a4f9ef4aa1 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldInitializer.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldInitializer.ts === +class A { +>A : Symbol(A, Decl(privateNameFieldInitializer.ts, 0, 0)) + + #field = 10; +>#field : Symbol(A.#field, Decl(privateNameFieldInitializer.ts, 0, 9)) + + #uninitialized; +>#uninitialized : Symbol(A.#uninitialized, Decl(privateNameFieldInitializer.ts, 1, 16)) +} + diff --git a/tests/baselines/reference/privateNameFieldInitializer.types b/tests/baselines/reference/privateNameFieldInitializer.types new file mode 100644 index 0000000000000..e6e701777c80c --- /dev/null +++ b/tests/baselines/reference/privateNameFieldInitializer.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldInitializer.ts === +class A { +>A : A + + #field = 10; +>#field : number +>10 : 10 + + #uninitialized; +>#uninitialized : any +} + diff --git a/tests/baselines/reference/privateNameFieldUnaryMutation.js b/tests/baselines/reference/privateNameFieldUnaryMutation.js new file mode 100644 index 0000000000000..91d4faecb4584 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldUnaryMutation.js @@ -0,0 +1,77 @@ +//// [privateNameFieldUnaryMutation.ts] +class C { + #test: number = 24; + constructor() { + this.#test++; + this.#test--; + ++this.#test; + --this.#test; + const a = this.#test++; + const b = this.#test--; + const c = ++this.#test; + const d = --this.#test; + for (this.#test = 0; this.#test < 10; ++this.#test) {} + for (this.#test = 0; this.#test < 10; this.#test++) {} + } + test() { + this.getInstance().#test++; + this.getInstance().#test--; + ++this.getInstance().#test; + --this.getInstance().#test; + const a = this.getInstance().#test++; + const b = this.getInstance().#test--; + const c = ++this.getInstance().#test; + const d = --this.getInstance().#test; + for (this.getInstance().#test = 0; this.getInstance().#test < 10; ++this.getInstance().#test) {} + for (this.getInstance().#test = 0; this.getInstance().#test < 10; this.getInstance().#test++) {} + } + getInstance() { return new C(); } +} + + +//// [privateNameFieldUnaryMutation.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var _test; +class C { + constructor() { + var _a, _b; + _test.set(this, 24); + __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) + 1); + __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) - 1); + __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) + 1); + __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) - 1); + const a = (__classPrivateFieldSet(this, _test, (_a = +__classPrivateFieldGet(this, _test)) + 1), _a); + const b = (__classPrivateFieldSet(this, _test, (_b = +__classPrivateFieldGet(this, _test)) - 1), _b); + const c = __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) + 1); + const d = __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) - 1); + for (__classPrivateFieldSet(this, _test, 0); __classPrivateFieldGet(this, _test) < 10; __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) + 1)) { } + for (__classPrivateFieldSet(this, _test, 0); __classPrivateFieldGet(this, _test) < 10; __classPrivateFieldSet(this, _test, +__classPrivateFieldGet(this, _test) + 1)) { } + } + test() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; + __classPrivateFieldSet(_a = this.getInstance(), _test, +__classPrivateFieldGet(_a, _test) + 1); + __classPrivateFieldSet(_b = this.getInstance(), _test, +__classPrivateFieldGet(_b, _test) - 1); + __classPrivateFieldSet(_c = this.getInstance(), _test, +__classPrivateFieldGet(_c, _test) + 1); + __classPrivateFieldSet(_d = this.getInstance(), _test, +__classPrivateFieldGet(_d, _test) - 1); + const a = (__classPrivateFieldSet(_e = this.getInstance(), _test, (_f = +__classPrivateFieldGet(_e, _test)) + 1), _f); + const b = (__classPrivateFieldSet(_g = this.getInstance(), _test, (_h = +__classPrivateFieldGet(_g, _test)) - 1), _h); + const c = __classPrivateFieldSet(_j = this.getInstance(), _test, +__classPrivateFieldGet(_j, _test) + 1); + const d = __classPrivateFieldSet(_k = this.getInstance(), _test, +__classPrivateFieldGet(_k, _test) - 1); + for (__classPrivateFieldSet(this.getInstance(), _test, 0); __classPrivateFieldGet(this.getInstance(), _test) < 10; __classPrivateFieldSet(_l = this.getInstance(), _test, +__classPrivateFieldGet(_l, _test) + 1)) { } + for (__classPrivateFieldSet(this.getInstance(), _test, 0); __classPrivateFieldGet(this.getInstance(), _test) < 10; __classPrivateFieldSet(_m = this.getInstance(), _test, +__classPrivateFieldGet(_m, _test) + 1)) { } + } + getInstance() { return new C(); } +} +_test = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldUnaryMutation.symbols b/tests/baselines/reference/privateNameFieldUnaryMutation.symbols new file mode 100644 index 0000000000000..8344e04c91189 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldUnaryMutation.symbols @@ -0,0 +1,148 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldUnaryMutation.ts === +class C { +>C : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + #test: number = 24; +>#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) + + constructor() { + this.#test++; +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + this.#test--; +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + ++this.#test; +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + --this.#test; +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + const a = this.#test++; +>a : Symbol(a, Decl(privateNameFieldUnaryMutation.ts, 7, 13)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + const b = this.#test--; +>b : Symbol(b, Decl(privateNameFieldUnaryMutation.ts, 8, 13)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + const c = ++this.#test; +>c : Symbol(c, Decl(privateNameFieldUnaryMutation.ts, 9, 13)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + const d = --this.#test; +>d : Symbol(d, Decl(privateNameFieldUnaryMutation.ts, 10, 13)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + for (this.#test = 0; this.#test < 10; ++this.#test) {} +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + + for (this.#test = 0; this.#test < 10; this.#test++) {} +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>this.#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) + } + test() { +>test : Symbol(C.test, Decl(privateNameFieldUnaryMutation.ts, 13, 5)) + + this.getInstance().#test++; +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + this.getInstance().#test--; +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + ++this.getInstance().#test; +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + --this.getInstance().#test; +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + const a = this.getInstance().#test++; +>a : Symbol(a, Decl(privateNameFieldUnaryMutation.ts, 19, 13)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + const b = this.getInstance().#test--; +>b : Symbol(b, Decl(privateNameFieldUnaryMutation.ts, 20, 13)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + const c = ++this.getInstance().#test; +>c : Symbol(c, Decl(privateNameFieldUnaryMutation.ts, 21, 13)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + const d = --this.getInstance().#test; +>d : Symbol(d, Decl(privateNameFieldUnaryMutation.ts, 22, 13)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + for (this.getInstance().#test = 0; this.getInstance().#test < 10; ++this.getInstance().#test) {} +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + + for (this.getInstance().#test = 0; this.getInstance().#test < 10; this.getInstance().#test++) {} +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this.getInstance().#test : Symbol(C.#test, Decl(privateNameFieldUnaryMutation.ts, 0, 9)) +>this.getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>this : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) + } + getInstance() { return new C(); } +>getInstance : Symbol(C.getInstance, Decl(privateNameFieldUnaryMutation.ts, 25, 5)) +>C : Symbol(C, Decl(privateNameFieldUnaryMutation.ts, 0, 0)) +} + diff --git a/tests/baselines/reference/privateNameFieldUnaryMutation.types b/tests/baselines/reference/privateNameFieldUnaryMutation.types new file mode 100644 index 0000000000000..4fc0d7805d95a --- /dev/null +++ b/tests/baselines/reference/privateNameFieldUnaryMutation.types @@ -0,0 +1,200 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldUnaryMutation.ts === +class C { +>C : C + + #test: number = 24; +>#test : number +>24 : 24 + + constructor() { + this.#test++; +>this.#test++ : number +>this.#test : number +>this : this + + this.#test--; +>this.#test-- : number +>this.#test : number +>this : this + + ++this.#test; +>++this.#test : number +>this.#test : number +>this : this + + --this.#test; +>--this.#test : number +>this.#test : number +>this : this + + const a = this.#test++; +>a : number +>this.#test++ : number +>this.#test : number +>this : this + + const b = this.#test--; +>b : number +>this.#test-- : number +>this.#test : number +>this : this + + const c = ++this.#test; +>c : number +>++this.#test : number +>this.#test : number +>this : this + + const d = --this.#test; +>d : number +>--this.#test : number +>this.#test : number +>this : this + + for (this.#test = 0; this.#test < 10; ++this.#test) {} +>this.#test = 0 : 0 +>this.#test : number +>this : this +>0 : 0 +>this.#test < 10 : boolean +>this.#test : number +>this : this +>10 : 10 +>++this.#test : number +>this.#test : number +>this : this + + for (this.#test = 0; this.#test < 10; this.#test++) {} +>this.#test = 0 : 0 +>this.#test : number +>this : this +>0 : 0 +>this.#test < 10 : boolean +>this.#test : number +>this : this +>10 : 10 +>this.#test++ : number +>this.#test : number +>this : this + } + test() { +>test : () => void + + this.getInstance().#test++; +>this.getInstance().#test++ : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + this.getInstance().#test--; +>this.getInstance().#test-- : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + ++this.getInstance().#test; +>++this.getInstance().#test : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + --this.getInstance().#test; +>--this.getInstance().#test : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + const a = this.getInstance().#test++; +>a : number +>this.getInstance().#test++ : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + const b = this.getInstance().#test--; +>b : number +>this.getInstance().#test-- : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + const c = ++this.getInstance().#test; +>c : number +>++this.getInstance().#test : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + const d = --this.getInstance().#test; +>d : number +>--this.getInstance().#test : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + for (this.getInstance().#test = 0; this.getInstance().#test < 10; ++this.getInstance().#test) {} +>this.getInstance().#test = 0 : 0 +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C +>0 : 0 +>this.getInstance().#test < 10 : boolean +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C +>10 : 10 +>++this.getInstance().#test : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + + for (this.getInstance().#test = 0; this.getInstance().#test < 10; this.getInstance().#test++) {} +>this.getInstance().#test = 0 : 0 +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C +>0 : 0 +>this.getInstance().#test < 10 : boolean +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C +>10 : 10 +>this.getInstance().#test++ : number +>this.getInstance().#test : number +>this.getInstance() : C +>this.getInstance : () => C +>this : this +>getInstance : () => C + } + getInstance() { return new C(); } +>getInstance : () => C +>new C() : C +>C : typeof C +} + diff --git a/tests/baselines/reference/privateNameFieldsESNext.errors.txt b/tests/baselines/reference/privateNameFieldsESNext.errors.txt new file mode 100644 index 0000000000000..dcf0fc0319059 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldsESNext.errors.txt @@ -0,0 +1,32 @@ +tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts(8,9): error TS2322: Type '"hello"' is not assignable to type 'number'. +tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts(11,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts(12,5): error TS18019: 'static' modifier cannot be used with a private identifier + + +==== tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts (3 errors) ==== + class C { + a = 123; + #a = 10; + c = "hello"; + #b; + method() { + console.log(this.#a); + this.#a = "hello"; + ~~~~~~~ +!!! error TS2322: Type '"hello"' is not assignable to type 'number'. + console.log(this.#b); + } + static #m = "test"; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + static #x; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + static test() { + console.log(this.#m); + console.log(this.#x = "test"); + } + #something = () => 1234; + } + + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameFieldsESNext.js b/tests/baselines/reference/privateNameFieldsESNext.js new file mode 100644 index 0000000000000..acc37caa3cc8f --- /dev/null +++ b/tests/baselines/reference/privateNameFieldsESNext.js @@ -0,0 +1,46 @@ +//// [privateNameFieldsESNext.ts] +class C { + a = 123; + #a = 10; + c = "hello"; + #b; + method() { + console.log(this.#a); + this.#a = "hello"; + console.log(this.#b); + } + static #m = "test"; + static #x; + static test() { + console.log(this.#m); + console.log(this.#x = "test"); + } + #something = () => 1234; +} + + + +//// [privateNameFieldsESNext.js] +class C { + constructor() { + this.a = 123; + this.#a = 10; + this.c = "hello"; + this.#something = () => 1234; + } + #a; + #b; + method() { + console.log(this.#a); + this.#a = "hello"; + console.log(this.#b); + } + static #m; + static #x; + static test() { + console.log(this.#m); + console.log(this.#x = "test"); + } + #something; +} +C.#m = "test"; diff --git a/tests/baselines/reference/privateNameFieldsESNext.symbols b/tests/baselines/reference/privateNameFieldsESNext.symbols new file mode 100644 index 0000000000000..5ed63d12d2fef --- /dev/null +++ b/tests/baselines/reference/privateNameFieldsESNext.symbols @@ -0,0 +1,65 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts === +class C { +>C : Symbol(C, Decl(privateNameFieldsESNext.ts, 0, 0)) + + a = 123; +>a : Symbol(C.a, Decl(privateNameFieldsESNext.ts, 0, 9)) + + #a = 10; +>#a : Symbol(C.#a, Decl(privateNameFieldsESNext.ts, 1, 12)) + + c = "hello"; +>c : Symbol(C.c, Decl(privateNameFieldsESNext.ts, 2, 12)) + + #b; +>#b : Symbol(C.#b, Decl(privateNameFieldsESNext.ts, 3, 16)) + + method() { +>method : Symbol(C.method, Decl(privateNameFieldsESNext.ts, 4, 7)) + + console.log(this.#a); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this.#a : Symbol(C.#a, Decl(privateNameFieldsESNext.ts, 1, 12)) +>this : Symbol(C, Decl(privateNameFieldsESNext.ts, 0, 0)) + + this.#a = "hello"; +>this.#a : Symbol(C.#a, Decl(privateNameFieldsESNext.ts, 1, 12)) +>this : Symbol(C, Decl(privateNameFieldsESNext.ts, 0, 0)) + + console.log(this.#b); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this.#b : Symbol(C.#b, Decl(privateNameFieldsESNext.ts, 3, 16)) +>this : Symbol(C, Decl(privateNameFieldsESNext.ts, 0, 0)) + } + static #m = "test"; +>#m : Symbol(C.#m, Decl(privateNameFieldsESNext.ts, 9, 5)) + + static #x; +>#x : Symbol(C.#x, Decl(privateNameFieldsESNext.ts, 10, 23)) + + static test() { +>test : Symbol(C.test, Decl(privateNameFieldsESNext.ts, 11, 14)) + + console.log(this.#m); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this.#m : Symbol(C.#m, Decl(privateNameFieldsESNext.ts, 9, 5)) +>this : Symbol(C, Decl(privateNameFieldsESNext.ts, 0, 0)) + + console.log(this.#x = "test"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this.#x : Symbol(C.#x, Decl(privateNameFieldsESNext.ts, 10, 23)) +>this : Symbol(C, Decl(privateNameFieldsESNext.ts, 0, 0)) + } + #something = () => 1234; +>#something : Symbol(C.#something, Decl(privateNameFieldsESNext.ts, 15, 5)) +} + + diff --git a/tests/baselines/reference/privateNameFieldsESNext.types b/tests/baselines/reference/privateNameFieldsESNext.types new file mode 100644 index 0000000000000..e3f007ae8784e --- /dev/null +++ b/tests/baselines/reference/privateNameFieldsESNext.types @@ -0,0 +1,79 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts === +class C { +>C : C + + a = 123; +>a : number +>123 : 123 + + #a = 10; +>#a : number +>10 : 10 + + c = "hello"; +>c : string +>"hello" : "hello" + + #b; +>#b : any + + method() { +>method : () => void + + console.log(this.#a); +>console.log(this.#a) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this.#a : number +>this : this + + this.#a = "hello"; +>this.#a = "hello" : "hello" +>this.#a : number +>this : this +>"hello" : "hello" + + console.log(this.#b); +>console.log(this.#b) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this.#b : any +>this : this + } + static #m = "test"; +>#m : string +>"test" : "test" + + static #x; +>#x : any + + static test() { +>test : () => void + + console.log(this.#m); +>console.log(this.#m) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this.#m : string +>this : typeof C + + console.log(this.#x = "test"); +>console.log(this.#x = "test") : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this.#x = "test" : "test" +>this.#x : any +>this : typeof C +>"test" : "test" + } + #something = () => 1234; +>#something : () => number +>() => 1234 : () => number +>1234 : 1234 +} + + diff --git a/tests/baselines/reference/privateNameImplicitDeclaration.errors.txt b/tests/baselines/reference/privateNameImplicitDeclaration.errors.txt new file mode 100644 index 0000000000000..0ddda2061e955 --- /dev/null +++ b/tests/baselines/reference/privateNameImplicitDeclaration.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.js(4,14): error TS2339: Property '#x' does not exist on type 'C'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.js (1 errors) ==== + class C { + constructor() { + /** @type {string} */ + this.#x; + ~~ +!!! error TS2339: Property '#x' does not exist on type 'C'. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameImplicitDeclaration.symbols b/tests/baselines/reference/privateNameImplicitDeclaration.symbols new file mode 100644 index 0000000000000..44e89e73deaf7 --- /dev/null +++ b/tests/baselines/reference/privateNameImplicitDeclaration.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.js === +class C { +>C : Symbol(C, Decl(privateNameImplicitDeclaration.js, 0, 0)) + + constructor() { + /** @type {string} */ + this.#x; +>this : Symbol(C, Decl(privateNameImplicitDeclaration.js, 0, 0)) + } +} + + diff --git a/tests/baselines/reference/privateNameImplicitDeclaration.types b/tests/baselines/reference/privateNameImplicitDeclaration.types new file mode 100644 index 0000000000000..13f80356b4f30 --- /dev/null +++ b/tests/baselines/reference/privateNameImplicitDeclaration.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.js === +class C { +>C : C + + constructor() { + /** @type {string} */ + this.#x; +>this.#x : any +>this : this + } +} + + diff --git a/tests/baselines/reference/privateNameInLhsReceiverExpression.js b/tests/baselines/reference/privateNameInLhsReceiverExpression.js new file mode 100644 index 0000000000000..1f1fa882554c3 --- /dev/null +++ b/tests/baselines/reference/privateNameInLhsReceiverExpression.js @@ -0,0 +1,51 @@ +//// [privateNameInLhsReceiverExpression.ts] +class Test { + #y = 123; + static something(obj: { [key: string]: Test }) { + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y = 1; + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y += 1; + } +} + + + +//// [privateNameInLhsReceiverExpression.js] +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _y; +class Test { + constructor() { + _y.set(this, 123); + } + static something(obj) { + var _x, _a, _x_1, _b, _c; + __classPrivateFieldSet(obj[(new (_a = class { + constructor() { + _x.set(this, 1); + this.s = "prop"; + } + }, + _x = new WeakMap(), + _a)).s], _y, 1); + __classPrivateFieldSet(_c = obj[(new (_b = class { + constructor() { + _x_1.set(this, 1); + this.s = "prop"; + } + }, + _x_1 = new WeakMap(), + _b)).s], _y, __classPrivateFieldGet(_c, _y) + 1); + } +} +_y = new WeakMap(); diff --git a/tests/baselines/reference/privateNameInLhsReceiverExpression.symbols b/tests/baselines/reference/privateNameInLhsReceiverExpression.symbols new file mode 100644 index 0000000000000..eb0c6f7dc800d --- /dev/null +++ b/tests/baselines/reference/privateNameInLhsReceiverExpression.symbols @@ -0,0 +1,32 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInLhsReceiverExpression.ts === +class Test { +>Test : Symbol(Test, Decl(privateNameInLhsReceiverExpression.ts, 0, 0)) + + #y = 123; +>#y : Symbol(Test.#y, Decl(privateNameInLhsReceiverExpression.ts, 0, 12)) + + static something(obj: { [key: string]: Test }) { +>something : Symbol(Test.something, Decl(privateNameInLhsReceiverExpression.ts, 1, 13)) +>obj : Symbol(obj, Decl(privateNameInLhsReceiverExpression.ts, 2, 21)) +>key : Symbol(key, Decl(privateNameInLhsReceiverExpression.ts, 2, 29)) +>Test : Symbol(Test, Decl(privateNameInLhsReceiverExpression.ts, 0, 0)) + + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y = 1; +>obj[(new class { #x = 1; readonly s = "prop"; }).s].#y : Symbol(Test.#y, Decl(privateNameInLhsReceiverExpression.ts, 0, 12)) +>obj : Symbol(obj, Decl(privateNameInLhsReceiverExpression.ts, 2, 21)) +>(new class { #x = 1; readonly s = "prop"; }).s : Symbol((Anonymous class).s, Decl(privateNameInLhsReceiverExpression.ts, 3, 32)) +>#x : Symbol((Anonymous class).#x, Decl(privateNameInLhsReceiverExpression.ts, 3, 24)) +>s : Symbol((Anonymous class).s, Decl(privateNameInLhsReceiverExpression.ts, 3, 32)) +>s : Symbol((Anonymous class).s, Decl(privateNameInLhsReceiverExpression.ts, 3, 32)) + + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y += 1; +>obj[(new class { #x = 1; readonly s = "prop"; }).s].#y : Symbol(Test.#y, Decl(privateNameInLhsReceiverExpression.ts, 0, 12)) +>obj : Symbol(obj, Decl(privateNameInLhsReceiverExpression.ts, 2, 21)) +>(new class { #x = 1; readonly s = "prop"; }).s : Symbol((Anonymous class).s, Decl(privateNameInLhsReceiverExpression.ts, 4, 32)) +>#x : Symbol((Anonymous class).#x, Decl(privateNameInLhsReceiverExpression.ts, 4, 24)) +>s : Symbol((Anonymous class).s, Decl(privateNameInLhsReceiverExpression.ts, 4, 32)) +>s : Symbol((Anonymous class).s, Decl(privateNameInLhsReceiverExpression.ts, 4, 32)) + } +} + + diff --git a/tests/baselines/reference/privateNameInLhsReceiverExpression.types b/tests/baselines/reference/privateNameInLhsReceiverExpression.types new file mode 100644 index 0000000000000..b8130575ad87e --- /dev/null +++ b/tests/baselines/reference/privateNameInLhsReceiverExpression.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameInLhsReceiverExpression.ts === +class Test { +>Test : Test + + #y = 123; +>#y : number +>123 : 123 + + static something(obj: { [key: string]: Test }) { +>something : (obj: { [key: string]: Test; }) => void +>obj : { [key: string]: Test; } +>key : string + + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y = 1; +>obj[(new class { #x = 1; readonly s = "prop"; }).s].#y = 1 : 1 +>obj[(new class { #x = 1; readonly s = "prop"; }).s].#y : number +>obj[(new class { #x = 1; readonly s = "prop"; }).s] : Test +>obj : { [key: string]: Test; } +>(new class { #x = 1; readonly s = "prop"; }).s : "prop" +>(new class { #x = 1; readonly s = "prop"; }) : (Anonymous class) +>new class { #x = 1; readonly s = "prop"; } : (Anonymous class) +>class { #x = 1; readonly s = "prop"; } : typeof (Anonymous class) +>#x : number +>1 : 1 +>s : "prop" +>"prop" : "prop" +>s : "prop" +>1 : 1 + + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y += 1; +>obj[(new class { #x = 1; readonly s = "prop"; }).s].#y += 1 : number +>obj[(new class { #x = 1; readonly s = "prop"; }).s].#y : number +>obj[(new class { #x = 1; readonly s = "prop"; }).s] : Test +>obj : { [key: string]: Test; } +>(new class { #x = 1; readonly s = "prop"; }).s : "prop" +>(new class { #x = 1; readonly s = "prop"; }) : (Anonymous class) +>new class { #x = 1; readonly s = "prop"; } : (Anonymous class) +>class { #x = 1; readonly s = "prop"; } : typeof (Anonymous class) +>#x : number +>1 : 1 +>s : "prop" +>"prop" : "prop" +>s : "prop" +>1 : 1 + } +} + + diff --git a/tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt b/tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt index bdfe78ee02a78..9df4540af12d7 100644 --- a/tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt +++ b/tests/baselines/reference/privateNameInObjectLiteral-1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts(2,5): error TS18016: Private names are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts(2,5): error TS18016: Private identifiers are not allowed outside class bodies. ==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts (1 errors) ==== const obj = { #foo: 1 ~~~~ -!!! error TS18016: Private names are not allowed outside class bodies. +!!! error TS18016: Private identifiers are not allowed outside class bodies. }; \ No newline at end of file diff --git a/tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt b/tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt index a75b09041d830..17a10e6ccbc4a 100644 --- a/tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt +++ b/tests/baselines/reference/privateNameInObjectLiteral-2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts(2,5): error TS18016: Private names are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts(2,5): error TS18016: Private identifiers are not allowed outside class bodies. ==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts (1 errors) ==== const obj = { #foo() { ~~~~ -!!! error TS18016: Private names are not allowed outside class bodies. +!!! error TS18016: Private identifiers are not allowed outside class bodies. } }; diff --git a/tests/baselines/reference/privateNameInObjectLiteral.errors.txt b/tests/baselines/reference/privateNameInObjectLiteral.errors.txt deleted file mode 100644 index 2f5101ec98646..0000000000000 --- a/tests/baselines/reference/privateNameInObjectLiteral.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts(2,5): error TS18010: Private names are not allowed outside class bodies. - - -==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts (1 errors) ==== - const obj = { - #foo: "#foo", - ~~~~ -!!! error TS18010: Private names are not allowed outside class bodies. - #bar: () => true, - #baz() { - return true; - } - }; - \ No newline at end of file diff --git a/tests/baselines/reference/privateNameInObjectLiteral.js b/tests/baselines/reference/privateNameInObjectLiteral.js deleted file mode 100644 index a95d80d4add5f..0000000000000 --- a/tests/baselines/reference/privateNameInObjectLiteral.js +++ /dev/null @@ -1,18 +0,0 @@ -//// [privateNameInObjectLiteral.ts] -const obj = { - #foo: "#foo", - #bar: () => true, - #baz() { - return true; - } -}; - - -//// [privateNameInObjectLiteral.js] -var obj = { - #foo: "#foo", - #bar: function () { return true; }, - #baz: function () { - return true; - } -}; diff --git a/tests/baselines/reference/privateNameInObjectLiteral.symbols b/tests/baselines/reference/privateNameInObjectLiteral.symbols deleted file mode 100644 index f5592c7384305..0000000000000 --- a/tests/baselines/reference/privateNameInObjectLiteral.symbols +++ /dev/null @@ -1,17 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts === -const obj = { ->obj : Symbol(obj, Decl(privateNameInObjectLiteral.ts, 0, 5)) - - #foo: "#foo", ->#foo : Symbol(#foo, Decl(privateNameInObjectLiteral.ts, 0, 13)) - - #bar: () => true, ->#bar : Symbol(#bar, Decl(privateNameInObjectLiteral.ts, 1, 17)) - - #baz() { ->#baz : Symbol(#baz, Decl(privateNameInObjectLiteral.ts, 2, 21)) - - return true; - } -}; - diff --git a/tests/baselines/reference/privateNameInObjectLiteral.types b/tests/baselines/reference/privateNameInObjectLiteral.types deleted file mode 100644 index 372dc87bae5c3..0000000000000 --- a/tests/baselines/reference/privateNameInObjectLiteral.types +++ /dev/null @@ -1,22 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts === -const obj = { ->obj : {} ->{ #foo: "#foo", #bar: () => true, #baz() { return true; }} : {} - - #foo: "#foo", ->#foo : string ->"#foo" : "#foo" - - #bar: () => true, ->#bar : () => boolean ->() => true : () => boolean ->true : true - - #baz() { ->#baz : () => boolean - - return true; ->true : true - } -}; - diff --git a/tests/baselines/reference/privateNameJsBadAssignment.errors.txt b/tests/baselines/reference/privateNameJsBadAssignment.errors.txt new file mode 100644 index 0000000000000..faf9be5985006 --- /dev/null +++ b/tests/baselines/reference/privateNameJsBadAssignment.errors.txt @@ -0,0 +1,29 @@ +tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(1,9): error TS2339: Property '#nope' does not exist on type 'typeof import("tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment")'. +tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(3,13): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(6,3): error TS2339: Property '#foo' does not exist on type 'typeof B'. +tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(11,14): error TS2339: Property '#foo' does not exist on type 'C'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js (4 errors) ==== + exports.#nope = 1; // Error (outside class body) + ~~~~~ +!!! error TS2339: Property '#nope' does not exist on type 'typeof import("tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment")'. + function A() { } + A.prototype.#no = 2; // Error (outside class body) + ~~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + + class B {} + B.#foo = 3; // Error (outside class body) + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'typeof B'. + + class C { + #bar = 6; + constructor () { + this.#foo = 3; // Error (undeclared) + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'C'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameJsBadAssignment.symbols b/tests/baselines/reference/privateNameJsBadAssignment.symbols new file mode 100644 index 0000000000000..0f86dc2554cea --- /dev/null +++ b/tests/baselines/reference/privateNameJsBadAssignment.symbols @@ -0,0 +1,30 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js === +exports.#nope = 1; // Error (outside class body) +>exports : Symbol(#nope, Decl(privateNameJsBadAssignment.js, 0, 0)) + +function A() { } +>A : Symbol(A, Decl(privateNameJsBadAssignment.js, 0, 18)) + +A.prototype.#no = 2; // Error (outside class body) +>A.prototype : Symbol(A.#no, Decl(privateNameJsBadAssignment.js, 1, 16)) +>A : Symbol(A, Decl(privateNameJsBadAssignment.js, 0, 18)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) + +class B {} +>B : Symbol(B, Decl(privateNameJsBadAssignment.js, 2, 20), Decl(privateNameJsBadAssignment.js, 4, 10)) + +B.#foo = 3; // Error (outside class body) +>B : Symbol(B, Decl(privateNameJsBadAssignment.js, 2, 20), Decl(privateNameJsBadAssignment.js, 4, 10)) + +class C { +>C : Symbol(C, Decl(privateNameJsBadAssignment.js, 5, 11)) + + #bar = 6; +>#bar : Symbol(C.#bar, Decl(privateNameJsBadAssignment.js, 7, 9)) + + constructor () { + this.#foo = 3; // Error (undeclared) +>this : Symbol(C, Decl(privateNameJsBadAssignment.js, 5, 11)) + } +} + diff --git a/tests/baselines/reference/privateNameJsBadAssignment.types b/tests/baselines/reference/privateNameJsBadAssignment.types new file mode 100644 index 0000000000000..39b34820c2f60 --- /dev/null +++ b/tests/baselines/reference/privateNameJsBadAssignment.types @@ -0,0 +1,43 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js === +exports.#nope = 1; // Error (outside class body) +>exports.#nope = 1 : 1 +>exports.#nope : any +>exports : typeof import("tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment") +>1 : 1 + +function A() { } +>A : typeof A + +A.prototype.#no = 2; // Error (outside class body) +>A.prototype.#no = 2 : 2 +>A.prototype.#no : any +>A.prototype : any +>A : typeof A +>prototype : any +>2 : 2 + +class B {} +>B : B + +B.#foo = 3; // Error (outside class body) +>B.#foo = 3 : 3 +>B.#foo : any +>B : typeof B +>3 : 3 + +class C { +>C : C + + #bar = 6; +>#bar : number +>6 : 6 + + constructor () { + this.#foo = 3; // Error (undeclared) +>this.#foo = 3 : 3 +>this.#foo : any +>this : this +>3 : 3 + } +} + diff --git a/tests/baselines/reference/privateNameJsBadDeclaration.errors.txt b/tests/baselines/reference/privateNameJsBadDeclaration.errors.txt new file mode 100644 index 0000000000000..206e257745708 --- /dev/null +++ b/tests/baselines/reference/privateNameJsBadDeclaration.errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/classes/members/privateNames/privateNameJsPrototype.js(3,3): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameJsPrototype.js(7,3): error TS18016: Private identifiers are not allowed outside class bodies. +tests/cases/conformance/classes/members/privateNames/privateNameJsPrototype.js(11,10): error TS2339: Property '#z' does not exist on type 'C'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameJsPrototype.js (3 errors) ==== + function A() { } + A.prototype = { + #x: 1 // Error + ~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + } + class B { } + B.prototype = { + #y: 2 // Error + ~~ +!!! error TS18016: Private identifiers are not allowed outside class bodies. + } + class C { + constructor() { + this.#z = 3; + ~~ +!!! error TS2339: Property '#z' does not exist on type 'C'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameJsBadDeclaration.symbols b/tests/baselines/reference/privateNameJsBadDeclaration.symbols new file mode 100644 index 0000000000000..33a45250dcec5 --- /dev/null +++ b/tests/baselines/reference/privateNameJsBadDeclaration.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameJsPrototype.js === +function A() { } +>A : Symbol(A, Decl(privateNameJsPrototype.js, 0, 0), Decl(privateNameJsPrototype.js, 0, 16)) + +A.prototype = { +>A.prototype : Symbol(A.prototype, Decl(privateNameJsPrototype.js, 0, 16)) +>A : Symbol(A, Decl(privateNameJsPrototype.js, 0, 0), Decl(privateNameJsPrototype.js, 0, 16)) +>prototype : Symbol(A.prototype, Decl(privateNameJsPrototype.js, 0, 16)) + + #x: 1 // Error +>#x : Symbol(#x, Decl(privateNameJsPrototype.js, 1, 15)) +} +class B { } +>B : Symbol(B, Decl(privateNameJsPrototype.js, 3, 1), Decl(privateNameJsPrototype.js, 4, 11)) + +B.prototype = { +>B.prototype : Symbol(B.prototype, Decl(privateNameJsPrototype.js, 4, 11)) +>B : Symbol(B, Decl(privateNameJsPrototype.js, 3, 1), Decl(privateNameJsPrototype.js, 4, 11)) +>prototype : Symbol(B.prototype, Decl(privateNameJsPrototype.js, 4, 11)) + + #y: 2 // Error +>#y : Symbol(#y, Decl(privateNameJsPrototype.js, 5, 15)) +} +class C { +>C : Symbol(C, Decl(privateNameJsPrototype.js, 7, 1)) + + constructor() { + this.#z = 3; +>this : Symbol(C, Decl(privateNameJsPrototype.js, 7, 1)) + } +} diff --git a/tests/baselines/reference/privateNameJsBadDeclaration.types b/tests/baselines/reference/privateNameJsBadDeclaration.types new file mode 100644 index 0000000000000..0ccbbeef0a9ba --- /dev/null +++ b/tests/baselines/reference/privateNameJsBadDeclaration.types @@ -0,0 +1,40 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameJsPrototype.js === +function A() { } +>A : typeof A + +A.prototype = { +>A.prototype = { #x: 1 // Error} : {} +>A.prototype : {} +>A : typeof A +>prototype : {} +>{ #x: 1 // Error} : {} + + #x: 1 // Error +>#x : number +>1 : 1 +} +class B { } +>B : B + +B.prototype = { +>B.prototype = { #y: 2 // Error} : {} +>B.prototype : B +>B : typeof B +>prototype : B +>{ #y: 2 // Error} : {} + + #y: 2 // Error +>#y : number +>2 : 2 +} +class C { +>C : C + + constructor() { + this.#z = 3; +>this.#z = 3 : 3 +>this.#z : any +>this : this +>3 : 3 + } +} diff --git a/tests/baselines/reference/privateNameJsx.errors.txt b/tests/baselines/reference/privateNameJsx.errors.txt new file mode 100644 index 0000000000000..380252cb21f00 --- /dev/null +++ b/tests/baselines/reference/privateNameJsx.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/privateNameJsx.tsx(4,27): error TS1003: Identifier expected. + + +==== tests/cases/compiler/privateNameJsx.tsx (1 errors) ==== + class Test { + #prop = () =>
; + render() { + return ; + +!!! error TS1003: Identifier expected. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameJsx.js b/tests/baselines/reference/privateNameJsx.js new file mode 100644 index 0000000000000..9b4098f1e196b --- /dev/null +++ b/tests/baselines/reference/privateNameJsx.js @@ -0,0 +1,22 @@ +//// [privateNameJsx.tsx] +class Test { + #prop = () =>
; + render() { + return ; + } +} + + + +//// [privateNameJsx.jsx] +var _prop; +var Test = /** @class */ (function () { + function Test() { + _prop.set(this, function () { return
; }); + } + Test.prototype.render = function () { + return ; + }; + return Test; +}()); +_prop = new WeakMap(); diff --git a/tests/baselines/reference/privateNameJsx.symbols b/tests/baselines/reference/privateNameJsx.symbols new file mode 100644 index 0000000000000..1236bcacb7b06 --- /dev/null +++ b/tests/baselines/reference/privateNameJsx.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/privateNameJsx.tsx === +class Test { +>Test : Symbol(Test, Decl(privateNameJsx.tsx, 0, 0)) + + #prop = () =>
; +>#prop : Symbol(Test.#prop, Decl(privateNameJsx.tsx, 0, 12)) + + render() { +>render : Symbol(Test.render, Decl(privateNameJsx.tsx, 1, 26)) + + return ; +>this : Symbol(Test, Decl(privateNameJsx.tsx, 0, 0)) + } +} + + diff --git a/tests/baselines/reference/privateNameJsx.types b/tests/baselines/reference/privateNameJsx.types new file mode 100644 index 0000000000000..a0d9559719924 --- /dev/null +++ b/tests/baselines/reference/privateNameJsx.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/privateNameJsx.tsx === +class Test { +>Test : Test + + #prop = () =>
; +>#prop : () => any +>() =>
: () => any +>
: any +>div : any + + render() { +>render : () => any + + return ; +> : any +>this.#prop : any +>this : this +> : any + } +} + + diff --git a/tests/baselines/reference/privateNameNestedClassFieldShadowing.errors.txt b/tests/baselines/reference/privateNameNestedClassFieldShadowing.errors.txt new file mode 100644 index 0000000000000..eacd9de9f6153 --- /dev/null +++ b/tests/baselines/reference/privateNameNestedClassFieldShadowing.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts(7,31): error TS18014: The property '#x' cannot be accessed on type 'Base' within this class because it is shadowed by another private identifier with the same spelling. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts (1 errors) ==== + class Base { + #x; + constructor() { + class Derived { + #x; + testBase(x: Base) { + console.log(x.#x); + ~~ +!!! error TS18014: The property '#x' cannot be accessed on type 'Base' within this class because it is shadowed by another private identifier with the same spelling. +!!! related TS18017 tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts:5:13: The shadowing declaration of '#x' is defined here +!!! related TS18018 tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts:2:5: The declaration of '#x' that you probably intended to use is defined here + } + testDerived(x: Derived) { + console.log(x.#x); + } + } + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameNestedClassFieldShadowing.js b/tests/baselines/reference/privateNameNestedClassFieldShadowing.js new file mode 100644 index 0000000000000..ae661e3230b6a --- /dev/null +++ b/tests/baselines/reference/privateNameNestedClassFieldShadowing.js @@ -0,0 +1,44 @@ +//// [privateNameNestedClassFieldShadowing.ts] +class Base { + #x; + constructor() { + class Derived { + #x; + testBase(x: Base) { + console.log(x.#x); + } + testDerived(x: Derived) { + console.log(x.#x); + } + } + } +} + + +//// [privateNameNestedClassFieldShadowing.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _x; +class Base { + constructor() { + var _x_1; + _x.set(this, void 0); + class Derived { + constructor() { + _x_1.set(this, void 0); + } + testBase(x) { + console.log(__classPrivateFieldGet(x, _x_1)); + } + testDerived(x) { + console.log(__classPrivateFieldGet(x, _x_1)); + } + } + _x_1 = new WeakMap(); + } +} +_x = new WeakMap(); diff --git a/tests/baselines/reference/privateNameNestedClassFieldShadowing.symbols b/tests/baselines/reference/privateNameNestedClassFieldShadowing.symbols new file mode 100644 index 0000000000000..f9f8dd370d5e6 --- /dev/null +++ b/tests/baselines/reference/privateNameNestedClassFieldShadowing.symbols @@ -0,0 +1,41 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts === +class Base { +>Base : Symbol(Base, Decl(privateNameNestedClassFieldShadowing.ts, 0, 0)) + + #x; +>#x : Symbol(Base.#x, Decl(privateNameNestedClassFieldShadowing.ts, 0, 12)) + + constructor() { + class Derived { +>Derived : Symbol(Derived, Decl(privateNameNestedClassFieldShadowing.ts, 2, 19)) + + #x; +>#x : Symbol(Derived.#x, Decl(privateNameNestedClassFieldShadowing.ts, 3, 23)) + + testBase(x: Base) { +>testBase : Symbol(Derived.testBase, Decl(privateNameNestedClassFieldShadowing.ts, 4, 15)) +>x : Symbol(x, Decl(privateNameNestedClassFieldShadowing.ts, 5, 21)) +>Base : Symbol(Base, Decl(privateNameNestedClassFieldShadowing.ts, 0, 0)) + + console.log(x.#x); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(privateNameNestedClassFieldShadowing.ts, 5, 21)) + } + testDerived(x: Derived) { +>testDerived : Symbol(Derived.testDerived, Decl(privateNameNestedClassFieldShadowing.ts, 7, 13)) +>x : Symbol(x, Decl(privateNameNestedClassFieldShadowing.ts, 8, 24)) +>Derived : Symbol(Derived, Decl(privateNameNestedClassFieldShadowing.ts, 2, 19)) + + console.log(x.#x); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x.#x : Symbol(Derived.#x, Decl(privateNameNestedClassFieldShadowing.ts, 3, 23)) +>x : Symbol(x, Decl(privateNameNestedClassFieldShadowing.ts, 8, 24)) + } + } + } +} + diff --git a/tests/baselines/reference/privateNameNestedClassFieldShadowing.types b/tests/baselines/reference/privateNameNestedClassFieldShadowing.types new file mode 100644 index 0000000000000..e6525dfbcac4f --- /dev/null +++ b/tests/baselines/reference/privateNameNestedClassFieldShadowing.types @@ -0,0 +1,42 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts === +class Base { +>Base : Base + + #x; +>#x : any + + constructor() { + class Derived { +>Derived : Derived + + #x; +>#x : any + + testBase(x: Base) { +>testBase : (x: Base) => void +>x : Base + + console.log(x.#x); +>console.log(x.#x) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>x.#x : any +>x : Base + } + testDerived(x: Derived) { +>testDerived : (x: Derived) => void +>x : Derived + + console.log(x.#x); +>console.log(x.#x) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>x.#x : any +>x : Derived + } + } + } +} + diff --git a/tests/baselines/reference/privateNameNestedClassNameConflict.js b/tests/baselines/reference/privateNameNestedClassNameConflict.js new file mode 100644 index 0000000000000..23bbeeaae8838 --- /dev/null +++ b/tests/baselines/reference/privateNameNestedClassNameConflict.js @@ -0,0 +1,26 @@ +//// [privateNameNestedClassNameConflict.ts] +class A { + #foo: string; + constructor() { + class A { + #foo: string; + } + } +} + + +//// [privateNameNestedClassNameConflict.js] +var _foo; +class A { + constructor() { + var _foo_1; + _foo.set(this, void 0); + class A { + constructor() { + _foo_1.set(this, void 0); + } + } + _foo_1 = new WeakMap(); + } +} +_foo = new WeakMap(); diff --git a/tests/baselines/reference/privateNameNestedClassNameConflict.symbols b/tests/baselines/reference/privateNameNestedClassNameConflict.symbols new file mode 100644 index 0000000000000..5fec01b052701 --- /dev/null +++ b/tests/baselines/reference/privateNameNestedClassNameConflict.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNestedClassNameConflict.ts === +class A { +>A : Symbol(A, Decl(privateNameNestedClassNameConflict.ts, 0, 0)) + + #foo: string; +>#foo : Symbol(A.#foo, Decl(privateNameNestedClassNameConflict.ts, 0, 9)) + + constructor() { + class A { +>A : Symbol(A, Decl(privateNameNestedClassNameConflict.ts, 2, 19)) + + #foo: string; +>#foo : Symbol(A.#foo, Decl(privateNameNestedClassNameConflict.ts, 3, 17)) + } + } +} + diff --git a/tests/baselines/reference/privateNameNestedClassNameConflict.types b/tests/baselines/reference/privateNameNestedClassNameConflict.types new file mode 100644 index 0000000000000..de6589940da50 --- /dev/null +++ b/tests/baselines/reference/privateNameNestedClassNameConflict.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameNestedClassNameConflict.ts === +class A { +>A : A + + #foo: string; +>#foo : string + + constructor() { + class A { +>A : A + + #foo: string; +>#foo : string + } + } +} + diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt index 5b4b1c66695e3..a012c9d2b5d12 100644 --- a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.errors.txt @@ -1,17 +1,12 @@ -tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts(7,9): error TS2339: Property '#foo' does not exist on type 'A'. -tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts(7,9): error TS18013: Property '#foo' is not accessible outside class 'A' because it has a private name. +tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts(5,9): error TS18013: Property '#foo' is not accessible outside class 'A' because it has a private identifier. -==== tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts (2 errors) ==== - // @target es6 - +==== tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts (1 errors) ==== class A { #foo: number = 3; } new A().#foo = 4; // Error ~~~~ -!!! error TS2339: Property '#foo' does not exist on type 'A'. - ~~~~ -!!! error TS18013: Property '#foo' is not accessible outside class 'A' because it has a private name. +!!! error TS18013: Property '#foo' is not accessible outside class 'A' because it has a private identifier. \ No newline at end of file diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js index 355f1676c2377..3bb84305a4ac8 100644 --- a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.js @@ -1,6 +1,4 @@ //// [privateNameNotAccessibleOutsideDefiningClass.ts] -// @target es6 - class A { #foo: number = 3; } @@ -10,11 +8,11 @@ new A().#foo = 4; // Error //// [privateNameNotAccessibleOutsideDefiningClass.js] "use strict"; -// @target es6 -var A = /** @class */ (function () { - function A() { - this[] = 3; +var _foo; +class A { + constructor() { + _foo.set(this, 3); } - return A; -}()); +} +_foo = new WeakMap(); new A(). = 4; // Error diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols index 8d9427fc6d603..e35a576c3f47a 100644 --- a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.symbols @@ -1,11 +1,9 @@ === tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNameNotAccessibleOutsideDefiningClass.ts, 0, 0)) #foo: number = 3; ->#foo : Symbol(A.#foo, Decl(privateNameNotAccessibleOutsideDefiningClass.ts, 2, 9)) +>#foo : Symbol(A.#foo, Decl(privateNameNotAccessibleOutsideDefiningClass.ts, 0, 9)) } new A().#foo = 4; // Error diff --git a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types index e6a0f5ac8f55b..19bf4a9476ca0 100644 --- a/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types +++ b/tests/baselines/reference/privateNameNotAccessibleOutsideDefiningClass.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts === -// @target es6 - class A { >A : A diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt b/tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt index 2e72fffc7ba78..0dbe9de23ce41 100644 --- a/tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.errors.txt @@ -1,15 +1,14 @@ -tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(3,7): error TS1134: Variable declaration expected. -tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(3,12): error TS1134: Variable declaration expected. -tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(3,14): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(1,7): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(1,12): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts(1,14): error TS1134: Variable declaration expected. ==== tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts (3 errors) ==== - // @target es6 - const #foo = 3; ~~~~ !!! error TS1134: Variable declaration expected. ~ !!! error TS1134: Variable declaration expected. ~ -!!! error TS1134: Variable declaration expected. \ No newline at end of file +!!! error TS1134: Variable declaration expected. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.js b/tests/baselines/reference/privateNameNotAllowedOutsideClass.js index ff2b64b910ca1..2400cc26e6ff2 100644 --- a/tests/baselines/reference/privateNameNotAllowedOutsideClass.js +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.js @@ -1,10 +1,8 @@ //// [privateNameNotAllowedOutsideClass.ts] -// @target es6 - -const #foo = 3; +const #foo = 3; + //// [privateNameNotAllowedOutsideClass.js] "use strict"; -// @target es6 -var ; +const ; 3; diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols b/tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols index 6d6883e7fdf59..9d184ec55b53b 100644 --- a/tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.symbols @@ -1,5 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts === -// @target es6 +const #foo = 3; No type information for this code. -No type information for this code.const #foo = 3; No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/privateNameNotAllowedOutsideClass.types b/tests/baselines/reference/privateNameNotAllowedOutsideClass.types index 534e5b042580f..20826f41a55e1 100644 --- a/tests/baselines/reference/privateNameNotAllowedOutsideClass.types +++ b/tests/baselines/reference/privateNameNotAllowedOutsideClass.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts === -// @target es6 - const #foo = 3; >3 : 3 diff --git a/tests/baselines/reference/privateNameSneakyRuntimeException.js b/tests/baselines/reference/privateNameSneakyRuntimeException.js deleted file mode 100644 index 3a5b3a971f311..0000000000000 --- a/tests/baselines/reference/privateNameSneakyRuntimeException.js +++ /dev/null @@ -1,47 +0,0 @@ -//// [privateNameSneakyRuntimeException.ts] -// @target es6 - -function createClass () { - return class { - #foo = 3; - equals(other: any) { - return this.#foo = other.#foo; - } - }; -} - -const a = new (createClass())(); -const b = new (createClass())(); - -console.log(a.equals(b)); // OK at compile time but will be a runtime error - - -tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js(6,18): error TS1011: An element access expression should take an argument. -tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js(9,26): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js(9,34): error TS1003: Identifier expected. - - -==== tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.js (3 errors) ==== - "use strict"; - // @target es6 - function createClass() { - return /** @class */ (function () { - function class_1() { - this[] = 3; - -!!! error TS1011: An element access expression should take an argument. - } - class_1.prototype.equals = function (other) { - return this. = other.; - ~ -!!! error TS1003: Identifier expected. - ~ -!!! error TS1003: Identifier expected. - }; - return class_1; - }()); - } - var a = new (createClass())(); - var b = new (createClass())(); - console.log(a.equals(b)); // OK at compile time but will be a runtime error - \ No newline at end of file diff --git a/tests/baselines/reference/privateNameSneakyRuntimeException.symbols b/tests/baselines/reference/privateNameSneakyRuntimeException.symbols deleted file mode 100644 index 585bdbf782c43..0000000000000 --- a/tests/baselines/reference/privateNameSneakyRuntimeException.symbols +++ /dev/null @@ -1,39 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts === -// @target es6 - -function createClass () { ->createClass : Symbol(createClass, Decl(privateNameSneakyRuntimeException.ts, 0, 0)) - - return class { - #foo = 3; ->#foo : Symbol((Anonymous class).#foo, Decl(privateNameSneakyRuntimeException.ts, 3, 18)) - - equals(other: any) { ->equals : Symbol((Anonymous class).equals, Decl(privateNameSneakyRuntimeException.ts, 4, 17)) ->other : Symbol(other, Decl(privateNameSneakyRuntimeException.ts, 5, 15)) - - return this.#foo = other.#foo; ->this.#foo : Symbol((Anonymous class).#foo, Decl(privateNameSneakyRuntimeException.ts, 3, 18)) ->this : Symbol((Anonymous class), Decl(privateNameSneakyRuntimeException.ts, 3, 10)) ->other : Symbol(other, Decl(privateNameSneakyRuntimeException.ts, 5, 15)) - } - }; -} - -const a = new (createClass())(); ->a : Symbol(a, Decl(privateNameSneakyRuntimeException.ts, 11, 5)) ->createClass : Symbol(createClass, Decl(privateNameSneakyRuntimeException.ts, 0, 0)) - -const b = new (createClass())(); ->b : Symbol(b, Decl(privateNameSneakyRuntimeException.ts, 12, 5)) ->createClass : Symbol(createClass, Decl(privateNameSneakyRuntimeException.ts, 0, 0)) - -console.log(a.equals(b)); // OK at compile time but will be a runtime error ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->a.equals : Symbol((Anonymous class).equals, Decl(privateNameSneakyRuntimeException.ts, 4, 17)) ->a : Symbol(a, Decl(privateNameSneakyRuntimeException.ts, 11, 5)) ->equals : Symbol((Anonymous class).equals, Decl(privateNameSneakyRuntimeException.ts, 4, 17)) ->b : Symbol(b, Decl(privateNameSneakyRuntimeException.ts, 12, 5)) - diff --git a/tests/baselines/reference/privateNameSneakyRuntimeException.types b/tests/baselines/reference/privateNameSneakyRuntimeException.types deleted file mode 100644 index 6f080bb585fca..0000000000000 --- a/tests/baselines/reference/privateNameSneakyRuntimeException.types +++ /dev/null @@ -1,52 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts === -// @target es6 - -function createClass () { ->createClass : () => typeof (Anonymous class) - - return class { ->class { #foo = 3; equals(other: any) { return this.#foo = other.#foo; } } : typeof (Anonymous class) - - #foo = 3; ->#foo : number ->3 : 3 - - equals(other: any) { ->equals : (other: any) => any ->other : any - - return this.#foo = other.#foo; ->this.#foo = other.#foo : any ->this.#foo : number ->this : this ->other.#foo : any ->other : any - } - }; -} - -const a = new (createClass())(); ->a : (Anonymous class) ->new (createClass())() : (Anonymous class) ->(createClass()) : typeof (Anonymous class) ->createClass() : typeof (Anonymous class) ->createClass : () => typeof (Anonymous class) - -const b = new (createClass())(); ->b : (Anonymous class) ->new (createClass())() : (Anonymous class) ->(createClass()) : typeof (Anonymous class) ->createClass() : typeof (Anonymous class) ->createClass : () => typeof (Anonymous class) - -console.log(a.equals(b)); // OK at compile time but will be a runtime error ->console.log(a.equals(b)) : void ->console.log : (message?: any, ...optionalParams: any[]) => void ->console : Console ->log : (message?: any, ...optionalParams: any[]) => void ->a.equals(b) : any ->a.equals : (other: any) => any ->a : (Anonymous class) ->equals : (other: any) => any ->b : (Anonymous class) - diff --git a/tests/baselines/reference/privateNameUnused.errors.txt b/tests/baselines/reference/privateNameUnused.errors.txt new file mode 100644 index 0000000000000..cb4bd1853f0d9 --- /dev/null +++ b/tests/baselines/reference/privateNameUnused.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts(3,5): error TS6133: '#unused' is declared but its value is never read. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts (1 errors) ==== + export class A { + #used = "used"; + #unused = "unused"; + ~~~~~~~ +!!! error TS6133: '#unused' is declared but its value is never read. + constructor () { + console.log(this.#used); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameUnused.symbols b/tests/baselines/reference/privateNameUnused.symbols new file mode 100644 index 0000000000000..4b85303d6f2ed --- /dev/null +++ b/tests/baselines/reference/privateNameUnused.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts === +export class A { +>A : Symbol(A, Decl(privateNameUnused.ts, 0, 0)) + + #used = "used"; +>#used : Symbol(A.#used, Decl(privateNameUnused.ts, 0, 16)) + + #unused = "unused"; +>#unused : Symbol(A.#unused, Decl(privateNameUnused.ts, 1, 19)) + + constructor () { + console.log(this.#used); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this.#used : Symbol(A.#used, Decl(privateNameUnused.ts, 0, 16)) +>this : Symbol(A, Decl(privateNameUnused.ts, 0, 0)) + } +} + diff --git a/tests/baselines/reference/privateNameUnused.types b/tests/baselines/reference/privateNameUnused.types new file mode 100644 index 0000000000000..18c1e43f89d24 --- /dev/null +++ b/tests/baselines/reference/privateNameUnused.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts === +export class A { +>A : A + + #used = "used"; +>#used : string +>"used" : "used" + + #unused = "unused"; +>#unused : string +>"unused" : "unused" + + constructor () { + console.log(this.#used); +>console.log(this.#used) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this.#used : string +>this : this + } +} + diff --git a/tests/baselines/reference/privateNameWeakMapCollision.errors.txt b/tests/baselines/reference/privateNameWeakMapCollision.errors.txt new file mode 100644 index 0000000000000..6c4904cec79e1 --- /dev/null +++ b/tests/baselines/reference/privateNameWeakMapCollision.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/privateNameWeakMapCollision.ts(2,9): error TS18027: Compiler reserves name 'WeakMap' when emitting private identifier downlevel. + + +==== tests/cases/compiler/privateNameWeakMapCollision.ts (1 errors) ==== + function test() { + let WeakMap; + ~~~~~~~ +!!! error TS18027: Compiler reserves name 'WeakMap' when emitting private identifier downlevel. + class C { + #x; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameWeakMapCollision.js b/tests/baselines/reference/privateNameWeakMapCollision.js new file mode 100644 index 0000000000000..8b810f62240ae --- /dev/null +++ b/tests/baselines/reference/privateNameWeakMapCollision.js @@ -0,0 +1,20 @@ +//// [privateNameWeakMapCollision.ts] +function test() { + let WeakMap; + class C { + #x; + } +} + + +//// [privateNameWeakMapCollision.js] +function test() { + var _x; + let WeakMap; + class C { + constructor() { + _x.set(this, void 0); + } + } + _x = new WeakMap(); +} diff --git a/tests/baselines/reference/privateNameWeakMapCollision.symbols b/tests/baselines/reference/privateNameWeakMapCollision.symbols new file mode 100644 index 0000000000000..5bfd7d8070508 --- /dev/null +++ b/tests/baselines/reference/privateNameWeakMapCollision.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/privateNameWeakMapCollision.ts === +function test() { +>test : Symbol(test, Decl(privateNameWeakMapCollision.ts, 0, 0)) + + let WeakMap; +>WeakMap : Symbol(WeakMap, Decl(privateNameWeakMapCollision.ts, 1, 7)) + + class C { +>C : Symbol(C, Decl(privateNameWeakMapCollision.ts, 1, 16)) + + #x; +>#x : Symbol(C.#x, Decl(privateNameWeakMapCollision.ts, 2, 13)) + } +} + diff --git a/tests/baselines/reference/privateNameWeakMapCollision.types b/tests/baselines/reference/privateNameWeakMapCollision.types new file mode 100644 index 0000000000000..377c3f214c436 --- /dev/null +++ b/tests/baselines/reference/privateNameWeakMapCollision.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/privateNameWeakMapCollision.ts === +function test() { +>test : () => void + + let WeakMap; +>WeakMap : any + + class C { +>C : C + + #x; +>#x : any + } +} + diff --git a/tests/baselines/reference/privateNamesAndDecorators.errors.txt b/tests/baselines/reference/privateNamesAndDecorators.errors.txt index a17770c1cb2a7..aea3772ca2e9d 100644 --- a/tests/baselines/reference/privateNamesAndDecorators.errors.txt +++ b/tests/baselines/reference/privateNamesAndDecorators.errors.txt @@ -1,8 +1,9 @@ tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts(4,5): error TS1206: Decorators are not valid here. tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts(6,5): error TS1206: Decorators are not valid here. +tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts(7,5): error TS18022: A method cannot be named with a private identifier. -==== tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts (2 errors) ==== +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.ts (3 errors) ==== declare function dec(target: T): T; class A { @@ -14,5 +15,7 @@ tests/cases/conformance/classes/members/privateNames/privateNamesAndDecorators.t ~ !!! error TS1206: Decorators are not valid here. #bar(): void { } + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. } \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndDecorators.js b/tests/baselines/reference/privateNamesAndDecorators.js index 3c50944ab04dc..63183cf3df9ba 100644 --- a/tests/baselines/reference/privateNamesAndDecorators.js +++ b/tests/baselines/reference/privateNamesAndDecorators.js @@ -10,10 +10,12 @@ class A { //// [privateNamesAndDecorators.js] +var _foo; var A = /** @class */ (function () { function A() { - this[] = 1; + _foo.set(this, 1); } - A.prototype[] = function () { }; + A.prototype. = function () { }; return A; }()); +_foo = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesAndFields.js b/tests/baselines/reference/privateNamesAndFields.js index 06aaa64003b63..5af74f92ab9a0 100644 --- a/tests/baselines/reference/privateNamesAndFields.js +++ b/tests/baselines/reference/privateNamesAndFields.js @@ -1,6 +1,4 @@ //// [privateNamesAndFields.ts] -// @target es6 - class A { #foo: number; constructor () { @@ -17,43 +15,28 @@ class B extends A { } -tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.js(18,15): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.js(26,16): error TS1003: Identifier expected. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.js (2 errors) ==== - "use strict"; - // @target es6 - var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - var A = /** @class */ (function () { - function A() { - this. = 3; - ~ -!!! error TS1003: Identifier expected. - } - return A; - }()); - var B = /** @class */ (function (_super) { - __extends(B, _super); - function B() { - var _this = _super.call(this) || this; - _this. = "some string"; - ~ -!!! error TS1003: Identifier expected. - return _this; - } - return B; - }(A)); - \ No newline at end of file +//// [privateNamesAndFields.js] +"use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var _foo, _foo_1; +class A { + constructor() { + _foo.set(this, void 0); + __classPrivateFieldSet(this, _foo, 3); + } +} +_foo = new WeakMap(); +class B extends A { + constructor() { + super(); + _foo_1.set(this, void 0); + __classPrivateFieldSet(this, _foo_1, "some string"); + } +} +_foo_1 = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesAndFields.symbols b/tests/baselines/reference/privateNamesAndFields.symbols index 5300cd0427ff0..e3fca52448510 100644 --- a/tests/baselines/reference/privateNamesAndFields.symbols +++ b/tests/baselines/reference/privateNamesAndFields.symbols @@ -1,33 +1,31 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) #foo: number; ->#foo : Symbol(A.#foo, Decl(privateNamesAndFields.ts, 2, 9)) +>#foo : Symbol(A.#foo, Decl(privateNamesAndFields.ts, 0, 9)) constructor () { this.#foo = 3; ->this.#foo : Symbol(A.#foo, Decl(privateNamesAndFields.ts, 2, 9)) +>this.#foo : Symbol(A.#foo, Decl(privateNamesAndFields.ts, 0, 9)) >this : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) } } class B extends A { ->B : Symbol(B, Decl(privateNamesAndFields.ts, 7, 1)) +>B : Symbol(B, Decl(privateNamesAndFields.ts, 5, 1)) >A : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) #foo: string; ->#foo : Symbol(B.#foo, Decl(privateNamesAndFields.ts, 9, 19)) +>#foo : Symbol(B.#foo, Decl(privateNamesAndFields.ts, 7, 19)) constructor () { super(); >super : Symbol(A, Decl(privateNamesAndFields.ts, 0, 0)) this.#foo = "some string"; ->this.#foo : Symbol(B.#foo, Decl(privateNamesAndFields.ts, 9, 19)) ->this : Symbol(B, Decl(privateNamesAndFields.ts, 7, 1)) +>this.#foo : Symbol(B.#foo, Decl(privateNamesAndFields.ts, 7, 19)) +>this : Symbol(B, Decl(privateNamesAndFields.ts, 5, 1)) } } diff --git a/tests/baselines/reference/privateNamesAndFields.types b/tests/baselines/reference/privateNamesAndFields.types index 88a48ecd81298..d794cefa06328 100644 --- a/tests/baselines/reference/privateNamesAndFields.types +++ b/tests/baselines/reference/privateNamesAndFields.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts === -// @target es6 - class A { >A : A diff --git a/tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt b/tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt index 58e321374b8c1..c44ec084989b9 100644 --- a/tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt +++ b/tests/baselines/reference/privateNamesAndGenericClasses-2.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(24,3): error TS2339: Property '#foo' does not exist on type 'C'. -tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(24,3): error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. +tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(3,5): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(24,3): error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private identifier. tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(25,1): error TS2322: Type 'C' is not assignable to type 'C'. Type 'string' is not assignable to type 'number'. tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClasses-2.ts(26,1): error TS2322: Type 'C' is not assignable to type 'C'. @@ -10,6 +10,8 @@ tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClass class C { #foo: T; #bar(): T { + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. return this.#foo; } constructor(t: T) { @@ -32,9 +34,7 @@ tests/cases/conformance/classes/members/privateNames/privateNamesAndGenericClass const x: number = a.baz // OK a.#foo; // Error ~~~~ -!!! error TS2339: Property '#foo' does not exist on type 'C'. - ~~~~ -!!! error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. +!!! error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private identifier. a = b; // Error ~ !!! error TS2322: Type 'C' is not assignable to type 'C'. diff --git a/tests/baselines/reference/privateNamesAndGenericClasses-2.js b/tests/baselines/reference/privateNamesAndGenericClasses-2.js index fb344944965a7..0d62474bc636c 100644 --- a/tests/baselines/reference/privateNamesAndGenericClasses-2.js +++ b/tests/baselines/reference/privateNamesAndGenericClasses-2.js @@ -29,21 +29,37 @@ b = a; // Error //// [privateNamesAndGenericClasses-2.js] "use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo; class C { constructor(t) { - this. = t; - t = this.(); + _foo.set(this, void 0); + __classPrivateFieldSet(this, _foo, t); + t = this..call(this); } () { - return this.; + return __classPrivateFieldGet(this, _foo); } set baz(t) { - this. = t; + __classPrivateFieldSet(this, _foo, t); } get baz() { - return this.; + return __classPrivateFieldGet(this, _foo); } } +_foo = new WeakMap(); let a = new C(3); let b = new C("hello"); a.baz = 5; // OK diff --git a/tests/baselines/reference/privateNamesAndIndexedAccess.js b/tests/baselines/reference/privateNamesAndIndexedAccess.js index 805c31f9ff3b1..67be3d4cb6006 100644 --- a/tests/baselines/reference/privateNamesAndIndexedAccess.js +++ b/tests/baselines/reference/privateNamesAndIndexedAccess.js @@ -14,10 +14,12 @@ class C { //// [privateNamesAndIndexedAccess.js] "use strict"; +var _bar, _bar_1; class C { constructor() { this.foo = 3; - this[] = 3; + _bar_1.set(this, 3); + _bar_1.set(this, void 0); // will never use this syntax, already taken: this.badAlways = 3; // Error const ok = 3; @@ -25,3 +27,4 @@ class C { const badForNow; } } +_bar = new WeakMap(), _bar_1 = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesAndMethods.errors.txt b/tests/baselines/reference/privateNamesAndMethods.errors.txt new file mode 100644 index 0000000000000..a213c9911be49 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndMethods.errors.txt @@ -0,0 +1,51 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts(2,5): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts(3,11): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts(4,12): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts(8,9): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts(11,9): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts(24,5): error TS18022: A method cannot be named with a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts (6 errors) ==== + class A { + #foo(a: number) {} + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + async #bar(a: number) {} + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + async *#baz(a: number) { + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + return 3; + } + #_quux: number; + get #quux (): number { + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + return this.#_quux; + } + set #quux (val: number) { + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + this.#_quux = val; + } + constructor () { + this.#foo(30); + this.#bar(30); + this.#baz(30); + this.#quux = this.#quux + 1; + this.#quux++; + } + } + + class B extends A { + #foo(a: string) {} + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + constructor () { + super(); + this.#foo("str"); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndMethods.js b/tests/baselines/reference/privateNamesAndMethods.js index 4df5f690afa0f..c216ce98e5cb3 100644 --- a/tests/baselines/reference/privateNamesAndMethods.js +++ b/tests/baselines/reference/privateNamesAndMethods.js @@ -15,7 +15,7 @@ class A { constructor () { this.#foo(30); this.#bar(30); - this.#bar(30); + this.#baz(30); this.#quux = this.#quux + 1; this.#quux++; } @@ -30,94 +30,32 @@ class B extends A { } -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(3,14): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(4,14): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(5,14): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(6,15): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(6,23): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(7,14): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(9,5): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(9,9): error TS1005: '=>' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(10,15): error TS1005: '=>' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(11,16): error TS1005: ';' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(14,12): error TS1005: ';' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(15,21): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(17,15): error TS1005: ';' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(18,15): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(20,1): error TS1128: Declaration or statement expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(22,5): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(22,9): error TS1005: '=>' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(23,19): error TS1005: ';' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(25,14): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js(27,1): error TS1128: Declaration or statement expected. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.js (20 errors) ==== - class A { - constructor() { - this.(30); - ~ -!!! error TS1003: Identifier expected. - this.(30); - ~ -!!! error TS1003: Identifier expected. - this.(30); - ~ -!!! error TS1003: Identifier expected. - this. = this. + 1; - ~ -!!! error TS1003: Identifier expected. - ~ -!!! error TS1003: Identifier expected. - this.++; - ~~ -!!! error TS1003: Identifier expected. - } - (a) { } - ~ -!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. - ~ -!!! error TS1005: '=>' expected. - async (a) { } - ~ -!!! error TS1005: '=>' expected. - async *(a) { - ~ -!!! error TS1005: ';' expected. - return 3; - } - get () { - ~ -!!! error TS1005: ';' expected. - return this.; - ~ -!!! error TS1003: Identifier expected. - } - set (val) { - ~ -!!! error TS1005: ';' expected. - this. = val; - ~ -!!! error TS1003: Identifier expected. - } +//// [privateNamesAndMethods.js] +class A { + constructor() { + this.#foo(30); + this.#bar(30); + this.#baz(30); + this.#quux = this.#quux + 1; + this.#quux++; + } + #foo(a) { } + async #bar(a) { } + async *#baz(a) { + return 3; + } + #_quux; + get #quux() { + return this.#_quux; + } + set #quux(val) { + this.#_quux = val; } - ~ -!!! error TS1128: Declaration or statement expected. - class B extends A { - (a) { } - ~ -!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. - ~ -!!! error TS1005: '=>' expected. - constructor() { - ~ -!!! error TS1005: ';' expected. - super(); - this.("str"); - ~ -!!! error TS1003: Identifier expected. - } +} +class B extends A { + #foo(a) { } + constructor() { + super(); + this.#foo("str"); } - ~ -!!! error TS1128: Declaration or statement expected. - \ No newline at end of file +} diff --git a/tests/baselines/reference/privateNamesAndMethods.symbols b/tests/baselines/reference/privateNamesAndMethods.symbols index 817f1dcd31112..868a08790c591 100644 --- a/tests/baselines/reference/privateNamesAndMethods.symbols +++ b/tests/baselines/reference/privateNamesAndMethods.symbols @@ -44,8 +44,8 @@ class A { >this.#bar : Symbol(A.#bar, Decl(privateNamesAndMethods.ts, 1, 22)) >this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) - this.#bar(30); ->this.#bar : Symbol(A.#bar, Decl(privateNamesAndMethods.ts, 1, 22)) + this.#baz(30); +>this.#baz : Symbol(A.#baz, Decl(privateNamesAndMethods.ts, 2, 28)) >this : Symbol(A, Decl(privateNamesAndMethods.ts, 0, 0)) this.#quux = this.#quux + 1; diff --git a/tests/baselines/reference/privateNamesAndMethods.types b/tests/baselines/reference/privateNamesAndMethods.types index 9f8fa569f1719..2d9a1d9363422 100644 --- a/tests/baselines/reference/privateNamesAndMethods.types +++ b/tests/baselines/reference/privateNamesAndMethods.types @@ -50,9 +50,9 @@ class A { >this : this >30 : 30 - this.#bar(30); ->this.#bar(30) : Promise ->this.#bar : (a: number) => Promise + this.#baz(30); +>this.#baz(30) : AsyncGenerator +>this.#baz : (a: number) => AsyncGenerator >this : this >30 : 30 diff --git a/tests/baselines/reference/privateNamesAndStaticFields.errors.txt b/tests/baselines/reference/privateNamesAndStaticFields.errors.txt new file mode 100644 index 0000000000000..df111ef53e34e --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticFields.errors.txt @@ -0,0 +1,40 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts(2,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts(3,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts(6,11): error TS18013: Property '#foo' is not accessible outside class 'B' because it has a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts(7,11): error TS2339: Property '#bar' does not exist on type 'typeof B'. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts(12,5): error TS18019: 'static' modifier cannot be used with a private identifier + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts (5 errors) ==== + class A { + static #foo: number; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + static #bar: number; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + constructor () { + A.#foo = 3; + B.#foo; // Error + ~~~~ +!!! error TS18013: Property '#foo' is not accessible outside class 'B' because it has a private identifier. + B.#bar; // Error + ~~~~ +!!! error TS2339: Property '#bar' does not exist on type 'typeof B'. + } + } + + class B extends A { + static #foo: string; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + constructor () { + super(); + B.#foo = "some string"; + } + } + + // We currently filter out static private identifier fields in `getUnmatchedProperties`. + // We will need a more robust solution when we support static fields + const willErrorSomeDay: typeof A = class {}; // OK for now + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndStaticFields.js b/tests/baselines/reference/privateNamesAndStaticFields.js index cd9bead54c5b1..5b3458d049a7f 100644 --- a/tests/baselines/reference/privateNamesAndStaticFields.js +++ b/tests/baselines/reference/privateNamesAndStaticFields.js @@ -1,10 +1,11 @@ //// [privateNamesAndStaticFields.ts] -// @target es6 - class A { static #foo: number; + static #bar: number; constructor () { A.#foo = 3; + B.#foo; // Error + B.#bar; // Error } } @@ -15,45 +16,44 @@ class B extends A { B.#foo = "some string"; } } + +// We currently filter out static private identifier fields in `getUnmatchedProperties`. +// We will need a more robust solution when we support static fields +const willErrorSomeDay: typeof A = class {}; // OK for now -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.js(18,12): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.js(26,12): error TS1003: Identifier expected. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.js (2 errors) ==== - "use strict"; - // @target es6 - var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - var A = /** @class */ (function () { - function A() { - A. = 3; - ~ -!!! error TS1003: Identifier expected. - } - return A; - }()); - var B = /** @class */ (function (_super) { - __extends(B, _super); - function B() { - var _this = _super.call(this) || this; - B. = "some string"; - ~ -!!! error TS1003: Identifier expected. - return _this; - } - return B; - }(A)); - \ No newline at end of file +//// [privateNamesAndStaticFields.js] +"use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo, _bar, _foo_1; +class A { + constructor() { + __classPrivateFieldSet(A, _foo, 3); + __classPrivateFieldGet(B, _foo); // Error + __classPrivateFieldGet(B, _bar); // Error + } +} +_foo = new WeakMap(), _bar = new WeakMap(); +class B extends A { + constructor() { + super(); + __classPrivateFieldSet(B, _foo_1, "some string"); + } +} +_foo_1 = new WeakMap(); +// We currently filter out static private identifier fields in `getUnmatchedProperties`. +// We will need a more robust solution when we support static fields +const willErrorSomeDay = class { +}; // OK for now diff --git a/tests/baselines/reference/privateNamesAndStaticFields.symbols b/tests/baselines/reference/privateNamesAndStaticFields.symbols index 5898928bfb741..e2109f68a3cc1 100644 --- a/tests/baselines/reference/privateNamesAndStaticFields.symbols +++ b/tests/baselines/reference/privateNamesAndStaticFields.symbols @@ -1,33 +1,46 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) static #foo: number; ->#foo : Symbol(A.#foo, Decl(privateNamesAndStaticFields.ts, 2, 9)) +>#foo : Symbol(A.#foo, Decl(privateNamesAndStaticFields.ts, 0, 9)) + + static #bar: number; +>#bar : Symbol(A.#bar, Decl(privateNamesAndStaticFields.ts, 1, 24)) constructor () { A.#foo = 3; ->A.#foo : Symbol(A.#foo, Decl(privateNamesAndStaticFields.ts, 2, 9)) +>A.#foo : Symbol(A.#foo, Decl(privateNamesAndStaticFields.ts, 0, 9)) >A : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) + + B.#foo; // Error +>B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 8, 1)) + + B.#bar; // Error +>B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 8, 1)) } } class B extends A { ->B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 7, 1)) +>B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 8, 1)) >A : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) static #foo: string; ->#foo : Symbol(B.#foo, Decl(privateNamesAndStaticFields.ts, 9, 19)) +>#foo : Symbol(B.#foo, Decl(privateNamesAndStaticFields.ts, 10, 19)) constructor () { super(); >super : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) B.#foo = "some string"; ->B.#foo : Symbol(B.#foo, Decl(privateNamesAndStaticFields.ts, 9, 19)) ->B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 7, 1)) +>B.#foo : Symbol(B.#foo, Decl(privateNamesAndStaticFields.ts, 10, 19)) +>B : Symbol(B, Decl(privateNamesAndStaticFields.ts, 8, 1)) } } +// We currently filter out static private identifier fields in `getUnmatchedProperties`. +// We will need a more robust solution when we support static fields +const willErrorSomeDay: typeof A = class {}; // OK for now +>willErrorSomeDay : Symbol(willErrorSomeDay, Decl(privateNamesAndStaticFields.ts, 20, 5)) +>A : Symbol(A, Decl(privateNamesAndStaticFields.ts, 0, 0)) + diff --git a/tests/baselines/reference/privateNamesAndStaticFields.types b/tests/baselines/reference/privateNamesAndStaticFields.types index ba630cbcf7709..5625a161fc148 100644 --- a/tests/baselines/reference/privateNamesAndStaticFields.types +++ b/tests/baselines/reference/privateNamesAndStaticFields.types @@ -1,18 +1,27 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts === -// @target es6 - class A { >A : A static #foo: number; >#foo : number + static #bar: number; +>#bar : number + constructor () { A.#foo = 3; >A.#foo = 3 : 3 >A.#foo : number >A : typeof A >3 : 3 + + B.#foo; // Error +>B.#foo : any +>B : typeof B + + B.#bar; // Error +>B.#bar : any +>B : typeof B } } @@ -36,3 +45,10 @@ class B extends A { } } +// We currently filter out static private identifier fields in `getUnmatchedProperties`. +// We will need a more robust solution when we support static fields +const willErrorSomeDay: typeof A = class {}; // OK for now +>willErrorSomeDay : typeof A +>A : typeof A +>class {} : typeof willErrorSomeDay + diff --git a/tests/baselines/reference/privateNamesAndStaticMethods.errors.txt b/tests/baselines/reference/privateNamesAndStaticMethods.errors.txt new file mode 100644 index 0000000000000..180593deac962 --- /dev/null +++ b/tests/baselines/reference/privateNamesAndStaticMethods.errors.txt @@ -0,0 +1,54 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts(2,12): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts(3,18): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts(4,19): error TS18022: A method cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts(7,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts(8,16): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts(11,16): error TS18023: An accessor cannot be named with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts(24,12): error TS18022: A method cannot be named with a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.ts (7 errors) ==== + class A { + static #foo(a: number) {} + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + static async #bar(a: number) {} + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + static async *#baz(a: number) { + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + return 3; + } + static #_quux: number; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + static get #quux (): number { + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + return this.#_quux; + } + static set #quux (val: number) { + ~~~~~ +!!! error TS18023: An accessor cannot be named with a private identifier. + this.#_quux = val; + } + constructor () { + A.#foo(30); + A.#bar(30); + A.#bar(30); + A.#quux = A.#quux + 1; + A.#quux++; + } + } + + class B extends A { + static #foo(a: string) {} + ~~~~ +!!! error TS18022: A method cannot be named with a private identifier. + constructor () { + super(); + B.#foo("str"); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesAndStaticMethods.js b/tests/baselines/reference/privateNamesAndStaticMethods.js index 9bb578ef6ccd6..f21d0ccd5273d 100644 --- a/tests/baselines/reference/privateNamesAndStaticMethods.js +++ b/tests/baselines/reference/privateNamesAndStaticMethods.js @@ -30,65 +30,33 @@ class B extends A { } -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(4,11): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(5,11): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(6,11): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(7,12): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(7,17): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(8,11): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(12,19): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(16,21): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(19,15): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js(26,11): error TS1003: Identifier expected. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticMethods.js (10 errors) ==== - "use strict"; - class A { - constructor() { - A.(30); - ~ -!!! error TS1003: Identifier expected. - A.(30); - ~ -!!! error TS1003: Identifier expected. - A.(30); - ~ -!!! error TS1003: Identifier expected. - A. = A. + 1; - ~ -!!! error TS1003: Identifier expected. - ~ -!!! error TS1003: Identifier expected. - A.++; - ~~ -!!! error TS1003: Identifier expected. - } - static (a) { } - static async (a) { } - static async *(a) { - ~ -!!! error TS1003: Identifier expected. - return 3; - } - static get () { - return this.; - ~ -!!! error TS1003: Identifier expected. - } - static set (val) { - this. = val; - ~ -!!! error TS1003: Identifier expected. - } +//// [privateNamesAndStaticMethods.js] +"use strict"; +class A { + constructor() { + A.#foo(30); + A.#bar(30); + A.#bar(30); + A.#quux = A.#quux + 1; + A.#quux++; + } + static #foo(a) { } + static async #bar(a) { } + static async *#baz(a) { + return 3; + } + static #_quux; + static get #quux() { + return this.#_quux; + } + static set #quux(val) { + this.#_quux = val; } - class B extends A { - static (a) { } - constructor() { - super(); - B.("str"); - ~ -!!! error TS1003: Identifier expected. - } +} +class B extends A { + static #foo(a) { } + constructor() { + super(); + B.#foo("str"); } - \ No newline at end of file +} diff --git a/tests/baselines/reference/privateNamesAndkeyof.js b/tests/baselines/reference/privateNamesAndkeyof.js index d73251c6a530e..46750f78874dd 100644 --- a/tests/baselines/reference/privateNamesAndkeyof.js +++ b/tests/baselines/reference/privateNamesAndkeyof.js @@ -1,6 +1,4 @@ //// [privateNamesAndkeyof.ts] -// @target es6 - class A { #foo = 3; bar = 3; @@ -10,20 +8,14 @@ class A { type T = keyof A // should not include '#foo' -tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.js(5,14): error TS1011: An element access expression should take an argument. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.js (1 errors) ==== - "use strict"; - // @target es6 - var A = /** @class */ (function () { - function A() { - this[] = 3; - -!!! error TS1011: An element access expression should take an argument. - this.bar = 3; - this.baz = 3; - } - return A; - }()); - \ No newline at end of file +//// [privateNamesAndkeyof.js] +"use strict"; +var _foo; +class A { + constructor() { + _foo.set(this, 3); + this.bar = 3; + this.baz = 3; + } +} +_foo = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesAndkeyof.symbols b/tests/baselines/reference/privateNamesAndkeyof.symbols index 3b633505522a1..dbad7e0aa748f 100644 --- a/tests/baselines/reference/privateNamesAndkeyof.symbols +++ b/tests/baselines/reference/privateNamesAndkeyof.symbols @@ -1,20 +1,18 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNamesAndkeyof.ts, 0, 0)) #foo = 3; ->#foo : Symbol(A.#foo, Decl(privateNamesAndkeyof.ts, 2, 9)) +>#foo : Symbol(A.#foo, Decl(privateNamesAndkeyof.ts, 0, 9)) bar = 3; ->bar : Symbol(A.bar, Decl(privateNamesAndkeyof.ts, 3, 13)) +>bar : Symbol(A.bar, Decl(privateNamesAndkeyof.ts, 1, 13)) baz = 3; ->baz : Symbol(A.baz, Decl(privateNamesAndkeyof.ts, 4, 12)) +>baz : Symbol(A.baz, Decl(privateNamesAndkeyof.ts, 2, 12)) } type T = keyof A // should not include '#foo' ->T : Symbol(T, Decl(privateNamesAndkeyof.ts, 6, 1)) +>T : Symbol(T, Decl(privateNamesAndkeyof.ts, 4, 1)) >A : Symbol(A, Decl(privateNamesAndkeyof.ts, 0, 0)) diff --git a/tests/baselines/reference/privateNamesAndkeyof.types b/tests/baselines/reference/privateNamesAndkeyof.types index f8d3d99de7369..23625ad025cfc 100644 --- a/tests/baselines/reference/privateNamesAndkeyof.types +++ b/tests/baselines/reference/privateNamesAndkeyof.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts === -// @target es6 - class A { >A : A diff --git a/tests/baselines/reference/privateNamesConstructorChain-1.errors.txt b/tests/baselines/reference/privateNamesConstructorChain-1.errors.txt new file mode 100644 index 0000000000000..034eb16a76c58 --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-1.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts(3,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts(6,15): error TS2339: Property '#bar' does not exist on type 'typeof Child'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts (2 errors) ==== + class Parent { + #foo = 3; + static #bar = 5; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + accessChildProps() { + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + Child.#bar; // Error: not found + ~~~~ +!!! error TS2339: Property '#bar' does not exist on type 'typeof Child'. + } + } + + class Child extends Parent { + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + #bar = "bar"; // OK + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesConstructorChain-1.js b/tests/baselines/reference/privateNamesConstructorChain-1.js new file mode 100644 index 0000000000000..dfba142f9aa53 --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-1.js @@ -0,0 +1,43 @@ +//// [privateNamesConstructorChain-1.ts] +class Parent { + #foo = 3; + static #bar = 5; + accessChildProps() { + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + Child.#bar; // Error: not found + } +} + +class Child extends Parent { + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + #bar = "bar"; // OK +} + + +//// [privateNamesConstructorChain-1.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo, _bar, _foo_1, _bar_1; +class Parent { + constructor() { + _foo.set(this, 3); + } + accessChildProps() { + __classPrivateFieldGet(new Child(), _foo); // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + __classPrivateFieldGet(Child, _bar); // Error: not found + } +} +_foo = new WeakMap(), _bar = new WeakMap(); +_bar.set(Parent, 5); +class Child extends Parent { + constructor() { + super(...arguments); + _foo_1.set(this, "foo"); // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + _bar_1.set(this, "bar"); // OK + } +} +_foo_1 = new WeakMap(), _bar_1 = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesConstructorChain-1.symbols b/tests/baselines/reference/privateNamesConstructorChain-1.symbols new file mode 100644 index 0000000000000..eccaeb18711cd --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-1.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts === +class Parent { +>Parent : Symbol(Parent, Decl(privateNamesConstructorChain-1.ts, 0, 0)) + + #foo = 3; +>#foo : Symbol(Parent.#foo, Decl(privateNamesConstructorChain-1.ts, 0, 14)) + + static #bar = 5; +>#bar : Symbol(Parent.#bar, Decl(privateNamesConstructorChain-1.ts, 1, 13)) + + accessChildProps() { +>accessChildProps : Symbol(Parent.accessChildProps, Decl(privateNamesConstructorChain-1.ts, 2, 20)) + + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) +>new Child().#foo : Symbol(Parent.#foo, Decl(privateNamesConstructorChain-1.ts, 0, 14)) +>Child : Symbol(Child, Decl(privateNamesConstructorChain-1.ts, 7, 1)) + + Child.#bar; // Error: not found +>Child : Symbol(Child, Decl(privateNamesConstructorChain-1.ts, 7, 1)) + } +} + +class Child extends Parent { +>Child : Symbol(Child, Decl(privateNamesConstructorChain-1.ts, 7, 1)) +>Parent : Symbol(Parent, Decl(privateNamesConstructorChain-1.ts, 0, 0)) + + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) +>#foo : Symbol(Child.#foo, Decl(privateNamesConstructorChain-1.ts, 9, 28)) + + #bar = "bar"; // OK +>#bar : Symbol(Child.#bar, Decl(privateNamesConstructorChain-1.ts, 10, 17)) +} + diff --git a/tests/baselines/reference/privateNamesConstructorChain-1.types b/tests/baselines/reference/privateNamesConstructorChain-1.types new file mode 100644 index 0000000000000..db4e52d2ba524 --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-1.types @@ -0,0 +1,39 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts === +class Parent { +>Parent : Parent + + #foo = 3; +>#foo : number +>3 : 3 + + static #bar = 5; +>#bar : number +>5 : 5 + + accessChildProps() { +>accessChildProps : () => void + + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) +>new Child().#foo : number +>new Child() : Child +>Child : typeof Child + + Child.#bar; // Error: not found +>Child.#bar : any +>Child : typeof Child + } +} + +class Child extends Parent { +>Child : Child +>Parent : Parent + + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) +>#foo : string +>"foo" : "foo" + + #bar = "bar"; // OK +>#bar : string +>"bar" : "bar" +} + diff --git a/tests/baselines/reference/privateNamesConstructorChain-2.errors.txt b/tests/baselines/reference/privateNamesConstructorChain-2.errors.txt new file mode 100644 index 0000000000000..02465f88f8572 --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-2.errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts(3,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts(6,15): error TS2339: Property '#bar' does not exist on type 'typeof Child'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts (2 errors) ==== + class Parent { + #foo = 3; + static #bar = 5; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + accessChildProps() { + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + Child.#bar; // Error: not found + ~~~~ +!!! error TS2339: Property '#bar' does not exist on type 'typeof Child'. + } + } + + class Child extends Parent { + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + #bar = "bar"; // OK + } + + new Parent().accessChildProps(); + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesConstructorChain-2.js b/tests/baselines/reference/privateNamesConstructorChain-2.js new file mode 100644 index 0000000000000..0d0069a47a9ad --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-2.js @@ -0,0 +1,46 @@ +//// [privateNamesConstructorChain-2.ts] +class Parent { + #foo = 3; + static #bar = 5; + accessChildProps() { + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + Child.#bar; // Error: not found + } +} + +class Child extends Parent { + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + #bar = "bar"; // OK +} + +new Parent().accessChildProps(); + + +//// [privateNamesConstructorChain-2.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo, _bar, _foo_1, _bar_1; +class Parent { + constructor() { + _foo.set(this, 3); + } + accessChildProps() { + __classPrivateFieldGet(new Child(), _foo); // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + __classPrivateFieldGet(Child, _bar); // Error: not found + } +} +_foo = new WeakMap(), _bar = new WeakMap(); +_bar.set(Parent, 5); +class Child extends Parent { + constructor() { + super(...arguments); + _foo_1.set(this, "foo"); // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + _bar_1.set(this, "bar"); // OK + } +} +_foo_1 = new WeakMap(), _bar_1 = new WeakMap(); +new Parent().accessChildProps(); diff --git a/tests/baselines/reference/privateNamesConstructorChain-2.symbols b/tests/baselines/reference/privateNamesConstructorChain-2.symbols new file mode 100644 index 0000000000000..b3c8aeabab572 --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-2.symbols @@ -0,0 +1,41 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts === +class Parent { +>Parent : Symbol(Parent, Decl(privateNamesConstructorChain-2.ts, 0, 0)) +>T : Symbol(T, Decl(privateNamesConstructorChain-2.ts, 0, 13)) + + #foo = 3; +>#foo : Symbol(Parent.#foo, Decl(privateNamesConstructorChain-2.ts, 0, 17)) + + static #bar = 5; +>#bar : Symbol(Parent.#bar, Decl(privateNamesConstructorChain-2.ts, 1, 13)) + + accessChildProps() { +>accessChildProps : Symbol(Parent.accessChildProps, Decl(privateNamesConstructorChain-2.ts, 2, 20)) + + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) +>new Child().#foo : Symbol(Parent.#foo, Decl(privateNamesConstructorChain-2.ts, 0, 17)) +>Child : Symbol(Child, Decl(privateNamesConstructorChain-2.ts, 7, 1)) + + Child.#bar; // Error: not found +>Child : Symbol(Child, Decl(privateNamesConstructorChain-2.ts, 7, 1)) + } +} + +class Child extends Parent { +>Child : Symbol(Child, Decl(privateNamesConstructorChain-2.ts, 7, 1)) +>T : Symbol(T, Decl(privateNamesConstructorChain-2.ts, 9, 12)) +>Parent : Symbol(Parent, Decl(privateNamesConstructorChain-2.ts, 0, 0)) +>T : Symbol(T, Decl(privateNamesConstructorChain-2.ts, 9, 12)) + + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) +>#foo : Symbol(Child.#foo, Decl(privateNamesConstructorChain-2.ts, 9, 34)) + + #bar = "bar"; // OK +>#bar : Symbol(Child.#bar, Decl(privateNamesConstructorChain-2.ts, 10, 17)) +} + +new Parent().accessChildProps(); +>new Parent().accessChildProps : Symbol(Parent.accessChildProps, Decl(privateNamesConstructorChain-2.ts, 2, 20)) +>Parent : Symbol(Parent, Decl(privateNamesConstructorChain-2.ts, 0, 0)) +>accessChildProps : Symbol(Parent.accessChildProps, Decl(privateNamesConstructorChain-2.ts, 2, 20)) + diff --git a/tests/baselines/reference/privateNamesConstructorChain-2.types b/tests/baselines/reference/privateNamesConstructorChain-2.types new file mode 100644 index 0000000000000..fed19c191fe29 --- /dev/null +++ b/tests/baselines/reference/privateNamesConstructorChain-2.types @@ -0,0 +1,46 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts === +class Parent { +>Parent : Parent + + #foo = 3; +>#foo : number +>3 : 3 + + static #bar = 5; +>#bar : number +>5 : 5 + + accessChildProps() { +>accessChildProps : () => void + + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) +>new Child().#foo : number +>new Child() : Child +>Child : typeof Child + + Child.#bar; // Error: not found +>Child.#bar : any +>Child : typeof Child + } +} + +class Child extends Parent { +>Child : Child +>Parent : Parent + + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) +>#foo : string +>"foo" : "foo" + + #bar = "bar"; // OK +>#bar : string +>"bar" : "bar" +} + +new Parent().accessChildProps(); +>new Parent().accessChildProps() : void +>new Parent().accessChildProps : () => void +>new Parent() : Parent +>Parent : typeof Parent +>accessChildProps : () => void + diff --git a/tests/baselines/reference/privateNamesInGenericClasses.errors.txt b/tests/baselines/reference/privateNamesInGenericClasses.errors.txt index f47a95f00b276..d617432535020 100644 --- a/tests/baselines/reference/privateNamesInGenericClasses.errors.txt +++ b/tests/baselines/reference/privateNamesInGenericClasses.errors.txt @@ -1,12 +1,11 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(10,3): error TS2339: Property '#foo' does not exist on type 'C'. -tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(10,3): error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. +tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(10,3): error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private identifier. tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(11,1): error TS2322: Type 'C' is not assignable to type 'C'. Type 'string' is not assignable to type 'number'. tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts(12,1): error TS2322: Type 'C' is not assignable to type 'C'. Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts (4 errors) ==== +==== tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasses.ts (3 errors) ==== class C { #foo: T; bar(x: C) { return x.#foo; } // OK @@ -18,9 +17,7 @@ tests/cases/conformance/classes/members/privateNames/privateNamesInGenericClasse declare let b: C; a.#foo; // Error ~~~~ -!!! error TS2339: Property '#foo' does not exist on type 'C'. - ~~~~ -!!! error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private name. +!!! error TS18013: Property '#foo' is not accessible outside class 'C' because it has a private identifier. a = b; // Error ~ !!! error TS2322: Type 'C' is not assignable to type 'C'. diff --git a/tests/baselines/reference/privateNamesInGenericClasses.js b/tests/baselines/reference/privateNamesInGenericClasses.js index 59772b09fa1de..27227fc0218e7 100644 --- a/tests/baselines/reference/privateNamesInGenericClasses.js +++ b/tests/baselines/reference/privateNamesInGenericClasses.js @@ -15,11 +15,22 @@ b = a; // Error //// [privateNamesInGenericClasses.js] "use strict"; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo; class C { - bar(x) { return x.; } // OK - baz(x) { return x.; } // OK - quux(x) { return x.; } // OK + constructor() { + _foo.set(this, void 0); + } + bar(x) { return __classPrivateFieldGet(x, _foo); } // OK + baz(x) { return __classPrivateFieldGet(x, _foo); } // OK + quux(x) { return __classPrivateFieldGet(x, _foo); } // OK } +_foo = new WeakMap(); a.; // Error a = b; // Error b = a; // Error diff --git a/tests/baselines/reference/privateNamesInNestedClasses-1.errors.txt b/tests/baselines/reference/privateNamesInNestedClasses-1.errors.txt new file mode 100644 index 0000000000000..dc3330816b67d --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses-1.errors.txt @@ -0,0 +1,34 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts(11,18): error TS18014: The property '#foo' cannot be accessed on type 'A' within this class because it is shadowed by another private identifier with the same spelling. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts (1 errors) ==== + class A { + #foo = "A's #foo"; + #bar = "A's #bar"; + method () { + class B { + #foo = "B's #foo"; + bar (a: any) { + a.#foo; // OK, no compile-time error, don't know what `a` is + } + baz (a: A) { + a.#foo; // compile-time error, shadowed + ~~~~ +!!! error TS18014: The property '#foo' cannot be accessed on type 'A' within this class because it is shadowed by another private identifier with the same spelling. +!!! related TS18017 tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts:6:12: The shadowing declaration of '#foo' is defined here +!!! related TS18018 tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts:2:4: The declaration of '#foo' that you probably intended to use is defined here + } + quux (b: B) { + b.#foo; // OK + } + } + const a = new A(); + new B().bar(a); + new B().baz(a); + const b = new B(); + new B().quux(b); + } + } + + new A().method(); + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesInNestedClasses-1.js b/tests/baselines/reference/privateNamesInNestedClasses-1.js new file mode 100644 index 0000000000000..12804200745da --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses-1.js @@ -0,0 +1,68 @@ +//// [privateNamesInNestedClasses-1.ts] +class A { + #foo = "A's #foo"; + #bar = "A's #bar"; + method () { + class B { + #foo = "B's #foo"; + bar (a: any) { + a.#foo; // OK, no compile-time error, don't know what `a` is + } + baz (a: A) { + a.#foo; // compile-time error, shadowed + } + quux (b: B) { + b.#foo; // OK + } + } + const a = new A(); + new B().bar(a); + new B().baz(a); + const b = new B(); + new B().quux(b); + } +} + +new A().method(); + + +//// [privateNamesInNestedClasses-1.js] +"use strict"; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo, _bar; +class A { + constructor() { + _foo.set(this, "A's #foo"); + _bar.set(this, "A's #bar"); + } + method() { + var _foo_1; + class B { + constructor() { + _foo_1.set(this, "B's #foo"); + } + bar(a) { + __classPrivateFieldGet(a, _foo_1); // OK, no compile-time error, don't know what `a` is + } + baz(a) { + __classPrivateFieldGet(a, _foo_1); // compile-time error, shadowed + } + quux(b) { + __classPrivateFieldGet(b, _foo_1); // OK + } + } + _foo_1 = new WeakMap(); + const a = new A(); + new B().bar(a); + new B().baz(a); + const b = new B(); + new B().quux(b); + } +} +_foo = new WeakMap(), _bar = new WeakMap(); +new A().method(); diff --git a/tests/baselines/reference/privateNamesInNestedClasses-1.symbols b/tests/baselines/reference/privateNamesInNestedClasses-1.symbols new file mode 100644 index 0000000000000..857b11ded03e0 --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses-1.symbols @@ -0,0 +1,77 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts === +class A { +>A : Symbol(A, Decl(privateNamesInNestedClasses-1.ts, 0, 0)) + + #foo = "A's #foo"; +>#foo : Symbol(A.#foo, Decl(privateNamesInNestedClasses-1.ts, 0, 9)) + + #bar = "A's #bar"; +>#bar : Symbol(A.#bar, Decl(privateNamesInNestedClasses-1.ts, 1, 21)) + + method () { +>method : Symbol(A.method, Decl(privateNamesInNestedClasses-1.ts, 2, 21)) + + class B { +>B : Symbol(B, Decl(privateNamesInNestedClasses-1.ts, 3, 14)) + + #foo = "B's #foo"; +>#foo : Symbol(B.#foo, Decl(privateNamesInNestedClasses-1.ts, 4, 16)) + + bar (a: any) { +>bar : Symbol(B.bar, Decl(privateNamesInNestedClasses-1.ts, 5, 29)) +>a : Symbol(a, Decl(privateNamesInNestedClasses-1.ts, 6, 16)) + + a.#foo; // OK, no compile-time error, don't know what `a` is +>a : Symbol(a, Decl(privateNamesInNestedClasses-1.ts, 6, 16)) + } + baz (a: A) { +>baz : Symbol(B.baz, Decl(privateNamesInNestedClasses-1.ts, 8, 12)) +>a : Symbol(a, Decl(privateNamesInNestedClasses-1.ts, 9, 16)) +>A : Symbol(A, Decl(privateNamesInNestedClasses-1.ts, 0, 0)) + + a.#foo; // compile-time error, shadowed +>a : Symbol(a, Decl(privateNamesInNestedClasses-1.ts, 9, 16)) + } + quux (b: B) { +>quux : Symbol(B.quux, Decl(privateNamesInNestedClasses-1.ts, 11, 12)) +>b : Symbol(b, Decl(privateNamesInNestedClasses-1.ts, 12, 17)) +>B : Symbol(B, Decl(privateNamesInNestedClasses-1.ts, 3, 14)) + + b.#foo; // OK +>b.#foo : Symbol(B.#foo, Decl(privateNamesInNestedClasses-1.ts, 4, 16)) +>b : Symbol(b, Decl(privateNamesInNestedClasses-1.ts, 12, 17)) + } + } + const a = new A(); +>a : Symbol(a, Decl(privateNamesInNestedClasses-1.ts, 16, 12)) +>A : Symbol(A, Decl(privateNamesInNestedClasses-1.ts, 0, 0)) + + new B().bar(a); +>new B().bar : Symbol(B.bar, Decl(privateNamesInNestedClasses-1.ts, 5, 29)) +>B : Symbol(B, Decl(privateNamesInNestedClasses-1.ts, 3, 14)) +>bar : Symbol(B.bar, Decl(privateNamesInNestedClasses-1.ts, 5, 29)) +>a : Symbol(a, Decl(privateNamesInNestedClasses-1.ts, 16, 12)) + + new B().baz(a); +>new B().baz : Symbol(B.baz, Decl(privateNamesInNestedClasses-1.ts, 8, 12)) +>B : Symbol(B, Decl(privateNamesInNestedClasses-1.ts, 3, 14)) +>baz : Symbol(B.baz, Decl(privateNamesInNestedClasses-1.ts, 8, 12)) +>a : Symbol(a, Decl(privateNamesInNestedClasses-1.ts, 16, 12)) + + const b = new B(); +>b : Symbol(b, Decl(privateNamesInNestedClasses-1.ts, 19, 12)) +>B : Symbol(B, Decl(privateNamesInNestedClasses-1.ts, 3, 14)) + + new B().quux(b); +>new B().quux : Symbol(B.quux, Decl(privateNamesInNestedClasses-1.ts, 11, 12)) +>B : Symbol(B, Decl(privateNamesInNestedClasses-1.ts, 3, 14)) +>quux : Symbol(B.quux, Decl(privateNamesInNestedClasses-1.ts, 11, 12)) +>b : Symbol(b, Decl(privateNamesInNestedClasses-1.ts, 19, 12)) + } +} + +new A().method(); +>new A().method : Symbol(A.method, Decl(privateNamesInNestedClasses-1.ts, 2, 21)) +>A : Symbol(A, Decl(privateNamesInNestedClasses-1.ts, 0, 0)) +>method : Symbol(A.method, Decl(privateNamesInNestedClasses-1.ts, 2, 21)) + diff --git a/tests/baselines/reference/privateNamesInNestedClasses.types b/tests/baselines/reference/privateNamesInNestedClasses-1.types similarity index 91% rename from tests/baselines/reference/privateNamesInNestedClasses.types rename to tests/baselines/reference/privateNamesInNestedClasses-1.types index 12986429358da..b94193b8f082c 100644 --- a/tests/baselines/reference/privateNamesInNestedClasses.types +++ b/tests/baselines/reference/privateNamesInNestedClasses-1.types @@ -1,6 +1,4 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts === -// @target es6 - +=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts === class A { >A : A diff --git a/tests/baselines/reference/privateNamesInNestedClasses-2.errors.txt b/tests/baselines/reference/privateNamesInNestedClasses-2.errors.txt new file mode 100644 index 0000000000000..82119522d4243 --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses-2.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts(2,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts(9,27): error TS18014: The property '#x' cannot be accessed on type 'typeof A' within this class because it is shadowed by another private identifier with the same spelling. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts (2 errors) ==== + class A { + static #x = 5; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + constructor () { + class B { + #x = 5; + constructor() { + class C { + constructor() { + A.#x // error + ~~ +!!! error TS18014: The property '#x' cannot be accessed on type 'typeof A' within this class because it is shadowed by another private identifier with the same spelling. +!!! related TS18017 tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts:5:13: The shadowing declaration of '#x' is defined here +!!! related TS18018 tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts:2:12: The declaration of '#x' that you probably intended to use is defined here + } + } + } + } + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesInNestedClasses-2.js b/tests/baselines/reference/privateNamesInNestedClasses-2.js new file mode 100644 index 0000000000000..896beb6308339 --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses-2.js @@ -0,0 +1,45 @@ +//// [privateNamesInNestedClasses-2.ts] +class A { + static #x = 5; + constructor () { + class B { + #x = 5; + constructor() { + class C { + constructor() { + A.#x // error + } + } + } + } + } +} + + +//// [privateNamesInNestedClasses-2.js] +"use strict"; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _x; +class A { + constructor() { + var _x_1; + class B { + constructor() { + _x_1.set(this, 5); + class C { + constructor() { + __classPrivateFieldGet(A, _x_1); // error + } + } + } + } + _x_1 = new WeakMap(); + } +} +_x = new WeakMap(); +_x.set(A, 5); diff --git a/tests/baselines/reference/privateNamesInNestedClasses-2.symbols b/tests/baselines/reference/privateNamesInNestedClasses-2.symbols new file mode 100644 index 0000000000000..1d82e18c994bc --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses-2.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts === +class A { +>A : Symbol(A, Decl(privateNamesInNestedClasses-2.ts, 0, 0)) + + static #x = 5; +>#x : Symbol(A.#x, Decl(privateNamesInNestedClasses-2.ts, 0, 9)) + + constructor () { + class B { +>B : Symbol(B, Decl(privateNamesInNestedClasses-2.ts, 2, 20)) + + #x = 5; +>#x : Symbol(B.#x, Decl(privateNamesInNestedClasses-2.ts, 3, 17)) + + constructor() { + class C { +>C : Symbol(C, Decl(privateNamesInNestedClasses-2.ts, 5, 27)) + + constructor() { + A.#x // error +>A : Symbol(A, Decl(privateNamesInNestedClasses-2.ts, 0, 0)) + } + } + } + } + } +} + diff --git a/tests/baselines/reference/privateNamesInNestedClasses-2.types b/tests/baselines/reference/privateNamesInNestedClasses-2.types new file mode 100644 index 0000000000000..b051b401fbf30 --- /dev/null +++ b/tests/baselines/reference/privateNamesInNestedClasses-2.types @@ -0,0 +1,31 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts === +class A { +>A : A + + static #x = 5; +>#x : number +>5 : 5 + + constructor () { + class B { +>B : B + + #x = 5; +>#x : number +>5 : 5 + + constructor() { + class C { +>C : C + + constructor() { + A.#x // error +>A.#x : any +>A : typeof A + } + } + } + } + } +} + diff --git a/tests/baselines/reference/privateNamesInNestedClasses.errors.txt b/tests/baselines/reference/privateNamesInNestedClasses.errors.txt deleted file mode 100644 index 86aa021ad0326..0000000000000 --- a/tests/baselines/reference/privateNamesInNestedClasses.errors.txt +++ /dev/null @@ -1,36 +0,0 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts(13,18): error TS2339: Property '#foo' does not exist on type 'A'. -tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts(13,18): error TS18014: This usage of '#foo' refers to the private member declared in its enclosing class. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts (2 errors) ==== - // @target es6 - - class A { - #foo = "A's #foo"; - #bar = "A's #bar"; - method () { - class B { - #foo = "B's #foo"; - bar (a: any) { - a.#foo; // OK, no compile-time error, don't know what `a` is - } - baz (a: A) { - a.#foo; // compile-time error, shadowed - ~~~~ -!!! error TS2339: Property '#foo' does not exist on type 'A'. - ~~~~ -!!! error TS18014: This usage of '#foo' refers to the private member declared in its enclosing class. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. - } - quux (b: B) { - b.#foo; // OK - } - } - const a = new A(); - new B().bar(a); - new B().baz(a); - const b = new B(); - new B().quux(b); - } - } - - new A().method(); \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesInNestedClasses.js b/tests/baselines/reference/privateNamesInNestedClasses.js deleted file mode 100644 index 40d45516ddd1a..0000000000000 --- a/tests/baselines/reference/privateNamesInNestedClasses.js +++ /dev/null @@ -1,62 +0,0 @@ -//// [privateNamesInNestedClasses.ts] -// @target es6 - -class A { - #foo = "A's #foo"; - #bar = "A's #bar"; - method () { - class B { - #foo = "B's #foo"; - bar (a: any) { - a.#foo; // OK, no compile-time error, don't know what `a` is - } - baz (a: A) { - a.#foo; // compile-time error, shadowed - } - quux (b: B) { - b.#foo; // OK - } - } - const a = new A(); - new B().bar(a); - new B().baz(a); - const b = new B(); - new B().quux(b); - } -} - -new A().method(); - -//// [privateNamesInNestedClasses.js] -"use strict"; -// @target es6 -var A = /** @class */ (function () { - function A() { - this[] = "A's #foo"; - this[] = "A's #bar"; - } - A.prototype.method = function () { - var B = /** @class */ (function () { - function B() { - this[] = "B's #foo"; - } - B.prototype.bar = function (a) { - a.; // OK, no compile-time error, don't know what `a` is - }; - B.prototype.baz = function (a) { - a.; // compile-time error, shadowed - }; - B.prototype.quux = function (b) { - b.; // OK - }; - return B; - }()); - var a = new A(); - new B().bar(a); - new B().baz(a); - var b = new B(); - new B().quux(b); - }; - return A; -}()); -new A().method(); diff --git a/tests/baselines/reference/privateNamesInNestedClasses.symbols b/tests/baselines/reference/privateNamesInNestedClasses.symbols deleted file mode 100644 index 14eaae87aa402..0000000000000 --- a/tests/baselines/reference/privateNamesInNestedClasses.symbols +++ /dev/null @@ -1,79 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts === -// @target es6 - -class A { ->A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) - - #foo = "A's #foo"; ->#foo : Symbol(A.#foo, Decl(privateNamesInNestedClasses.ts, 2, 9)) - - #bar = "A's #bar"; ->#bar : Symbol(A.#bar, Decl(privateNamesInNestedClasses.ts, 3, 21)) - - method () { ->method : Symbol(A.method, Decl(privateNamesInNestedClasses.ts, 4, 21)) - - class B { ->B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) - - #foo = "B's #foo"; ->#foo : Symbol(B.#foo, Decl(privateNamesInNestedClasses.ts, 6, 16)) - - bar (a: any) { ->bar : Symbol(B.bar, Decl(privateNamesInNestedClasses.ts, 7, 29)) ->a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 8, 16)) - - a.#foo; // OK, no compile-time error, don't know what `a` is ->a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 8, 16)) - } - baz (a: A) { ->baz : Symbol(B.baz, Decl(privateNamesInNestedClasses.ts, 10, 12)) ->a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 11, 16)) ->A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) - - a.#foo; // compile-time error, shadowed ->a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 11, 16)) - } - quux (b: B) { ->quux : Symbol(B.quux, Decl(privateNamesInNestedClasses.ts, 13, 12)) ->b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 14, 17)) ->B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) - - b.#foo; // OK ->b.#foo : Symbol(B.#foo, Decl(privateNamesInNestedClasses.ts, 6, 16)) ->b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 14, 17)) - } - } - const a = new A(); ->a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 18, 12)) ->A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) - - new B().bar(a); ->new B().bar : Symbol(B.bar, Decl(privateNamesInNestedClasses.ts, 7, 29)) ->B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) ->bar : Symbol(B.bar, Decl(privateNamesInNestedClasses.ts, 7, 29)) ->a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 18, 12)) - - new B().baz(a); ->new B().baz : Symbol(B.baz, Decl(privateNamesInNestedClasses.ts, 10, 12)) ->B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) ->baz : Symbol(B.baz, Decl(privateNamesInNestedClasses.ts, 10, 12)) ->a : Symbol(a, Decl(privateNamesInNestedClasses.ts, 18, 12)) - - const b = new B(); ->b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 21, 12)) ->B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) - - new B().quux(b); ->new B().quux : Symbol(B.quux, Decl(privateNamesInNestedClasses.ts, 13, 12)) ->B : Symbol(B, Decl(privateNamesInNestedClasses.ts, 5, 14)) ->quux : Symbol(B.quux, Decl(privateNamesInNestedClasses.ts, 13, 12)) ->b : Symbol(b, Decl(privateNamesInNestedClasses.ts, 21, 12)) - } -} - -new A().method(); ->new A().method : Symbol(A.method, Decl(privateNamesInNestedClasses.ts, 4, 21)) ->A : Symbol(A, Decl(privateNamesInNestedClasses.ts, 0, 0)) ->method : Symbol(A.method, Decl(privateNamesInNestedClasses.ts, 4, 21)) - diff --git a/tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt b/tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt new file mode 100644 index 0000000000000..e5da07f40eb64 --- /dev/null +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(2,12): error TS18010: An accessibility modifier cannot be used with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(3,13): error TS18010: An accessibility modifier cannot be used with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(4,15): error TS18010: An accessibility modifier cannot be used with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(9,14): error TS18019: 'abstract' modifier cannot be used with a private identifier + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts (4 errors) ==== + class A { + public #foo = 3; // Error + ~~~~ +!!! error TS18010: An accessibility modifier cannot be used with a private identifier. + private #bar = 3; // Error + ~~~~ +!!! error TS18010: An accessibility modifier cannot be used with a private identifier. + protected #baz = 3; // Error + ~~~~ +!!! error TS18010: An accessibility modifier cannot be used with a private identifier. + readonly #qux = 3; // OK + } + + abstract class B { + abstract #quux = 3; // Error + ~~~~~ +!!! error TS18019: 'abstract' modifier cannot be used with a private identifier + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesIncompatibleModifiers.js b/tests/baselines/reference/privateNamesIncompatibleModifiers.js new file mode 100644 index 0000000000000..82d8551e7fad0 --- /dev/null +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.js @@ -0,0 +1,31 @@ +//// [privateNamesIncompatibleModifiers.ts] +class A { + public #foo = 3; // Error + private #bar = 3; // Error + protected #baz = 3; // Error + readonly #qux = 3; // OK +} + +abstract class B { + abstract #quux = 3; // Error +} + + +//// [privateNamesIncompatibleModifiers.js] +"use strict"; +var _foo, _bar, _baz, _qux, _quux; +class A { + constructor() { + _foo.set(this, 3); // Error + _bar.set(this, 3); // Error + _baz.set(this, 3); // Error + _qux.set(this, 3); // OK + } +} +_foo = new WeakMap(), _bar = new WeakMap(), _baz = new WeakMap(), _qux = new WeakMap(); +class B { + constructor() { + _quux.set(this, 3); // Error + } +} +_quux = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesIncompatibleModifiers.symbols b/tests/baselines/reference/privateNamesIncompatibleModifiers.symbols new file mode 100644 index 0000000000000..45b7114c1ae3f --- /dev/null +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.symbols @@ -0,0 +1,24 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts === +class A { +>A : Symbol(A, Decl(privateNamesIncompatibleModifiers.ts, 0, 0)) + + public #foo = 3; // Error +>#foo : Symbol(A.#foo, Decl(privateNamesIncompatibleModifiers.ts, 0, 9)) + + private #bar = 3; // Error +>#bar : Symbol(A.#bar, Decl(privateNamesIncompatibleModifiers.ts, 1, 20)) + + protected #baz = 3; // Error +>#baz : Symbol(A.#baz, Decl(privateNamesIncompatibleModifiers.ts, 2, 21)) + + readonly #qux = 3; // OK +>#qux : Symbol(A.#qux, Decl(privateNamesIncompatibleModifiers.ts, 3, 23)) +} + +abstract class B { +>B : Symbol(B, Decl(privateNamesIncompatibleModifiers.ts, 5, 1)) + + abstract #quux = 3; // Error +>#quux : Symbol(B.#quux, Decl(privateNamesIncompatibleModifiers.ts, 7, 18)) +} + diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.types b/tests/baselines/reference/privateNamesIncompatibleModifiers.types similarity index 67% rename from tests/baselines/reference/privateNamesNoAccessibilityModifiers.types rename to tests/baselines/reference/privateNamesIncompatibleModifiers.types index d727c9a2f2dc3..f4929fd813907 100644 --- a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.types +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.types @@ -1,6 +1,4 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts === -// @target es6 - +=== tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts === class A { >A : A @@ -21,3 +19,11 @@ class A { >3 : 3 } +abstract class B { +>B : B + + abstract #quux = 3; // Error +>#quux : number +>3 : 3 +} + diff --git a/tests/baselines/reference/privateNamesInterfaceExtendingClass.errors.txt b/tests/baselines/reference/privateNamesInterfaceExtendingClass.errors.txt new file mode 100644 index 0000000000000..aa883e0facd32 --- /dev/null +++ b/tests/baselines/reference/privateNamesInterfaceExtendingClass.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts(10,7): error TS18013: Property '#prop' is not accessible outside class 'C' because it has a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts (1 errors) ==== + class C { + #prop; + func(x: I) { + x.#prop = 123; + } + } + interface I extends C {} + + function func(x: I) { + x.#prop = 123; + ~~~~~ +!!! error TS18013: Property '#prop' is not accessible outside class 'C' because it has a private identifier. + } + + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesInterfaceExtendingClass.js b/tests/baselines/reference/privateNamesInterfaceExtendingClass.js new file mode 100644 index 0000000000000..f6bbc9fa54dc8 --- /dev/null +++ b/tests/baselines/reference/privateNamesInterfaceExtendingClass.js @@ -0,0 +1,36 @@ +//// [privateNamesInterfaceExtendingClass.ts] +class C { + #prop; + func(x: I) { + x.#prop = 123; + } +} +interface I extends C {} + +function func(x: I) { + x.#prop = 123; +} + + + +//// [privateNamesInterfaceExtendingClass.js] +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; +}; +var _prop; +class C { + constructor() { + _prop.set(this, void 0); + } + func(x) { + __classPrivateFieldSet(x, _prop, 123); + } +} +_prop = new WeakMap(); +function func(x) { + x. = 123; +} diff --git a/tests/baselines/reference/privateNamesInterfaceExtendingClass.symbols b/tests/baselines/reference/privateNamesInterfaceExtendingClass.symbols new file mode 100644 index 0000000000000..6689c22923ea3 --- /dev/null +++ b/tests/baselines/reference/privateNamesInterfaceExtendingClass.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts === +class C { +>C : Symbol(C, Decl(privateNamesInterfaceExtendingClass.ts, 0, 0)) + + #prop; +>#prop : Symbol(C.#prop, Decl(privateNamesInterfaceExtendingClass.ts, 0, 9)) + + func(x: I) { +>func : Symbol(C.func, Decl(privateNamesInterfaceExtendingClass.ts, 1, 10)) +>x : Symbol(x, Decl(privateNamesInterfaceExtendingClass.ts, 2, 9)) +>I : Symbol(I, Decl(privateNamesInterfaceExtendingClass.ts, 5, 1)) + + x.#prop = 123; +>x.#prop : Symbol(C.#prop, Decl(privateNamesInterfaceExtendingClass.ts, 0, 9)) +>x : Symbol(x, Decl(privateNamesInterfaceExtendingClass.ts, 2, 9)) + } +} +interface I extends C {} +>I : Symbol(I, Decl(privateNamesInterfaceExtendingClass.ts, 5, 1)) +>C : Symbol(C, Decl(privateNamesInterfaceExtendingClass.ts, 0, 0)) + +function func(x: I) { +>func : Symbol(func, Decl(privateNamesInterfaceExtendingClass.ts, 6, 24)) +>x : Symbol(x, Decl(privateNamesInterfaceExtendingClass.ts, 8, 14)) +>I : Symbol(I, Decl(privateNamesInterfaceExtendingClass.ts, 5, 1)) + + x.#prop = 123; +>x : Symbol(x, Decl(privateNamesInterfaceExtendingClass.ts, 8, 14)) +} + + diff --git a/tests/baselines/reference/privateNamesInterfaceExtendingClass.types b/tests/baselines/reference/privateNamesInterfaceExtendingClass.types new file mode 100644 index 0000000000000..b320c59283e13 --- /dev/null +++ b/tests/baselines/reference/privateNamesInterfaceExtendingClass.types @@ -0,0 +1,32 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts === +class C { +>C : C + + #prop; +>#prop : any + + func(x: I) { +>func : (x: I) => void +>x : I + + x.#prop = 123; +>x.#prop = 123 : 123 +>x.#prop : any +>x : I +>123 : 123 + } +} +interface I extends C {} + +function func(x: I) { +>func : (x: I) => void +>x : I + + x.#prop = 123; +>x.#prop = 123 : 123 +>x.#prop : any +>x : I +>123 : 123 +} + + diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt deleted file mode 100644 index 079f4940d4ef5..0000000000000 --- a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.errors.txt +++ /dev/null @@ -1,21 +0,0 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts(4,12): error TS18010: Accessibility modifiers cannot be used with private names. -tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts(5,13): error TS18010: Accessibility modifiers cannot be used with private names. -tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts(6,15): error TS18010: Accessibility modifiers cannot be used with private names. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts (3 errors) ==== - // @target es6 - - class A { - public #foo = 3; // Error - ~~~~ -!!! error TS18010: Accessibility modifiers cannot be used with private names. - private #bar = 3; // Error - ~~~~ -!!! error TS18010: Accessibility modifiers cannot be used with private names. - protected #baz = 3; // Error - ~~~~ -!!! error TS18010: Accessibility modifiers cannot be used with private names. - readonly #qux = 3; // OK - } - \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.js b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.js deleted file mode 100644 index 3c3acaf9f4672..0000000000000 --- a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.js +++ /dev/null @@ -1,23 +0,0 @@ -//// [privateNamesNoAccessibilityModifiers.ts] -// @target es6 - -class A { - public #foo = 3; // Error - private #bar = 3; // Error - protected #baz = 3; // Error - readonly #qux = 3; // OK -} - - -//// [privateNamesNoAccessibilityModifiers.js] -"use strict"; -// @target es6 -var A = /** @class */ (function () { - function A() { - this[] = 3; // Error - this[] = 3; // Error - this[] = 3; // Error - this[] = 3; // OK - } - return A; -}()); diff --git a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols b/tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols deleted file mode 100644 index 49bd89a39842a..0000000000000 --- a/tests/baselines/reference/privateNamesNoAccessibilityModifiers.symbols +++ /dev/null @@ -1,19 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts === -// @target es6 - -class A { ->A : Symbol(A, Decl(privateNamesNoAccessibilityModifiers.ts, 0, 0)) - - public #foo = 3; // Error ->#foo : Symbol(A.#foo, Decl(privateNamesNoAccessibilityModifiers.ts, 2, 9)) - - private #bar = 3; // Error ->#bar : Symbol(A.#bar, Decl(privateNamesNoAccessibilityModifiers.ts, 3, 20)) - - protected #baz = 3; // Error ->#baz : Symbol(A.#baz, Decl(privateNamesNoAccessibilityModifiers.ts, 4, 21)) - - readonly #qux = 3; // OK ->#qux : Symbol(A.#qux, Decl(privateNamesNoAccessibilityModifiers.ts, 5, 23)) -} - diff --git a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.js b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.js deleted file mode 100644 index e25509c4c843a..0000000000000 --- a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.js +++ /dev/null @@ -1,43 +0,0 @@ -//// [privateNamesNoConflictWhenInheriting.ts] -// @target es6 - -class A { - #foo: number; -} - -class B extends A { - #foo: string; // OK: private names are unique to each class -} - -const b: A = new B() // OK - - -//// [privateNamesNoConflictWhenInheriting.js] -"use strict"; -// @target es6 -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -var A = /** @class */ (function () { - function A() { - } - return A; -}()); -var B = /** @class */ (function (_super) { - __extends(B, _super); - function B() { - return _super !== null && _super.apply(this, arguments) || this; - } - return B; -}(A)); -var b = new B(); // OK diff --git a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols deleted file mode 100644 index d1442d5750cd5..0000000000000 --- a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.symbols +++ /dev/null @@ -1,23 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts === -// @target es6 - -class A { ->A : Symbol(A, Decl(privateNamesNoConflictWhenInheriting.ts, 0, 0)) - - #foo: number; ->#foo : Symbol(A.#foo, Decl(privateNamesNoConflictWhenInheriting.ts, 2, 9)) -} - -class B extends A { ->B : Symbol(B, Decl(privateNamesNoConflictWhenInheriting.ts, 4, 1)) ->A : Symbol(A, Decl(privateNamesNoConflictWhenInheriting.ts, 0, 0)) - - #foo: string; // OK: private names are unique to each class ->#foo : Symbol(B.#foo, Decl(privateNamesNoConflictWhenInheriting.ts, 6, 19)) -} - -const b: A = new B() // OK ->b : Symbol(b, Decl(privateNamesNoConflictWhenInheriting.ts, 10, 5)) ->A : Symbol(A, Decl(privateNamesNoConflictWhenInheriting.ts, 0, 0)) ->B : Symbol(B, Decl(privateNamesNoConflictWhenInheriting.ts, 4, 1)) - diff --git a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.types b/tests/baselines/reference/privateNamesNoConflictWhenInheriting.types deleted file mode 100644 index fd88a20816e15..0000000000000 --- a/tests/baselines/reference/privateNamesNoConflictWhenInheriting.types +++ /dev/null @@ -1,23 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts === -// @target es6 - -class A { ->A : A - - #foo: number; ->#foo : number -} - -class B extends A { ->B : B ->A : A - - #foo: string; // OK: private names are unique to each class ->#foo : string -} - -const b: A = new B() // OK ->b : A ->new B() : B ->B : typeof B - diff --git a/tests/baselines/reference/privateNamesNoDelete.errors.txt b/tests/baselines/reference/privateNamesNoDelete.errors.txt index 27c1ba93a77f4..d593fe107a181 100644 --- a/tests/baselines/reference/privateNamesNoDelete.errors.txt +++ b/tests/baselines/reference/privateNamesNoDelete.errors.txt @@ -1,15 +1,13 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts(6,16): error TS18011: The operand of a delete operator cannot be a private name. +tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts(4,16): error TS18011: The operand of a 'delete' operator cannot be a private identifier. ==== tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts (1 errors) ==== - // @target es6 - class A { #v = 1; constructor() { delete this.#v; // Error: The operand of a delete operator cannot be a private name. ~~~~~~~ -!!! error TS18011: The operand of a delete operator cannot be a private name. +!!! error TS18011: The operand of a 'delete' operator cannot be a private identifier. } } \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNoDelete.js b/tests/baselines/reference/privateNamesNoDelete.js index 1b1f285d4c7c6..22aecf24cca31 100644 --- a/tests/baselines/reference/privateNamesNoDelete.js +++ b/tests/baselines/reference/privateNamesNoDelete.js @@ -1,6 +1,4 @@ //// [privateNamesNoDelete.ts] -// @target es6 - class A { #v = 1; constructor() { @@ -11,11 +9,17 @@ class A { //// [privateNamesNoDelete.js] "use strict"; -// @target es6 -var A = /** @class */ (function () { - function A() { - this[] = 1; - delete this.; // Error: The operand of a delete operator cannot be a private name. +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); } - return A; -}()); + return privateMap.get(receiver); +}; +var _v; +class A { + constructor() { + _v.set(this, 1); + delete __classPrivateFieldGet(this, _v); // Error: The operand of a delete operator cannot be a private name. + } +} +_v = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesNoDelete.symbols b/tests/baselines/reference/privateNamesNoDelete.symbols index 50e2542c07877..b69a1bd67a218 100644 --- a/tests/baselines/reference/privateNamesNoDelete.symbols +++ b/tests/baselines/reference/privateNamesNoDelete.symbols @@ -1,15 +1,13 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNamesNoDelete.ts, 0, 0)) #v = 1; ->#v : Symbol(A.#v, Decl(privateNamesNoDelete.ts, 2, 9)) +>#v : Symbol(A.#v, Decl(privateNamesNoDelete.ts, 0, 9)) constructor() { delete this.#v; // Error: The operand of a delete operator cannot be a private name. ->this.#v : Symbol(A.#v, Decl(privateNamesNoDelete.ts, 2, 9)) +>this.#v : Symbol(A.#v, Decl(privateNamesNoDelete.ts, 0, 9)) >this : Symbol(A, Decl(privateNamesNoDelete.ts, 0, 0)) } } diff --git a/tests/baselines/reference/privateNamesNoDelete.types b/tests/baselines/reference/privateNamesNoDelete.types index 681651a4f770a..d23b8712dbdcb 100644 --- a/tests/baselines/reference/privateNamesNoDelete.types +++ b/tests/baselines/reference/privateNamesNoDelete.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts === -// @target es6 - class A { >A : A diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt b/tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt index 942bea1e251a8..7d6b45dc9581c 100644 --- a/tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.errors.txt @@ -1,12 +1,10 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(4,12): error TS1138: Parameter declaration expected. -tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(4,24): error TS1005: ';' expected. -tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(4,26): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. -tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(5,1): error TS1128: Declaration or statement expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(2,12): error TS1138: Parameter declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(2,24): error TS1005: ';' expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(2,26): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts(3,1): error TS1128: Declaration or statement expected. ==== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts (4 errors) ==== - // @target es6 - class A { setFoo(#foo: string) {} ~~~~ diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.js b/tests/baselines/reference/privateNamesNotAllowedAsParameters.js index 8c3a394e1ac03..9d735a8c47302 100644 --- a/tests/baselines/reference/privateNamesNotAllowedAsParameters.js +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.js @@ -1,17 +1,16 @@ //// [privateNamesNotAllowedAsParameters.ts] -// @target es6 - class A { setFoo(#foo: string) {} } //// [privateNamesNotAllowedAsParameters.js] -// @target es6 -var A = /** @class */ (function () { - function A() { +var _foo; +class A { + constructor() { + _foo.set(this, void 0); } - A.prototype.setFoo = function () { }; - return A; -}()); + setFoo() { } +} +_foo = new WeakMap(); { } diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols b/tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols index b7ea0b4850fb9..d4225b871538f 100644 --- a/tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.symbols @@ -1,11 +1,9 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts === -// @target es6 - class A { >A : Symbol(A, Decl(privateNamesNotAllowedAsParameters.ts, 0, 0)) setFoo(#foo: string) {} ->setFoo : Symbol(A.setFoo, Decl(privateNamesNotAllowedAsParameters.ts, 2, 9)) ->#foo : Symbol(A.#foo, Decl(privateNamesNotAllowedAsParameters.ts, 3, 11)) +>setFoo : Symbol(A.setFoo, Decl(privateNamesNotAllowedAsParameters.ts, 0, 9)) +>#foo : Symbol(A.#foo, Decl(privateNamesNotAllowedAsParameters.ts, 1, 11)) } diff --git a/tests/baselines/reference/privateNamesNotAllowedAsParameters.types b/tests/baselines/reference/privateNamesNotAllowedAsParameters.types index effe8726a9470..b11ecd42efe52 100644 --- a/tests/baselines/reference/privateNamesNotAllowedAsParameters.types +++ b/tests/baselines/reference/privateNamesNotAllowedAsParameters.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts === -// @target es6 - class A { >A : A diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt index 5d79de2754392..6fe9395d11dec 100644 --- a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.errors.txt @@ -1,15 +1,14 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(3,7): error TS1134: Variable declaration expected. -tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(3,12): error TS1134: Variable declaration expected. -tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(3,14): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(1,7): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(1,12): error TS1134: Variable declaration expected. +tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts(1,14): error TS1134: Variable declaration expected. ==== tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts (3 errors) ==== - // @target es6 - const #foo = 3; ~~~~ !!! error TS1134: Variable declaration expected. ~ !!! error TS1134: Variable declaration expected. ~ -!!! error TS1134: Variable declaration expected. \ No newline at end of file +!!! error TS1134: Variable declaration expected. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js index 3a5f19724d38e..807be5d60de39 100644 --- a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.js @@ -1,10 +1,8 @@ //// [privateNamesNotAllowedInVariableDeclarations.ts] -// @target es6 - -const #foo = 3; +const #foo = 3; + //// [privateNamesNotAllowedInVariableDeclarations.js] "use strict"; -// @target es6 -var ; +const ; 3; diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols index 8a90d43a114c9..5b0ec461b466c 100644 --- a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.symbols @@ -1,5 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts === -// @target es6 +const #foo = 3; No type information for this code. -No type information for this code.const #foo = 3; No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types index 1def5f332d291..82cdaa63a9fb0 100644 --- a/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types +++ b/tests/baselines/reference/privateNamesNotAllowedInVariableDeclarations.types @@ -1,6 +1,4 @@ === tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts === -// @target es6 - const #foo = 3; >3 : 3 diff --git a/tests/baselines/reference/privateNamesUnique-1.errors.txt b/tests/baselines/reference/privateNamesUnique-1.errors.txt new file mode 100644 index 0000000000000..d85360c43a709 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-1.errors.txt @@ -0,0 +1,18 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesUnique-1.ts(9,7): error TS2322: Type 'B' is not assignable to type 'A'. + Property '#foo' in type 'B' refers to a different member that cannot be accessed from within type 'A'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesUnique-1.ts (1 errors) ==== + class A { + #foo: number; + } + + class B { + #foo: number; + } + + const b: A = new B(); // Error: Property #foo is missing + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property '#foo' in type 'B' refers to a different member that cannot be accessed from within type 'A'. + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesUnique-1.js b/tests/baselines/reference/privateNamesUnique-1.js new file mode 100644 index 0000000000000..1fb8b7255c9bf --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-1.js @@ -0,0 +1,28 @@ +//// [privateNamesUnique-1.ts] +class A { + #foo: number; +} + +class B { + #foo: number; +} + +const b: A = new B(); // Error: Property #foo is missing + + +//// [privateNamesUnique-1.js] +"use strict"; +var _foo, _foo_1; +class A { + constructor() { + _foo.set(this, void 0); + } +} +_foo = new WeakMap(); +class B { + constructor() { + _foo_1.set(this, void 0); + } +} +_foo_1 = new WeakMap(); +const b = new B(); // Error: Property #foo is missing diff --git a/tests/baselines/reference/privateNamesUnique-1.symbols b/tests/baselines/reference/privateNamesUnique-1.symbols new file mode 100644 index 0000000000000..0421f09423e14 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-1.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique-1.ts === +class A { +>A : Symbol(A, Decl(privateNamesUnique-1.ts, 0, 0)) + + #foo: number; +>#foo : Symbol(A.#foo, Decl(privateNamesUnique-1.ts, 0, 9)) +} + +class B { +>B : Symbol(B, Decl(privateNamesUnique-1.ts, 2, 1)) + + #foo: number; +>#foo : Symbol(B.#foo, Decl(privateNamesUnique-1.ts, 4, 9)) +} + +const b: A = new B(); // Error: Property #foo is missing +>b : Symbol(b, Decl(privateNamesUnique-1.ts, 8, 5)) +>A : Symbol(A, Decl(privateNamesUnique-1.ts, 0, 0)) +>B : Symbol(B, Decl(privateNamesUnique-1.ts, 2, 1)) + diff --git a/tests/baselines/reference/privateNamesUnique.types b/tests/baselines/reference/privateNamesUnique-1.types similarity index 82% rename from tests/baselines/reference/privateNamesUnique.types rename to tests/baselines/reference/privateNamesUnique-1.types index a9d738ee0ca5b..1fb2dabc027d8 100644 --- a/tests/baselines/reference/privateNamesUnique.types +++ b/tests/baselines/reference/privateNamesUnique-1.types @@ -1,6 +1,4 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts === -// @target es6 - +=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique-1.ts === class A { >A : A diff --git a/tests/baselines/reference/privateNamesUnique-2.errors.txt b/tests/baselines/reference/privateNamesUnique-2.errors.txt new file mode 100644 index 0000000000000..55408a44b3902 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-2.errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/classes/members/privateNames/a.ts(4,15): error TS18013: Property '#x' is not accessible outside class 'Foo' because it has a private identifier. + + +==== tests/cases/conformance/classes/members/privateNames/a.ts (1 errors) ==== + export class Foo { + #x; + copy(other: import("./b").Foo) { + other.#x; // error + ~~ +!!! error TS18013: Property '#x' is not accessible outside class 'Foo' because it has a private identifier. + } + } + +==== tests/cases/conformance/classes/members/privateNames/b.ts (0 errors) ==== + export class Foo { + #x; + } + +==== tests/cases/conformance/classes/members/privateNames/main.ts (0 errors) ==== + import { Foo as A } from "./a"; + import { Foo as B } from "./b"; + + const a = new A(); + const b = new B(); + a.copy(b); // error + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesUnique-2.js b/tests/baselines/reference/privateNamesUnique-2.js new file mode 100644 index 0000000000000..4f772551b544a --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-2.js @@ -0,0 +1,55 @@ +//// [tests/cases/conformance/classes/members/privateNames/privateNamesUnique-2.ts] //// + +//// [a.ts] +export class Foo { + #x; + copy(other: import("./b").Foo) { + other.#x; // error + } +} + +//// [b.ts] +export class Foo { + #x; +} + +//// [main.ts] +import { Foo as A } from "./a"; +import { Foo as B } from "./b"; + +const a = new A(); +const b = new B(); +a.copy(b); // error + + +//// [b.js] +var _x; +export class Foo { + constructor() { + _x.set(this, void 0); + } +} +_x = new WeakMap(); +//// [a.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _x; +export class Foo { + constructor() { + _x.set(this, void 0); + } + copy(other) { + __classPrivateFieldGet(other, _x); // error + } +} +_x = new WeakMap(); +//// [main.js] +import { Foo as A } from "./a"; +import { Foo as B } from "./b"; +const a = new A(); +const b = new B(); +a.copy(b); // error diff --git a/tests/baselines/reference/privateNamesUnique-2.symbols b/tests/baselines/reference/privateNamesUnique-2.symbols new file mode 100644 index 0000000000000..4e2aa4f7517f5 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-2.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/classes/members/privateNames/a.ts === +export class Foo { +>Foo : Symbol(Foo, Decl(a.ts, 0, 0)) + + #x; +>#x : Symbol(Foo.#x, Decl(a.ts, 0, 18)) + + copy(other: import("./b").Foo) { +>copy : Symbol(Foo.copy, Decl(a.ts, 1, 7)) +>other : Symbol(other, Decl(a.ts, 2, 9)) +>Foo : Symbol(Foo, Decl(b.ts, 0, 0)) + + other.#x; // error +>other : Symbol(other, Decl(a.ts, 2, 9)) + } +} + +=== tests/cases/conformance/classes/members/privateNames/b.ts === +export class Foo { +>Foo : Symbol(Foo, Decl(b.ts, 0, 0)) + + #x; +>#x : Symbol(Foo.#x, Decl(b.ts, 0, 18)) +} + +=== tests/cases/conformance/classes/members/privateNames/main.ts === +import { Foo as A } from "./a"; +>Foo : Symbol(A, Decl(a.ts, 0, 0)) +>A : Symbol(A, Decl(main.ts, 0, 8)) + +import { Foo as B } from "./b"; +>Foo : Symbol(B, Decl(b.ts, 0, 0)) +>B : Symbol(B, Decl(main.ts, 1, 8)) + +const a = new A(); +>a : Symbol(a, Decl(main.ts, 3, 5)) +>A : Symbol(A, Decl(main.ts, 0, 8)) + +const b = new B(); +>b : Symbol(b, Decl(main.ts, 4, 5)) +>B : Symbol(B, Decl(main.ts, 1, 8)) + +a.copy(b); // error +>a.copy : Symbol(A.copy, Decl(a.ts, 1, 7)) +>a : Symbol(a, Decl(main.ts, 3, 5)) +>copy : Symbol(A.copy, Decl(a.ts, 1, 7)) +>b : Symbol(b, Decl(main.ts, 4, 5)) + diff --git a/tests/baselines/reference/privateNamesUnique-2.types b/tests/baselines/reference/privateNamesUnique-2.types new file mode 100644 index 0000000000000..882f5b293903b --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-2.types @@ -0,0 +1,51 @@ +=== tests/cases/conformance/classes/members/privateNames/a.ts === +export class Foo { +>Foo : Foo + + #x; +>#x : any + + copy(other: import("./b").Foo) { +>copy : (other: import("tests/cases/conformance/classes/members/privateNames/b").Foo) => void +>other : import("tests/cases/conformance/classes/members/privateNames/b").Foo + + other.#x; // error +>other.#x : any +>other : import("tests/cases/conformance/classes/members/privateNames/b").Foo + } +} + +=== tests/cases/conformance/classes/members/privateNames/b.ts === +export class Foo { +>Foo : Foo + + #x; +>#x : any +} + +=== tests/cases/conformance/classes/members/privateNames/main.ts === +import { Foo as A } from "./a"; +>Foo : typeof A +>A : typeof A + +import { Foo as B } from "./b"; +>Foo : typeof B +>B : typeof B + +const a = new A(); +>a : A +>new A() : A +>A : typeof A + +const b = new B(); +>b : B +>new B() : B +>B : typeof B + +a.copy(b); // error +>a.copy(b) : void +>a.copy : (other: B) => void +>a : A +>copy : (other: B) => void +>b : B + diff --git a/tests/baselines/reference/privateNamesUnique-3.errors.txt b/tests/baselines/reference/privateNamesUnique-3.errors.txt new file mode 100644 index 0000000000000..84b6affc6dde6 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-3.errors.txt @@ -0,0 +1,29 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts(3,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts(3,12): error TS2300: Duplicate identifier '#foo'. +tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts(9,5): error TS18019: 'static' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts(11,11): error TS2339: Property '#foo' does not exist on type 'B'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts (4 errors) ==== + class A { + #foo = 1; + static #foo = true; // error (duplicate) + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + ~~~~ +!!! error TS2300: Duplicate identifier '#foo'. + // because static and instance private names + // share the same lexical scope + // https://tc39.es/proposal-class-fields/#prod-ClassBody + } + class B { + static #foo = true; + ~~~~~~ +!!! error TS18019: 'static' modifier cannot be used with a private identifier + test(x: B) { + x.#foo; // error (#foo is a static property on B, not an instance property) + ~~~~ +!!! error TS2339: Property '#foo' does not exist on type 'B'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesUnique-3.js b/tests/baselines/reference/privateNamesUnique-3.js new file mode 100644 index 0000000000000..9575d6d89c57d --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-3.js @@ -0,0 +1,41 @@ +//// [privateNamesUnique-3.ts] +class A { + #foo = 1; + static #foo = true; // error (duplicate) + // because static and instance private names + // share the same lexical scope + // https://tc39.es/proposal-class-fields/#prod-ClassBody +} +class B { + static #foo = true; + test(x: B) { + x.#foo; // error (#foo is a static property on B, not an instance property) + } +} + + +//// [privateNamesUnique-3.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo, _foo_1, _foo_2; +class A { + constructor() { + _foo_1.set(this, 1); + // because static and instance private names + // share the same lexical scope + // https://tc39.es/proposal-class-fields/#prod-ClassBody + } +} +_foo = new WeakMap(), _foo_1 = new WeakMap(); +_foo_1.set(A, true); // error (duplicate) +class B { + test(x) { + __classPrivateFieldGet(x, _foo_2); // error (#foo is a static property on B, not an instance property) + } +} +_foo_2 = new WeakMap(); +_foo_2.set(B, true); diff --git a/tests/baselines/reference/privateNamesUnique-3.symbols b/tests/baselines/reference/privateNamesUnique-3.symbols new file mode 100644 index 0000000000000..95a359a496291 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-3.symbols @@ -0,0 +1,30 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts === +class A { +>A : Symbol(A, Decl(privateNamesUnique-3.ts, 0, 0)) + + #foo = 1; +>#foo : Symbol(A.#foo, Decl(privateNamesUnique-3.ts, 0, 9)) + + static #foo = true; // error (duplicate) +>#foo : Symbol(A.#foo, Decl(privateNamesUnique-3.ts, 1, 13)) + + // because static and instance private names + // share the same lexical scope + // https://tc39.es/proposal-class-fields/#prod-ClassBody +} +class B { +>B : Symbol(B, Decl(privateNamesUnique-3.ts, 6, 1)) + + static #foo = true; +>#foo : Symbol(B.#foo, Decl(privateNamesUnique-3.ts, 7, 9)) + + test(x: B) { +>test : Symbol(B.test, Decl(privateNamesUnique-3.ts, 8, 23)) +>x : Symbol(x, Decl(privateNamesUnique-3.ts, 9, 9)) +>B : Symbol(B, Decl(privateNamesUnique-3.ts, 6, 1)) + + x.#foo; // error (#foo is a static property on B, not an instance property) +>x : Symbol(x, Decl(privateNamesUnique-3.ts, 9, 9)) + } +} + diff --git a/tests/baselines/reference/privateNamesUnique-3.types b/tests/baselines/reference/privateNamesUnique-3.types new file mode 100644 index 0000000000000..88cd037cb7929 --- /dev/null +++ b/tests/baselines/reference/privateNamesUnique-3.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts === +class A { +>A : A + + #foo = 1; +>#foo : number +>1 : 1 + + static #foo = true; // error (duplicate) +>#foo : boolean +>true : true + + // because static and instance private names + // share the same lexical scope + // https://tc39.es/proposal-class-fields/#prod-ClassBody +} +class B { +>B : B + + static #foo = true; +>#foo : boolean +>true : true + + test(x: B) { +>test : (x: B) => void +>x : B + + x.#foo; // error (#foo is a static property on B, not an instance property) +>x.#foo : any +>x : B + } +} + diff --git a/tests/baselines/reference/privateNamesUnique.errors.txt b/tests/baselines/reference/privateNamesUnique.errors.txt deleted file mode 100644 index 0c3b1ef188c17..0000000000000 --- a/tests/baselines/reference/privateNamesUnique.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts(11,7): error TS2322: Type 'B' is not assignable to type 'A'. - Property '#foo' is missing in type 'B'. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. - - -==== tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts (1 errors) ==== - // @target es6 - - class A { - #foo: number; - } - - class B { - #foo: number; - } - - const b: A = new B(); // Error: Property #foo is missing - ~ -!!! error TS2322: Type 'B' is not assignable to type 'A'. -!!! error TS2322: Property '#foo' is missing in type 'B'. While type 'B' has a private member with the same spelling, its declaration and accessibility are distinct. - \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesUnique.js b/tests/baselines/reference/privateNamesUnique.js deleted file mode 100644 index 52c8a3bc69799..0000000000000 --- a/tests/baselines/reference/privateNamesUnique.js +++ /dev/null @@ -1,28 +0,0 @@ -//// [privateNamesUnique.ts] -// @target es6 - -class A { - #foo: number; -} - -class B { - #foo: number; -} - -const b: A = new B(); // Error: Property #foo is missing - - -//// [privateNamesUnique.js] -"use strict"; -// @target es6 -var A = /** @class */ (function () { - function A() { - } - return A; -}()); -var B = /** @class */ (function () { - function B() { - } - return B; -}()); -var b = new B(); // Error: Property #foo is missing diff --git a/tests/baselines/reference/privateNamesUnique.symbols b/tests/baselines/reference/privateNamesUnique.symbols deleted file mode 100644 index 5266e47918187..0000000000000 --- a/tests/baselines/reference/privateNamesUnique.symbols +++ /dev/null @@ -1,22 +0,0 @@ -=== tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts === -// @target es6 - -class A { ->A : Symbol(A, Decl(privateNamesUnique.ts, 0, 0)) - - #foo: number; ->#foo : Symbol(A.#foo, Decl(privateNamesUnique.ts, 2, 9)) -} - -class B { ->B : Symbol(B, Decl(privateNamesUnique.ts, 4, 1)) - - #foo: number; ->#foo : Symbol(B.#foo, Decl(privateNamesUnique.ts, 6, 9)) -} - -const b: A = new B(); // Error: Property #foo is missing ->b : Symbol(b, Decl(privateNamesUnique.ts, 10, 5)) ->A : Symbol(A, Decl(privateNamesUnique.ts, 0, 0)) ->B : Symbol(B, Decl(privateNamesUnique.ts, 4, 1)) - diff --git a/tests/baselines/reference/privateNamesUseBeforeDef.errors.txt b/tests/baselines/reference/privateNamesUseBeforeDef.errors.txt new file mode 100644 index 0000000000000..7105d8d9481e8 --- /dev/null +++ b/tests/baselines/reference/privateNamesUseBeforeDef.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts(2,17): error TS2729: Property '#bar' is used before its initialization. +tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts(7,17): error TS2729: Property '#bar' is used before its initialization. + + +==== tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts (2 errors) ==== + class A { + #foo = this.#bar; // Error + ~~~~ +!!! error TS2729: Property '#bar' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts:3:5: '#bar' is declared here. + #bar = 3; + } + + class B { + #foo = this.#bar; // Error + ~~~~ +!!! error TS2729: Property '#bar' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts:8:5: '#bar' is declared here. + #bar = this.#foo; + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesUseBeforeDef.js b/tests/baselines/reference/privateNamesUseBeforeDef.js new file mode 100644 index 0000000000000..06b5316189dce --- /dev/null +++ b/tests/baselines/reference/privateNamesUseBeforeDef.js @@ -0,0 +1,34 @@ +//// [privateNamesUseBeforeDef.ts] +class A { + #foo = this.#bar; // Error + #bar = 3; +} + +class B { + #foo = this.#bar; // Error + #bar = this.#foo; +} + + +//// [privateNamesUseBeforeDef.js] +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var _foo, _bar, _foo_1, _bar_1; +class A { + constructor() { + _foo.set(this, __classPrivateFieldGet(this, _bar)); // Error + _bar.set(this, 3); + } +} +_foo = new WeakMap(), _bar = new WeakMap(); +class B { + constructor() { + _foo_1.set(this, __classPrivateFieldGet(this, _bar_1)); // Error + _bar_1.set(this, __classPrivateFieldGet(this, _foo_1)); + } +} +_foo_1 = new WeakMap(), _bar_1 = new WeakMap(); diff --git a/tests/baselines/reference/privateNamesUseBeforeDef.symbols b/tests/baselines/reference/privateNamesUseBeforeDef.symbols new file mode 100644 index 0000000000000..21df1931d9760 --- /dev/null +++ b/tests/baselines/reference/privateNamesUseBeforeDef.symbols @@ -0,0 +1,27 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts === +class A { +>A : Symbol(A, Decl(privateNamesUseBeforeDef.ts, 0, 0)) + + #foo = this.#bar; // Error +>#foo : Symbol(A.#foo, Decl(privateNamesUseBeforeDef.ts, 0, 9)) +>this.#bar : Symbol(A.#bar, Decl(privateNamesUseBeforeDef.ts, 1, 21)) +>this : Symbol(A, Decl(privateNamesUseBeforeDef.ts, 0, 0)) + + #bar = 3; +>#bar : Symbol(A.#bar, Decl(privateNamesUseBeforeDef.ts, 1, 21)) +} + +class B { +>B : Symbol(B, Decl(privateNamesUseBeforeDef.ts, 3, 1)) + + #foo = this.#bar; // Error +>#foo : Symbol(B.#foo, Decl(privateNamesUseBeforeDef.ts, 5, 9)) +>this.#bar : Symbol(B.#bar, Decl(privateNamesUseBeforeDef.ts, 6, 21)) +>this : Symbol(B, Decl(privateNamesUseBeforeDef.ts, 3, 1)) + + #bar = this.#foo; +>#bar : Symbol(B.#bar, Decl(privateNamesUseBeforeDef.ts, 6, 21)) +>this.#foo : Symbol(B.#foo, Decl(privateNamesUseBeforeDef.ts, 5, 9)) +>this : Symbol(B, Decl(privateNamesUseBeforeDef.ts, 3, 1)) +} + diff --git a/tests/baselines/reference/privateNamesUseBeforeDef.types b/tests/baselines/reference/privateNamesUseBeforeDef.types new file mode 100644 index 0000000000000..4f43c5b48234c --- /dev/null +++ b/tests/baselines/reference/privateNamesUseBeforeDef.types @@ -0,0 +1,28 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts === +class A { +>A : A + + #foo = this.#bar; // Error +>#foo : number +>this.#bar : number +>this : this + + #bar = 3; +>#bar : number +>3 : 3 +} + +class B { +>B : B + + #foo = this.#bar; // Error +>#foo : any +>this.#bar : any +>this : this + + #bar = this.#foo; +>#bar : any +>this.#foo : any +>this : this +} + diff --git a/tests/baselines/reference/shebangError.errors.txt b/tests/baselines/reference/shebangError.errors.txt index f94d4929d271e..169b106d0d6d2 100644 --- a/tests/baselines/reference/shebangError.errors.txt +++ b/tests/baselines/reference/shebangError.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/shebangError.ts(2,1): error TS18008: '#!' can only be used at the start of a file. +tests/cases/compiler/shebangError.ts(2,1): error TS18026: '#!' can only be used at the start of a file. tests/cases/compiler/shebangError.ts(2,2): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/compiler/shebangError.ts(2,12): error TS2304: Cannot find name 'env'. tests/cases/compiler/shebangError.ts(2,16): error TS1005: ';' expected. @@ -9,7 +9,7 @@ tests/cases/compiler/shebangError.ts(2,16): error TS2304: Cannot find name 'node var foo = 'Shebang is only allowed on the first line'; #!/usr/bin/env node -!!! error TS18008: '#!' can only be used at the start of a file. +!!! error TS18026: '#!' can only be used at the start of a file. ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. ~~~ diff --git a/tests/baselines/reference/strictModeInConstructor.errors.txt b/tests/baselines/reference/strictModeInConstructor.errors.txt index 9a80732842afe..bce4fb1d7b747 100644 --- a/tests/baselines/reference/strictModeInConstructor.errors.txt +++ b/tests/baselines/reference/strictModeInConstructor.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. ==== tests/cases/compiler/strictModeInConstructor.ts (1 errors) ==== @@ -38,7 +38,7 @@ tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' c ~~~~~~~~~~~~~~~~~~~~~ } ~~~~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. +!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers. } class Bs extends A { diff --git a/tests/baselines/reference/symbolType3.errors.txt b/tests/baselines/reference/symbolType3.errors.txt index dec7b109798dc..156cf9f3916b6 100644 --- a/tests/baselines/reference/symbolType3.errors.txt +++ b/tests/baselines/reference/symbolType3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/Symbols/symbolType3.ts(2,8): error TS2704: The operand of a delete operator cannot be a read-only property. +tests/cases/conformance/es6/Symbols/symbolType3.ts(2,8): error TS2704: The operand of a 'delete' operator cannot be a read-only property. tests/cases/conformance/es6/Symbols/symbolType3.ts(5,3): error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es6/Symbols/symbolType3.ts(6,3): error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/conformance/es6/Symbols/symbolType3.ts(7,3): error TS2469: The '+' operator cannot be applied to type 'symbol'. @@ -11,7 +11,7 @@ tests/cases/conformance/es6/Symbols/symbolType3.ts(12,2): error TS2469: The '+' var s = Symbol(); delete Symbol.iterator; ~~~~~~~~~~~~~~~ -!!! error TS2704: The operand of a delete operator cannot be a read-only property. +!!! error TS2704: The operand of a 'delete' operator cannot be a read-only property. void Symbol.toPrimitive; typeof Symbol.toStringTag; ++s; diff --git a/tests/baselines/reference/templateStringInDeleteExpression.errors.txt b/tests/baselines/reference/templateStringInDeleteExpression.errors.txt index 2827231ebc513..7b8cbdb7951b2 100644 --- a/tests/baselines/reference/templateStringInDeleteExpression.errors.txt +++ b/tests/baselines/reference/templateStringInDeleteExpression.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/es6/templates/templateStringInDeleteExpression.ts(1,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es6/templates/templateStringInDeleteExpression.ts(1,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/es6/templates/templateStringInDeleteExpression.ts (1 errors) ==== delete `abc${0}abc`; ~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/baselines/reference/templateStringInDeleteExpressionES6.errors.txt b/tests/baselines/reference/templateStringInDeleteExpressionES6.errors.txt index bdc53343fb144..104d2336516a1 100644 --- a/tests/baselines/reference/templateStringInDeleteExpressionES6.errors.txt +++ b/tests/baselines/reference/templateStringInDeleteExpressionES6.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/es6/templates/templateStringInDeleteExpressionES6.ts(1,8): error TS2703: The operand of a delete operator must be a property reference. +tests/cases/conformance/es6/templates/templateStringInDeleteExpressionES6.ts(1,8): error TS2703: The operand of a 'delete' operator must be a property reference. ==== tests/cases/conformance/es6/templates/templateStringInDeleteExpressionES6.ts (1 errors) ==== delete `abc${0}abc`; ~~~~~~~~~~~~ -!!! error TS2703: The operand of a delete operator must be a property reference. \ No newline at end of file +!!! error TS2703: The operand of a 'delete' operator must be a property reference. \ No newline at end of file diff --git a/tests/cases/compiler/privateNameJsx.tsx b/tests/cases/compiler/privateNameJsx.tsx new file mode 100644 index 0000000000000..a07cbf8b6df91 --- /dev/null +++ b/tests/cases/compiler/privateNameJsx.tsx @@ -0,0 +1,9 @@ +// @jsx: preserve + +class Test { + #prop = () =>
; + render() { + return ; + } +} + diff --git a/tests/cases/compiler/privateNameWeakMapCollision.ts b/tests/cases/compiler/privateNameWeakMapCollision.ts new file mode 100644 index 0000000000000..b9e91c5c15ac6 --- /dev/null +++ b/tests/cases/compiler/privateNameWeakMapCollision.ts @@ -0,0 +1,8 @@ +// @target: es2015 + +function test() { + let WeakMap; + class C { + #x; + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts b/tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts new file mode 100644 index 0000000000000..099e734594684 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameAndAny.ts @@ -0,0 +1,10 @@ +// @strict: true +// @target: es6 + +class A { + #foo = true; + method(thing: any) { + thing.#foo; // OK + thing.#bar; // Error + } +}; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts b/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts index 1f5da9ab9171e..c1d258c7be0aa 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts @@ -1,9 +1,13 @@ // @strict: true -// @target es6 +// @target: es6 class A { [k: string]: any; + #foo = 3; + ["#bar"] = this["#bar"] // Error (private identifiers should not prevent circularity checking for computeds) constructor(message: string) { - this.#f = 3 // Error Property '#f' does not exist on type 'A'. + this.#f = 3 // Error (index signatures do not implicitly declare private names) + this["#foo"] = 3; // Okay (type has index signature and "#foo" does not collide with private identifier #foo) + } } diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts b/tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts new file mode 100644 index 0000000000000..fc6c20828556c --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameAndPropertySignature.ts @@ -0,0 +1,16 @@ +type A = { + #foo: string +} + +interface B { + #foo: string; +} + +declare const x: { + #foo: number; + bar: { + #baz: string; + } +}; + +declare const y: [{ qux: { #quux: 3 } }]; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts b/tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts new file mode 100644 index 0000000000000..5dab0f08fed5c --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameAndStaticInitializer.ts @@ -0,0 +1,8 @@ +// @target: esnext, es2015 + +class A { + #foo = 1; + static inst = new A(); + #prop = 2; +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts b/tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts new file mode 100644 index 0000000000000..63ba5aa57af0a --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameBadAssignment.ts @@ -0,0 +1,16 @@ +// @target: es2015 + +exports.#nope = 1; // Error (outside class body) +function A() { } +A.prototype.#no = 2; // Error (outside class body) + +class B {} +B.#foo = 3; // Error (outside class body) + +class C { + #bar = 6; + constructor () { + exports.#bar = 6; // Error + this.#foo = 3; // Error (undeclared) + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts b/tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts new file mode 100644 index 0000000000000..2a8c589b11da9 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameBadDeclaration.ts @@ -0,0 +1,13 @@ +function A() { } +A.prototype = { + #x: 1 // Error +} +class B { } +B.prototype = { + #y: 2 // Error +} +class C { + constructor() { + this.#z = 3; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts b/tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts new file mode 100644 index 0000000000000..5e31c50599e31 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts @@ -0,0 +1,9 @@ +// @target: es2015 +class B {}; +class A extends B { + #x; + constructor() { + void 0; // Error: 'super' call must come first + super(); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts b/tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts new file mode 100644 index 0000000000000..79ddd495f5d8c --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameCircularReference.ts @@ -0,0 +1,8 @@ +// @strict: true +// @target: es6 + +class A { + #foo = this.#bar; + #bar = this.#foo; + ["#baz"] = this["#baz"]; // Error (should *not* be private name error) +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts b/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts index 1421db99944d8..1e1f1e8f50c8a 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts @@ -1,4 +1,4 @@ -// @target es6 +// @target: es6 class A { #constructor() {} // Error: `#constructor` is a reserved word. diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameConstructorSignature.ts b/tests/cases/conformance/classes/members/privateNames/privateNameConstructorSignature.ts new file mode 100644 index 0000000000000..9f074b7b6fdd0 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameConstructorSignature.ts @@ -0,0 +1,18 @@ +// @target: es2015 + +interface D { + x: number; +} +class C { + #x; + static test() { + new C().#x = 10; + const y = new C(); + const z = new y(); + z.x = 123; + } +} +interface C { + new (): D; +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameDeclaration.ts b/tests/cases/conformance/classes/members/privateNames/privateNameDeclaration.ts new file mode 100644 index 0000000000000..d3005ddff1645 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameDeclaration.ts @@ -0,0 +1,12 @@ +// @declaration: true +// @target: es2015 + +class A { + #foo: string; + #bar = 6; + baz: string; + qux = 6; + quux(): void { + + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts b/tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts new file mode 100644 index 0000000000000..018024073fb32 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameDeclarationMerging.ts @@ -0,0 +1,16 @@ +// @target: es6 + +class D {}; + +class C { + #x; + foo () { + const c = new C(); + c.#x; // OK + const d: D = new C(); + d.#x; // Error + } +} +interface C { + new (): D; +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts b/tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts index ba8160cb122ab..45ed8f020d757 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameDuplicateField.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { #foo = "foo"; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts b/tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts new file mode 100644 index 0000000000000..169351c9822ad --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameES5Ban.ts @@ -0,0 +1,14 @@ +// @target: es5, es3 + +class A { + constructor() {} + #field = 123; + #method() {} + static #sField = "hello world"; + static #sMethod() {} + get #acc() { return ""; } + set #acc(x: string) {} + static get #sAcc() { return 0; } + static set #sAcc(x: number) {} +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts b/tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts new file mode 100644 index 0000000000000..9df665c30c0fd --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameEnum.ts @@ -0,0 +1,4 @@ + +enum E { + #x +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameField.ts b/tests/cases/conformance/classes/members/privateNames/privateNameField.ts index d4b823c49da63..a6405e17289d0 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameField.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameField.ts @@ -1,9 +1,9 @@ // @strict: true -// @target es6 +// @target: es6 class A { #name: string; constructor(name: string) { this.#name = name; } -} \ No newline at end of file +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldAccess.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldAccess.ts new file mode 100644 index 0000000000000..4c02159bfa722 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldAccess.ts @@ -0,0 +1,8 @@ +// @target: es2015 + +class A { + #myField = "hello world"; + constructor() { + console.log(this.#myField); + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldAssignment.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldAssignment.ts new file mode 100644 index 0000000000000..673fdb37de614 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldAssignment.ts @@ -0,0 +1,36 @@ +// @target: es2015 + +class A { + #field = 0; + constructor() { + this.#field = 1; + this.#field += 2; + this.#field -= 3; + this.#field /= 4; + this.#field *= 5; + this.#field **= 6; + this.#field %= 7; + this.#field <<= 8; + this.#field >>= 9; + this.#field >>>= 10; + this.#field &= 11; + this.#field |= 12; + this.#field ^= 13; + A.getInstance().#field = 1; + A.getInstance().#field += 2; + A.getInstance().#field -= 3; + A.getInstance().#field /= 4; + A.getInstance().#field *= 5; + A.getInstance().#field **= 6; + A.getInstance().#field %= 7; + A.getInstance().#field <<= 8; + A.getInstance().#field >>= 9; + A.getInstance().#field >>>= 10; + A.getInstance().#field &= 11; + A.getInstance().#field |= 12; + A.getInstance().#field ^= 13; + } + static getInstance() { + return new A(); + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldCallExpression.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldCallExpression.ts new file mode 100644 index 0000000000000..996c01c8ef8a7 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldCallExpression.ts @@ -0,0 +1,20 @@ +// @target: es2015 + +class A { + #fieldFunc = function() { this.x = 10; }; + #fieldFunc2 = function(a, ...b) {}; + x = 1; + test() { + this.#fieldFunc(); + const func = this.#fieldFunc; + func(); + new this.#fieldFunc(); + + const arr = [ 1, 2 ]; + this.#fieldFunc2(0, ...arr, 3); + const b = new this.#fieldFunc2(0, ...arr, 3); + const str = this.#fieldFunc2`head${1}middle${2}tail`; + this.getInstance().#fieldFunc2`test${1}and${2}`; + } + getInstance() { return new A(); } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldClassExpression.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldClassExpression.ts new file mode 100644 index 0000000000000..e76ff48c8aabf --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldClassExpression.ts @@ -0,0 +1,15 @@ +// @target: es2015 + +class B { + #foo = class { + constructor() { + console.log("hello"); + } + static test = 123; + }; + #foo2 = class Foo { + static otherClass = 123; + }; +} + + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts new file mode 100644 index 0000000000000..8d941d757f366 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldDerivedClasses.ts @@ -0,0 +1,14 @@ +// @target: es2015 + +class Base { + #prop: number = 123; + static method(x: Derived) { + console.log(x.#prop); + } +} +class Derived extends Base { + static method(x: Derived) { + console.log(x.#prop); + } +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts new file mode 100644 index 0000000000000..7dc2b944c3735 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldDestructuredBinding.ts @@ -0,0 +1,25 @@ +// @target: esnext, es2015 + +class A { + #field = 1; + otherObject = new A(); + testObject() { + return { x: 10, y: 6 }; + } + testArray() { + return [10, 11]; + } + constructor() { + let y: number; + ({ x: this.#field, y } = this.testObject()); + ([this.#field, y] = this.testArray()); + ({ a: this.#field, b: [this.#field] } = { a: 1, b: [2] }); + [this.#field, [this.#field]] = [1, [2]]; + ({ a: this.#field = 1, b: [this.#field = 1] } = { b: [] }); + [this.#field = 2] = []; + [this.otherObject.#field = 2] = []; + } + static test(_a: A) { + [_a.#field] = [2]; + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldInitializer.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldInitializer.ts new file mode 100644 index 0000000000000..decfa7aec78b4 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldInitializer.ts @@ -0,0 +1,6 @@ +// @target: es2015 + +class A { + #field = 10; + #uninitialized; +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldUnaryMutation.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldUnaryMutation.ts new file mode 100644 index 0000000000000..a236a74737935 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldUnaryMutation.ts @@ -0,0 +1,30 @@ +// @target: es2015 + +class C { + #test: number = 24; + constructor() { + this.#test++; + this.#test--; + ++this.#test; + --this.#test; + const a = this.#test++; + const b = this.#test--; + const c = ++this.#test; + const d = --this.#test; + for (this.#test = 0; this.#test < 10; ++this.#test) {} + for (this.#test = 0; this.#test < 10; this.#test++) {} + } + test() { + this.getInstance().#test++; + this.getInstance().#test--; + ++this.getInstance().#test; + --this.getInstance().#test; + const a = this.getInstance().#test++; + const b = this.getInstance().#test--; + const c = ++this.getInstance().#test; + const d = --this.getInstance().#test; + for (this.getInstance().#test = 0; this.getInstance().#test < 10; ++this.getInstance().#test) {} + for (this.getInstance().#test = 0; this.getInstance().#test < 10; this.getInstance().#test++) {} + } + getInstance() { return new C(); } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts new file mode 100644 index 0000000000000..811b8e5e970aa --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldsESNext.ts @@ -0,0 +1,21 @@ +// @target: esnext + +class C { + a = 123; + #a = 10; + c = "hello"; + #b; + method() { + console.log(this.#a); + this.#a = "hello"; + console.log(this.#b); + } + static #m = "test"; + static #x; + static test() { + console.log(this.#m); + console.log(this.#x = "test"); + } + #something = () => 1234; +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.ts b/tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.ts new file mode 100644 index 0000000000000..62fc1c98b28e9 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameImplicitDeclaration.ts @@ -0,0 +1,12 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: privateNameImplicitDeclaration.js + +class C { + constructor() { + /** @type {string} */ + this.#x; + } +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameInLhsReceiverExpression.ts b/tests/cases/conformance/classes/members/privateNames/privateNameInLhsReceiverExpression.ts new file mode 100644 index 0000000000000..ef80b633271b6 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameInLhsReceiverExpression.ts @@ -0,0 +1,10 @@ +// @target: es2015 + +class Test { + #y = 123; + static something(obj: { [key: string]: Test }) { + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y = 1; + obj[(new class { #x = 1; readonly s = "prop"; }).s].#y += 1; + } +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.ts b/tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.ts new file mode 100644 index 0000000000000..38e210383d5da --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.ts @@ -0,0 +1,19 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: privateNameJsBadAssignment.js +// @target: es2015 + +exports.#nope = 1; // Error (outside class body) +function A() { } +A.prototype.#no = 2; // Error (outside class body) + +class B {} +B.#foo = 3; // Error (outside class body) + +class C { + #bar = 6; + constructor () { + this.#foo = 3; // Error (undeclared) + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameJsBadDeclaration.ts b/tests/cases/conformance/classes/members/privateNames/privateNameJsBadDeclaration.ts new file mode 100644 index 0000000000000..90e6197c6b3cc --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameJsBadDeclaration.ts @@ -0,0 +1,18 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: privateNameJsPrototype.js + +function A() { } +A.prototype = { + #x: 1 // Error +} +class B { } +B.prototype = { + #y: 2 // Error +} +class C { + constructor() { + this.#z = 3; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts b/tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts new file mode 100644 index 0000000000000..e7d55345dbeee --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameNestedClassFieldShadowing.ts @@ -0,0 +1,16 @@ +// @target: es2015 + +class Base { + #x; + constructor() { + class Derived { + #x; + testBase(x: Base) { + console.log(x.#x); + } + testDerived(x: Derived) { + console.log(x.#x); + } + } + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameNestedClassNameConflict.ts b/tests/cases/conformance/classes/members/privateNames/privateNameNestedClassNameConflict.ts new file mode 100644 index 0000000000000..71131413f8065 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameNestedClassNameConflict.ts @@ -0,0 +1,10 @@ +// @target: es2015 + +class A { + #foo: string; + constructor() { + class A { + #foo: string; + } + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts b/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts index 6f14d0ec8d72e..e56d8040527f3 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { #foo: number = 3; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts b/tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts index 26aacc421a19a..5d4c4a7e9e521 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameNotAllowedOutsideClass.ts @@ -1,4 +1,4 @@ // @strict: true -// @target es6 +// @target: es6 -const #foo = 3; \ No newline at end of file +const #foo = 3; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts b/tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts deleted file mode 100644 index f4450f031ab75..0000000000000 --- a/tests/cases/conformance/classes/members/privateNames/privateNameSneakyRuntimeException.ts +++ /dev/null @@ -1,16 +0,0 @@ -// @strict: true -// @target es6 - -function createClass () { - return class { - #foo = 3; - equals(other: any) { - return this.#foo = other.#foo; - } - }; -} - -const a = new (createClass())(); -const b = new (createClass())(); - -console.log(a.equals(b)); // OK at compile time but will be a runtime error diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts b/tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts new file mode 100644 index 0000000000000..f7bb388043ac7 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameUnused.ts @@ -0,0 +1,11 @@ +// @noUnusedLocals:true +// @noEmit: true +// @target: es2015 + +export class A { + #used = "used"; + #unused = "unused"; + constructor () { + console.log(this.#used); + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts index ebf44118093aa..ebd973c240f04 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndFields.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { #foo: number; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts index d564860b56e97..70968173e4db5 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndMethods.ts @@ -17,7 +17,7 @@ class A { constructor () { this.#foo(30); this.#bar(30); - this.#bar(30); + this.#baz(30); this.#quux = this.#quux + 1; this.#quux++; } diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts index ec9906a8ef00d..a83fb2d8796c7 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndStaticFields.ts @@ -1,10 +1,13 @@ // @strict: true -// @target es6 +// @target: es6 class A { static #foo: number; + static #bar: number; constructor () { A.#foo = 3; + B.#foo; // Error + B.#bar; // Error } } @@ -15,3 +18,7 @@ class B extends A { B.#foo = "some string"; } } + +// We currently filter out static private identifier fields in `getUnmatchedProperties`. +// We will need a more robust solution when we support static fields +const willErrorSomeDay: typeof A = class {}; // OK for now diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts index 1e178092c7e8d..1ea2826e0470e 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesAndkeyof.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { #foo = 3; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts new file mode 100644 index 0000000000000..92a3e67e66ec3 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-1.ts @@ -0,0 +1,15 @@ +// @target: es2015 + +class Parent { + #foo = 3; + static #bar = 5; + accessChildProps() { + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + Child.#bar; // Error: not found + } +} + +class Child extends Parent { + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + #bar = "bar"; // OK +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts new file mode 100644 index 0000000000000..96949805c9f51 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesConstructorChain-2.ts @@ -0,0 +1,17 @@ +// @target: es2015 + +class Parent { + #foo = 3; + static #bar = 5; + accessChildProps() { + new Child().#foo; // OK (`#foo` was added when `Parent`'s constructor was called on `child`) + Child.#bar; // Error: not found + } +} + +class Child extends Parent { + #foo = "foo"; // OK (Child's #foo does not conflict, as `Parent`'s `#foo` is not accessible) + #bar = "bar"; // OK +} + +new Parent().accessChildProps(); diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts similarity index 89% rename from tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts rename to tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts index dc6076ffbe096..4db3b473cf810 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-1.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { #foo = "A's #foo"; @@ -25,4 +25,4 @@ class A { } } -new A().method(); \ No newline at end of file +new A().method(); diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts new file mode 100644 index 0000000000000..3cf8f3904dc7b --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesInNestedClasses-2.ts @@ -0,0 +1,18 @@ +// @strict: true +// @target: es6 + +class A { + static #x = 5; + constructor () { + class B { + #x = 5; + constructor() { + class C { + constructor() { + A.#x // error + } + } + } + } + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts similarity index 66% rename from tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts rename to tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts index a70c8acd143ac..effcddcf4e30b 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { public #foo = 3; // Error @@ -7,3 +7,7 @@ class A { protected #baz = 3; // Error readonly #qux = 3; // OK } + +abstract class B { + abstract #quux = 3; // Error +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts new file mode 100644 index 0000000000000..c330e117003fe --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesInterfaceExtendingClass.ts @@ -0,0 +1,14 @@ +// @target: es2015 + +class C { + #prop; + func(x: I) { + x.#prop = 123; + } +} +interface I extends C {} + +function func(x: I) { + x.#prop = 123; +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts deleted file mode 100644 index 937ed9c4c3cfa..0000000000000 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts +++ /dev/null @@ -1,12 +0,0 @@ -// @strict: true -// @target es6 - -class A { - #foo: number; -} - -class B extends A { - #foo: string; // OK: private names are unique to each class -} - -const b: A = new B() // OK diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts index 70b099a0e5397..d469eafeb785d 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { #v = 1; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts index 5a71fc00803c2..3f1f49efd68dd 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedAsParameters.ts @@ -1,4 +1,4 @@ -// @target es6 +// @target: es6 class A { setFoo(#foo: string) {} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts index 26aacc421a19a..5d4c4a7e9e521 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesNotAllowedInVariableDeclarations.ts @@ -1,4 +1,4 @@ // @strict: true -// @target es6 +// @target: es6 -const #foo = 3; \ No newline at end of file +const #foo = 3; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-1.ts similarity index 83% rename from tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts rename to tests/cases/conformance/classes/members/privateNames/privateNamesUnique-1.ts index 1e9891095512d..82ba213b0f8ab 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-1.ts @@ -1,5 +1,5 @@ // @strict: true -// @target es6 +// @target: es6 class A { #foo: number; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-2.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-2.ts new file mode 100644 index 0000000000000..dd79f670e57af --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-2.ts @@ -0,0 +1,21 @@ +// @target: es2015 +// @filename: a.ts +export class Foo { + #x; + copy(other: import("./b").Foo) { + other.#x; // error + } +} + +// @filename: b.ts +export class Foo { + #x; +} + +// @filename: main.ts +import { Foo as A } from "./a"; +import { Foo as B } from "./b"; + +const a = new A(); +const b = new B(); +a.copy(b); // error diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts new file mode 100644 index 0000000000000..bb7e86607aa48 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesUnique-3.ts @@ -0,0 +1,15 @@ +// @target: es2015 + +class A { + #foo = 1; + static #foo = true; // error (duplicate) + // because static and instance private names + // share the same lexical scope + // https://tc39.es/proposal-class-fields/#prod-ClassBody +} +class B { + static #foo = true; + test(x: B) { + x.#foo; // error (#foo is a static property on B, not an instance property) + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts new file mode 100644 index 0000000000000..cc0c3bf8980f9 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesUseBeforeDef.ts @@ -0,0 +1,11 @@ +// @target: es2015 + +class A { + #foo = this.#bar; // Error + #bar = 3; +} + +class B { + #foo = this.#bar; // Error + #bar = this.#foo; +} diff --git a/tests/cases/conformance/jsdoc/jsdocPrivateName1.ts b/tests/cases/conformance/jsdoc/jsdocPrivateName1.ts new file mode 100644 index 0000000000000..b33fb4a4ee599 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocPrivateName1.ts @@ -0,0 +1,11 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @lib: dom,esnext +// @Filename: jsdocPrivateName1.js +// @target: es2015 + +class A { + /** @type {boolean} some number value */ + #foo = 3 // Error because not assignable to boolean +} diff --git a/tests/cases/conformance/jsdoc/jsdocPrivateName2.ts b/tests/cases/conformance/jsdoc/jsdocPrivateName2.ts new file mode 100644 index 0000000000000..32575b2538c72 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocPrivateName2.ts @@ -0,0 +1,13 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @lib: dom,esnext +// @Filename: jsdocPrivateName1.js + +// Expecting parse error for private field + +/** + * @typedef A + * @type {object} + * @property {string} #id + */ diff --git a/tests/cases/fourslash/codeFixMissingPrivateIdentifierMethodDeclaration.ts b/tests/cases/fourslash/codeFixMissingPrivateIdentifierMethodDeclaration.ts new file mode 100644 index 0000000000000..f8e6242a3babd --- /dev/null +++ b/tests/cases/fourslash/codeFixMissingPrivateIdentifierMethodDeclaration.ts @@ -0,0 +1,19 @@ +/// + +//// class A { +//// constructor() { +//// this.[|/*pnUse*/#prop|] = 123; +//// } +//// } + +verify.codeFix({ + description: "Declare property '#prop'", + index: 0, + newFileContent: `class A { + #prop: number; + constructor() { + this.#prop = 123; + } +}` +}); + diff --git a/tests/cases/fourslash/goToDefinitionPrivateName.ts b/tests/cases/fourslash/goToDefinitionPrivateName.ts new file mode 100644 index 0000000000000..4524fca577c8d --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionPrivateName.ts @@ -0,0 +1,12 @@ +/// + +//// class A { +//// [|/*pnDecl*/#foo|] = 3; +//// constructor() { +//// this.[|/*pnUse*/#foo|] +//// } +//// } + +verify.goToDefinition({ + pnUse: "pnDecl", +}); diff --git a/tests/cases/fourslash/hoverOverPrivateName.ts b/tests/cases/fourslash/hoverOverPrivateName.ts index 28e748b9aa43c..84c9361fff1a0 100644 --- a/tests/cases/fourslash/hoverOverPrivateName.ts +++ b/tests/cases/fourslash/hoverOverPrivateName.ts @@ -1,15 +1,27 @@ /// -////class A { -//// #foo: number; -//// -//// constructor () { -//// this./**/#foo = 3; -//// } -//// -////} +//// class A { +//// #f/*1*/oo = 3; +//// #b/*2*/ar: number; +//// #b/*3*/az = () => "hello"; +//// #q/*4*/ux(n: number): string { +//// return "" + n; +//// } +//// static #staticF/*5*/oo = 3; +//// static #staticB/*6*/ar: number; +//// static #staticB/*7*/az = () => "hello"; +//// static #staticQ/*8*/ux(n: number): string { +//// return "" + n; +//// } +//// } -goTo.marker(); -verify.quickInfoIs(""); -verify.goToDefinitionIs([]); -verify.noReferences(); \ No newline at end of file +verify.quickInfos({ + 1: "(property) A.#foo: number", + 2: "(property) A.#bar: number", + 3: "(property) A.#baz: () => string", + 4: "(method) A.#qux(n: number): string", + 5: "(property) A.#staticFoo: number", + 6: "(property) A.#staticBar: number", + 7: "(property) A.#staticBaz: () => string", + 8: "(method) A.#staticQux(n: number): string", +}); diff --git a/tests/cases/fourslash/navigationBarPrivateName.ts b/tests/cases/fourslash/navigationBarPrivateName.ts new file mode 100644 index 0000000000000..dd8c85f99470e --- /dev/null +++ b/tests/cases/fourslash/navigationBarPrivateName.ts @@ -0,0 +1,91 @@ +/// + +//// class A { +//// #foo: () => { +//// class B { +//// #bar: () => { +//// function baz () { +//// } +//// } +//// } +//// } +//// } + +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "A", + "kind": "class", + "childItems": [ + { + "text": "#foo", + "kind": "property" + } + ] + }, + { + "text": "B", + "kind": "class", + "childItems": [ + { + "text": "#bar", + "kind": "property" + } + ] + }, + { + "text": "baz", + "kind": "function" + } + ] +}); + +verify.navigationBar([ + { + "text": "", + "kind": "script", + "childItems": [ + { + "text": "A", + "kind": "class" + }, + { + "text": "B", + "kind": "class" + }, + { + "text": "baz", + "kind": "function" + } + ] + }, + { + "text": "A", + "kind": "class", + "childItems": [ + { + "text": "#foo", + "kind": "property" + } + ], + "indent": 1 + }, + { + "text": "B", + "kind": "class", + "childItems": [ + { + "text": "#bar", + "kind": "property" + } + ], + "indent": 1 + }, + { + "text": "baz", + "kind": "function", + "indent": 1 + } +]); From 407f3ecab25149ab16b9e251338c4693370219e4 Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Mon, 23 Dec 2019 13:03:51 +0000 Subject: [PATCH 08/16] fix privateIdentifier w !useDefineForClassFields Signed-off-by: Max Heiber --- src/compiler/transformers/classFields.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index c5b64a6fa7c70..1277be2aefded 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -618,7 +618,11 @@ namespace ts { function transformConstructorBody(node: ClassDeclaration | ClassExpression, constructor: ConstructorDeclaration | undefined, isDerivedClass: boolean) { const useDefineForClassFields = context.getCompilerOptions().useDefineForClassFields; - const properties = getProperties(node, /*requireInitializer*/ !useDefineForClassFields, /*isStatic*/ false) + let properties = getProperties(node, /*requireInitializer*/ false, /*isStatic*/ false); + if (!useDefineForClassFields) { + properties = filter(properties, property => !!property.initializer || isPrivateIdentifier(property.name)); + } + // Only generate synthetic constructor when there are property initializers to move. if (!constructor && !some(properties)) { From 0b4d2e06446f8da13d1edf6803810502d72b6626 Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Wed, 16 Oct 2019 11:58:54 +0100 Subject: [PATCH 09/16] Disallow PrivateIdentifier in Optional Chains Signed-off-by: Max Heiber --- src/compiler/checker.ts | 15 ++++++-- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/parser.ts | 3 +- src/compiler/transformers/esnext.ts | 9 ++++- src/compiler/utilities.ts | 3 +- .../privateIdentifierChain.1.errors.txt | 28 ++++++++++++++ .../reference/privateIdentifierChain.1.js | 28 ++++++++++++++ .../privateIdentifierChain.1.symbols | 35 ++++++++++++++++++ .../reference/privateIdentifierChain.1.types | 37 +++++++++++++++++++ .../privateIdentifierChain.1.ts | 15 ++++++++ .../fourslash/completionAfterQuestionDot.ts | 31 ++++++++++++++-- 11 files changed, 197 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/privateIdentifierChain.1.errors.txt create mode 100644 tests/baselines/reference/privateIdentifierChain.1.js create mode 100644 tests/baselines/reference/privateIdentifierChain.1.symbols create mode 100644 tests/baselines/reference/privateIdentifierChain.1.types create mode 100644 tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d9a23cdc5a672..88a7e6397a957 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23171,6 +23171,10 @@ namespace ts { const assignmentKind = getAssignmentTargetKind(node); const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); if (isPrivateIdentifier(right)) { + if (isOptionalChain(node)) { + grammarErrorOnNode(right, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); + return anyType; + } checkExternalEmitHelpers(node, ExternalEmitHelpers.ClassPrivateFieldGet); } const isAnyLike = isTypeAny(apparentType) || apparentType === silentNeverType; @@ -23548,9 +23552,14 @@ namespace ts { return true; } const prop = getPropertyOfType(type, propertyName); - return prop ? checkPropertyAccessibility(node, isSuper, type, prop) - // In js files properties of unions are allowed in completion - : isInJSFile(node) && (type.flags & TypeFlags.Union) !== 0 && (type).types.some(elementType => isValidPropertyAccessWithType(node, isSuper, propertyName, elementType)); + if (prop) { + if (isOptionalChain(node) && isPrivateIdentifierPropertyDeclaration(prop.valueDeclaration)) { + return false; + } + return checkPropertyAccessibility(node, isSuper, type, prop); + } + // In js files properties of unions are allowed in completion + return isInJSFile(node) && (type.flags & TypeFlags.Union) !== 0 && (type).types.some(elementType => isValidPropertyAccessWithType(node, isSuper, propertyName, elementType)); } /** diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c9627076641d6..64f348f223f8a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5433,5 +5433,9 @@ "Private identifiers are not allowed in variable declarations.": { "category": "Error", "code": 18029 + }, + "An optional chain cannot contain private identifiers.": { + "category": "Error", + "code": 18030 } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d130118534e49..2287c41431616 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4665,7 +4665,8 @@ namespace ts { const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); propertyAccess.expression = expression; propertyAccess.questionDotToken = questionDotToken; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ !questionDotToken); + // checker will error on private identifiers in optional chains, so don't have to catch them here + propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true); if (questionDotToken || expression.flags & NodeFlags.OptionalChain) { propertyAccess.flags |= NodeFlags.OptionalChain; } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 2300feeb0e20d..2d1d6aeab39e9 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -44,8 +44,13 @@ namespace ts { function flattenChain(chain: OptionalChain) { const links: OptionalChain[] = [chain]; while (!chain.questionDotToken && !isTaggedTemplateExpression(chain)) { - chain = cast(chain.expression, isOptionalChain); - links.unshift(chain); + if (isOptionalChain(chain.expression)) { + chain = chain.expression; + links.unshift(chain); + } + else { + return { expression: chain.expression, chain: links }; + } } return { expression: chain.expression, chain: links }; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 93343650841c7..51d19ec902dff 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2947,10 +2947,11 @@ namespace ts { } } - export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; + export type PropertyNameLiteral = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral; export function isPropertyNameLiteral(node: Node): node is PropertyNameLiteral { switch (node.kind) { case SyntaxKind.Identifier: + case SyntaxKind.PrivateIdentifier: case SyntaxKind.StringLiteral: case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.NumericLiteral: diff --git a/tests/baselines/reference/privateIdentifierChain.1.errors.txt b/tests/baselines/reference/privateIdentifierChain.1.errors.txt new file mode 100644 index 0000000000000..01120af87f0e3 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1.errors.txt @@ -0,0 +1,28 @@ +tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts(8,15): error TS18030: An optional chain cannot contain private identifiers. +tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts(9,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts(9,17): error TS18030: An optional chain cannot contain private identifiers. +tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts(10,22): error TS18030: An optional chain cannot contain private identifiers. + + +==== tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts (4 errors) ==== + class A { + a?: A + #b?: A; + getA(): A { + return new A(); + } + constructor() { + this?.#b; // Error + ~~ +!!! error TS18030: An optional chain cannot contain private identifiers. + this?.a.#b; // Error + ~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~ +!!! error TS18030: An optional chain cannot contain private identifiers. + this?.getA().#b; // Error + ~~ +!!! error TS18030: An optional chain cannot contain private identifiers. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateIdentifierChain.1.js b/tests/baselines/reference/privateIdentifierChain.1.js new file mode 100644 index 0000000000000..9ce965e2fe9f7 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1.js @@ -0,0 +1,28 @@ +//// [privateIdentifierChain.1.ts] +class A { + a?: A + #b?: A; + getA(): A { + return new A(); + } + constructor() { + this?.#b; // Error + this?.a.#b; // Error + this?.getA().#b; // Error + } +} + + +//// [privateIdentifierChain.1.js] +"use strict"; +class A { + constructor() { + this?.#b; // Error + this?.a.#b; // Error + this?.getA().#b; // Error + } + #b; + getA() { + return new A(); + } +} diff --git a/tests/baselines/reference/privateIdentifierChain.1.symbols b/tests/baselines/reference/privateIdentifierChain.1.symbols new file mode 100644 index 0000000000000..65c6b7392fc59 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1.symbols @@ -0,0 +1,35 @@ +=== tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts === +class A { +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + a?: A +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + #b?: A; +>#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + getA(): A { +>getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + return new A(); +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + } + constructor() { + this?.#b; // Error +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + this?.a.#b; // Error +>this?.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) + + this?.getA().#b; // Error +>this?.getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) + } +} + diff --git a/tests/baselines/reference/privateIdentifierChain.1.types b/tests/baselines/reference/privateIdentifierChain.1.types new file mode 100644 index 0000000000000..02a8bdffe11c6 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts === +class A { +>A : A + + a?: A +>a : A | undefined + + #b?: A; +>#b : A | undefined + + getA(): A { +>getA : () => A + + return new A(); +>new A() : A +>A : typeof A + } + constructor() { + this?.#b; // Error +>this?.#b : any +>this : this + + this?.a.#b; // Error +>this?.a.#b : any +>this?.a : A | undefined +>this : this +>a : A | undefined + + this?.getA().#b; // Error +>this?.getA().#b : any +>this?.getA() : A | undefined +>this?.getA : (() => A) | undefined +>this : this +>getA : (() => A) | undefined + } +} + diff --git a/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts b/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts new file mode 100644 index 0000000000000..9222baa72cd85 --- /dev/null +++ b/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts @@ -0,0 +1,15 @@ +// @strict: true +// @target: esnext + +class A { + a?: A + #b?: A; + getA(): A { + return new A(); + } + constructor() { + this?.#b; // Error + this?.a.#b; // Error + this?.getA().#b; // Error + } +} diff --git a/tests/cases/fourslash/completionAfterQuestionDot.ts b/tests/cases/fourslash/completionAfterQuestionDot.ts index 7d31e775a185a..3adb024ba95ed 100644 --- a/tests/cases/fourslash/completionAfterQuestionDot.ts +++ b/tests/cases/fourslash/completionAfterQuestionDot.ts @@ -1,20 +1,43 @@ /// // @strict: true -//// interface User { +//// class User { +//// #foo: User; +//// bar: User; //// address?: { //// city: string; //// "postal code": string; +//// }; +//// constructor() { +//// this.address[|?./*1*/|]; +//// this[|?./*2*/|]; +//// this?.bar[|?./*3*/|]; //// } //// }; -//// declare const user: User; -//// user.address[|?./**/|] verify.completions({ - marker: "", + marker: "1", exact: [ { name: "city", text: "(property) city: string" }, { name: "postal code", text: "(property) \"postal code\": string", insertText: "?.[\"postal code\"]", replacementSpan: test.ranges()[0] } ], preferences: { includeInsertTextCompletions: true }, }); + +verify.completions({ + marker: "2", + exact: [ + { name: "bar" }, + { name: "address" } + ], + preferences: { includeInsertTextCompletions: true }, +}); + +verify.completions({ + marker: "3", + exact: [ + { name: "bar" }, + { name: "address" } + ], + preferences: { includeInsertTextCompletions: true }, +}); From b4f250436293c71132bba2284baa2118f291d68f Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Tue, 5 Nov 2019 16:50:22 -0500 Subject: [PATCH 10/16] restrict privateIdentifier completions correctly Don't autocomplete privateIdentifiers in places where they are not allowed. Signed-off-by: Max Heiber --- src/compiler/checker.ts | 5 +-- .../fourslash/completionListPrivateNames.ts | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/completionListPrivateNames.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 88a7e6397a957..82c5cfdd80978 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23553,8 +23553,9 @@ namespace ts { } const prop = getPropertyOfType(type, propertyName); if (prop) { - if (isOptionalChain(node) && isPrivateIdentifierPropertyDeclaration(prop.valueDeclaration)) { - return false; + if (isPropertyAccessExpression(node) && prop.valueDeclaration && isPrivateIdentifierPropertyDeclaration(prop.valueDeclaration)) { + const declClass = getContainingClass(prop.valueDeclaration); + return !isOptionalChain(node) && !!findAncestor(node, parent => parent === declClass); } return checkPropertyAccessibility(node, isSuper, type, prop); } diff --git a/tests/cases/fourslash/completionListPrivateNames.ts b/tests/cases/fourslash/completionListPrivateNames.ts new file mode 100644 index 0000000000000..53d213c2fc716 --- /dev/null +++ b/tests/cases/fourslash/completionListPrivateNames.ts @@ -0,0 +1,32 @@ +/// + +////class Foo { +//// #x; +//// y; +////} +//// +////class Bar extends Foo { +//// #z; +//// t; +//// constructor() { +//// this./*1*/ +//// class Baz { +//// #z; +//// #u; +//// v; +//// constructor() { +//// this./*2*/ +//// new Bar()./*3*/ +//// } +//// } +//// } +////} +//// +////new Foo()./*4*/ + + + +verify.completions({ marker: "1", exact: ["#z", "t", "y"] }); +verify.completions({ marker: "2", exact: ["#z", "#u", "v"] }); +verify.completions({ marker: "3", exact: ["#z", "t", "y"] }); +verify.completions({ marker: "4", exact: ["y"] }); From 789676ef062fcc776f629bcbf0c2731ec0ab6894 Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Mon, 23 Dec 2019 12:38:30 +0000 Subject: [PATCH 11/16] make PrivateIdentifier not a PropertyNameLiteral Signed-off-by: Max Heiber --- src/compiler/utilities.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 51d19ec902dff..93343650841c7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2947,11 +2947,10 @@ namespace ts { } } - export type PropertyNameLiteral = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral; + export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; export function isPropertyNameLiteral(node: Node): node is PropertyNameLiteral { switch (node.kind) { case SyntaxKind.Identifier: - case SyntaxKind.PrivateIdentifier: case SyntaxKind.StringLiteral: case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.NumericLiteral: From 72367eb1625d5545768f82b58f2138ca3c54ee3d Mon Sep 17 00:00:00 2001 From: Max Heiber Date: Mon, 23 Dec 2019 15:23:20 +0000 Subject: [PATCH 12/16] fix for private field no initializer esnext Signed-off-by: Max Heiber --- src/compiler/transformers/classFields.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 1277be2aefded..1bbdf30baf6d5 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -769,6 +769,9 @@ namespace ts { Debug.fail("Undeclared private name for property declaration."); } } + if (isPrivateIdentifier(propertyName) && !property.initializer) { + return undefined; + } const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) : hasModifier(getOriginalNode(property), ModifierFlags.ParameterPropertyModifier) && isIdentifier(propertyName) ? propertyName From 35cf0381abce3683a556815197b3c0efc2cabe4d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 20 Dec 2019 17:20:06 -0800 Subject: [PATCH 13/16] Added test. --- .../jsDeclarationsPrivateFields01.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsPrivateFields01.ts diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsPrivateFields01.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsPrivateFields01.ts new file mode 100644 index 0000000000000..d93025c33bd89 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsPrivateFields01.ts @@ -0,0 +1,26 @@ +// @target: esnext +// @allowJS: true +// @declaration: true +// @emitDeclarationOnly: true + +// @filename: file.js +export class C { + #hello = "hello"; + #world = 100; + + #calcHello() { + return this.#hello; + } + + get #screamingHello() { + return this.#hello.toUpperCase(); + } + /** @param value {string} */ + set #screamingHello(value) { + throw "NO"; + } + + getWorld() { + return this.#world; + } +} From 915910e5d648cc0667c2902e38be0b12e6d28659 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 20 Dec 2019 17:20:17 -0800 Subject: [PATCH 14/16] Accepted baselines. --- .../jsDeclarationsPrivateFields01.js | 35 ++++++++++++++ .../jsDeclarationsPrivateFields01.symbols | 44 +++++++++++++++++ .../jsDeclarationsPrivateFields01.types | 48 +++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 tests/baselines/reference/jsDeclarationsPrivateFields01.js create mode 100644 tests/baselines/reference/jsDeclarationsPrivateFields01.symbols create mode 100644 tests/baselines/reference/jsDeclarationsPrivateFields01.types diff --git a/tests/baselines/reference/jsDeclarationsPrivateFields01.js b/tests/baselines/reference/jsDeclarationsPrivateFields01.js new file mode 100644 index 0000000000000..4bb849ffd0f70 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsPrivateFields01.js @@ -0,0 +1,35 @@ +//// [file.js] +export class C { + #hello = "hello"; + #world = 100; + + #calcHello() { + return this.#hello; + } + + get #screamingHello() { + return this.#hello.toUpperCase(); + } + /** @param value {string} */ + set #screamingHello(value) { + throw "NO"; + } + + getWorld() { + return this.#world; + } +} + + + + +//// [file.d.ts] +export class C { + "__#1@#hello": string; + "__#1@#world": number; + "__#1@#calcHello"(): string; + /** @param value {string} */ + set "__#1@#screamingHello"(arg: string); + get "__#1@#screamingHello"(): string; + getWorld(): number; +} diff --git a/tests/baselines/reference/jsDeclarationsPrivateFields01.symbols b/tests/baselines/reference/jsDeclarationsPrivateFields01.symbols new file mode 100644 index 0000000000000..9bf38a009e28e --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsPrivateFields01.symbols @@ -0,0 +1,44 @@ +=== tests/cases/conformance/jsdoc/declarations/file.js === +export class C { +>C : Symbol(C, Decl(file.js, 0, 0)) + + #hello = "hello"; +>#hello : Symbol(C.#hello, Decl(file.js, 0, 16)) + + #world = 100; +>#world : Symbol(C.#world, Decl(file.js, 1, 21)) + + #calcHello() { +>#calcHello : Symbol(C.#calcHello, Decl(file.js, 2, 17)) + + return this.#hello; +>this.#hello : Symbol(C.#hello, Decl(file.js, 0, 16)) +>this : Symbol(C, Decl(file.js, 0, 0)) + } + + get #screamingHello() { +>#screamingHello : Symbol(C.#screamingHello, Decl(file.js, 6, 5), Decl(file.js, 10, 5)) + + return this.#hello.toUpperCase(); +>this.#hello.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>this.#hello : Symbol(C.#hello, Decl(file.js, 0, 16)) +>this : Symbol(C, Decl(file.js, 0, 0)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) + } + /** @param value {string} */ + set #screamingHello(value) { +>#screamingHello : Symbol(C.#screamingHello, Decl(file.js, 6, 5), Decl(file.js, 10, 5)) +>value : Symbol(value, Decl(file.js, 12, 24)) + + throw "NO"; + } + + getWorld() { +>getWorld : Symbol(C.getWorld, Decl(file.js, 14, 5)) + + return this.#world; +>this.#world : Symbol(C.#world, Decl(file.js, 1, 21)) +>this : Symbol(C, Decl(file.js, 0, 0)) + } +} + diff --git a/tests/baselines/reference/jsDeclarationsPrivateFields01.types b/tests/baselines/reference/jsDeclarationsPrivateFields01.types new file mode 100644 index 0000000000000..1219b66b9eecc --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsPrivateFields01.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/jsdoc/declarations/file.js === +export class C { +>C : C + + #hello = "hello"; +>#hello : string +>"hello" : "hello" + + #world = 100; +>#world : number +>100 : 100 + + #calcHello() { +>#calcHello : () => string + + return this.#hello; +>this.#hello : string +>this : this + } + + get #screamingHello() { +>#screamingHello : string + + return this.#hello.toUpperCase(); +>this.#hello.toUpperCase() : string +>this.#hello.toUpperCase : () => string +>this.#hello : string +>this : this +>toUpperCase : () => string + } + /** @param value {string} */ + set #screamingHello(value) { +>#screamingHello : string +>value : string + + throw "NO"; +>"NO" : "NO" + } + + getWorld() { +>getWorld : () => number + + return this.#world; +>this.#world : number +>this : this + } +} + From 9979878febe50437100a61fbd7ded7424fcfddf7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 20 Dec 2019 18:05:34 -0800 Subject: [PATCH 15/16] Update symbol serializer to understand private fields in JS `.d.ts` emit. --- src/compiler/checker.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 82c5cfdd80978..31edd2dac2fa6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5593,7 +5593,26 @@ namespace ts { const staticType = getTypeOfSymbol(symbol); const staticBaseType = getBaseConstructorTypeOfClass(staticType as InterfaceType); const heritageClauses = !length(baseTypes) ? undefined : [createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))]; - const members = flatMap(getPropertiesOfType(classType), p => serializePropertySymbolForClass(p, /*isStatic*/ false, baseTypes[0])); + const symbolProps = getPropertiesOfType(classType); + const publicSymbolProps = filter(symbolProps, s => { + const valueDecl = s.valueDeclaration; + Debug.assertDefined(valueDecl); + return isClassElement(valueDecl) && isNamedDeclaration(valueDecl) + && !isPrivateIdentifier(valueDecl.name); + }); + const hasPrivateField = symbolProps !== publicSymbolProps; + // Boil down all private properties into a single one. + const privateProperties = hasPrivateField ? + [createProperty( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createPrivateIdentifier("#private"), + /*questionOrExclamationToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined, + )] : + emptyArray; + const publicProperties = flatMap(publicSymbolProps, p => serializePropertySymbolForClass(p, /*isStatic*/ false, baseTypes[0])); // Consider static members empty if symbol also has function or module meaning - function namespacey emit will handle statics const staticMembers = symbol.flags & (SymbolFlags.Function | SymbolFlags.ValueModule) ? [] @@ -5615,7 +5634,7 @@ namespace ts { localName, typeParamDecls, heritageClauses, - [...indexSignatures, ...staticMembers, ...constructors, ...members] + [...indexSignatures, ...staticMembers, ...constructors, ...publicProperties, ...privateProperties] ), symbol.declarations && filter(symbol.declarations, d => isClassDeclaration(d) || isClassExpression(d))[0]), modifierFlags); } From 8f6507a92ee1ac92cf1159d46db4d81ecbb5df92 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 20 Dec 2019 18:43:21 -0800 Subject: [PATCH 16/16] Accepted baselines. --- tests/baselines/reference/jsDeclarationsPrivateFields01.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/baselines/reference/jsDeclarationsPrivateFields01.js b/tests/baselines/reference/jsDeclarationsPrivateFields01.js index 4bb849ffd0f70..27f81482aaafb 100644 --- a/tests/baselines/reference/jsDeclarationsPrivateFields01.js +++ b/tests/baselines/reference/jsDeclarationsPrivateFields01.js @@ -25,11 +25,6 @@ export class C { //// [file.d.ts] export class C { - "__#1@#hello": string; - "__#1@#world": number; - "__#1@#calcHello"(): string; - /** @param value {string} */ - set "__#1@#screamingHello"(arg: string); - get "__#1@#screamingHello"(): string; getWorld(): number; + #private; }