From 4968b81a76bb9490a7573b484e6c91582177edf3 Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 9 Oct 2020 01:24:36 +0800 Subject: [PATCH 01/21] Add parser types emitter and pass the build --- src/compiler/binder.ts | 2 + src/compiler/checker.ts | 49 +++++++++++++------- src/compiler/emitter.ts | 7 +++ src/compiler/factory/nodeFactory.ts | 26 ++++++++++- src/compiler/factory/nodeTests.ts | 4 ++ src/compiler/parser.ts | 17 +++++-- src/compiler/transformers/declarations.ts | 10 ++-- src/compiler/types.ts | 20 ++++++-- src/compiler/visitorPublic.ts | 5 ++ src/services/navigationBar.ts | 2 +- tests/cases/conformance/enums/spreadEnum1.ts | 29 ++++++++++++ 11 files changed, 142 insertions(+), 29 deletions(-) create mode 100644 tests/cases/conformance/enums/spreadEnum1.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5e7695ffef366..2abf750aaf681 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2560,6 +2560,8 @@ namespace ts { return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); case SyntaxKind.EnumMember: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); + case SyntaxKind.SpreadEnumMember: + return undefined; case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 159ca30a18898..40bfa37326c45 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9432,7 +9432,7 @@ namespace ts { for (const declaration of symbol.declarations) { if (declaration.kind === SyntaxKind.EnumDeclaration) { for (const member of (declaration).members) { - if (member.initializer && isStringLiteralLike(member.initializer)) { + if (isSpreadEnumMember(member) || member.initializer && isStringLiteralLike(member.initializer)) { return links.enumKind = EnumKind.Literal; } if (!isLiteralEnumMember(member)) { @@ -9448,24 +9448,39 @@ namespace ts { return type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)!) : type; } - function getDeclaredTypeOfEnum(symbol: Symbol): Type { - const links = getSymbolLinks(symbol); - if (links.declaredType) { - return links.declaredType; - } - if (getEnumKind(symbol) === EnumKind.Literal) { - enumCount++; - const memberTypeList: Type[] = []; - for (const declaration of symbol.declarations) { - if (declaration.kind === SyntaxKind.EnumDeclaration) { - for (const member of (declaration).members) { + function getEnumMemberTypeList(symbol: Symbol): Type[] { + const memberTypeList: Type[] = []; + for (const declaration of symbol.declarations) { + if (declaration.kind === SyntaxKind.EnumDeclaration) { + for (const member of (declaration).members) { + if (isEnumMember(member)) { const value = getEnumMemberValue(member); const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; memberTypeList.push(getRegularTypeOfLiteralType(memberType)); } + else { + const referencedEnumDeclaration = getSymbolOfNode(member.name); + if (referencedEnumDeclaration) { + const declaredType = getDeclaredTypeOfEnum(referencedEnumDeclaration); + const types = declaredType.flags & TypeFlags.Union ? (declaredType).types : [declaredType]; + memberTypeList.push(...types); + } + } } } + } + return memberTypeList + } + + function getDeclaredTypeOfEnum(symbol: Symbol): Type { + const links = getSymbolLinks(symbol); + if (links.declaredType) { + return links.declaredType; + } + if (getEnumKind(symbol) === EnumKind.Literal) { + enumCount++; + const memberTypeList = getEnumMemberTypeList(symbol); if (memberTypeList.length) { const enumType = getUnionType(memberTypeList, UnionReduction.Literal, symbol, /*aliasTypeArguments*/ undefined); if (enumType.flags & TypeFlags.Union) { @@ -35674,9 +35689,11 @@ namespace ts { nodeLinks.flags |= NodeCheckFlags.EnumValuesComputed; let autoValue: number | undefined = 0; for (const member of node.members) { - const value = computeMemberValue(member, autoValue); - getNodeLinks(member).enumMemberValue = value; - autoValue = typeof value === "number" ? value + 1 : undefined; + if (isEnumMember(member)) { + const value = computeMemberValue(member, autoValue); + getNodeLinks(member).enumMemberValue = value; + autoValue = typeof value === "number" ? value + 1 : undefined; + } } } } @@ -35888,7 +35905,7 @@ namespace ts { } const firstEnumMember = enumDeclaration.members[0]; - if (!firstEnumMember.initializer) { + if (!isSpreadEnumMember(firstEnumMember) && !firstEnumMember.initializer) { if (seenEnumMissingInitialInitializer) { error(firstEnumMember.name, Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element); } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 237d3fee9cdc5..54f9e89d0645e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1534,6 +1534,8 @@ namespace ts { // Enum case SyntaxKind.EnumMember: return emitEnumMember(node); + case SyntaxKind.SpreadEnumMember: + return emitSpreadEnumMember(node); // JSDoc nodes (only used in codefixes currently) case SyntaxKind.JSDocParameterTag: @@ -3501,6 +3503,11 @@ namespace ts { emitInitializer(node.initializer, node.name.end, node); } + function emitSpreadEnumMember(node: SpreadEnumMember) { + emit(node.dotDotDotToken); + emitEntityName(node.name); + } + // // JSDoc // diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 3d1b6fdb9a7d3..586150230ef09 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -410,6 +410,8 @@ namespace ts { updateSpreadAssignment, createEnumMember, updateEnumMember, + createSpreadEnumMember, + updateSpreadEnumMember, createSourceFile, updateSourceFile, createBundle, @@ -3624,7 +3626,7 @@ namespace ts { decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, - members: readonly EnumMember[] + members: readonly EnumMemberLike[] ) { const node = createBaseNamedDeclaration( SyntaxKind.EnumDeclaration, @@ -3646,7 +3648,7 @@ namespace ts { decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, - members: readonly EnumMember[]) { + members: readonly EnumMemberLike[]) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -4848,6 +4850,26 @@ namespace ts { : node; } + // @api + function createSpreadEnumMember(dotDotDotToken: DotDotDotToken, name: EntityName) { + const node = createBaseNode(SyntaxKind.SpreadEnumMember); + node.dotDotDotToken = dotDotDotToken; + node.name = name; + node.transformFlags |= + propagateChildFlags(node.dotDotDotToken) | + propagateChildFlags(node.name) | + TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateSpreadEnumMember(node: SpreadEnumMember, dotDotDotToken: DotDotDotToken, name: EntityName) { + return node.dotDotDotToken !== dotDotDotToken + || node.name !== name + ? update(createSpreadEnumMember(dotDotDotToken, name), node) + : node; + } + // // Top-level nodes // diff --git a/src/compiler/factory/nodeTests.ts b/src/compiler/factory/nodeTests.ts index 2603094717507..87f9a147f1ed6 100644 --- a/src/compiler/factory/nodeTests.ts +++ b/src/compiler/factory/nodeTests.ts @@ -666,6 +666,10 @@ namespace ts { return node.kind === SyntaxKind.EnumMember; } + export function isSpreadEnumMember(node: Node): node is SpreadEnumMember { + return node.kind === SyntaxKind.SpreadEnumMember; + } + // Unparsed // TODO(rbuckton): isUnparsedPrologue diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a815a12db9a53..55091e693ef6c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -380,6 +380,9 @@ namespace ts { case SyntaxKind.EnumMember: return visitNode(cbNode, (node).name) || visitNode(cbNode, (node).initializer); + case SyntaxKind.SpreadEnumMember: + return visitNode(cbNode, (node).dotDotDotToken) || + visitNode(cbNode, (node).name); case SyntaxKind.ModuleDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || @@ -1839,7 +1842,7 @@ namespace ts { case ParsingContext.EnumMembers: // Include open bracket computed properties. This technically also lets in indexers, // which would be a candidate for improved error reporting. - return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName(); + return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName(); case ParsingContext.ObjectLiteralMembers: switch (token()) { case SyntaxKind.OpenBracketToken: @@ -6752,9 +6755,15 @@ namespace ts { // In a non-ambient declaration, the grammar allows uninitialized members only in a // ConstantEnumMemberSection, which starts at the beginning of an enum declaration // or any time an integer literal initializer is encountered. - function parseEnumMember(): EnumMember { + function parseEnumMember(): EnumMemberLike { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + if (dotDotDotToken) { + const name = parseEntityName(/*allowReservedWords*/ false); + return withJSDoc(finishNode(factory.createSpreadEnumMember(dotDotDotToken, name), pos), hasJSDoc); + } + const name = parsePropertyName(); const initializer = allowInAnd(parseInitializer); return withJSDoc(finishNode(factory.createEnumMember(name, initializer), pos), hasJSDoc); @@ -6763,13 +6772,13 @@ namespace ts { function parseEnumDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): EnumDeclaration { parseExpected(SyntaxKind.EnumKeyword); const name = parseIdentifier(); - let members; + let members: NodeArray | undefined; if (parseExpected(SyntaxKind.OpenBraceToken)) { members = doOutsideOfYieldAndAwaitContext(() => parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember)); parseExpected(SyntaxKind.CloseBraceToken); } else { - members = createMissingList(); + members = createMissingList(); } const node = factory.createEnumDeclaration(decorators, modifiers, name, members); return withJSDoc(finishNode(node, pos), hasJSDoc); diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 43539cb06ad71..5f07744b709b9 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1437,9 +1437,13 @@ namespace ts { case SyntaxKind.EnumDeclaration: { return cleanup(factory.updateEnumDeclaration(input, /*decorators*/ undefined, factory.createNodeArray(ensureModifiers(input)), input.name, factory.createNodeArray(mapDefined(input.members, m => { if (shouldStripInternal(m)) return; - // Rewrite enum values to their constants, if available - const constValue = resolver.getConstantValue(m); - return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m); + + if (isEnumMember(m)) { + // Rewrite enum values to their constants, if available + const constValue = resolver.getConstantValue(m); + return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m); + } + return m; })))); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2c37d20298dca..e5403aa6876df 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -345,6 +345,7 @@ namespace ts { // Enum EnumMember, + SpreadEnumMember, // Unparsed UnparsedPrologue, UnparsedPrepend, @@ -883,6 +884,7 @@ namespace ts { | InterfaceDeclaration | TypeAliasDeclaration | EnumMember + | SpreadEnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration @@ -1355,6 +1357,7 @@ namespace ts { | JsxAttribute | ShorthandPropertyAssignment | EnumMember + | SpreadEnumMember | JSDocPropertyTag | JSDocParameterTag; @@ -2857,10 +2860,19 @@ namespace ts { readonly initializer?: Expression; } + export interface SpreadEnumMember extends Declaration, JSDocContainer { + readonly kind: SyntaxKind.SpreadEnumMember; + readonly parent: EnumDeclaration; + readonly dotDotDotToken: DotDotDotToken; + readonly name: EntityName; + } + + export type EnumMemberLike = EnumMember | SpreadEnumMember; + export interface EnumDeclaration extends DeclarationStatement, JSDocContainer { readonly kind: SyntaxKind.EnumDeclaration; readonly name: Identifier; - readonly members: NodeArray; + readonly members: NodeArray; } export type ModuleName = @@ -6977,8 +6989,8 @@ namespace ts { updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; - createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; - updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; + createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMemberLike[]): EnumDeclaration; + updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMemberLike[]): EnumDeclaration; createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; createModuleBlock(statements: readonly Statement[]): ModuleBlock; @@ -7144,6 +7156,8 @@ namespace ts { createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; + createSpreadEnumMember(dotDotDotToken: DotDotDotToken, name: EntityName): SpreadEnumMember; + updateSpreadEnumMember(node: SpreadEnumMember, dotDotDotToken: DotDotDotToken, name: EntityName): SpreadEnumMember; // // Top-level nodes diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 8a06e110552dc..4a80db985e6cd 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1083,6 +1083,11 @@ namespace ts { return factory.updateEnumMember(node, nodeVisitor((node).name, visitor, isPropertyName), nodeVisitor((node).initializer, visitor, isExpression)); + case SyntaxKind.SpreadEnumMember: + return factory.updateSpreadEnumMember(node, + nodeVisitor((node).dotDotDotToken, tokenVisitor, isToken), + nodeVisitor((node).name, visitor, isEntityName) + ); // Top-level nodes case SyntaxKind.SourceFile: diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 4704e86846b90..9b32be1be7436 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -287,7 +287,7 @@ namespace ts.NavigationBar { case SyntaxKind.EnumDeclaration: startNode(node); for (const member of (node).members) { - if (!isComputedProperty(member)) { + if (isEnumMember(member) && !isComputedProperty(member)) { addLeafNode(member); } } diff --git a/tests/cases/conformance/enums/spreadEnum1.ts b/tests/cases/conformance/enums/spreadEnum1.ts new file mode 100644 index 0000000000000..4760e292c51cf --- /dev/null +++ b/tests/cases/conformance/enums/spreadEnum1.ts @@ -0,0 +1,29 @@ +// @declaration: true + +enum BasicEvents { + Start = "Start", + Finish = "Finish" +} + +enum AdvEvents { + ...BasicEvents, + Pause = "Pause", + Resume = "Resume" +} + +declare let basic: BasicEvents; + +declare let adv: AdvEvents; + +adv = basic; + +basic = BasicEvents.Start; +basic = BasicEvents.Finish; + +adv = AdvEvents.Start; +adv = AdvEvents.Finish; +adv = AdvEvents.Pause; +adv = AdvEvents.Resume; + +adv = BasicEvents.Start; +adv = BasicEvents.Finish; \ No newline at end of file From ceaf96d5ae7769b5dc27a276690e976519606573 Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 9 Oct 2020 16:52:47 +0800 Subject: [PATCH 02/21] accept baseline --- .../reference/api/tsserverlibrary.d.ts | 133 ++++++++++-------- tests/baselines/reference/api/typescript.d.ts | 133 ++++++++++-------- 2 files changed, 144 insertions(+), 122 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 15653ecacf258..a2a65f7553162 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -396,56 +396,57 @@ declare namespace ts { ShorthandPropertyAssignment = 289, SpreadAssignment = 290, EnumMember = 291, - UnparsedPrologue = 292, - UnparsedPrepend = 293, - UnparsedText = 294, - UnparsedInternalText = 295, - UnparsedSyntheticReference = 296, - SourceFile = 297, - Bundle = 298, - UnparsedSource = 299, - InputFiles = 300, - JSDocTypeExpression = 301, - JSDocNameReference = 302, - JSDocAllType = 303, - JSDocUnknownType = 304, - JSDocNullableType = 305, - JSDocNonNullableType = 306, - JSDocOptionalType = 307, - JSDocFunctionType = 308, - JSDocVariadicType = 309, - JSDocNamepathType = 310, - JSDocComment = 311, - JSDocTypeLiteral = 312, - JSDocSignature = 313, - JSDocTag = 314, - JSDocAugmentsTag = 315, - JSDocImplementsTag = 316, - JSDocAuthorTag = 317, - JSDocDeprecatedTag = 318, - JSDocClassTag = 319, - JSDocPublicTag = 320, - JSDocPrivateTag = 321, - JSDocProtectedTag = 322, - JSDocReadonlyTag = 323, - JSDocCallbackTag = 324, - JSDocEnumTag = 325, - JSDocParameterTag = 326, - JSDocReturnTag = 327, - JSDocThisTag = 328, - JSDocTypeTag = 329, - JSDocTemplateTag = 330, - JSDocTypedefTag = 331, - JSDocSeeTag = 332, - JSDocPropertyTag = 333, - SyntaxList = 334, - NotEmittedStatement = 335, - PartiallyEmittedExpression = 336, - CommaListExpression = 337, - MergeDeclarationMarker = 338, - EndOfDeclarationMarker = 339, - SyntheticReferenceExpression = 340, - Count = 341, + SpreadEnumMember = 292, + UnparsedPrologue = 293, + UnparsedPrepend = 294, + UnparsedText = 295, + UnparsedInternalText = 296, + UnparsedSyntheticReference = 297, + SourceFile = 298, + Bundle = 299, + UnparsedSource = 300, + InputFiles = 301, + JSDocTypeExpression = 302, + JSDocNameReference = 303, + JSDocAllType = 304, + JSDocUnknownType = 305, + JSDocNullableType = 306, + JSDocNonNullableType = 307, + JSDocOptionalType = 308, + JSDocFunctionType = 309, + JSDocVariadicType = 310, + JSDocNamepathType = 311, + JSDocComment = 312, + JSDocTypeLiteral = 313, + JSDocSignature = 314, + JSDocTag = 315, + JSDocAugmentsTag = 316, + JSDocImplementsTag = 317, + JSDocAuthorTag = 318, + JSDocDeprecatedTag = 319, + JSDocClassTag = 320, + JSDocPublicTag = 321, + JSDocPrivateTag = 322, + JSDocProtectedTag = 323, + JSDocReadonlyTag = 324, + JSDocCallbackTag = 325, + JSDocEnumTag = 326, + JSDocParameterTag = 327, + JSDocReturnTag = 328, + JSDocThisTag = 329, + JSDocTypeTag = 330, + JSDocTemplateTag = 331, + JSDocTypedefTag = 332, + JSDocSeeTag = 333, + JSDocPropertyTag = 334, + SyntaxList = 335, + NotEmittedStatement = 336, + PartiallyEmittedExpression = 337, + CommaListExpression = 338, + MergeDeclarationMarker = 339, + EndOfDeclarationMarker = 340, + SyntheticReferenceExpression = 341, + Count = 342, FirstAssignment = 62, LastAssignment = 77, FirstCompoundAssignment = 63, @@ -473,10 +474,10 @@ declare namespace ts { FirstStatement = 232, LastStatement = 248, FirstNode = 157, - FirstJSDocNode = 301, - LastJSDocNode = 333, - FirstJSDocTagNode = 314, - LastJSDocTagNode = 333, + FirstJSDocNode = 302, + LastJSDocNode = 334, + FirstJSDocTagNode = 315, + LastJSDocTagNode = 334, } export type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; export type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; @@ -558,7 +559,7 @@ declare namespace ts { } export interface JSDocContainer { } - export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; + export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | SpreadEnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; export type HasType = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertySignature | PropertyDeclaration | TypePredicateNode | ParenthesizedTypeNode | TypeOperatorNode | MappedTypeNode | AssertionExpression | TypeAliasDeclaration | JSDocTypeExpression | JSDocNonNullableType | JSDocNullableType | JSDocOptionalType | JSDocVariadicType; export type HasTypeArguments = CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement | JsxSelfClosingElement; export type HasInitializer = HasExpressionInitializer | ForStatement | ForInStatement | ForOfStatement | JsxAttribute; @@ -760,7 +761,7 @@ declare namespace ts { readonly parent: ObjectLiteralExpression; readonly expression: Expression; } - export type VariableLikeDeclaration = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertyAssignment | PropertySignature | JsxAttribute | ShorthandPropertyAssignment | EnumMember | JSDocPropertyTag | JSDocParameterTag; + export type VariableLikeDeclaration = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertyAssignment | PropertySignature | JsxAttribute | ShorthandPropertyAssignment | EnumMember | SpreadEnumMember | JSDocPropertyTag | JSDocParameterTag; export interface PropertyLikeDeclaration extends NamedDeclaration { readonly name: PropertyName; } @@ -1560,10 +1561,17 @@ declare namespace ts { readonly name: PropertyName; readonly initializer?: Expression; } + export interface SpreadEnumMember extends Declaration, JSDocContainer { + readonly kind: SyntaxKind.SpreadEnumMember; + readonly parent: EnumDeclaration; + readonly dotDotDotToken: DotDotDotToken; + readonly name: EntityName; + } + export type EnumMemberLike = EnumMember | SpreadEnumMember; export interface EnumDeclaration extends DeclarationStatement, JSDocContainer { readonly kind: SyntaxKind.EnumDeclaration; readonly name: Identifier; - readonly members: NodeArray; + readonly members: NodeArray; } export type ModuleName = Identifier | StringLiteral; export type ModuleBody = NamespaceBody | JSDocNamespaceBody; @@ -3396,8 +3404,8 @@ declare namespace ts { updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; - createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; - updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; + createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMemberLike[]): EnumDeclaration; + updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMemberLike[]): EnumDeclaration; createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; createModuleBlock(statements: readonly Statement[]): ModuleBlock; @@ -3532,6 +3540,8 @@ declare namespace ts { updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; + createSpreadEnumMember(dotDotDotToken: DotDotDotToken, name: EntityName): SpreadEnumMember; + updateSpreadEnumMember(node: SpreadEnumMember, dotDotDotToken: DotDotDotToken, name: EntityName): SpreadEnumMember; createSourceFile(statements: readonly Statement[], endOfFileToken: EndOfFileToken, flags: NodeFlags): SourceFile; updateSourceFile(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: readonly FileReference[], typeReferences?: readonly FileReference[], hasNoDefaultLib?: boolean, libReferences?: readonly FileReference[]): SourceFile; createNotEmittedStatement(original: Node): NotEmittedStatement; @@ -4477,6 +4487,7 @@ declare namespace ts { function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment; function isSpreadAssignment(node: Node): node is SpreadAssignment; function isEnumMember(node: Node): node is EnumMember; + function isSpreadEnumMember(node: Node): node is SpreadEnumMember; function isUnparsedPrepend(node: Node): node is UnparsedPrepend; function isSourceFile(node: Node): node is SourceFile; function isBundle(node: Node): node is Bundle; @@ -10466,9 +10477,9 @@ declare namespace ts { /** @deprecated Use `factory.updateTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ const updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode) => TypeAliasDeclaration; /** @deprecated Use `factory.createEnumDeclaration` or the factory supplied by your transformation context instead. */ - const createEnumDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]) => EnumDeclaration; + const createEnumDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMemberLike[]) => EnumDeclaration; /** @deprecated Use `factory.updateEnumDeclaration` or the factory supplied by your transformation context instead. */ - const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]) => EnumDeclaration; + const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMemberLike[]) => EnumDeclaration; /** @deprecated Use `factory.createModuleDeclaration` or the factory supplied by your transformation context instead. */ const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; /** @deprecated Use `factory.updateModuleDeclaration` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 26cdf6ba46056..629ba2172e8d1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -396,56 +396,57 @@ declare namespace ts { ShorthandPropertyAssignment = 289, SpreadAssignment = 290, EnumMember = 291, - UnparsedPrologue = 292, - UnparsedPrepend = 293, - UnparsedText = 294, - UnparsedInternalText = 295, - UnparsedSyntheticReference = 296, - SourceFile = 297, - Bundle = 298, - UnparsedSource = 299, - InputFiles = 300, - JSDocTypeExpression = 301, - JSDocNameReference = 302, - JSDocAllType = 303, - JSDocUnknownType = 304, - JSDocNullableType = 305, - JSDocNonNullableType = 306, - JSDocOptionalType = 307, - JSDocFunctionType = 308, - JSDocVariadicType = 309, - JSDocNamepathType = 310, - JSDocComment = 311, - JSDocTypeLiteral = 312, - JSDocSignature = 313, - JSDocTag = 314, - JSDocAugmentsTag = 315, - JSDocImplementsTag = 316, - JSDocAuthorTag = 317, - JSDocDeprecatedTag = 318, - JSDocClassTag = 319, - JSDocPublicTag = 320, - JSDocPrivateTag = 321, - JSDocProtectedTag = 322, - JSDocReadonlyTag = 323, - JSDocCallbackTag = 324, - JSDocEnumTag = 325, - JSDocParameterTag = 326, - JSDocReturnTag = 327, - JSDocThisTag = 328, - JSDocTypeTag = 329, - JSDocTemplateTag = 330, - JSDocTypedefTag = 331, - JSDocSeeTag = 332, - JSDocPropertyTag = 333, - SyntaxList = 334, - NotEmittedStatement = 335, - PartiallyEmittedExpression = 336, - CommaListExpression = 337, - MergeDeclarationMarker = 338, - EndOfDeclarationMarker = 339, - SyntheticReferenceExpression = 340, - Count = 341, + SpreadEnumMember = 292, + UnparsedPrologue = 293, + UnparsedPrepend = 294, + UnparsedText = 295, + UnparsedInternalText = 296, + UnparsedSyntheticReference = 297, + SourceFile = 298, + Bundle = 299, + UnparsedSource = 300, + InputFiles = 301, + JSDocTypeExpression = 302, + JSDocNameReference = 303, + JSDocAllType = 304, + JSDocUnknownType = 305, + JSDocNullableType = 306, + JSDocNonNullableType = 307, + JSDocOptionalType = 308, + JSDocFunctionType = 309, + JSDocVariadicType = 310, + JSDocNamepathType = 311, + JSDocComment = 312, + JSDocTypeLiteral = 313, + JSDocSignature = 314, + JSDocTag = 315, + JSDocAugmentsTag = 316, + JSDocImplementsTag = 317, + JSDocAuthorTag = 318, + JSDocDeprecatedTag = 319, + JSDocClassTag = 320, + JSDocPublicTag = 321, + JSDocPrivateTag = 322, + JSDocProtectedTag = 323, + JSDocReadonlyTag = 324, + JSDocCallbackTag = 325, + JSDocEnumTag = 326, + JSDocParameterTag = 327, + JSDocReturnTag = 328, + JSDocThisTag = 329, + JSDocTypeTag = 330, + JSDocTemplateTag = 331, + JSDocTypedefTag = 332, + JSDocSeeTag = 333, + JSDocPropertyTag = 334, + SyntaxList = 335, + NotEmittedStatement = 336, + PartiallyEmittedExpression = 337, + CommaListExpression = 338, + MergeDeclarationMarker = 339, + EndOfDeclarationMarker = 340, + SyntheticReferenceExpression = 341, + Count = 342, FirstAssignment = 62, LastAssignment = 77, FirstCompoundAssignment = 63, @@ -473,10 +474,10 @@ declare namespace ts { FirstStatement = 232, LastStatement = 248, FirstNode = 157, - FirstJSDocNode = 301, - LastJSDocNode = 333, - FirstJSDocTagNode = 314, - LastJSDocTagNode = 333, + FirstJSDocNode = 302, + LastJSDocNode = 334, + FirstJSDocTagNode = 315, + LastJSDocTagNode = 334, } export type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; export type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; @@ -558,7 +559,7 @@ declare namespace ts { } export interface JSDocContainer { } - export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; + export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | SpreadEnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; export type HasType = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertySignature | PropertyDeclaration | TypePredicateNode | ParenthesizedTypeNode | TypeOperatorNode | MappedTypeNode | AssertionExpression | TypeAliasDeclaration | JSDocTypeExpression | JSDocNonNullableType | JSDocNullableType | JSDocOptionalType | JSDocVariadicType; export type HasTypeArguments = CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement | JsxSelfClosingElement; export type HasInitializer = HasExpressionInitializer | ForStatement | ForInStatement | ForOfStatement | JsxAttribute; @@ -760,7 +761,7 @@ declare namespace ts { readonly parent: ObjectLiteralExpression; readonly expression: Expression; } - export type VariableLikeDeclaration = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertyAssignment | PropertySignature | JsxAttribute | ShorthandPropertyAssignment | EnumMember | JSDocPropertyTag | JSDocParameterTag; + export type VariableLikeDeclaration = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertyAssignment | PropertySignature | JsxAttribute | ShorthandPropertyAssignment | EnumMember | SpreadEnumMember | JSDocPropertyTag | JSDocParameterTag; export interface PropertyLikeDeclaration extends NamedDeclaration { readonly name: PropertyName; } @@ -1560,10 +1561,17 @@ declare namespace ts { readonly name: PropertyName; readonly initializer?: Expression; } + export interface SpreadEnumMember extends Declaration, JSDocContainer { + readonly kind: SyntaxKind.SpreadEnumMember; + readonly parent: EnumDeclaration; + readonly dotDotDotToken: DotDotDotToken; + readonly name: EntityName; + } + export type EnumMemberLike = EnumMember | SpreadEnumMember; export interface EnumDeclaration extends DeclarationStatement, JSDocContainer { readonly kind: SyntaxKind.EnumDeclaration; readonly name: Identifier; - readonly members: NodeArray; + readonly members: NodeArray; } export type ModuleName = Identifier | StringLiteral; export type ModuleBody = NamespaceBody | JSDocNamespaceBody; @@ -3396,8 +3404,8 @@ declare namespace ts { updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; - createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; - updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; + createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMemberLike[]): EnumDeclaration; + updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMemberLike[]): EnumDeclaration; createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; createModuleBlock(statements: readonly Statement[]): ModuleBlock; @@ -3532,6 +3540,8 @@ declare namespace ts { updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; + createSpreadEnumMember(dotDotDotToken: DotDotDotToken, name: EntityName): SpreadEnumMember; + updateSpreadEnumMember(node: SpreadEnumMember, dotDotDotToken: DotDotDotToken, name: EntityName): SpreadEnumMember; createSourceFile(statements: readonly Statement[], endOfFileToken: EndOfFileToken, flags: NodeFlags): SourceFile; updateSourceFile(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: readonly FileReference[], typeReferences?: readonly FileReference[], hasNoDefaultLib?: boolean, libReferences?: readonly FileReference[]): SourceFile; createNotEmittedStatement(original: Node): NotEmittedStatement; @@ -4477,6 +4487,7 @@ declare namespace ts { function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment; function isSpreadAssignment(node: Node): node is SpreadAssignment; function isEnumMember(node: Node): node is EnumMember; + function isSpreadEnumMember(node: Node): node is SpreadEnumMember; function isUnparsedPrepend(node: Node): node is UnparsedPrepend; function isSourceFile(node: Node): node is SourceFile; function isBundle(node: Node): node is Bundle; @@ -6840,9 +6851,9 @@ declare namespace ts { /** @deprecated Use `factory.updateTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ const updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode) => TypeAliasDeclaration; /** @deprecated Use `factory.createEnumDeclaration` or the factory supplied by your transformation context instead. */ - const createEnumDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]) => EnumDeclaration; + const createEnumDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMemberLike[]) => EnumDeclaration; /** @deprecated Use `factory.updateEnumDeclaration` or the factory supplied by your transformation context instead. */ - const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]) => EnumDeclaration; + const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMemberLike[]) => EnumDeclaration; /** @deprecated Use `factory.createModuleDeclaration` or the factory supplied by your transformation context instead. */ const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; /** @deprecated Use `factory.updateModuleDeclaration` or the factory supplied by your transformation context instead. */ From 01c26cc2d75802ad49f2215216c33c101e5b1253 Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 9 Oct 2020 17:51:36 +0800 Subject: [PATCH 03/21] resolve symbol --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 40bfa37326c45..129f867cba023 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9460,7 +9460,7 @@ namespace ts { memberTypeList.push(getRegularTypeOfLiteralType(memberType)); } else { - const referencedEnumDeclaration = getSymbolOfNode(member.name); + const referencedEnumDeclaration = resolveEntityName(member.name, SymbolFlags.Enum); if (referencedEnumDeclaration) { const declaredType = getDeclaredTypeOfEnum(referencedEnumDeclaration); const types = declaredType.flags & TypeFlags.Union ? (declaredType).types : [declaredType]; From 1d4cf14bbcb58661529447cb391b8a7f222fedc9 Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 9 Oct 2020 22:57:18 +0800 Subject: [PATCH 04/21] fixup symbols --- src/compiler/checker.ts | 25 ++++++ tests/baselines/reference/spreadEnum1.js | 64 +++++++++++++++ tests/baselines/reference/spreadEnum1.symbols | 71 ++++++++++++++++ tests/baselines/reference/spreadEnum1.types | 81 +++++++++++++++++++ tests/cases/conformance/enums/spreadEnum1.ts | 6 +- 5 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/spreadEnum1.js create mode 100644 tests/baselines/reference/spreadEnum1.symbols create mode 100644 tests/baselines/reference/spreadEnum1.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 129f867cba023..2ada2656dfeaf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1261,6 +1261,8 @@ namespace ts { } } + function combineSymbolTables(first: SymbolTable, second: SymbolTable): SymbolTable; + function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined; function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined { if (!first?.size) return second; if (!second?.size) return first; @@ -10398,6 +10400,29 @@ namespace ts { } } setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); + if (symbol.flags & SymbolFlags.Enum) { + const spreadEnumMembers: SpreadEnumMember[] = [] + symbol.declarations.forEach(decl => { + if (isEnumDeclaration(decl)) { + decl.members.forEach(member => { + if (isSpreadEnumMember(member)) { + spreadEnumMembers.push(member) + } + }) + } + }) + if (spreadEnumMembers.length) { + spreadEnumMembers.forEach(member => { + if (isIdentifier(member.name)) { + const sym = getResolvedSymbol(member.name) + if (sym.flags & SymbolFlags.Enum) { + members = combineSymbolTables(members, getExportsOfSymbol(sym)); + } + } + }) + setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); + } + } if (symbol.flags & SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); const baseConstructorType = getBaseConstructorTypeOfClass(classType); diff --git a/tests/baselines/reference/spreadEnum1.js b/tests/baselines/reference/spreadEnum1.js new file mode 100644 index 0000000000000..f22528de6b111 --- /dev/null +++ b/tests/baselines/reference/spreadEnum1.js @@ -0,0 +1,64 @@ +//// [spreadEnum1.ts] +enum BasicEvents { + Start = "Start", + Finish = "Finish" +} + +enum AdvEvents { + ...BasicEvents, + Pause = "Pause", + Resume = "Resume" +} + +declare let basic: BasicEvents; + +declare let adv: AdvEvents; + +// adv = basic; + +// basic = BasicEvents.Start; +// basic = BasicEvents.Finish; + +adv = AdvEvents.Start; +adv = AdvEvents.Finish; +adv = AdvEvents.Pause; +adv = AdvEvents.Resume; + +adv = BasicEvents.Start; +adv = BasicEvents.Finish; + +//// [spreadEnum1.js] +var BasicEvents; +(function (BasicEvents) { + BasicEvents["Start"] = "Start"; + BasicEvents["Finish"] = "Finish"; +})(BasicEvents || (BasicEvents = {})); +var AdvEvents; +(function (AdvEvents) { + AdvEvents[AdvEvents["BasicEvents"] = void 0] = "BasicEvents"; + AdvEvents["Pause"] = "Pause"; + AdvEvents["Resume"] = "Resume"; +})(AdvEvents || (AdvEvents = {})); +// adv = basic; +// basic = BasicEvents.Start; +// basic = BasicEvents.Finish; +adv = AdvEvents.Start; +adv = AdvEvents.Finish; +adv = AdvEvents.Pause; +adv = AdvEvents.Resume; +adv = BasicEvents.Start; +adv = BasicEvents.Finish; + + +//// [spreadEnum1.d.ts] +declare enum BasicEvents { + Start = "Start", + Finish = "Finish" +} +declare enum AdvEvents { + ...BasicEvents, + Pause = "Pause", + Resume = "Resume" +} +declare let basic: BasicEvents; +declare let adv: AdvEvents; diff --git a/tests/baselines/reference/spreadEnum1.symbols b/tests/baselines/reference/spreadEnum1.symbols new file mode 100644 index 0000000000000..71f05a7bb32df --- /dev/null +++ b/tests/baselines/reference/spreadEnum1.symbols @@ -0,0 +1,71 @@ +=== tests/cases/conformance/enums/spreadEnum1.ts === +enum BasicEvents { +>BasicEvents : Symbol(BasicEvents, Decl(spreadEnum1.ts, 0, 0)) + + Start = "Start", +>Start : Symbol(BasicEvents.Start, Decl(spreadEnum1.ts, 0, 18)) + + Finish = "Finish" +>Finish : Symbol(BasicEvents.Finish, Decl(spreadEnum1.ts, 1, 20)) +} + +enum AdvEvents { +>AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) + + ...BasicEvents, + Pause = "Pause", +>Pause : Symbol(AdvEvents.Pause, Decl(spreadEnum1.ts, 6, 19)) + + Resume = "Resume" +>Resume : Symbol(AdvEvents.Resume, Decl(spreadEnum1.ts, 7, 20)) +} + +declare let basic: BasicEvents; +>basic : Symbol(basic, Decl(spreadEnum1.ts, 11, 11)) +>BasicEvents : Symbol(BasicEvents, Decl(spreadEnum1.ts, 0, 0)) + +declare let adv: AdvEvents; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) + +// adv = basic; + +// basic = BasicEvents.Start; +// basic = BasicEvents.Finish; + +adv = AdvEvents.Start; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>AdvEvents.Start : Symbol(BasicEvents.Start, Decl(spreadEnum1.ts, 0, 18)) +>AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) +>Start : Symbol(BasicEvents.Start, Decl(spreadEnum1.ts, 0, 18)) + +adv = AdvEvents.Finish; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>AdvEvents.Finish : Symbol(BasicEvents.Finish, Decl(spreadEnum1.ts, 1, 20)) +>AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) +>Finish : Symbol(BasicEvents.Finish, Decl(spreadEnum1.ts, 1, 20)) + +adv = AdvEvents.Pause; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>AdvEvents.Pause : Symbol(AdvEvents.Pause, Decl(spreadEnum1.ts, 6, 19)) +>AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) +>Pause : Symbol(AdvEvents.Pause, Decl(spreadEnum1.ts, 6, 19)) + +adv = AdvEvents.Resume; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>AdvEvents.Resume : Symbol(AdvEvents.Resume, Decl(spreadEnum1.ts, 7, 20)) +>AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) +>Resume : Symbol(AdvEvents.Resume, Decl(spreadEnum1.ts, 7, 20)) + +adv = BasicEvents.Start; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>BasicEvents.Start : Symbol(BasicEvents.Start, Decl(spreadEnum1.ts, 0, 18)) +>BasicEvents : Symbol(BasicEvents, Decl(spreadEnum1.ts, 0, 0)) +>Start : Symbol(BasicEvents.Start, Decl(spreadEnum1.ts, 0, 18)) + +adv = BasicEvents.Finish; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>BasicEvents.Finish : Symbol(BasicEvents.Finish, Decl(spreadEnum1.ts, 1, 20)) +>BasicEvents : Symbol(BasicEvents, Decl(spreadEnum1.ts, 0, 0)) +>Finish : Symbol(BasicEvents.Finish, Decl(spreadEnum1.ts, 1, 20)) + diff --git a/tests/baselines/reference/spreadEnum1.types b/tests/baselines/reference/spreadEnum1.types new file mode 100644 index 0000000000000..65a77a35b61b2 --- /dev/null +++ b/tests/baselines/reference/spreadEnum1.types @@ -0,0 +1,81 @@ +=== tests/cases/conformance/enums/spreadEnum1.ts === +enum BasicEvents { +>BasicEvents : BasicEvents + + Start = "Start", +>Start : BasicEvents.Start +>"Start" : "Start" + + Finish = "Finish" +>Finish : BasicEvents.Finish +>"Finish" : "Finish" +} + +enum AdvEvents { +>AdvEvents : AdvEvents + + ...BasicEvents, +>BasicEvents : error + + Pause = "Pause", +>Pause : AdvEvents.Pause +>"Pause" : "Pause" + + Resume = "Resume" +>Resume : AdvEvents.Resume +>"Resume" : "Resume" +} + +declare let basic: BasicEvents; +>basic : BasicEvents + +declare let adv: AdvEvents; +>adv : AdvEvents + +// adv = basic; + +// basic = BasicEvents.Start; +// basic = BasicEvents.Finish; + +adv = AdvEvents.Start; +>adv = AdvEvents.Start : BasicEvents.Start +>adv : AdvEvents +>AdvEvents.Start : BasicEvents.Start +>AdvEvents : typeof AdvEvents +>Start : BasicEvents.Start + +adv = AdvEvents.Finish; +>adv = AdvEvents.Finish : BasicEvents.Finish +>adv : AdvEvents +>AdvEvents.Finish : BasicEvents.Finish +>AdvEvents : typeof AdvEvents +>Finish : BasicEvents.Finish + +adv = AdvEvents.Pause; +>adv = AdvEvents.Pause : AdvEvents.Pause +>adv : AdvEvents +>AdvEvents.Pause : AdvEvents.Pause +>AdvEvents : typeof AdvEvents +>Pause : AdvEvents.Pause + +adv = AdvEvents.Resume; +>adv = AdvEvents.Resume : AdvEvents.Resume +>adv : AdvEvents +>AdvEvents.Resume : AdvEvents.Resume +>AdvEvents : typeof AdvEvents +>Resume : AdvEvents.Resume + +adv = BasicEvents.Start; +>adv = BasicEvents.Start : BasicEvents.Start +>adv : AdvEvents +>BasicEvents.Start : BasicEvents.Start +>BasicEvents : typeof BasicEvents +>Start : BasicEvents.Start + +adv = BasicEvents.Finish; +>adv = BasicEvents.Finish : BasicEvents.Finish +>adv : AdvEvents +>BasicEvents.Finish : BasicEvents.Finish +>BasicEvents : typeof BasicEvents +>Finish : BasicEvents.Finish + diff --git a/tests/cases/conformance/enums/spreadEnum1.ts b/tests/cases/conformance/enums/spreadEnum1.ts index 4760e292c51cf..962d3ded3be1a 100644 --- a/tests/cases/conformance/enums/spreadEnum1.ts +++ b/tests/cases/conformance/enums/spreadEnum1.ts @@ -15,10 +15,10 @@ declare let basic: BasicEvents; declare let adv: AdvEvents; -adv = basic; +// adv = basic; -basic = BasicEvents.Start; -basic = BasicEvents.Finish; +// basic = BasicEvents.Start; +// basic = BasicEvents.Finish; adv = AdvEvents.Start; adv = AdvEvents.Finish; From 4469e0976bfee453643f43d3ec5f2ca98c11c772 Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 9 Oct 2020 23:55:36 +0800 Subject: [PATCH 05/21] make linter happy --- src/compiler/checker.ts | 16 ++--- src/compiler/transformers/ts.ts | 69 +++++++++++-------- tests/baselines/reference/spreadEnum1.js | 25 +++++-- tests/baselines/reference/spreadEnum1.symbols | 17 ++++- tests/baselines/reference/spreadEnum1.types | 20 +++++- tests/cases/conformance/enums/spreadEnum1.ts | 6 +- 6 files changed, 101 insertions(+), 52 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2ada2656dfeaf..6153786984410 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1262,7 +1262,7 @@ namespace ts { } function combineSymbolTables(first: SymbolTable, second: SymbolTable): SymbolTable; - function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined; + function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined; function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined { if (!first?.size) return second; if (!second?.size) return first; @@ -9472,7 +9472,7 @@ namespace ts { } } } - return memberTypeList + return memberTypeList; } function getDeclaredTypeOfEnum(symbol: Symbol): Type { @@ -10401,25 +10401,25 @@ namespace ts { } setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); if (symbol.flags & SymbolFlags.Enum) { - const spreadEnumMembers: SpreadEnumMember[] = [] + const spreadEnumMembers: SpreadEnumMember[] = []; symbol.declarations.forEach(decl => { if (isEnumDeclaration(decl)) { decl.members.forEach(member => { if (isSpreadEnumMember(member)) { - spreadEnumMembers.push(member) + spreadEnumMembers.push(member); } - }) + }); } - }) + }); if (spreadEnumMembers.length) { spreadEnumMembers.forEach(member => { if (isIdentifier(member.name)) { - const sym = getResolvedSymbol(member.name) + const sym = getResolvedSymbol(member.name); if (sym.flags & SymbolFlags.Enum) { members = combineSymbolTables(members, getExportsOfSymbol(sym)); } } - }) + }); setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); } } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 3e2e789259915..387bce35636c1 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2426,7 +2426,7 @@ namespace ts { const statements: Statement[] = []; startLexicalEnvironment(); - const members = map(node.members, transformEnumMember); + const members = map(node.members, transformEnumMemberLike); insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); addRange(statements, members); @@ -2442,37 +2442,50 @@ namespace ts { * * @param member The enum member node. */ - function transformEnumMember(member: EnumMember): Statement { - // enums don't support computed properties - // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes - // old emitter always generate 'expression' part of the name as-is. - const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false); - const valueExpression = transformEnumMemberDeclarationValue(member); - const innerAssignment = factory.createAssignment( - factory.createElementAccessExpression( - currentNamespaceContainerName, - name - ), - valueExpression - ); - const outerAssignment = valueExpression.kind === SyntaxKind.StringLiteral ? - innerAssignment : - factory.createAssignment( + function transformEnumMemberLike(member: EnumMemberLike): Statement { + if (isEnumMember(member)) { + // enums don't support computed properties + // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes + // old emitter always generate 'expression' part of the name as-is. + const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false); + const valueExpression = transformEnumMemberDeclarationValue(member); + const innerAssignment = factory.createAssignment( factory.createElementAccessExpression( currentNamespaceContainerName, - innerAssignment + name ), - name + valueExpression ); - return setTextRange( - factory.createExpressionStatement( - setTextRange( - outerAssignment, - member - ) - ), - member - ); + const outerAssignment = valueExpression.kind === SyntaxKind.StringLiteral ? + innerAssignment : + factory.createAssignment( + factory.createElementAccessExpression( + currentNamespaceContainerName, + innerAssignment + ), + name + ); + return setTextRange( + factory.createExpressionStatement( + setTextRange( + outerAssignment, + member + ) + ), + member + ); + } + else { + return setTextRange( + factory.createExpressionStatement( + setTextRange( + emitHelpers().createAssignHelper([currentNamespaceContainerName, member.name as Identifier]), + member + ) + ), + member + ); + } } /** diff --git a/tests/baselines/reference/spreadEnum1.js b/tests/baselines/reference/spreadEnum1.js index f22528de6b111..ebd75c2b9e50f 100644 --- a/tests/baselines/reference/spreadEnum1.js +++ b/tests/baselines/reference/spreadEnum1.js @@ -14,10 +14,10 @@ declare let basic: BasicEvents; declare let adv: AdvEvents; -// adv = basic; +adv = basic; -// basic = BasicEvents.Start; -// basic = BasicEvents.Finish; +basic = BasicEvents.Start; +basic = BasicEvents.Finish; adv = AdvEvents.Start; adv = AdvEvents.Finish; @@ -28,6 +28,17 @@ adv = BasicEvents.Start; adv = BasicEvents.Finish; //// [spreadEnum1.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; var BasicEvents; (function (BasicEvents) { BasicEvents["Start"] = "Start"; @@ -35,13 +46,13 @@ var BasicEvents; })(BasicEvents || (BasicEvents = {})); var AdvEvents; (function (AdvEvents) { - AdvEvents[AdvEvents["BasicEvents"] = void 0] = "BasicEvents"; + __assign(AdvEvents, BasicEvents); AdvEvents["Pause"] = "Pause"; AdvEvents["Resume"] = "Resume"; })(AdvEvents || (AdvEvents = {})); -// adv = basic; -// basic = BasicEvents.Start; -// basic = BasicEvents.Finish; +adv = basic; +basic = BasicEvents.Start; +basic = BasicEvents.Finish; adv = AdvEvents.Start; adv = AdvEvents.Finish; adv = AdvEvents.Pause; diff --git a/tests/baselines/reference/spreadEnum1.symbols b/tests/baselines/reference/spreadEnum1.symbols index 71f05a7bb32df..110b217867686 100644 --- a/tests/baselines/reference/spreadEnum1.symbols +++ b/tests/baselines/reference/spreadEnum1.symbols @@ -28,10 +28,21 @@ declare let adv: AdvEvents; >adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) >AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) -// adv = basic; +adv = basic; +>adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) +>basic : Symbol(basic, Decl(spreadEnum1.ts, 11, 11)) -// basic = BasicEvents.Start; -// basic = BasicEvents.Finish; +basic = BasicEvents.Start; +>basic : Symbol(basic, Decl(spreadEnum1.ts, 11, 11)) +>BasicEvents.Start : Symbol(BasicEvents.Start, Decl(spreadEnum1.ts, 0, 18)) +>BasicEvents : Symbol(BasicEvents, Decl(spreadEnum1.ts, 0, 0)) +>Start : Symbol(BasicEvents.Start, Decl(spreadEnum1.ts, 0, 18)) + +basic = BasicEvents.Finish; +>basic : Symbol(basic, Decl(spreadEnum1.ts, 11, 11)) +>BasicEvents.Finish : Symbol(BasicEvents.Finish, Decl(spreadEnum1.ts, 1, 20)) +>BasicEvents : Symbol(BasicEvents, Decl(spreadEnum1.ts, 0, 0)) +>Finish : Symbol(BasicEvents.Finish, Decl(spreadEnum1.ts, 1, 20)) adv = AdvEvents.Start; >adv : Symbol(adv, Decl(spreadEnum1.ts, 13, 11)) diff --git a/tests/baselines/reference/spreadEnum1.types b/tests/baselines/reference/spreadEnum1.types index 65a77a35b61b2..a8cc23ce09f95 100644 --- a/tests/baselines/reference/spreadEnum1.types +++ b/tests/baselines/reference/spreadEnum1.types @@ -32,10 +32,24 @@ declare let basic: BasicEvents; declare let adv: AdvEvents; >adv : AdvEvents -// adv = basic; +adv = basic; +>adv = basic : BasicEvents +>adv : AdvEvents +>basic : BasicEvents -// basic = BasicEvents.Start; -// basic = BasicEvents.Finish; +basic = BasicEvents.Start; +>basic = BasicEvents.Start : BasicEvents.Start +>basic : BasicEvents +>BasicEvents.Start : BasicEvents.Start +>BasicEvents : typeof BasicEvents +>Start : BasicEvents.Start + +basic = BasicEvents.Finish; +>basic = BasicEvents.Finish : BasicEvents.Finish +>basic : BasicEvents +>BasicEvents.Finish : BasicEvents.Finish +>BasicEvents : typeof BasicEvents +>Finish : BasicEvents.Finish adv = AdvEvents.Start; >adv = AdvEvents.Start : BasicEvents.Start diff --git a/tests/cases/conformance/enums/spreadEnum1.ts b/tests/cases/conformance/enums/spreadEnum1.ts index 962d3ded3be1a..4760e292c51cf 100644 --- a/tests/cases/conformance/enums/spreadEnum1.ts +++ b/tests/cases/conformance/enums/spreadEnum1.ts @@ -15,10 +15,10 @@ declare let basic: BasicEvents; declare let adv: AdvEvents; -// adv = basic; +adv = basic; -// basic = BasicEvents.Start; -// basic = BasicEvents.Finish; +basic = BasicEvents.Start; +basic = BasicEvents.Finish; adv = AdvEvents.Start; adv = AdvEvents.Finish; From d6fe7d41b373f305759fbb8029b3e74de2f86c4d Mon Sep 17 00:00:00 2001 From: kingwl Date: Sat, 10 Oct 2020 18:00:37 +0800 Subject: [PATCH 06/21] use late bound --- src/compiler/checker.ts | 69 ++++++++++--------- src/compiler/types.ts | 4 +- src/compiler/utilities.ts | 3 +- src/services/completions.ts | 2 +- src/services/documentHighlights.ts | 1 + .../completionsWithSpreadEnumMember.ts | 19 +++++ 6 files changed, 62 insertions(+), 36 deletions(-) create mode 100644 tests/cases/fourslash/completionsWithSpreadEnumMember.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6153786984410..d409833268dd0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -578,6 +578,7 @@ namespace ts { getAliasedSymbol: resolveAlias, getEmitResolver, getExportsOfModule: getExportsOfModuleAsArray, + getExportsOfSymbol: getExportsOfSymbolAsArray, getExportsAndPropertiesOfModule, getSymbolWalker: createGetSymbolWalker( getRestTypeOfSignature, @@ -3426,6 +3427,10 @@ namespace ts { return symbolsToArray(getExportsOfModule(moduleSymbol)); } + function getExportsOfSymbolAsArray(symbol: Symbol): Symbol[] { + return symbolsToArray(getExportsOfSymbol(symbol)); + } + function getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[] { const exports = getExportsOfModuleAsArray(moduleSymbol); const exportEquals = resolveExternalModuleSymbol(moduleSymbol); @@ -9450,31 +9455,6 @@ namespace ts { return type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)!) : type; } - function getEnumMemberTypeList(symbol: Symbol): Type[] { - const memberTypeList: Type[] = []; - for (const declaration of symbol.declarations) { - if (declaration.kind === SyntaxKind.EnumDeclaration) { - for (const member of (declaration).members) { - if (isEnumMember(member)) { - const value = getEnumMemberValue(member); - const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); - getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; - memberTypeList.push(getRegularTypeOfLiteralType(memberType)); - } - else { - const referencedEnumDeclaration = resolveEntityName(member.name, SymbolFlags.Enum); - if (referencedEnumDeclaration) { - const declaredType = getDeclaredTypeOfEnum(referencedEnumDeclaration); - const types = declaredType.flags & TypeFlags.Union ? (declaredType).types : [declaredType]; - memberTypeList.push(...types); - } - } - } - } - } - return memberTypeList; - } - function getDeclaredTypeOfEnum(symbol: Symbol): Type { const links = getSymbolLinks(symbol); if (links.declaredType) { @@ -9482,7 +9462,16 @@ namespace ts { } if (getEnumKind(symbol) === EnumKind.Literal) { enumCount++; - const memberTypeList = getEnumMemberTypeList(symbol); + const memberTypeList: Type[] = []; + const enumExports = getExportsOfSymbol(symbol); + enumExports.forEach(enumExport => { + if (isEnumMember(enumExport.valueDeclaration)) { + const value = getEnumMemberValue(enumExport.valueDeclaration); + const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, enumExport)); + getSymbolLinks(enumExport).declaredType = memberType; + memberTypeList.push(getRegularTypeOfLiteralType(memberType)); + } + }) if (memberTypeList.length) { const enumType = getUnionType(memberTypeList, UnionReduction.Literal, symbol, /*aliasTypeArguments*/ undefined); if (enumType.flags & TypeFlags.Union) { @@ -9736,7 +9725,7 @@ namespace ts { * late-bound members that `addDeclarationToSymbol` in binder.ts performs for early-bound * members. */ - function addDeclarationToLateBoundSymbol(symbol: Symbol, member: LateBoundDeclaration | BinaryExpression, symbolFlags: SymbolFlags) { + function addDeclarationToLateBoundSymbol(symbol: Symbol, member: LateBoundDeclaration | BinaryExpression | EnumMember, symbolFlags: SymbolFlags) { Debug.assert(!!(getCheckFlags(symbol) & CheckFlags.Late), "Expected a late-bound symbol."); symbol.flags |= symbolFlags; getSymbolLinks(member.symbol).lateSymbol = symbol; @@ -9781,7 +9770,7 @@ namespace ts { * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: UnderscoreEscapedMap, decl: LateBoundDeclaration | LateBoundBinaryExpressionDeclaration) { + function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: UnderscoreEscapedMap, decl: LateBoundDeclaration | LateBoundBinaryExpressionDeclaration | EnumMember) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -9789,7 +9778,7 @@ namespace ts { // fall back to the early-bound name of this member. links.resolvedSymbol = decl.symbol; const declName = isBinaryExpression(decl) ? decl.left : decl.name; - const type = isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : checkComputedPropertyName(declName); + const type = isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : isEnumMember(decl) ? getTypeOfNode(decl) : checkComputedPropertyName(cast(declName, isComputedPropertyName)); if (isTypeUsableAsPropertyName(type)) { const memberName = getPropertyNameFromType(type); const symbolFlags = decl.symbol.flags; @@ -9844,8 +9833,20 @@ namespace ts { const members = getMembersOfDeclaration(decl); if (members) { for (const member of members) { - if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { + if (isSpreadEnumMember(member)) { + const symbol = resolveEntityName(member.name, SymbolFlags.Enum); + if (symbol) { + const enumExports = getExportsOfSymbol(symbol); + enumExports.forEach(enumExport => { + if (isEnumMember(enumExport.valueDeclaration)) { + lateBindMember(symbol, earlySymbols, lateSymbols, enumExport.valueDeclaration); + } + }) + } + } + else if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { lateBindMember(symbol, earlySymbols, lateSymbols, member); + } } } @@ -35942,9 +35943,11 @@ namespace ts { } } - function checkEnumMember(node: EnumMember) { - if (isPrivateIdentifier(node.name)) { - error(node, Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); + function checkEnumMember(node: EnumMemberLike) { + if (isEnumMember(node)) { + if (isPrivateIdentifier(node.name)) { + error(node, Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); + } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e5403aa6876df..6b849cee72ffc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2777,6 +2777,7 @@ namespace ts { export type ObjectTypeDeclaration = | ClassLikeDeclaration | InterfaceDeclaration + | EnumDeclaration | TypeLiteralNode ; @@ -4049,6 +4050,7 @@ namespace ts { /** Follow a *single* alias to get the immediately aliased symbol. */ /* @internal */ getImmediateAliasedSymbol(symbol: Symbol): Symbol | undefined; getExportsOfModule(moduleSymbol: Symbol): Symbol[]; + getExportsOfSymbol(symbol: Symbol): Symbol[]; /** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */ /* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[]; getJsxIntrinsicTagNamesAt(location: Node): Symbol[]; @@ -4640,7 +4642,7 @@ namespace ts { Classifiable = Class | Enum | TypeAlias | Interface | TypeParameter | Module | Alias, /* @internal */ - LateBindingContainer = Class | Interface | TypeLiteral | ObjectLiteral | Function, + LateBindingContainer = Class | Interface | TypeLiteral | ObjectLiteral | Function | Enum, } /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ec0b768a1ad92..8c4b653a6f9e8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1372,12 +1372,13 @@ namespace ts { } } - export function getMembersOfDeclaration(node: Declaration): NodeArray | undefined { + export function getMembersOfDeclaration(node: Declaration): NodeArray | undefined { switch (node.kind) { case SyntaxKind.InterfaceDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.TypeLiteral: + case SyntaxKind.EnumDeclaration: return (node).members; case SyntaxKind.ObjectLiteralExpression: return (node).properties; diff --git a/src/services/completions.ts b/src/services/completions.ts index b7ac7e26925a4..2cc72d7b1d20a 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1182,7 +1182,7 @@ namespace ts.Completions { symbol = skipAlias(symbol, typeChecker); if (symbol.flags & (SymbolFlags.Module | SymbolFlags.Enum)) { // Extract module or enum members - const exportedSymbols = typeChecker.getExportsOfModule(symbol); + const exportedSymbols = symbol.flags & SymbolFlags.Enum ? typeChecker.getExportsOfSymbol(symbol) : typeChecker.getExportsOfModule(symbol); Debug.assertEachIsDefined(exportedSymbols, "getExportsOfModule() should all be defined"); const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(isImportType ? node : (node.parent), symbol.name); const isValidTypeAccess = (symbol: Symbol) => symbolCanBeReferencedAtTypeLocation(symbol); diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index b0282393cce6f..a434f313d717a 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -243,6 +243,7 @@ namespace ts { // Syntactically invalid positions that the parser might produce anyway case SyntaxKind.ObjectLiteralExpression: + case SyntaxKind.EnumDeclaration: return undefined; default: diff --git a/tests/cases/fourslash/completionsWithSpreadEnumMember.ts b/tests/cases/fourslash/completionsWithSpreadEnumMember.ts new file mode 100644 index 0000000000000..de4cdfcecad29 --- /dev/null +++ b/tests/cases/fourslash/completionsWithSpreadEnumMember.ts @@ -0,0 +1,19 @@ +/// + +//// enum A { +//// f = 'f' +//// } + +//// enum B { +//// ...A, +//// b = 'b' +//// } + +//// B./*1*/ + +verify.completions({ + marker: '1', + includes: [ + "f" + ] +}) From 1049b19b9f60600c0f8a44eb090cfe78154ee43e Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 02:40:22 +0800 Subject: [PATCH 07/21] use late bound --- src/compiler/checker.ts | 47 +++---- .../reference/api/tsserverlibrary.d.ts | 3 +- tests/baselines/reference/api/typescript.d.ts | 3 +- tests/baselines/reference/spreadEnum2.js | 118 ++++++++++++++++++ tests/baselines/reference/spreadEnum2.symbols | 115 +++++++++++++++++ tests/cases/conformance/enums/spreadEnum2.ts | 45 +++++++ 6 files changed, 297 insertions(+), 34 deletions(-) create mode 100644 tests/baselines/reference/spreadEnum2.js create mode 100644 tests/baselines/reference/spreadEnum2.symbols create mode 100644 tests/cases/conformance/enums/spreadEnum2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d409833268dd0..1659708d07712 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9465,7 +9465,7 @@ namespace ts { const memberTypeList: Type[] = []; const enumExports = getExportsOfSymbol(symbol); enumExports.forEach(enumExport => { - if (isEnumMember(enumExport.valueDeclaration)) { + if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { const value = getEnumMemberValue(enumExport.valueDeclaration); const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, enumExport)); getSymbolLinks(enumExport).declaredType = memberType; @@ -9780,7 +9780,7 @@ namespace ts { const declName = isBinaryExpression(decl) ? decl.left : decl.name; const type = isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : isEnumMember(decl) ? getTypeOfNode(decl) : checkComputedPropertyName(cast(declName, isComputedPropertyName)); if (isTypeUsableAsPropertyName(type)) { - const memberName = getPropertyNameFromType(type); + const memberName = isEnumMember(decl) ? getTextOfPropertyName(decl.name) : getPropertyNameFromType(type); const symbolFlags = decl.symbol.flags; // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations. @@ -9834,19 +9834,25 @@ namespace ts { if (members) { for (const member of members) { if (isSpreadEnumMember(member)) { - const symbol = resolveEntityName(member.name, SymbolFlags.Enum); - if (symbol) { - const enumExports = getExportsOfSymbol(symbol); + const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); + if (enumSymbol) { + const enumExports = getExportsOfSymbol(enumSymbol); + const spreadEnumMemberExports = createSymbolTable(); enumExports.forEach(enumExport => { - if (isEnumMember(enumExport.valueDeclaration)) { - lateBindMember(symbol, earlySymbols, lateSymbols, enumExport.valueDeclaration); + if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { + const memberName = getTextOfPropertyName(enumExport.valueDeclaration.name); + const enumSymbol = createSymbol(SymbolFlags.Alias | SymbolFlags.EnumMember, memberName); + enumSymbol.target = enumExport; + enumSymbol.declarations = enumExport.declarations; + enumSymbol.valueDeclaration = enumExport.valueDeclaration; + spreadEnumMemberExports.set(memberName, enumSymbol); } }) + addToSymbolTable(lateSymbols, spreadEnumMemberExports, Diagnostics.Expression_expected); } } else if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { lateBindMember(symbol, earlySymbols, lateSymbols, member); - } } } @@ -10401,29 +10407,6 @@ namespace ts { } } setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); - if (symbol.flags & SymbolFlags.Enum) { - const spreadEnumMembers: SpreadEnumMember[] = []; - symbol.declarations.forEach(decl => { - if (isEnumDeclaration(decl)) { - decl.members.forEach(member => { - if (isSpreadEnumMember(member)) { - spreadEnumMembers.push(member); - } - }); - } - }); - if (spreadEnumMembers.length) { - spreadEnumMembers.forEach(member => { - if (isIdentifier(member.name)) { - const sym = getResolvedSymbol(member.name); - if (sym.flags & SymbolFlags.Enum) { - members = combineSymbolTables(members, getExportsOfSymbol(sym)); - } - } - }); - setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); - } - } if (symbol.flags & SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); const baseConstructorType = getBaseConstructorTypeOfClass(classType); @@ -16741,7 +16724,7 @@ namespace ts { * * Ternary.Maybe if they are related with assumptions of other relationships, or * * Ternary.False if they are not related. */ - function isRelatedTo(originalSource: Type, originalTarget: Type, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { + function isRelatedTo(originalSource: Type, originalTarget: Type, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { // Before normalization: if `source` is type an object type, and `target` is primitive, // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a2a65f7553162..60fae39f711c6 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1508,7 +1508,7 @@ declare namespace ts { readonly variableDeclaration?: VariableDeclaration; readonly block: Block; } - export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; + export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | EnumDeclaration | TypeLiteralNode; export type DeclarationWithTypeParameters = DeclarationWithTypeParameterChildren | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; export type DeclarationWithTypeParameterChildren = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { @@ -2233,6 +2233,7 @@ declare namespace ts { /** Follow all aliases to get the original symbol. */ getAliasedSymbol(symbol: Symbol): Symbol; getExportsOfModule(moduleSymbol: Symbol): Symbol[]; + getExportsOfSymbol(symbol: Symbol): Symbol[]; getJsxIntrinsicTagNamesAt(location: Node): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; getAmbientModules(): Symbol[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 629ba2172e8d1..3c0837a32ab4a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1508,7 +1508,7 @@ declare namespace ts { readonly variableDeclaration?: VariableDeclaration; readonly block: Block; } - export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; + export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | EnumDeclaration | TypeLiteralNode; export type DeclarationWithTypeParameters = DeclarationWithTypeParameterChildren | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; export type DeclarationWithTypeParameterChildren = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { @@ -2233,6 +2233,7 @@ declare namespace ts { /** Follow all aliases to get the original symbol. */ getAliasedSymbol(symbol: Symbol): Symbol; getExportsOfModule(moduleSymbol: Symbol): Symbol[]; + getExportsOfSymbol(symbol: Symbol): Symbol[]; getJsxIntrinsicTagNamesAt(location: Node): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; getAmbientModules(): Symbol[]; diff --git a/tests/baselines/reference/spreadEnum2.js b/tests/baselines/reference/spreadEnum2.js new file mode 100644 index 0000000000000..17fa044980161 --- /dev/null +++ b/tests/baselines/reference/spreadEnum2.js @@ -0,0 +1,118 @@ +//// [spreadEnum2.ts] +enum A { + AA = 'A' +} + +enum B { + ...A, + BB = 'B' +} + +enum C { + ...B, + CC = 'C' +} + +enum D { + ...C, + DD = 'D' +} + +enum E { + ...D, + EE = 'E' +} + +A.AA; + +B.AA; +B.BB; + +C.AA; +C.BB; +C.CC; + +D.AA; +D.BB; +D.CC; +D.DD; + +E.AA; +E.BB; +E.CC; +E.DD; +E.EE; + +//// [spreadEnum2.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var A; +(function (A) { + A["AA"] = "A"; +})(A || (A = {})); +var B; +(function (B) { + __assign(B, A); + B["BB"] = "B"; +})(B || (B = {})); +var C; +(function (C) { + __assign(C, B); + C["CC"] = "C"; +})(C || (C = {})); +var D; +(function (D) { + __assign(D, C); + D["DD"] = "D"; +})(D || (D = {})); +var E; +(function (E) { + __assign(E, D); + E["EE"] = "E"; +})(E || (E = {})); +A.AA; +B.AA; +B.BB; +C.AA; +C.BB; +C.CC; +D.AA; +D.BB; +D.CC; +D.DD; +E.AA; +E.BB; +E.CC; +E.DD; +E.EE; + + +//// [spreadEnum2.d.ts] +declare enum A { + AA = "A" +} +declare enum B { + ...A, + BB = "B" +} +declare enum C { + ...B, + CC = "C" +} +declare enum D { + ...C, + DD = "D" +} +declare enum E { + ...D, + EE = "E" +} diff --git a/tests/baselines/reference/spreadEnum2.symbols b/tests/baselines/reference/spreadEnum2.symbols new file mode 100644 index 0000000000000..7eb8f4c0c44e0 --- /dev/null +++ b/tests/baselines/reference/spreadEnum2.symbols @@ -0,0 +1,115 @@ +=== tests/cases/conformance/enums/spreadEnum2.ts === +enum A { +>A : Symbol(A, Decl(spreadEnum2.ts, 0, 0)) + + AA = 'A' +>AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) +} + +enum B { +>B : Symbol(B, Decl(spreadEnum2.ts, 2, 1)) + + ...A, + BB = 'B' +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) +} + +enum C { +>C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) + + ...B, + CC = 'C' +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) +} + +enum D { +>D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) + + ...C, + DD = 'D' +>DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) +} + +enum E { +>E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) + + ...D, + EE = 'E' +>EE : Symbol(E.EE, Decl(spreadEnum2.ts, 20, 9)) +} + +A.AA; +>A.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) +>A : Symbol(A, Decl(spreadEnum2.ts, 0, 0)) +>AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) + +B.AA; +>B.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>B : Symbol(B, Decl(spreadEnum2.ts, 2, 1)) +>AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) + +B.BB; +>B.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) +>B : Symbol(B, Decl(spreadEnum2.ts, 2, 1)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) + +C.AA; +>C.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) +>AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) + +C.BB; +>C.BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) +>BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) + +C.CC; +>C.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) +>C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) + +D.AA; +>D.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) +>AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) + +D.BB; +>D.BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) +>BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) + +D.CC; +>D.CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) +>D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) +>CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) + +D.DD; +>D.DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) +>D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) +>DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) + +E.AA; +>E.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) +>AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) + +E.BB; +>E.BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) +>BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) + +E.CC; +>E.CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) +>CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) + +E.DD; +>E.DD : Symbol(DD, Decl(spreadEnum2.ts, 15, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) +>DD : Symbol(DD, Decl(spreadEnum2.ts, 15, 9)) + +E.EE; +>E.EE : Symbol(E.EE, Decl(spreadEnum2.ts, 20, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) +>EE : Symbol(E.EE, Decl(spreadEnum2.ts, 20, 9)) + diff --git a/tests/cases/conformance/enums/spreadEnum2.ts b/tests/cases/conformance/enums/spreadEnum2.ts new file mode 100644 index 0000000000000..b640988882833 --- /dev/null +++ b/tests/cases/conformance/enums/spreadEnum2.ts @@ -0,0 +1,45 @@ +// @declaration: true + +enum A { + AA = 'A' +} + +enum B { + ...A, + BB = 'B' +} + +enum C { + ...B, + CC = 'C' +} + +enum D { + ...C, + DD = 'D' +} + +enum E { + ...D, + EE = 'E' +} + +A.AA; + +B.AA; +B.BB; + +C.AA; +C.BB; +C.CC; + +D.AA; +D.BB; +D.CC; +D.DD; + +E.AA; +E.BB; +E.CC; +E.DD; +E.EE; \ No newline at end of file From 4bde32db4702f2488286aa95cff213f7632f530f Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 02:51:12 +0800 Subject: [PATCH 08/21] revert changes --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1659708d07712..87f5c5cd0f2ec 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9725,7 +9725,7 @@ namespace ts { * late-bound members that `addDeclarationToSymbol` in binder.ts performs for early-bound * members. */ - function addDeclarationToLateBoundSymbol(symbol: Symbol, member: LateBoundDeclaration | BinaryExpression | EnumMember, symbolFlags: SymbolFlags) { + function addDeclarationToLateBoundSymbol(symbol: Symbol, member: LateBoundDeclaration | BinaryExpression, symbolFlags: SymbolFlags) { Debug.assert(!!(getCheckFlags(symbol) & CheckFlags.Late), "Expected a late-bound symbol."); symbol.flags |= symbolFlags; getSymbolLinks(member.symbol).lateSymbol = symbol; @@ -9770,7 +9770,7 @@ namespace ts { * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: UnderscoreEscapedMap, decl: LateBoundDeclaration | LateBoundBinaryExpressionDeclaration | EnumMember) { + function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: UnderscoreEscapedMap, decl: LateBoundDeclaration | LateBoundBinaryExpressionDeclaration) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -9778,9 +9778,9 @@ namespace ts { // fall back to the early-bound name of this member. links.resolvedSymbol = decl.symbol; const declName = isBinaryExpression(decl) ? decl.left : decl.name; - const type = isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : isEnumMember(decl) ? getTypeOfNode(decl) : checkComputedPropertyName(cast(declName, isComputedPropertyName)); + const type = isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : checkComputedPropertyName(declName); if (isTypeUsableAsPropertyName(type)) { - const memberName = isEnumMember(decl) ? getTextOfPropertyName(decl.name) : getPropertyNameFromType(type); + const memberName = getPropertyNameFromType(type); const symbolFlags = decl.symbol.flags; // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations. @@ -16724,7 +16724,7 @@ namespace ts { * * Ternary.Maybe if they are related with assumptions of other relationships, or * * Ternary.False if they are not related. */ - function isRelatedTo(originalSource: Type, originalTarget: Type, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { + function isRelatedTo(originalSource: Type, originalTarget: Type, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { // Before normalization: if `source` is type an object type, and `target` is primitive, // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) { From 0cde3e247ff71b75c26a6c0b3fd3067073802995 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 03:55:15 +0800 Subject: [PATCH 09/21] use clone symbol --- src/compiler/checker.ts | 8 +- tests/baselines/reference/spreadEnum2.symbols | 40 +++--- tests/baselines/reference/spreadEnum2.types | 128 ++++++++++++++++++ 3 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 tests/baselines/reference/spreadEnum2.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 87f5c5cd0f2ec..40a6b771e44f9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9840,12 +9840,8 @@ namespace ts { const spreadEnumMemberExports = createSymbolTable(); enumExports.forEach(enumExport => { if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { - const memberName = getTextOfPropertyName(enumExport.valueDeclaration.name); - const enumSymbol = createSymbol(SymbolFlags.Alias | SymbolFlags.EnumMember, memberName); - enumSymbol.target = enumExport; - enumSymbol.declarations = enumExport.declarations; - enumSymbol.valueDeclaration = enumExport.valueDeclaration; - spreadEnumMemberExports.set(memberName, enumSymbol); + const enumSymbol = cloneSymbol(enumExport); + spreadEnumMemberExports.set(enumExport.escapedName, enumSymbol); } }) addToSymbolTable(lateSymbols, spreadEnumMemberExports, Diagnostics.Expression_expected); diff --git a/tests/baselines/reference/spreadEnum2.symbols b/tests/baselines/reference/spreadEnum2.symbols index 7eb8f4c0c44e0..818a0756308fc 100644 --- a/tests/baselines/reference/spreadEnum2.symbols +++ b/tests/baselines/reference/spreadEnum2.symbols @@ -44,9 +44,9 @@ A.AA; >AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) B.AA; ->B.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>B.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) >B : Symbol(B, Decl(spreadEnum2.ts, 2, 1)) ->AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) B.BB; >B.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) @@ -54,14 +54,14 @@ B.BB; >BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) C.AA; ->C.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>C.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) >C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) ->AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) C.BB; ->C.BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>C.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) >C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) ->BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) C.CC; >C.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) @@ -69,19 +69,19 @@ C.CC; >CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) D.AA; ->D.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>D.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) >D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) ->AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) D.BB; ->D.BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>D.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) >D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) ->BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) D.CC; ->D.CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) +>D.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) >D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) ->CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) D.DD; >D.DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) @@ -89,24 +89,24 @@ D.DD; >DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) E.AA; ->E.AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>E.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) >E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->AA : Symbol(AA, Decl(spreadEnum2.ts, 0, 8)) +>AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) E.BB; ->E.BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>E.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) >E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->BB : Symbol(BB, Decl(spreadEnum2.ts, 5, 9)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) E.CC; ->E.CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) +>E.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) >E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->CC : Symbol(CC, Decl(spreadEnum2.ts, 10, 9)) +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) E.DD; ->E.DD : Symbol(DD, Decl(spreadEnum2.ts, 15, 9)) +>E.DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) >E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->DD : Symbol(DD, Decl(spreadEnum2.ts, 15, 9)) +>DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) E.EE; >E.EE : Symbol(E.EE, Decl(spreadEnum2.ts, 20, 9)) diff --git a/tests/baselines/reference/spreadEnum2.types b/tests/baselines/reference/spreadEnum2.types new file mode 100644 index 0000000000000..9ce352b7cb7f3 --- /dev/null +++ b/tests/baselines/reference/spreadEnum2.types @@ -0,0 +1,128 @@ +=== tests/cases/conformance/enums/spreadEnum2.ts === +enum A { +>A : A + + AA = 'A' +>AA : A.AA +>'A' : "A" +} + +enum B { +>B : B + + ...A, +>A : error + + BB = 'B' +>BB : B.BB +>'B' : "B" +} + +enum C { +>C : C + + ...B, +>B : error + + CC = 'C' +>CC : C.CC +>'C' : "C" +} + +enum D { +>D : D + + ...C, +>C : error + + DD = 'D' +>DD : D.DD +>'D' : "D" +} + +enum E { +>E : E + + ...D, +>D : error + + EE = 'E' +>EE : E.EE +>'E' : "E" +} + +A.AA; +>A.AA : A +>A : typeof A +>AA : A + +B.AA; +>B.AA : A.AA +>B : typeof B +>AA : A.AA + +B.BB; +>B.BB : B.BB +>B : typeof B +>BB : B.BB + +C.AA; +>C.AA : A.AA +>C : typeof C +>AA : A.AA + +C.BB; +>C.BB : B.BB +>C : typeof C +>BB : B.BB + +C.CC; +>C.CC : C.CC +>C : typeof C +>CC : C.CC + +D.AA; +>D.AA : A.AA +>D : typeof D +>AA : A.AA + +D.BB; +>D.BB : B.BB +>D : typeof D +>BB : B.BB + +D.CC; +>D.CC : C.CC +>D : typeof D +>CC : C.CC + +D.DD; +>D.DD : D.DD +>D : typeof D +>DD : D.DD + +E.AA; +>E.AA : A.AA +>E : typeof E +>AA : A.AA + +E.BB; +>E.BB : B.BB +>E : typeof E +>BB : B.BB + +E.CC; +>E.CC : C.CC +>E : typeof E +>CC : C.CC + +E.DD; +>E.DD : D.DD +>E : typeof E +>DD : D.DD + +E.EE; +>E.EE : E.EE +>E : typeof E +>EE : E.EE + From 9b9372eb942a40a613d4866b0d5c8cfbf6a88fcd Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 04:10:51 +0800 Subject: [PATCH 10/21] update cases --- src/compiler/checker.ts | 37 ++++++-- tests/baselines/reference/spreadEnum2.js | 7 +- tests/baselines/reference/spreadEnum2.symbols | 89 ++++++++++--------- tests/baselines/reference/spreadEnum2.types | 34 +++---- tests/cases/conformance/enums/spreadEnum2.ts | 3 +- 5 files changed, 100 insertions(+), 70 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 40a6b771e44f9..c9a5b6424e23e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9463,15 +9463,27 @@ namespace ts { if (getEnumKind(symbol) === EnumKind.Literal) { enumCount++; const memberTypeList: Type[] = []; - const enumExports = getExportsOfSymbol(symbol); - enumExports.forEach(enumExport => { - if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { - const value = getEnumMemberValue(enumExport.valueDeclaration); - const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, enumExport)); - getSymbolLinks(enumExport).declaredType = memberType; - memberTypeList.push(getRegularTypeOfLiteralType(memberType)); - } - }) + for (const declaration of symbol.declarations) { + if (declaration.kind === SyntaxKind.EnumDeclaration) { + for (const member of (declaration).members) { + if (isEnumMember(member)) { + appendEnumMemberIntoTypeList(member, memberTypeList) + } + else { + const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); + if (enumSymbol) { + const enumExports = getExportsOfSymbol(symbol); + enumExports.forEach(enumExport => { + if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { + appendEnumMemberIntoTypeList(enumExport.valueDeclaration, memberTypeList); + } + }) + } + } + } + } + } + if (memberTypeList.length) { const enumType = getUnionType(memberTypeList, UnionReduction.Literal, symbol, /*aliasTypeArguments*/ undefined); if (enumType.flags & TypeFlags.Union) { @@ -9484,6 +9496,13 @@ namespace ts { const enumType = createType(TypeFlags.Enum); enumType.symbol = symbol; return links.declaredType = enumType; + + function appendEnumMemberIntoTypeList(member: EnumMember, memberTypeList: Type[]) { + const value = getEnumMemberValue(member); + const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); + getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; + memberTypeList.push(getRegularTypeOfLiteralType(memberType)); + } } function getDeclaredTypeOfEnumMember(symbol: Symbol): Type { diff --git a/tests/baselines/reference/spreadEnum2.js b/tests/baselines/reference/spreadEnum2.js index 17fa044980161..bc3a079af34b2 100644 --- a/tests/baselines/reference/spreadEnum2.js +++ b/tests/baselines/reference/spreadEnum2.js @@ -1,6 +1,7 @@ //// [spreadEnum2.ts] enum A { - AA = 'A' + AA = 'A', + AAA = 'AAA' } enum B { @@ -58,6 +59,7 @@ var __assign = (this && this.__assign) || function () { var A; (function (A) { A["AA"] = "A"; + A["AAA"] = "AAA"; })(A || (A = {})); var B; (function (B) { @@ -98,7 +100,8 @@ E.EE; //// [spreadEnum2.d.ts] declare enum A { - AA = "A" + AA = "A", + AAA = "AAA" } declare enum B { ...A, diff --git a/tests/baselines/reference/spreadEnum2.symbols b/tests/baselines/reference/spreadEnum2.symbols index 818a0756308fc..1a7a7fbd05c17 100644 --- a/tests/baselines/reference/spreadEnum2.symbols +++ b/tests/baselines/reference/spreadEnum2.symbols @@ -2,40 +2,43 @@ enum A { >A : Symbol(A, Decl(spreadEnum2.ts, 0, 0)) - AA = 'A' + AA = 'A', >AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) + + AAA = 'AAA' +>AAA : Symbol(A.AAA, Decl(spreadEnum2.ts, 1, 13)) } enum B { ->B : Symbol(B, Decl(spreadEnum2.ts, 2, 1)) +>B : Symbol(B, Decl(spreadEnum2.ts, 3, 1)) ...A, BB = 'B' ->BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) } enum C { ->C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) +>C : Symbol(C, Decl(spreadEnum2.ts, 8, 1)) ...B, CC = 'C' ->CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) } enum D { ->D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) +>D : Symbol(D, Decl(spreadEnum2.ts, 13, 1)) ...C, DD = 'D' ->DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) +>DD : Symbol(D.DD, Decl(spreadEnum2.ts, 16, 9)) } enum E { ->E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) +>E : Symbol(E, Decl(spreadEnum2.ts, 18, 1)) ...D, EE = 'E' ->EE : Symbol(E.EE, Decl(spreadEnum2.ts, 20, 9)) +>EE : Symbol(E.EE, Decl(spreadEnum2.ts, 21, 9)) } A.AA; @@ -45,71 +48,71 @@ A.AA; B.AA; >B.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) ->B : Symbol(B, Decl(spreadEnum2.ts, 2, 1)) +>B : Symbol(B, Decl(spreadEnum2.ts, 3, 1)) >AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) B.BB; ->B.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) ->B : Symbol(B, Decl(spreadEnum2.ts, 2, 1)) ->BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) +>B.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) +>B : Symbol(B, Decl(spreadEnum2.ts, 3, 1)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) C.AA; >C.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) ->C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) +>C : Symbol(C, Decl(spreadEnum2.ts, 8, 1)) >AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) C.BB; ->C.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) ->C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) ->BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) +>C.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) +>C : Symbol(C, Decl(spreadEnum2.ts, 8, 1)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) C.CC; ->C.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) ->C : Symbol(C, Decl(spreadEnum2.ts, 7, 1)) ->CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) +>C.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) +>C : Symbol(C, Decl(spreadEnum2.ts, 8, 1)) +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) D.AA; >D.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) ->D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) +>D : Symbol(D, Decl(spreadEnum2.ts, 13, 1)) >AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) D.BB; ->D.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) ->D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) ->BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) +>D.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) +>D : Symbol(D, Decl(spreadEnum2.ts, 13, 1)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) D.CC; ->D.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) ->D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) ->CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) +>D.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) +>D : Symbol(D, Decl(spreadEnum2.ts, 13, 1)) +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) D.DD; ->D.DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) ->D : Symbol(D, Decl(spreadEnum2.ts, 12, 1)) ->DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) +>D.DD : Symbol(D.DD, Decl(spreadEnum2.ts, 16, 9)) +>D : Symbol(D, Decl(spreadEnum2.ts, 13, 1)) +>DD : Symbol(D.DD, Decl(spreadEnum2.ts, 16, 9)) E.AA; >E.AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) ->E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) +>E : Symbol(E, Decl(spreadEnum2.ts, 18, 1)) >AA : Symbol(A.AA, Decl(spreadEnum2.ts, 0, 8)) E.BB; ->E.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) ->E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->BB : Symbol(B.BB, Decl(spreadEnum2.ts, 5, 9)) +>E.BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 18, 1)) +>BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) E.CC; ->E.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) ->E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->CC : Symbol(C.CC, Decl(spreadEnum2.ts, 10, 9)) +>E.CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 18, 1)) +>CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) E.DD; ->E.DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) ->E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->DD : Symbol(D.DD, Decl(spreadEnum2.ts, 15, 9)) +>E.DD : Symbol(D.DD, Decl(spreadEnum2.ts, 16, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 18, 1)) +>DD : Symbol(D.DD, Decl(spreadEnum2.ts, 16, 9)) E.EE; ->E.EE : Symbol(E.EE, Decl(spreadEnum2.ts, 20, 9)) ->E : Symbol(E, Decl(spreadEnum2.ts, 17, 1)) ->EE : Symbol(E.EE, Decl(spreadEnum2.ts, 20, 9)) +>E.EE : Symbol(E.EE, Decl(spreadEnum2.ts, 21, 9)) +>E : Symbol(E, Decl(spreadEnum2.ts, 18, 1)) +>EE : Symbol(E.EE, Decl(spreadEnum2.ts, 21, 9)) diff --git a/tests/baselines/reference/spreadEnum2.types b/tests/baselines/reference/spreadEnum2.types index 9ce352b7cb7f3..55f820fb9c65b 100644 --- a/tests/baselines/reference/spreadEnum2.types +++ b/tests/baselines/reference/spreadEnum2.types @@ -2,9 +2,13 @@ enum A { >A : A - AA = 'A' + AA = 'A', >AA : A.AA >'A' : "A" + + AAA = 'AAA' +>AAA : A.AAA +>'AAA' : "AAA" } enum B { @@ -52,9 +56,9 @@ enum E { } A.AA; ->A.AA : A +>A.AA : A.AA >A : typeof A ->AA : A +>AA : A.AA B.AA; >B.AA : A.AA @@ -67,9 +71,9 @@ B.BB; >BB : B.BB C.AA; ->C.AA : A.AA +>C.AA : A >C : typeof C ->AA : A.AA +>AA : A C.BB; >C.BB : B.BB @@ -82,14 +86,14 @@ C.CC; >CC : C.CC D.AA; ->D.AA : A.AA +>D.AA : A >D : typeof D ->AA : A.AA +>AA : A D.BB; ->D.BB : B.BB +>D.BB : B >D : typeof D ->BB : B.BB +>BB : B D.CC; >D.CC : C.CC @@ -102,19 +106,19 @@ D.DD; >DD : D.DD E.AA; ->E.AA : A.AA +>E.AA : A >E : typeof E ->AA : A.AA +>AA : A E.BB; ->E.BB : B.BB +>E.BB : B >E : typeof E ->BB : B.BB +>BB : B E.CC; ->E.CC : C.CC +>E.CC : C >E : typeof E ->CC : C.CC +>CC : C E.DD; >E.DD : D.DD diff --git a/tests/cases/conformance/enums/spreadEnum2.ts b/tests/cases/conformance/enums/spreadEnum2.ts index b640988882833..e392a716f394b 100644 --- a/tests/cases/conformance/enums/spreadEnum2.ts +++ b/tests/cases/conformance/enums/spreadEnum2.ts @@ -1,7 +1,8 @@ // @declaration: true enum A { - AA = 'A' + AA = 'A', + AAA = 'AAA' } enum B { From ab6bcfc7d4a94c77d935f1d2f2bac3270d060150 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 04:12:13 +0800 Subject: [PATCH 11/21] make linter happy] --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9a5b6424e23e..1ac0de200d575 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9467,7 +9467,7 @@ namespace ts { if (declaration.kind === SyntaxKind.EnumDeclaration) { for (const member of (declaration).members) { if (isEnumMember(member)) { - appendEnumMemberIntoTypeList(member, memberTypeList) + appendEnumMemberIntoTypeList(member, memberTypeList); } else { const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); @@ -9477,7 +9477,7 @@ namespace ts { if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { appendEnumMemberIntoTypeList(enumExport.valueDeclaration, memberTypeList); } - }) + }); } } } @@ -9862,7 +9862,7 @@ namespace ts { const enumSymbol = cloneSymbol(enumExport); spreadEnumMemberExports.set(enumExport.escapedName, enumSymbol); } - }) + }); addToSymbolTable(lateSymbols, spreadEnumMemberExports, Diagnostics.Expression_expected); } } From c993dd08ef7c10459f2ccff729bf5ece1af7cb93 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 23:01:55 +0800 Subject: [PATCH 12/21] fix minor issue --- src/compiler/binder.ts | 2 -- src/compiler/checker.ts | 4 ++++ src/compiler/utilities.ts | 4 ++++ src/compiler/utilitiesPublic.ts | 1 + src/services/breakpoints.ts | 1 + src/services/classifier2020.ts | 1 + src/services/findAllReferences.ts | 1 + src/services/jsDoc.ts | 1 + src/services/utilities.ts | 2 ++ tests/baselines/reference/spreadEnum1.types | 2 +- tests/baselines/reference/spreadEnum2.types | 8 ++++---- 11 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2abf750aaf681..5e7695ffef366 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2560,8 +2560,6 @@ namespace ts { return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); case SyntaxKind.EnumMember: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); - case SyntaxKind.SpreadEnumMember: - return undefined; case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ac0de200d575..2a8b08c5a0b68 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32337,6 +32337,7 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: + case SyntaxKind.SpreadEnumMember: return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue; case SyntaxKind.SourceFile: return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue | DeclarationSpaces.ExportNamespace; @@ -35947,6 +35948,9 @@ namespace ts { error(node, Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); } } + else { + checkExpression(node.name); + } } function getFirstNonAmbientClassOrFunctionDeclaration(symbol: Symbol): Declaration | undefined { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8c4b653a6f9e8..ae1ded5fa87e1 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1041,6 +1041,7 @@ namespace ts { case SyntaxKind.ModuleDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: + case SyntaxKind.SpreadEnumMember: case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.MethodDeclaration: @@ -1860,6 +1861,8 @@ namespace ts { case SyntaxKind.PropertyAssignment: case SyntaxKind.BindingElement: return (parent as HasInitializer).initializer === node; + case SyntaxKind.SpreadEnumMember: + return (parent as SpreadEnumMember).name === node; case SyntaxKind.ExpressionStatement: case SyntaxKind.IfStatement: case SyntaxKind.DoStatement: @@ -2837,6 +2840,7 @@ namespace ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.EnumMember: + case SyntaxKind.SpreadEnumMember: case SyntaxKind.PropertyAssignment: case SyntaxKind.PropertyAccessExpression: // Name in member declaration or property name in property access diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 0f702eba480a1..3a25572144eca 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1657,6 +1657,7 @@ namespace ts { || kind === SyntaxKind.Constructor || kind === SyntaxKind.EnumDeclaration || kind === SyntaxKind.EnumMember + || kind === SyntaxKind.SpreadEnumMember || kind === SyntaxKind.ExportSpecifier || kind === SyntaxKind.FunctionDeclaration || kind === SyntaxKind.FunctionExpression diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index eee180ffe144f..e979223f343b2 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -188,6 +188,7 @@ namespace ts.BreakpointResolver { case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: + case SyntaxKind.SpreadEnumMember: case SyntaxKind.BindingElement: // span on complete node return textSpan(node); diff --git a/src/services/classifier2020.ts b/src/services/classifier2020.ts index 263d1ca89d2c1..0580aa0abc245 100644 --- a/src/services/classifier2020.ts +++ b/src/services/classifier2020.ts @@ -232,6 +232,7 @@ namespace ts.classifier.v2020 { [SyntaxKind.ModuleDeclaration, TokenType.namespace], [SyntaxKind.EnumDeclaration, TokenType.enum], [SyntaxKind.EnumMember, TokenType.enumMember], + [SyntaxKind.SpreadAssignment, TokenType.enumMember], [SyntaxKind.ClassDeclaration, TokenType.class], [SyntaxKind.MethodDeclaration, TokenType.member], [SyntaxKind.FunctionDeclaration, TokenType.function], diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 158b16d00c7f1..856ea46a48834 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -547,6 +547,7 @@ namespace ts.FindAllReferences { case SyntaxKind.DefaultKeyword: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: + case SyntaxKind.SpreadEnumMember: case SyntaxKind.ExportSpecifier: case SyntaxKind.ImportClause: // default import case SyntaxKind.ImportEqualsDeclaration: diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 8b45c762da1e9..3f7df13c5b7aa 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -341,6 +341,7 @@ namespace ts.JsDoc { case SyntaxKind.PropertySignature: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: + case SyntaxKind.SpreadEnumMember: case SyntaxKind.TypeAliasDeclaration: return { commentOwner }; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index ee06e960550de..96b394f973634 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -56,6 +56,7 @@ namespace ts { return (node as JSDocTypedefTag).name === undefined ? SemanticMeaning.Value | SemanticMeaning.Type : SemanticMeaning.Type; case SyntaxKind.EnumMember: + case SyntaxKind.SpreadEnumMember: case SyntaxKind.ClassDeclaration: return SemanticMeaning.Value | SemanticMeaning.Type; @@ -410,6 +411,7 @@ namespace ts { case SyntaxKind.Constructor: return ScriptElementKind.constructorImplementationElement; case SyntaxKind.TypeParameter: return ScriptElementKind.typeParameterElement; case SyntaxKind.EnumMember: return ScriptElementKind.enumMemberElement; + case SyntaxKind.SpreadEnumMember: return ScriptElementKind.enumMemberElement; case SyntaxKind.Parameter: return hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement; case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.ImportSpecifier: diff --git a/tests/baselines/reference/spreadEnum1.types b/tests/baselines/reference/spreadEnum1.types index a8cc23ce09f95..b23e3782a2a70 100644 --- a/tests/baselines/reference/spreadEnum1.types +++ b/tests/baselines/reference/spreadEnum1.types @@ -15,7 +15,7 @@ enum AdvEvents { >AdvEvents : AdvEvents ...BasicEvents, ->BasicEvents : error +>BasicEvents : typeof BasicEvents Pause = "Pause", >Pause : AdvEvents.Pause diff --git a/tests/baselines/reference/spreadEnum2.types b/tests/baselines/reference/spreadEnum2.types index 55f820fb9c65b..406600945377c 100644 --- a/tests/baselines/reference/spreadEnum2.types +++ b/tests/baselines/reference/spreadEnum2.types @@ -15,7 +15,7 @@ enum B { >B : B ...A, ->A : error +>A : typeof A BB = 'B' >BB : B.BB @@ -26,7 +26,7 @@ enum C { >C : C ...B, ->B : error +>B : typeof B CC = 'C' >CC : C.CC @@ -37,7 +37,7 @@ enum D { >D : D ...C, ->C : error +>C : typeof C DD = 'D' >DD : D.DD @@ -48,7 +48,7 @@ enum E { >E : E ...D, ->D : error +>D : typeof D EE = 'E' >EE : E.EE From 408c93feda33895fff36fbcabf93033673c4410c Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 23:28:29 +0800 Subject: [PATCH 13/21] Fix enum types --- src/compiler/checker.ts | 56 ++++++++++++--------- tests/baselines/reference/spreadEnum1.types | 16 +++--- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2a8b08c5a0b68..e9636b8a55cc5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9465,22 +9465,13 @@ namespace ts { const memberTypeList: Type[] = []; for (const declaration of symbol.declarations) { if (declaration.kind === SyntaxKind.EnumDeclaration) { - for (const member of (declaration).members) { - if (isEnumMember(member)) { - appendEnumMemberIntoTypeList(member, memberTypeList); - } - else { - const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); - if (enumSymbol) { - const enumExports = getExportsOfSymbol(symbol); - enumExports.forEach(enumExport => { - if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { - appendEnumMemberIntoTypeList(enumExport.valueDeclaration, memberTypeList); - } - }); - } - } - } + const members = getEnumMembers(declaration); + members.forEach(member => { + const value = getEnumMemberValue(member); + const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); + getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; + memberTypeList.push(getRegularTypeOfLiteralType(memberType)); + }); } } @@ -9496,13 +9487,6 @@ namespace ts { const enumType = createType(TypeFlags.Enum); enumType.symbol = symbol; return links.declaredType = enumType; - - function appendEnumMemberIntoTypeList(member: EnumMember, memberTypeList: Type[]) { - const value = getEnumMemberValue(member); - const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); - getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; - memberTypeList.push(getRegularTypeOfLiteralType(memberType)); - } } function getDeclaredTypeOfEnumMember(symbol: Symbol): Type { @@ -38014,6 +37998,32 @@ namespace ts { return symbol && getPropertiesOfType(getTypeOfSymbol(symbol)) || emptyArray; } + function getEnumMembers(node: EnumDeclaration): EnumMember[] { + const declaration = getParseTreeNode(node, isEnumDeclaration); + if (!declaration) { + return emptyArray; + } + + const members: EnumMember[] = []; + for (const member of eclaration.members) { + if (isEnumMember(member)) { + members.push(member); + } + else { + const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); + if (enumSymbol) { + const enumExports = getExportsOfSymbol(enumSymbol); + enumExports.forEach(enumExport => { + if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { + members.push(enumExport.valueDeclaration); + } + }); + } + } + } + return members; + } + function getNodeCheckFlags(node: Node): NodeCheckFlags { return getNodeLinks(node).flags || 0; } diff --git a/tests/baselines/reference/spreadEnum1.types b/tests/baselines/reference/spreadEnum1.types index b23e3782a2a70..65c8a4c3e2c86 100644 --- a/tests/baselines/reference/spreadEnum1.types +++ b/tests/baselines/reference/spreadEnum1.types @@ -3,11 +3,11 @@ enum BasicEvents { >BasicEvents : BasicEvents Start = "Start", ->Start : BasicEvents.Start +>Start : BasicEvents >"Start" : "Start" Finish = "Finish" ->Finish : BasicEvents.Finish +>Finish : BasicEvents >"Finish" : "Finish" } @@ -52,18 +52,18 @@ basic = BasicEvents.Finish; >Finish : BasicEvents.Finish adv = AdvEvents.Start; ->adv = AdvEvents.Start : BasicEvents.Start +>adv = AdvEvents.Start : BasicEvents >adv : AdvEvents ->AdvEvents.Start : BasicEvents.Start +>AdvEvents.Start : BasicEvents >AdvEvents : typeof AdvEvents ->Start : BasicEvents.Start +>Start : BasicEvents adv = AdvEvents.Finish; ->adv = AdvEvents.Finish : BasicEvents.Finish +>adv = AdvEvents.Finish : BasicEvents >adv : AdvEvents ->AdvEvents.Finish : BasicEvents.Finish +>AdvEvents.Finish : BasicEvents >AdvEvents : typeof AdvEvents ->Finish : BasicEvents.Finish +>Finish : BasicEvents adv = AdvEvents.Pause; >adv = AdvEvents.Pause : AdvEvents.Pause From 576ee847aa829d61f68b077d5a0c6bbd40504015 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 11 Oct 2020 23:48:21 +0800 Subject: [PATCH 14/21] minor refactor --- src/compiler/checker.ts | 47 ++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e9636b8a55cc5..b6aa43745905e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9837,18 +9837,13 @@ namespace ts { if (members) { for (const member of members) { if (isSpreadEnumMember(member)) { - const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); - if (enumSymbol) { - const enumExports = getExportsOfSymbol(enumSymbol); - const spreadEnumMemberExports = createSymbolTable(); - enumExports.forEach(enumExport => { - if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { - const enumSymbol = cloneSymbol(enumExport); - spreadEnumMemberExports.set(enumExport.escapedName, enumSymbol); - } - }); - addToSymbolTable(lateSymbols, spreadEnumMemberExports, Diagnostics.Expression_expected); - } + const spreadEnumMemberExports = createSymbolTable(); + const enumMembers = getExportedFromSpreadEnumMember(member); + enumMembers.forEach(enumMember => { + const enumSymbol = cloneSymbol(getSymbolOfNode(enumMember)); + spreadEnumMemberExports.set(enumSymbol.escapedName, enumSymbol); + }); + addToSymbolTable(lateSymbols, spreadEnumMemberExports, Diagnostics.Expression_expected); } else if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { lateBindMember(symbol, earlySymbols, lateSymbols, member); @@ -38005,25 +38000,33 @@ namespace ts { } const members: EnumMember[] = []; - for (const member of eclaration.members) { + for (const member of declaration.members) { if (isEnumMember(member)) { members.push(member); } else { - const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); - if (enumSymbol) { - const enumExports = getExportsOfSymbol(enumSymbol); - enumExports.forEach(enumExport => { - if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { - members.push(enumExport.valueDeclaration); - } - }); - } + members.push(...getExportedFromSpreadEnumMember(member)); } } return members; } + function getExportedFromSpreadEnumMember(member: SpreadEnumMember): EnumMember[] { + const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); + if (!enumSymbol) { + return emptyArray; + } + + const members: EnumMember[] = []; + const enumExports = getExportsOfSymbol(enumSymbol); + enumExports.forEach(enumExport => { + if (enumExport.valueDeclaration && isEnumMember(enumExport.valueDeclaration)) { + members.push(enumExport.valueDeclaration); + } + }); + return members; + } + function getNodeCheckFlags(node: Node): NodeCheckFlags { return getNodeLinks(node).flags || 0; } From c7c9938bc3fcd728c2103015a85ca6bcdf717159 Mon Sep 17 00:00:00 2001 From: kingwl Date: Mon, 12 Oct 2020 01:12:25 +0800 Subject: [PATCH 15/21] Add some check --- src/compiler/checker.ts | 53 +++- src/compiler/diagnosticMessages.json | 23 +- src/compiler/utilitiesPublic.ts | 1 - tests/baselines/reference/spreadEnum1.symbols | 2 + tests/baselines/reference/spreadEnum2.symbols | 8 + .../reference/spreadEnum3.errors.txt | 96 ++++++++ tests/baselines/reference/spreadEnum3.js | 226 ++++++++++++++++++ tests/baselines/reference/spreadEnum3.symbols | 174 ++++++++++++++ tests/baselines/reference/spreadEnum3.types | 202 ++++++++++++++++ tests/baselines/reference/spreadEnum4.js | 76 ++++++ tests/baselines/reference/spreadEnum4.symbols | 44 ++++ tests/baselines/reference/spreadEnum4.types | 48 ++++ .../reference/spreadEnum5.errors.txt | 48 ++++ tests/baselines/reference/spreadEnum5.js | 99 ++++++++ tests/baselines/reference/spreadEnum5.symbols | 116 +++++++++ tests/baselines/reference/spreadEnum5.types | 121 ++++++++++ tests/cases/conformance/enums/spreadEnum3.ts | 79 ++++++ tests/cases/conformance/enums/spreadEnum4.ts | 23 ++ tests/cases/conformance/enums/spreadEnum5.ts | 40 ++++ 19 files changed, 1467 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/spreadEnum3.errors.txt create mode 100644 tests/baselines/reference/spreadEnum3.js create mode 100644 tests/baselines/reference/spreadEnum3.symbols create mode 100644 tests/baselines/reference/spreadEnum3.types create mode 100644 tests/baselines/reference/spreadEnum4.js create mode 100644 tests/baselines/reference/spreadEnum4.symbols create mode 100644 tests/baselines/reference/spreadEnum4.types create mode 100644 tests/baselines/reference/spreadEnum5.errors.txt create mode 100644 tests/baselines/reference/spreadEnum5.js create mode 100644 tests/baselines/reference/spreadEnum5.symbols create mode 100644 tests/baselines/reference/spreadEnum5.types create mode 100644 tests/cases/conformance/enums/spreadEnum3.ts create mode 100644 tests/cases/conformance/enums/spreadEnum4.ts create mode 100644 tests/cases/conformance/enums/spreadEnum5.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b6aa43745905e..e6b1bcea2c7a8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9838,7 +9838,7 @@ namespace ts { for (const member of members) { if (isSpreadEnumMember(member)) { const spreadEnumMemberExports = createSymbolTable(); - const enumMembers = getExportedFromSpreadEnumMember(member); + const enumMembers = getExportsFromSpreadEnumMember(member); enumMembers.forEach(enumMember => { const enumSymbol = cloneSymbol(getSymbolOfNode(enumMember)); spreadEnumMemberExports.set(enumSymbol.escapedName, enumSymbol); @@ -30988,10 +30988,11 @@ namespace ts { (node.parent.kind === SyntaxKind.ElementAccessExpression && (node.parent).expression === node) || ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node) || (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)) || + (node.parent.kind === SyntaxKind.SpreadEnumMember) || (node.parent.kind === SyntaxKind.ExportSpecifier); // We allow reexporting const enums if (!ok) { - error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query); + error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query_or_spread_enum_member); } if (compilerOptions.isolatedModules) { @@ -35873,7 +35874,7 @@ namespace ts { checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); checkExportsOnMergedDeclarations(node); - node.members.forEach(checkEnumMember); + node.members.forEach(checkEnumMemberLike); computeEnumMemberValues(node); @@ -35921,15 +35922,47 @@ namespace ts { } } - function checkEnumMember(node: EnumMemberLike) { + function checkEnumMemberLike(node: EnumMemberLike) { if (isEnumMember(node)) { - if (isPrivateIdentifier(node.name)) { - error(node, Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); - } + checkEnumMember(node); } else { - checkExpression(node.name); + checkSpreadEnumMember(node); + } + } + + function checkEnumMember(node: EnumMember) { + if (isPrivateIdentifier(node.name)) { + error(node, Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); + } + } + + function checkGrammarSpreadEnumMember(symbol: Symbol, container: Symbol, node: SpreadEnumMember) { + if (getEnumKind(symbol) !== EnumKind.Literal) { + error(node.name, Diagnostics.Spread_enum_member_can_only_reference_to_literal_enum_reference); + } + + const symbolIsConstEnum = isConstEnumSymbol(symbol); + const containerIsConstEnum = isConstEnumSymbol(container); + if (!compilerOptions.preserveConstEnums && symbolIsConstEnum !== containerIsConstEnum) { + const diag = symbolIsConstEnum ? + Diagnostics.Spread_enum_member_cannot_reference_to_const_enum_without_preserveConstEnums_flag : + Diagnostics.Spread_enum_member_cannot_reference_to_non_const_enum_inside_const_enum_declaration_without_preserveConstEnums_flag; + error(node.name, diag); + } + } + + function checkSpreadEnumMember(node: SpreadEnumMember) { + const container = node.parent; + const symbol = getSymbolOfNode(container); + const enumSymbol = getSymbolAtLocation(node.name); + if (!enumSymbol || !(enumSymbol.flags & SymbolFlags.Enum)) { + error(node.name, Diagnostics.Enum_expected); + return; } + + checkGrammarSpreadEnumMember(enumSymbol, symbol, node); + checkExpression(node.name); } function getFirstNonAmbientClassOrFunctionDeclaration(symbol: Symbol): Declaration | undefined { @@ -38005,13 +38038,13 @@ namespace ts { members.push(member); } else { - members.push(...getExportedFromSpreadEnumMember(member)); + members.push(...getExportsFromSpreadEnumMember(member)); } } return members; } - function getExportedFromSpreadEnumMember(member: SpreadEnumMember): EnumMember[] { + function getExportsFromSpreadEnumMember(member: SpreadEnumMember): EnumMember[] { const enumSymbol = resolveEntityName(member.name, SymbolFlags.Enum); if (!enumSymbol) { return emptyArray; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fa6ab53f32508..66b9841e2ac88 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1196,6 +1196,27 @@ "category": "Error", "code": 1391 }, + "Spread enum member cannot reference to const enum without 'preserveConstEnums' flag.": { + "category": "Error", + "code": 1392 + }, + "Spread enum member can only reference to literal enum reference.": { + "category": "Error", + "code": 1393 + }, + "Enum expected.": { + "category": "Error", + "code": 1394 + }, + "Duplicated enum member referenced by spread enum member.": { + "category": "Error", + "code": 1395 + }, + "Spread enum member cannot reference to non-const enum inside const enum declaration without 'preserveConstEnums' flag.": { + "category": "Error", + "code": 1396 + }, + "The types of '{0}' are incompatible between these types.": { "category": "Error", "code": 2200 @@ -1913,7 +1934,7 @@ "category": "Error", "code": 2474 }, - "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.": { + "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member.": { "category": "Error", "code": 2475 }, diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 3a25572144eca..0f702eba480a1 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1657,7 +1657,6 @@ namespace ts { || kind === SyntaxKind.Constructor || kind === SyntaxKind.EnumDeclaration || kind === SyntaxKind.EnumMember - || kind === SyntaxKind.SpreadEnumMember || kind === SyntaxKind.ExportSpecifier || kind === SyntaxKind.FunctionDeclaration || kind === SyntaxKind.FunctionExpression diff --git a/tests/baselines/reference/spreadEnum1.symbols b/tests/baselines/reference/spreadEnum1.symbols index 110b217867686..d826f4567bba1 100644 --- a/tests/baselines/reference/spreadEnum1.symbols +++ b/tests/baselines/reference/spreadEnum1.symbols @@ -13,6 +13,8 @@ enum AdvEvents { >AdvEvents : Symbol(AdvEvents, Decl(spreadEnum1.ts, 3, 1)) ...BasicEvents, +>BasicEvents : Symbol(BasicEvents, Decl(spreadEnum1.ts, 0, 0)) + Pause = "Pause", >Pause : Symbol(AdvEvents.Pause, Decl(spreadEnum1.ts, 6, 19)) diff --git a/tests/baselines/reference/spreadEnum2.symbols b/tests/baselines/reference/spreadEnum2.symbols index 1a7a7fbd05c17..176e6a6339ac5 100644 --- a/tests/baselines/reference/spreadEnum2.symbols +++ b/tests/baselines/reference/spreadEnum2.symbols @@ -13,6 +13,8 @@ enum B { >B : Symbol(B, Decl(spreadEnum2.ts, 3, 1)) ...A, +>A : Symbol(A, Decl(spreadEnum2.ts, 0, 0)) + BB = 'B' >BB : Symbol(B.BB, Decl(spreadEnum2.ts, 6, 9)) } @@ -21,6 +23,8 @@ enum C { >C : Symbol(C, Decl(spreadEnum2.ts, 8, 1)) ...B, +>B : Symbol(B, Decl(spreadEnum2.ts, 3, 1)) + CC = 'C' >CC : Symbol(C.CC, Decl(spreadEnum2.ts, 11, 9)) } @@ -29,6 +33,8 @@ enum D { >D : Symbol(D, Decl(spreadEnum2.ts, 13, 1)) ...C, +>C : Symbol(C, Decl(spreadEnum2.ts, 8, 1)) + DD = 'D' >DD : Symbol(D.DD, Decl(spreadEnum2.ts, 16, 9)) } @@ -37,6 +43,8 @@ enum E { >E : Symbol(E, Decl(spreadEnum2.ts, 18, 1)) ...D, +>D : Symbol(D, Decl(spreadEnum2.ts, 13, 1)) + EE = 'E' >EE : Symbol(E.EE, Decl(spreadEnum2.ts, 21, 9)) } diff --git a/tests/baselines/reference/spreadEnum3.errors.txt b/tests/baselines/reference/spreadEnum3.errors.txt new file mode 100644 index 0000000000000..da07c879628e9 --- /dev/null +++ b/tests/baselines/reference/spreadEnum3.errors.txt @@ -0,0 +1,96 @@ +tests/cases/conformance/enums/spreadEnum3.ts(55,8): error TS1393: Spread enum member can only reference to literal enum reference. +tests/cases/conformance/enums/spreadEnum3.ts(60,8): error TS1393: Spread enum member can only reference to literal enum reference. +tests/cases/conformance/enums/spreadEnum3.ts(65,8): error TS1393: Spread enum member can only reference to literal enum reference. +tests/cases/conformance/enums/spreadEnum3.ts(70,8): error TS1392: Spread enum member cannot reference to const enum without 'preserveConstEnums' flag. +tests/cases/conformance/enums/spreadEnum3.ts(75,8): error TS1396: Spread enum member cannot reference to non-const enum inside const enum declaration without 'preserveConstEnums' flag. + + +==== tests/cases/conformance/enums/spreadEnum3.ts (5 errors) ==== + enum LiteralEnum1 { + A, + B, + C + } + + enum LiteralEnum2 { + A = 1, + B = 2, + C = 3 + } + + enum LiteralEnum3 { + A = 'A' + 'A', + B = 'B' + 'B' + } + + enum NumericEnum1 { + A = 1 + 1, + B = 2 + 1, + C = 3 + 1 + } + + enum NumericEnum2 { + A = LiteralEnum1.A, + B = LiteralEnum2.B + } + + enum NumericEnum3 { + ['A'] = LiteralEnum1.A, + ['B'] = LiteralEnum2.B + } + + const enum ConstEnum { + A = 'A', + B = 'B' + } + + enum R1 { + ...LiteralEnum1, + R1 = 'R1' + } + + enum R2 { + ...LiteralEnum2, + R2 = 'R2' + } + + enum R3 { + ...LiteralEnum3, + R3 = 'R3' + } + + enum R4 { + ...NumericEnum1, + ~~~~~~~~~~~~ +!!! error TS1393: Spread enum member can only reference to literal enum reference. + R4 = 'R4' + } + + enum R5 { + ...NumericEnum2, + ~~~~~~~~~~~~ +!!! error TS1393: Spread enum member can only reference to literal enum reference. + R5 = 'R5' + } + + enum R6 { + ...NumericEnum3, + ~~~~~~~~~~~~ +!!! error TS1393: Spread enum member can only reference to literal enum reference. + R6 = 'R6' + } + + enum R7 { + ...ConstEnum, + ~~~~~~~~~ +!!! error TS1392: Spread enum member cannot reference to const enum without 'preserveConstEnums' flag. + R7 = 'R7' + } + + const enum R8 { + ...LiteralEnum1, + ~~~~~~~~~~~~ +!!! error TS1396: Spread enum member cannot reference to non-const enum inside const enum declaration without 'preserveConstEnums' flag. + R8 = 'R8' + } + \ No newline at end of file diff --git a/tests/baselines/reference/spreadEnum3.js b/tests/baselines/reference/spreadEnum3.js new file mode 100644 index 0000000000000..89b9e731c5cfa --- /dev/null +++ b/tests/baselines/reference/spreadEnum3.js @@ -0,0 +1,226 @@ +//// [spreadEnum3.ts] +enum LiteralEnum1 { + A, + B, + C +} + +enum LiteralEnum2 { + A = 1, + B = 2, + C = 3 +} + +enum LiteralEnum3 { + A = 'A' + 'A', + B = 'B' + 'B' +} + +enum NumericEnum1 { + A = 1 + 1, + B = 2 + 1, + C = 3 + 1 +} + +enum NumericEnum2 { + A = LiteralEnum1.A, + B = LiteralEnum2.B +} + +enum NumericEnum3 { + ['A'] = LiteralEnum1.A, + ['B'] = LiteralEnum2.B +} + +const enum ConstEnum { + A = 'A', + B = 'B' +} + +enum R1 { + ...LiteralEnum1, + R1 = 'R1' +} + +enum R2 { + ...LiteralEnum2, + R2 = 'R2' +} + +enum R3 { + ...LiteralEnum3, + R3 = 'R3' +} + +enum R4 { + ...NumericEnum1, + R4 = 'R4' +} + +enum R5 { + ...NumericEnum2, + R5 = 'R5' +} + +enum R6 { + ...NumericEnum3, + R6 = 'R6' +} + +enum R7 { + ...ConstEnum, + R7 = 'R7' +} + +const enum R8 { + ...LiteralEnum1, + R8 = 'R8' +} + + +//// [spreadEnum3.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var LiteralEnum1; +(function (LiteralEnum1) { + LiteralEnum1[LiteralEnum1["A"] = 0] = "A"; + LiteralEnum1[LiteralEnum1["B"] = 1] = "B"; + LiteralEnum1[LiteralEnum1["C"] = 2] = "C"; +})(LiteralEnum1 || (LiteralEnum1 = {})); +var LiteralEnum2; +(function (LiteralEnum2) { + LiteralEnum2[LiteralEnum2["A"] = 1] = "A"; + LiteralEnum2[LiteralEnum2["B"] = 2] = "B"; + LiteralEnum2[LiteralEnum2["C"] = 3] = "C"; +})(LiteralEnum2 || (LiteralEnum2 = {})); +var LiteralEnum3; +(function (LiteralEnum3) { + LiteralEnum3["A"] = "AA"; + LiteralEnum3["B"] = "BB"; +})(LiteralEnum3 || (LiteralEnum3 = {})); +var NumericEnum1; +(function (NumericEnum1) { + NumericEnum1[NumericEnum1["A"] = 2] = "A"; + NumericEnum1[NumericEnum1["B"] = 3] = "B"; + NumericEnum1[NumericEnum1["C"] = 4] = "C"; +})(NumericEnum1 || (NumericEnum1 = {})); +var NumericEnum2; +(function (NumericEnum2) { + NumericEnum2[NumericEnum2["A"] = 0] = "A"; + NumericEnum2[NumericEnum2["B"] = 2] = "B"; +})(NumericEnum2 || (NumericEnum2 = {})); +var NumericEnum3; +(function (NumericEnum3) { + NumericEnum3[NumericEnum3['A'] = 0] = 'A'; + NumericEnum3[NumericEnum3['B'] = 2] = 'B'; +})(NumericEnum3 || (NumericEnum3 = {})); +var R1; +(function (R1) { + __assign(R1, LiteralEnum1); + R1["R1"] = "R1"; +})(R1 || (R1 = {})); +var R2; +(function (R2) { + __assign(R2, LiteralEnum2); + R2["R2"] = "R2"; +})(R2 || (R2 = {})); +var R3; +(function (R3) { + __assign(R3, LiteralEnum3); + R3["R3"] = "R3"; +})(R3 || (R3 = {})); +var R4; +(function (R4) { + __assign(R4, NumericEnum1); + R4["R4"] = "R4"; +})(R4 || (R4 = {})); +var R5; +(function (R5) { + __assign(R5, NumericEnum2); + R5["R5"] = "R5"; +})(R5 || (R5 = {})); +var R6; +(function (R6) { + __assign(R6, NumericEnum3); + R6["R6"] = "R6"; +})(R6 || (R6 = {})); +var R7; +(function (R7) { + __assign(R7, ConstEnum); + R7["R7"] = "R7"; +})(R7 || (R7 = {})); + + +//// [spreadEnum3.d.ts] +declare enum LiteralEnum1 { + A = 0, + B = 1, + C = 2 +} +declare enum LiteralEnum2 { + A = 1, + B = 2, + C = 3 +} +declare enum LiteralEnum3 { + A = "AA", + B = "BB" +} +declare enum NumericEnum1 { + A = 2, + B = 3, + C = 4 +} +declare enum NumericEnum2 { + A = 0, + B = 2 +} +declare enum NumericEnum3 { + ['A'] = 0, + ['B'] = 2 +} +declare const enum ConstEnum { + A = "A", + B = "B" +} +declare enum R1 { + ...LiteralEnum1, + R1 = "R1" +} +declare enum R2 { + ...LiteralEnum2, + R2 = "R2" +} +declare enum R3 { + ...LiteralEnum3, + R3 = "R3" +} +declare enum R4 { + ...NumericEnum1, + R4 = "R4" +} +declare enum R5 { + ...NumericEnum2, + R5 = "R5" +} +declare enum R6 { + ...NumericEnum3, + R6 = "R6" +} +declare enum R7 { + ...ConstEnum, + R7 = "R7" +} +declare const enum R8 { + ...LiteralEnum1, + R8 = "R8" +} diff --git a/tests/baselines/reference/spreadEnum3.symbols b/tests/baselines/reference/spreadEnum3.symbols new file mode 100644 index 0000000000000..6cf983a82400a --- /dev/null +++ b/tests/baselines/reference/spreadEnum3.symbols @@ -0,0 +1,174 @@ +=== tests/cases/conformance/enums/spreadEnum3.ts === +enum LiteralEnum1 { +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum3.ts, 0, 0)) + + A, +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum3.ts, 0, 19)) + + B, +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum3.ts, 1, 6)) + + C +>C : Symbol(LiteralEnum1.C, Decl(spreadEnum3.ts, 2, 6)) +} + +enum LiteralEnum2 { +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum3.ts, 4, 1)) + + A = 1, +>A : Symbol(LiteralEnum2.A, Decl(spreadEnum3.ts, 6, 19)) + + B = 2, +>B : Symbol(LiteralEnum2.B, Decl(spreadEnum3.ts, 7, 10)) + + C = 3 +>C : Symbol(LiteralEnum2.C, Decl(spreadEnum3.ts, 8, 10)) +} + +enum LiteralEnum3 { +>LiteralEnum3 : Symbol(LiteralEnum3, Decl(spreadEnum3.ts, 10, 1)) + + A = 'A' + 'A', +>A : Symbol(LiteralEnum3.A, Decl(spreadEnum3.ts, 12, 19)) + + B = 'B' + 'B' +>B : Symbol(LiteralEnum3.B, Decl(spreadEnum3.ts, 13, 18)) +} + +enum NumericEnum1 { +>NumericEnum1 : Symbol(NumericEnum1, Decl(spreadEnum3.ts, 15, 1)) + + A = 1 + 1, +>A : Symbol(NumericEnum1.A, Decl(spreadEnum3.ts, 17, 19)) + + B = 2 + 1, +>B : Symbol(NumericEnum1.B, Decl(spreadEnum3.ts, 18, 14)) + + C = 3 + 1 +>C : Symbol(NumericEnum1.C, Decl(spreadEnum3.ts, 19, 14)) +} + +enum NumericEnum2 { +>NumericEnum2 : Symbol(NumericEnum2, Decl(spreadEnum3.ts, 21, 1)) + + A = LiteralEnum1.A, +>A : Symbol(NumericEnum2.A, Decl(spreadEnum3.ts, 23, 19)) +>LiteralEnum1.A : Symbol(LiteralEnum1.A, Decl(spreadEnum3.ts, 0, 19)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum3.ts, 0, 0)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum3.ts, 0, 19)) + + B = LiteralEnum2.B +>B : Symbol(NumericEnum2.B, Decl(spreadEnum3.ts, 24, 23)) +>LiteralEnum2.B : Symbol(LiteralEnum2.B, Decl(spreadEnum3.ts, 7, 10)) +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum3.ts, 4, 1)) +>B : Symbol(LiteralEnum2.B, Decl(spreadEnum3.ts, 7, 10)) +} + +enum NumericEnum3 { +>NumericEnum3 : Symbol(NumericEnum3, Decl(spreadEnum3.ts, 26, 1)) + + ['A'] = LiteralEnum1.A, +>['A'] : Symbol(NumericEnum3['A'], Decl(spreadEnum3.ts, 28, 19)) +>'A' : Symbol(NumericEnum3['A'], Decl(spreadEnum3.ts, 28, 19)) +>LiteralEnum1.A : Symbol(LiteralEnum1.A, Decl(spreadEnum3.ts, 0, 19)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum3.ts, 0, 0)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum3.ts, 0, 19)) + + ['B'] = LiteralEnum2.B +>['B'] : Symbol(NumericEnum3['B'], Decl(spreadEnum3.ts, 29, 27)) +>'B' : Symbol(NumericEnum3['B'], Decl(spreadEnum3.ts, 29, 27)) +>LiteralEnum2.B : Symbol(LiteralEnum2.B, Decl(spreadEnum3.ts, 7, 10)) +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum3.ts, 4, 1)) +>B : Symbol(LiteralEnum2.B, Decl(spreadEnum3.ts, 7, 10)) +} + +const enum ConstEnum { +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum3.ts, 31, 1)) + + A = 'A', +>A : Symbol(ConstEnum.A, Decl(spreadEnum3.ts, 33, 22)) + + B = 'B' +>B : Symbol(ConstEnum.B, Decl(spreadEnum3.ts, 34, 12)) +} + +enum R1 { +>R1 : Symbol(R1, Decl(spreadEnum3.ts, 36, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum3.ts, 0, 0)) + + R1 = 'R1' +>R1 : Symbol(R1.R1, Decl(spreadEnum3.ts, 39, 20)) +} + +enum R2 { +>R2 : Symbol(R2, Decl(spreadEnum3.ts, 41, 1)) + + ...LiteralEnum2, +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum3.ts, 4, 1)) + + R2 = 'R2' +>R2 : Symbol(R2.R2, Decl(spreadEnum3.ts, 44, 20)) +} + +enum R3 { +>R3 : Symbol(R3, Decl(spreadEnum3.ts, 46, 1)) + + ...LiteralEnum3, +>LiteralEnum3 : Symbol(LiteralEnum3, Decl(spreadEnum3.ts, 10, 1)) + + R3 = 'R3' +>R3 : Symbol(R3.R3, Decl(spreadEnum3.ts, 49, 20)) +} + +enum R4 { +>R4 : Symbol(R4, Decl(spreadEnum3.ts, 51, 1)) + + ...NumericEnum1, +>NumericEnum1 : Symbol(NumericEnum1, Decl(spreadEnum3.ts, 15, 1)) + + R4 = 'R4' +>R4 : Symbol(R4.R4, Decl(spreadEnum3.ts, 54, 20)) +} + +enum R5 { +>R5 : Symbol(R5, Decl(spreadEnum3.ts, 56, 1)) + + ...NumericEnum2, +>NumericEnum2 : Symbol(NumericEnum2, Decl(spreadEnum3.ts, 21, 1)) + + R5 = 'R5' +>R5 : Symbol(R5.R5, Decl(spreadEnum3.ts, 59, 20)) +} + +enum R6 { +>R6 : Symbol(R6, Decl(spreadEnum3.ts, 61, 1)) + + ...NumericEnum3, +>NumericEnum3 : Symbol(NumericEnum3, Decl(spreadEnum3.ts, 26, 1)) + + R6 = 'R6' +>R6 : Symbol(R6.R6, Decl(spreadEnum3.ts, 64, 20)) +} + +enum R7 { +>R7 : Symbol(R7, Decl(spreadEnum3.ts, 66, 1)) + + ...ConstEnum, +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum3.ts, 31, 1)) + + R7 = 'R7' +>R7 : Symbol(R7.R7, Decl(spreadEnum3.ts, 69, 17)) +} + +const enum R8 { +>R8 : Symbol(R8, Decl(spreadEnum3.ts, 71, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum3.ts, 0, 0)) + + R8 = 'R8' +>R8 : Symbol(R8.R8, Decl(spreadEnum3.ts, 74, 20)) +} + diff --git a/tests/baselines/reference/spreadEnum3.types b/tests/baselines/reference/spreadEnum3.types new file mode 100644 index 0000000000000..9856c8657a52d --- /dev/null +++ b/tests/baselines/reference/spreadEnum3.types @@ -0,0 +1,202 @@ +=== tests/cases/conformance/enums/spreadEnum3.ts === +enum LiteralEnum1 { +>LiteralEnum1 : LiteralEnum1 + + A, +>A : LiteralEnum1.A + + B, +>B : LiteralEnum1.B + + C +>C : LiteralEnum1.C +} + +enum LiteralEnum2 { +>LiteralEnum2 : LiteralEnum2 + + A = 1, +>A : LiteralEnum2.A +>1 : 1 + + B = 2, +>B : LiteralEnum2.B +>2 : 2 + + C = 3 +>C : LiteralEnum2.C +>3 : 3 +} + +enum LiteralEnum3 { +>LiteralEnum3 : LiteralEnum3 + + A = 'A' + 'A', +>A : LiteralEnum3.A +>'A' + 'A' : string +>'A' : "A" +>'A' : "A" + + B = 'B' + 'B' +>B : LiteralEnum3.B +>'B' + 'B' : string +>'B' : "B" +>'B' : "B" +} + +enum NumericEnum1 { +>NumericEnum1 : NumericEnum1 + + A = 1 + 1, +>A : NumericEnum1 +>1 + 1 : number +>1 : 1 +>1 : 1 + + B = 2 + 1, +>B : NumericEnum1 +>2 + 1 : number +>2 : 2 +>1 : 1 + + C = 3 + 1 +>C : NumericEnum1 +>3 + 1 : number +>3 : 3 +>1 : 1 +} + +enum NumericEnum2 { +>NumericEnum2 : NumericEnum2 + + A = LiteralEnum1.A, +>A : NumericEnum2 +>LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1 : typeof LiteralEnum1 +>A : LiteralEnum1.A + + B = LiteralEnum2.B +>B : NumericEnum2 +>LiteralEnum2.B : LiteralEnum2.B +>LiteralEnum2 : typeof LiteralEnum2 +>B : LiteralEnum2.B +} + +enum NumericEnum3 { +>NumericEnum3 : NumericEnum3 + + ['A'] = LiteralEnum1.A, +>['A'] : NumericEnum3 +>'A' : "A" +>LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1 : typeof LiteralEnum1 +>A : LiteralEnum1.A + + ['B'] = LiteralEnum2.B +>['B'] : NumericEnum3 +>'B' : "B" +>LiteralEnum2.B : LiteralEnum2.B +>LiteralEnum2 : typeof LiteralEnum2 +>B : LiteralEnum2.B +} + +const enum ConstEnum { +>ConstEnum : ConstEnum + + A = 'A', +>A : ConstEnum.A +>'A' : "A" + + B = 'B' +>B : ConstEnum.B +>'B' : "B" +} + +enum R1 { +>R1 : R1 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R1 = 'R1' +>R1 : R1.R1 +>'R1' : "R1" +} + +enum R2 { +>R2 : R2 + + ...LiteralEnum2, +>LiteralEnum2 : typeof LiteralEnum2 + + R2 = 'R2' +>R2 : R2.R2 +>'R2' : "R2" +} + +enum R3 { +>R3 : R3 + + ...LiteralEnum3, +>LiteralEnum3 : typeof LiteralEnum3 + + R3 = 'R3' +>R3 : R3.R3 +>'R3' : "R3" +} + +enum R4 { +>R4 : R4 + + ...NumericEnum1, +>NumericEnum1 : typeof NumericEnum1 + + R4 = 'R4' +>R4 : R4.R4 +>'R4' : "R4" +} + +enum R5 { +>R5 : R5 + + ...NumericEnum2, +>NumericEnum2 : typeof NumericEnum2 + + R5 = 'R5' +>R5 : R5.R5 +>'R5' : "R5" +} + +enum R6 { +>R6 : R6 + + ...NumericEnum3, +>NumericEnum3 : typeof NumericEnum3 + + R6 = 'R6' +>R6 : R6.R6 +>'R6' : "R6" +} + +enum R7 { +>R7 : R7 + + ...ConstEnum, +>ConstEnum : typeof ConstEnum + + R7 = 'R7' +>R7 : R7.R7 +>'R7' : "R7" +} + +const enum R8 { +>R8 : R8 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R8 = 'R8' +>R8 : R8.R8 +>'R8' : "R8" +} + diff --git a/tests/baselines/reference/spreadEnum4.js b/tests/baselines/reference/spreadEnum4.js new file mode 100644 index 0000000000000..1a27972441208 --- /dev/null +++ b/tests/baselines/reference/spreadEnum4.js @@ -0,0 +1,76 @@ +//// [spreadEnum4.ts] +enum LiteralEnum1 { + A, + B, + C +} + +const enum ConstEnum { + A = 'A', + B = 'B' +} + +enum R1 { + ...ConstEnum, + R1 = 'R1' +} + +const enum R2 { + ...LiteralEnum1, + R2 = 'R2' +} + + +//// [spreadEnum4.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var LiteralEnum1; +(function (LiteralEnum1) { + LiteralEnum1[LiteralEnum1["A"] = 0] = "A"; + LiteralEnum1[LiteralEnum1["B"] = 1] = "B"; + LiteralEnum1[LiteralEnum1["C"] = 2] = "C"; +})(LiteralEnum1 || (LiteralEnum1 = {})); +var ConstEnum; +(function (ConstEnum) { + ConstEnum["A"] = "A"; + ConstEnum["B"] = "B"; +})(ConstEnum || (ConstEnum = {})); +var R1; +(function (R1) { + __assign(R1, ConstEnum); + R1["R1"] = "R1"; +})(R1 || (R1 = {})); +var R2; +(function (R2) { + __assign(R2, LiteralEnum1); + R2["R2"] = "R2"; +})(R2 || (R2 = {})); + + +//// [spreadEnum4.d.ts] +declare enum LiteralEnum1 { + A = 0, + B = 1, + C = 2 +} +declare const enum ConstEnum { + A = "A", + B = "B" +} +declare enum R1 { + ...ConstEnum, + R1 = "R1" +} +declare const enum R2 { + ...LiteralEnum1, + R2 = "R2" +} diff --git a/tests/baselines/reference/spreadEnum4.symbols b/tests/baselines/reference/spreadEnum4.symbols new file mode 100644 index 0000000000000..d25beef4a1d45 --- /dev/null +++ b/tests/baselines/reference/spreadEnum4.symbols @@ -0,0 +1,44 @@ +=== tests/cases/conformance/enums/spreadEnum4.ts === +enum LiteralEnum1 { +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum4.ts, 0, 0)) + + A, +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum4.ts, 0, 19)) + + B, +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum4.ts, 1, 6)) + + C +>C : Symbol(LiteralEnum1.C, Decl(spreadEnum4.ts, 2, 6)) +} + +const enum ConstEnum { +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum4.ts, 4, 1)) + + A = 'A', +>A : Symbol(ConstEnum.A, Decl(spreadEnum4.ts, 6, 22)) + + B = 'B' +>B : Symbol(ConstEnum.B, Decl(spreadEnum4.ts, 7, 12)) +} + +enum R1 { +>R1 : Symbol(R1, Decl(spreadEnum4.ts, 9, 1)) + + ...ConstEnum, +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum4.ts, 4, 1)) + + R1 = 'R1' +>R1 : Symbol(R1.R1, Decl(spreadEnum4.ts, 12, 17)) +} + +const enum R2 { +>R2 : Symbol(R2, Decl(spreadEnum4.ts, 14, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum4.ts, 0, 0)) + + R2 = 'R2' +>R2 : Symbol(R2.R2, Decl(spreadEnum4.ts, 17, 20)) +} + diff --git a/tests/baselines/reference/spreadEnum4.types b/tests/baselines/reference/spreadEnum4.types new file mode 100644 index 0000000000000..3651c110ff802 --- /dev/null +++ b/tests/baselines/reference/spreadEnum4.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/enums/spreadEnum4.ts === +enum LiteralEnum1 { +>LiteralEnum1 : LiteralEnum1 + + A, +>A : LiteralEnum1.A + + B, +>B : LiteralEnum1.B + + C +>C : LiteralEnum1.C +} + +const enum ConstEnum { +>ConstEnum : ConstEnum + + A = 'A', +>A : ConstEnum.A +>'A' : "A" + + B = 'B' +>B : ConstEnum.B +>'B' : "B" +} + +enum R1 { +>R1 : R1 + + ...ConstEnum, +>ConstEnum : typeof ConstEnum + + R1 = 'R1' +>R1 : R1.R1 +>'R1' : "R1" +} + +const enum R2 { +>R2 : R2 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R2 = 'R2' +>R2 : R2.R2 +>'R2' : "R2" +} + diff --git a/tests/baselines/reference/spreadEnum5.errors.txt b/tests/baselines/reference/spreadEnum5.errors.txt new file mode 100644 index 0000000000000..e81358720c4cf --- /dev/null +++ b/tests/baselines/reference/spreadEnum5.errors.txt @@ -0,0 +1,48 @@ +tests/cases/conformance/enums/spreadEnum5.ts(12,8): error TS1392: Spread enum member cannot reference to const enum without 'preserveConstEnums' flag. +tests/cases/conformance/enums/spreadEnum5.ts(17,8): error TS1396: Spread enum member cannot reference to non-const enum inside const enum declaration without 'preserveConstEnums' flag. + + +==== tests/cases/conformance/enums/spreadEnum5.ts (2 errors) ==== + enum LiteralEnum1 { + A, + B + } + + const enum ConstEnum { + A = 'A', + B = 'B' + } + + enum R1 { + ...ConstEnum, + ~~~~~~~~~ +!!! error TS1392: Spread enum member cannot reference to const enum without 'preserveConstEnums' flag. + R1 = 'R1' + } + + const enum R2 { + ...LiteralEnum1, + ~~~~~~~~~~~~ +!!! error TS1396: Spread enum member cannot reference to non-const enum inside const enum declaration without 'preserveConstEnums' flag. + R2 = 'R2' + } + + const enum R3 { + ...ConstEnum, + R3 = 'R3' + } + + LiteralEnum1.A; + LiteralEnum1.B; + ConstEnum.A; + ConstEnum.B; + R1.A; + R1.B; + R1.R1; + R2.A; + R2.B; + R2.R2; + R3.A; + R3.B; + R3.R3; + \ No newline at end of file diff --git a/tests/baselines/reference/spreadEnum5.js b/tests/baselines/reference/spreadEnum5.js new file mode 100644 index 0000000000000..cad5afbcc534e --- /dev/null +++ b/tests/baselines/reference/spreadEnum5.js @@ -0,0 +1,99 @@ +//// [spreadEnum5.ts] +enum LiteralEnum1 { + A, + B +} + +const enum ConstEnum { + A = 'A', + B = 'B' +} + +enum R1 { + ...ConstEnum, + R1 = 'R1' +} + +const enum R2 { + ...LiteralEnum1, + R2 = 'R2' +} + +const enum R3 { + ...ConstEnum, + R3 = 'R3' +} + +LiteralEnum1.A; +LiteralEnum1.B; +ConstEnum.A; +ConstEnum.B; +R1.A; +R1.B; +R1.R1; +R2.A; +R2.B; +R2.R2; +R3.A; +R3.B; +R3.R3; + + +//// [spreadEnum5.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var LiteralEnum1; +(function (LiteralEnum1) { + LiteralEnum1[LiteralEnum1["A"] = 0] = "A"; + LiteralEnum1[LiteralEnum1["B"] = 1] = "B"; +})(LiteralEnum1 || (LiteralEnum1 = {})); +var R1; +(function (R1) { + __assign(R1, ConstEnum); + R1["R1"] = "R1"; +})(R1 || (R1 = {})); +LiteralEnum1.A; +LiteralEnum1.B; +"A" /* A */; +"B" /* B */; +"A" /* A */; +"B" /* B */; +R1.R1; +R2.A; +R2.B; +"R2" /* R2 */; +"A" /* A */; +"B" /* B */; +"R3" /* R3 */; + + +//// [spreadEnum5.d.ts] +declare enum LiteralEnum1 { + A = 0, + B = 1 +} +declare const enum ConstEnum { + A = "A", + B = "B" +} +declare enum R1 { + ...ConstEnum, + R1 = "R1" +} +declare const enum R2 { + ...LiteralEnum1, + R2 = "R2" +} +declare const enum R3 { + ...ConstEnum, + R3 = "R3" +} diff --git a/tests/baselines/reference/spreadEnum5.symbols b/tests/baselines/reference/spreadEnum5.symbols new file mode 100644 index 0000000000000..8e56ffe514f6e --- /dev/null +++ b/tests/baselines/reference/spreadEnum5.symbols @@ -0,0 +1,116 @@ +=== tests/cases/conformance/enums/spreadEnum5.ts === +enum LiteralEnum1 { +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum5.ts, 0, 0)) + + A, +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum5.ts, 0, 19)) + + B +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum5.ts, 1, 6)) +} + +const enum ConstEnum { +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum5.ts, 3, 1)) + + A = 'A', +>A : Symbol(ConstEnum.A, Decl(spreadEnum5.ts, 5, 22)) + + B = 'B' +>B : Symbol(ConstEnum.B, Decl(spreadEnum5.ts, 6, 12)) +} + +enum R1 { +>R1 : Symbol(R1, Decl(spreadEnum5.ts, 8, 1)) + + ...ConstEnum, +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum5.ts, 3, 1)) + + R1 = 'R1' +>R1 : Symbol(R1.R1, Decl(spreadEnum5.ts, 11, 17)) +} + +const enum R2 { +>R2 : Symbol(R2, Decl(spreadEnum5.ts, 13, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum5.ts, 0, 0)) + + R2 = 'R2' +>R2 : Symbol(R2.R2, Decl(spreadEnum5.ts, 16, 20)) +} + +const enum R3 { +>R3 : Symbol(R3, Decl(spreadEnum5.ts, 18, 1)) + + ...ConstEnum, +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum5.ts, 3, 1)) + + R3 = 'R3' +>R3 : Symbol(R3.R3, Decl(spreadEnum5.ts, 21, 17)) +} + +LiteralEnum1.A; +>LiteralEnum1.A : Symbol(LiteralEnum1.A, Decl(spreadEnum5.ts, 0, 19)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum5.ts, 0, 0)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum5.ts, 0, 19)) + +LiteralEnum1.B; +>LiteralEnum1.B : Symbol(LiteralEnum1.B, Decl(spreadEnum5.ts, 1, 6)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum5.ts, 0, 0)) +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum5.ts, 1, 6)) + +ConstEnum.A; +>ConstEnum.A : Symbol(ConstEnum.A, Decl(spreadEnum5.ts, 5, 22)) +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum5.ts, 3, 1)) +>A : Symbol(ConstEnum.A, Decl(spreadEnum5.ts, 5, 22)) + +ConstEnum.B; +>ConstEnum.B : Symbol(ConstEnum.B, Decl(spreadEnum5.ts, 6, 12)) +>ConstEnum : Symbol(ConstEnum, Decl(spreadEnum5.ts, 3, 1)) +>B : Symbol(ConstEnum.B, Decl(spreadEnum5.ts, 6, 12)) + +R1.A; +>R1.A : Symbol(ConstEnum.A, Decl(spreadEnum5.ts, 5, 22)) +>R1 : Symbol(R1, Decl(spreadEnum5.ts, 8, 1)) +>A : Symbol(ConstEnum.A, Decl(spreadEnum5.ts, 5, 22)) + +R1.B; +>R1.B : Symbol(ConstEnum.B, Decl(spreadEnum5.ts, 6, 12)) +>R1 : Symbol(R1, Decl(spreadEnum5.ts, 8, 1)) +>B : Symbol(ConstEnum.B, Decl(spreadEnum5.ts, 6, 12)) + +R1.R1; +>R1.R1 : Symbol(R1.R1, Decl(spreadEnum5.ts, 11, 17)) +>R1 : Symbol(R1, Decl(spreadEnum5.ts, 8, 1)) +>R1 : Symbol(R1.R1, Decl(spreadEnum5.ts, 11, 17)) + +R2.A; +>R2.A : Symbol(LiteralEnum1.A, Decl(spreadEnum5.ts, 0, 19)) +>R2 : Symbol(R2, Decl(spreadEnum5.ts, 13, 1)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum5.ts, 0, 19)) + +R2.B; +>R2.B : Symbol(LiteralEnum1.B, Decl(spreadEnum5.ts, 1, 6)) +>R2 : Symbol(R2, Decl(spreadEnum5.ts, 13, 1)) +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum5.ts, 1, 6)) + +R2.R2; +>R2.R2 : Symbol(R2.R2, Decl(spreadEnum5.ts, 16, 20)) +>R2 : Symbol(R2, Decl(spreadEnum5.ts, 13, 1)) +>R2 : Symbol(R2.R2, Decl(spreadEnum5.ts, 16, 20)) + +R3.A; +>R3.A : Symbol(ConstEnum.A, Decl(spreadEnum5.ts, 5, 22)) +>R3 : Symbol(R3, Decl(spreadEnum5.ts, 18, 1)) +>A : Symbol(ConstEnum.A, Decl(spreadEnum5.ts, 5, 22)) + +R3.B; +>R3.B : Symbol(ConstEnum.B, Decl(spreadEnum5.ts, 6, 12)) +>R3 : Symbol(R3, Decl(spreadEnum5.ts, 18, 1)) +>B : Symbol(ConstEnum.B, Decl(spreadEnum5.ts, 6, 12)) + +R3.R3; +>R3.R3 : Symbol(R3.R3, Decl(spreadEnum5.ts, 21, 17)) +>R3 : Symbol(R3, Decl(spreadEnum5.ts, 18, 1)) +>R3 : Symbol(R3.R3, Decl(spreadEnum5.ts, 21, 17)) + diff --git a/tests/baselines/reference/spreadEnum5.types b/tests/baselines/reference/spreadEnum5.types new file mode 100644 index 0000000000000..5db60b5b2d8c5 --- /dev/null +++ b/tests/baselines/reference/spreadEnum5.types @@ -0,0 +1,121 @@ +=== tests/cases/conformance/enums/spreadEnum5.ts === +enum LiteralEnum1 { +>LiteralEnum1 : LiteralEnum1 + + A, +>A : LiteralEnum1.A + + B +>B : LiteralEnum1.B +} + +const enum ConstEnum { +>ConstEnum : ConstEnum + + A = 'A', +>A : ConstEnum.A +>'A' : "A" + + B = 'B' +>B : ConstEnum.B +>'B' : "B" +} + +enum R1 { +>R1 : R1 + + ...ConstEnum, +>ConstEnum : typeof ConstEnum + + R1 = 'R1' +>R1 : R1.R1 +>'R1' : "R1" +} + +const enum R2 { +>R2 : R2 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R2 = 'R2' +>R2 : R2.R2 +>'R2' : "R2" +} + +const enum R3 { +>R3 : R3 + + ...ConstEnum, +>ConstEnum : typeof ConstEnum + + R3 = 'R3' +>R3 : R3.R3 +>'R3' : "R3" +} + +LiteralEnum1.A; +>LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1 : typeof LiteralEnum1 +>A : LiteralEnum1.A + +LiteralEnum1.B; +>LiteralEnum1.B : LiteralEnum1.B +>LiteralEnum1 : typeof LiteralEnum1 +>B : LiteralEnum1.B + +ConstEnum.A; +>ConstEnum.A : ConstEnum.A +>ConstEnum : typeof ConstEnum +>A : ConstEnum.A + +ConstEnum.B; +>ConstEnum.B : ConstEnum.B +>ConstEnum : typeof ConstEnum +>B : ConstEnum.B + +R1.A; +>R1.A : ConstEnum.A +>R1 : typeof R1 +>A : ConstEnum.A + +R1.B; +>R1.B : ConstEnum.B +>R1 : typeof R1 +>B : ConstEnum.B + +R1.R1; +>R1.R1 : R1.R1 +>R1 : typeof R1 +>R1 : R1.R1 + +R2.A; +>R2.A : LiteralEnum1.A +>R2 : typeof R2 +>A : LiteralEnum1.A + +R2.B; +>R2.B : LiteralEnum1.B +>R2 : typeof R2 +>B : LiteralEnum1.B + +R2.R2; +>R2.R2 : R2.R2 +>R2 : typeof R2 +>R2 : R2.R2 + +R3.A; +>R3.A : ConstEnum +>R3 : typeof R3 +>A : ConstEnum + +R3.B; +>R3.B : ConstEnum +>R3 : typeof R3 +>B : ConstEnum + +R3.R3; +>R3.R3 : R3.R3 +>R3 : typeof R3 +>R3 : R3.R3 + diff --git a/tests/cases/conformance/enums/spreadEnum3.ts b/tests/cases/conformance/enums/spreadEnum3.ts new file mode 100644 index 0000000000000..6f5f3b972292f --- /dev/null +++ b/tests/cases/conformance/enums/spreadEnum3.ts @@ -0,0 +1,79 @@ +// @declaration: true + +enum LiteralEnum1 { + A, + B, + C +} + +enum LiteralEnum2 { + A = 1, + B = 2, + C = 3 +} + +enum LiteralEnum3 { + A = 'A' + 'A', + B = 'B' + 'B' +} + +enum NumericEnum1 { + A = 1 + 1, + B = 2 + 1, + C = 3 + 1 +} + +enum NumericEnum2 { + A = LiteralEnum1.A, + B = LiteralEnum2.B +} + +enum NumericEnum3 { + ['A'] = LiteralEnum1.A, + ['B'] = LiteralEnum2.B +} + +const enum ConstEnum { + A = 'A', + B = 'B' +} + +enum R1 { + ...LiteralEnum1, + R1 = 'R1' +} + +enum R2 { + ...LiteralEnum2, + R2 = 'R2' +} + +enum R3 { + ...LiteralEnum3, + R3 = 'R3' +} + +enum R4 { + ...NumericEnum1, + R4 = 'R4' +} + +enum R5 { + ...NumericEnum2, + R5 = 'R5' +} + +enum R6 { + ...NumericEnum3, + R6 = 'R6' +} + +enum R7 { + ...ConstEnum, + R7 = 'R7' +} + +const enum R8 { + ...LiteralEnum1, + R8 = 'R8' +} diff --git a/tests/cases/conformance/enums/spreadEnum4.ts b/tests/cases/conformance/enums/spreadEnum4.ts new file mode 100644 index 0000000000000..8af0776cd7619 --- /dev/null +++ b/tests/cases/conformance/enums/spreadEnum4.ts @@ -0,0 +1,23 @@ +// @declaration: true +// @preserveConstEnums: true + +enum LiteralEnum1 { + A, + B, + C +} + +const enum ConstEnum { + A = 'A', + B = 'B' +} + +enum R1 { + ...ConstEnum, + R1 = 'R1' +} + +const enum R2 { + ...LiteralEnum1, + R2 = 'R2' +} diff --git a/tests/cases/conformance/enums/spreadEnum5.ts b/tests/cases/conformance/enums/spreadEnum5.ts new file mode 100644 index 0000000000000..baae02f2aa84e --- /dev/null +++ b/tests/cases/conformance/enums/spreadEnum5.ts @@ -0,0 +1,40 @@ +// @declaration: true + +enum LiteralEnum1 { + A, + B +} + +const enum ConstEnum { + A = 'A', + B = 'B' +} + +enum R1 { + ...ConstEnum, + R1 = 'R1' +} + +const enum R2 { + ...LiteralEnum1, + R2 = 'R2' +} + +const enum R3 { + ...ConstEnum, + R3 = 'R3' +} + +LiteralEnum1.A; +LiteralEnum1.B; +ConstEnum.A; +ConstEnum.B; +R1.A; +R1.B; +R1.R1; +R2.A; +R2.B; +R2.R2; +R3.A; +R3.B; +R3.R3; From 668cb6f7a3714275ab82f08b9fd44ce240ff095a Mon Sep 17 00:00:00 2001 From: kingwl Date: Mon, 12 Oct 2020 01:23:11 +0800 Subject: [PATCH 16/21] Add more cases --- .../reference/spreadEnum6.errors.txt | 100 +++++++ tests/baselines/reference/spreadEnum6.js | 216 +++++++++++++ tests/baselines/reference/spreadEnum6.symbols | 276 +++++++++++++++++ tests/baselines/reference/spreadEnum6.types | 283 ++++++++++++++++++ .../reference/spreadEnum7.errors.txt | 67 +++++ tests/baselines/reference/spreadEnum7.js | 173 +++++++++++ tests/baselines/reference/spreadEnum7.symbols | 114 +++++++ tests/baselines/reference/spreadEnum7.types | 125 ++++++++ tests/cases/conformance/enums/spreadEnum6.ts | 86 ++++++ tests/cases/conformance/enums/spreadEnum7.ts | 57 ++++ 10 files changed, 1497 insertions(+) create mode 100644 tests/baselines/reference/spreadEnum6.errors.txt create mode 100644 tests/baselines/reference/spreadEnum6.js create mode 100644 tests/baselines/reference/spreadEnum6.symbols create mode 100644 tests/baselines/reference/spreadEnum6.types create mode 100644 tests/baselines/reference/spreadEnum7.errors.txt create mode 100644 tests/baselines/reference/spreadEnum7.js create mode 100644 tests/baselines/reference/spreadEnum7.symbols create mode 100644 tests/baselines/reference/spreadEnum7.types create mode 100644 tests/cases/conformance/enums/spreadEnum6.ts create mode 100644 tests/cases/conformance/enums/spreadEnum7.ts diff --git a/tests/baselines/reference/spreadEnum6.errors.txt b/tests/baselines/reference/spreadEnum6.errors.txt new file mode 100644 index 0000000000000..9c6f00eedfacc --- /dev/null +++ b/tests/baselines/reference/spreadEnum6.errors.txt @@ -0,0 +1,100 @@ +tests/cases/conformance/enums/spreadEnum6.ts(2,5): error TS1109: Expression expected. +tests/cases/conformance/enums/spreadEnum6.ts(3,5): error TS1109: Expression expected. +tests/cases/conformance/enums/spreadEnum6.ts(7,5): error TS1109: Expression expected. +tests/cases/conformance/enums/spreadEnum6.ts(8,5): error TS1109: Expression expected. + + +==== tests/cases/conformance/enums/spreadEnum6.ts (4 errors) ==== + enum LiteralEnum1 { + A = 0, + ~ +!!! error TS1109: Expression expected. + B + ~ +!!! error TS1109: Expression expected. + } + + enum LiteralEnum1 { + C, + ~ +!!! error TS1109: Expression expected. + D + ~ +!!! error TS1109: Expression expected. + } + + enum LiteralEnum2 { + E = 0, + F + } + + enum LiteralEnum2 { + G, + H + } + + enum R1 { + ...LiteralEnum1, + R1 = 'R1' + } + + enum R1 { + R11 = 'R11' + } + + enum R2 { + ...LiteralEnum1, + R2 = 'R2' + } + + enum R2 { + ...LiteralEnum2, + R22 = 'R22' + } + + enum R3 { + ...R1, + ...R2, + R3 = 'R3' + } + + LiteralEnum1.A; + LiteralEnum1.B; + LiteralEnum1.C; + LiteralEnum1.D; + R1.A; + R1.B; + R1.C; + R1.D; + R1.R1; + R1.R11; + + LiteralEnum2.E; + LiteralEnum2.F; + LiteralEnum2.G; + LiteralEnum2.H; + R2.A; + R2.B; + R2.C; + R2.D; + R2.E; + R2.F; + R2.G; + R2.H; + R2.R2; + R2.R22 + + R3.A; + R3.B; + R3.C; + R3.D; + R3.E; + R3.F; + R3.G; + R3.H; + R3.R1; + R3.R11; + R3.R2; + R3.R22; + R3.R3; + \ No newline at end of file diff --git a/tests/baselines/reference/spreadEnum6.js b/tests/baselines/reference/spreadEnum6.js new file mode 100644 index 0000000000000..ec411b920386a --- /dev/null +++ b/tests/baselines/reference/spreadEnum6.js @@ -0,0 +1,216 @@ +//// [spreadEnum6.ts] +enum LiteralEnum1 { + A = 0, + B +} + +enum LiteralEnum1 { + C, + D +} + +enum LiteralEnum2 { + E = 0, + F +} + +enum LiteralEnum2 { + G, + H +} + +enum R1 { + ...LiteralEnum1, + R1 = 'R1' +} + +enum R1 { + R11 = 'R11' +} + +enum R2 { + ...LiteralEnum1, + R2 = 'R2' +} + +enum R2 { + ...LiteralEnum2, + R22 = 'R22' +} + +enum R3 { + ...R1, + ...R2, + R3 = 'R3' +} + +LiteralEnum1.A; +LiteralEnum1.B; +LiteralEnum1.C; +LiteralEnum1.D; +R1.A; +R1.B; +R1.C; +R1.D; +R1.R1; +R1.R11; + +LiteralEnum2.E; +LiteralEnum2.F; +LiteralEnum2.G; +LiteralEnum2.H; +R2.A; +R2.B; +R2.C; +R2.D; +R2.E; +R2.F; +R2.G; +R2.H; +R2.R2; +R2.R22 + +R3.A; +R3.B; +R3.C; +R3.D; +R3.E; +R3.F; +R3.G; +R3.H; +R3.R1; +R3.R11; +R3.R2; +R3.R22; +R3.R3; + + +//// [spreadEnum6.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var LiteralEnum1; +(function (LiteralEnum1) { + LiteralEnum1[LiteralEnum1["A"] = 0] = "A"; + LiteralEnum1[LiteralEnum1["B"] = 1] = "B"; +})(LiteralEnum1 || (LiteralEnum1 = {})); +(function (LiteralEnum1) { + LiteralEnum1[LiteralEnum1["C"] = 0] = "C"; + LiteralEnum1[LiteralEnum1["D"] = 1] = "D"; +})(LiteralEnum1 || (LiteralEnum1 = {})); +var LiteralEnum2; +(function (LiteralEnum2) { + LiteralEnum2[LiteralEnum2["E"] = 0] = "E"; + LiteralEnum2[LiteralEnum2["F"] = 1] = "F"; +})(LiteralEnum2 || (LiteralEnum2 = {})); +(function (LiteralEnum2) { + LiteralEnum2[LiteralEnum2["G"] = 0] = "G"; + LiteralEnum2[LiteralEnum2["H"] = 1] = "H"; +})(LiteralEnum2 || (LiteralEnum2 = {})); +var R1; +(function (R1) { + __assign(R1, LiteralEnum1); + R1["R1"] = "R1"; +})(R1 || (R1 = {})); +(function (R1) { + R1["R11"] = "R11"; +})(R1 || (R1 = {})); +var R2; +(function (R2) { + __assign(R2, LiteralEnum1); + R2["R2"] = "R2"; +})(R2 || (R2 = {})); +(function (R2) { + __assign(R2, LiteralEnum2); + R2["R22"] = "R22"; +})(R2 || (R2 = {})); +var R3; +(function (R3) { + __assign(R3, R1); + __assign(R3, R2); + R3["R3"] = "R3"; +})(R3 || (R3 = {})); +LiteralEnum1.A; +LiteralEnum1.B; +LiteralEnum1.C; +LiteralEnum1.D; +R1.A; +R1.B; +R1.C; +R1.D; +R1.R1; +R1.R11; +LiteralEnum2.E; +LiteralEnum2.F; +LiteralEnum2.G; +LiteralEnum2.H; +R2.A; +R2.B; +R2.C; +R2.D; +R2.E; +R2.F; +R2.G; +R2.H; +R2.R2; +R2.R22; +R3.A; +R3.B; +R3.C; +R3.D; +R3.E; +R3.F; +R3.G; +R3.H; +R3.R1; +R3.R11; +R3.R2; +R3.R22; +R3.R3; + + +//// [spreadEnum6.d.ts] +declare enum LiteralEnum1 { + A = 0, + B = 1 +} +declare enum LiteralEnum1 { + C = 0, + D = 1 +} +declare enum LiteralEnum2 { + E = 0, + F = 1 +} +declare enum LiteralEnum2 { + G = 0, + H = 1 +} +declare enum R1 { + ...LiteralEnum1, + R1 = "R1" +} +declare enum R1 { + R11 = "R11" +} +declare enum R2 { + ...LiteralEnum1, + R2 = "R2" +} +declare enum R2 { + ...LiteralEnum2, + R22 = "R22" +} +declare enum R3 { + ...R1, + ...R2, + R3 = "R3" +} diff --git a/tests/baselines/reference/spreadEnum6.symbols b/tests/baselines/reference/spreadEnum6.symbols new file mode 100644 index 0000000000000..e1ab0221bb279 --- /dev/null +++ b/tests/baselines/reference/spreadEnum6.symbols @@ -0,0 +1,276 @@ +=== tests/cases/conformance/enums/spreadEnum6.ts === +enum LiteralEnum1 { +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) + + A = 0, +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) + + B +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) +} + +enum LiteralEnum1 { +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) + + C, +>C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) + + D +>D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) +} + +enum LiteralEnum2 { +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum6.ts, 8, 1), Decl(spreadEnum6.ts, 13, 1)) + + E = 0, +>E : Symbol(LiteralEnum2.E, Decl(spreadEnum6.ts, 10, 19)) + + F +>F : Symbol(LiteralEnum2.F, Decl(spreadEnum6.ts, 11, 10)) +} + +enum LiteralEnum2 { +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum6.ts, 8, 1), Decl(spreadEnum6.ts, 13, 1)) + + G, +>G : Symbol(LiteralEnum2.G, Decl(spreadEnum6.ts, 15, 19)) + + H +>H : Symbol(LiteralEnum2.H, Decl(spreadEnum6.ts, 16, 6)) +} + +enum R1 { +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) + + R1 = 'R1' +>R1 : Symbol(R1.R1, Decl(spreadEnum6.ts, 21, 20)) +} + +enum R1 { +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) + + R11 = 'R11' +>R11 : Symbol(R1.R11, Decl(spreadEnum6.ts, 25, 9)) +} + +enum R2 { +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) + + R2 = 'R2' +>R2 : Symbol(R2.R2, Decl(spreadEnum6.ts, 30, 20)) +} + +enum R2 { +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) + + ...LiteralEnum2, +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum6.ts, 8, 1), Decl(spreadEnum6.ts, 13, 1)) + + R22 = 'R22' +>R22 : Symbol(R2.R22, Decl(spreadEnum6.ts, 35, 20)) +} + +enum R3 { +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) + + ...R1, +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) + + ...R2, +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) + + R3 = 'R3' +>R3 : Symbol(R3.R3, Decl(spreadEnum6.ts, 41, 10)) +} + +LiteralEnum1.A; +>LiteralEnum1.A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) + +LiteralEnum1.B; +>LiteralEnum1.B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) + +LiteralEnum1.C; +>LiteralEnum1.C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) +>C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) + +LiteralEnum1.D; +>LiteralEnum1.D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum6.ts, 0, 0), Decl(spreadEnum6.ts, 3, 1)) +>D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) + +R1.A; +>R1.A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) + +R1.B; +>R1.B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) + +R1.C; +>R1.C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) +>C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) + +R1.D; +>R1.D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) +>D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) + +R1.R1; +>R1.R1 : Symbol(R1.R1, Decl(spreadEnum6.ts, 21, 20)) +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) +>R1 : Symbol(R1.R1, Decl(spreadEnum6.ts, 21, 20)) + +R1.R11; +>R1.R11 : Symbol(R1.R11, Decl(spreadEnum6.ts, 25, 9)) +>R1 : Symbol(R1, Decl(spreadEnum6.ts, 18, 1), Decl(spreadEnum6.ts, 23, 1)) +>R11 : Symbol(R1.R11, Decl(spreadEnum6.ts, 25, 9)) + +LiteralEnum2.E; +>LiteralEnum2.E : Symbol(LiteralEnum2.E, Decl(spreadEnum6.ts, 10, 19)) +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum6.ts, 8, 1), Decl(spreadEnum6.ts, 13, 1)) +>E : Symbol(LiteralEnum2.E, Decl(spreadEnum6.ts, 10, 19)) + +LiteralEnum2.F; +>LiteralEnum2.F : Symbol(LiteralEnum2.F, Decl(spreadEnum6.ts, 11, 10)) +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum6.ts, 8, 1), Decl(spreadEnum6.ts, 13, 1)) +>F : Symbol(LiteralEnum2.F, Decl(spreadEnum6.ts, 11, 10)) + +LiteralEnum2.G; +>LiteralEnum2.G : Symbol(LiteralEnum2.G, Decl(spreadEnum6.ts, 15, 19)) +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum6.ts, 8, 1), Decl(spreadEnum6.ts, 13, 1)) +>G : Symbol(LiteralEnum2.G, Decl(spreadEnum6.ts, 15, 19)) + +LiteralEnum2.H; +>LiteralEnum2.H : Symbol(LiteralEnum2.H, Decl(spreadEnum6.ts, 16, 6)) +>LiteralEnum2 : Symbol(LiteralEnum2, Decl(spreadEnum6.ts, 8, 1), Decl(spreadEnum6.ts, 13, 1)) +>H : Symbol(LiteralEnum2.H, Decl(spreadEnum6.ts, 16, 6)) + +R2.A; +>R2.A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) + +R2.B; +>R2.B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) + +R2.C; +>R2.C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) + +R2.D; +>R2.D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) + +R2.E; +>R2.E : Symbol(LiteralEnum2.E, Decl(spreadEnum6.ts, 10, 19)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>E : Symbol(LiteralEnum2.E, Decl(spreadEnum6.ts, 10, 19)) + +R2.F; +>R2.F : Symbol(LiteralEnum2.F, Decl(spreadEnum6.ts, 11, 10)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>F : Symbol(LiteralEnum2.F, Decl(spreadEnum6.ts, 11, 10)) + +R2.G; +>R2.G : Symbol(LiteralEnum2.G, Decl(spreadEnum6.ts, 15, 19)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>G : Symbol(LiteralEnum2.G, Decl(spreadEnum6.ts, 15, 19)) + +R2.H; +>R2.H : Symbol(LiteralEnum2.H, Decl(spreadEnum6.ts, 16, 6)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>H : Symbol(LiteralEnum2.H, Decl(spreadEnum6.ts, 16, 6)) + +R2.R2; +>R2.R2 : Symbol(R2.R2, Decl(spreadEnum6.ts, 30, 20)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>R2 : Symbol(R2.R2, Decl(spreadEnum6.ts, 30, 20)) + +R2.R22 +>R2.R22 : Symbol(R2.R22, Decl(spreadEnum6.ts, 35, 20)) +>R2 : Symbol(R2, Decl(spreadEnum6.ts, 27, 1), Decl(spreadEnum6.ts, 32, 1)) +>R22 : Symbol(R2.R22, Decl(spreadEnum6.ts, 35, 20)) + +R3.A; +>R3.A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum6.ts, 0, 19)) + +R3.B; +>R3.B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum6.ts, 1, 10)) + +R3.C; +>R3.C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>C : Symbol(LiteralEnum1.C, Decl(spreadEnum6.ts, 5, 19)) + +R3.D; +>R3.D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>D : Symbol(LiteralEnum1.D, Decl(spreadEnum6.ts, 6, 6)) + +R3.E; +>R3.E : Symbol(LiteralEnum2.E, Decl(spreadEnum6.ts, 10, 19)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>E : Symbol(LiteralEnum2.E, Decl(spreadEnum6.ts, 10, 19)) + +R3.F; +>R3.F : Symbol(LiteralEnum2.F, Decl(spreadEnum6.ts, 11, 10)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>F : Symbol(LiteralEnum2.F, Decl(spreadEnum6.ts, 11, 10)) + +R3.G; +>R3.G : Symbol(LiteralEnum2.G, Decl(spreadEnum6.ts, 15, 19)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>G : Symbol(LiteralEnum2.G, Decl(spreadEnum6.ts, 15, 19)) + +R3.H; +>R3.H : Symbol(LiteralEnum2.H, Decl(spreadEnum6.ts, 16, 6)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>H : Symbol(LiteralEnum2.H, Decl(spreadEnum6.ts, 16, 6)) + +R3.R1; +>R3.R1 : Symbol(R1.R1, Decl(spreadEnum6.ts, 21, 20)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>R1 : Symbol(R1.R1, Decl(spreadEnum6.ts, 21, 20)) + +R3.R11; +>R3.R11 : Symbol(R1.R11, Decl(spreadEnum6.ts, 25, 9)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>R11 : Symbol(R1.R11, Decl(spreadEnum6.ts, 25, 9)) + +R3.R2; +>R3.R2 : Symbol(R2.R2, Decl(spreadEnum6.ts, 30, 20)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>R2 : Symbol(R2.R2, Decl(spreadEnum6.ts, 30, 20)) + +R3.R22; +>R3.R22 : Symbol(R2.R22, Decl(spreadEnum6.ts, 35, 20)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>R22 : Symbol(R2.R22, Decl(spreadEnum6.ts, 35, 20)) + +R3.R3; +>R3.R3 : Symbol(R3.R3, Decl(spreadEnum6.ts, 41, 10)) +>R3 : Symbol(R3, Decl(spreadEnum6.ts, 37, 1)) +>R3 : Symbol(R3.R3, Decl(spreadEnum6.ts, 41, 10)) + diff --git a/tests/baselines/reference/spreadEnum6.types b/tests/baselines/reference/spreadEnum6.types new file mode 100644 index 0000000000000..e5dd09d175435 --- /dev/null +++ b/tests/baselines/reference/spreadEnum6.types @@ -0,0 +1,283 @@ +=== tests/cases/conformance/enums/spreadEnum6.ts === +enum LiteralEnum1 { +>LiteralEnum1 : LiteralEnum1 + + A = 0, +>A : LiteralEnum1.A +>0 : 0 + + B +>B : LiteralEnum1.B +} + +enum LiteralEnum1 { +>LiteralEnum1 : LiteralEnum1 + + C, +>C : LiteralEnum1.A + + D +>D : LiteralEnum1.B +} + +enum LiteralEnum2 { +>LiteralEnum2 : LiteralEnum2 + + E = 0, +>E : LiteralEnum1.A +>0 : 0 + + F +>F : LiteralEnum1.B +} + +enum LiteralEnum2 { +>LiteralEnum2 : LiteralEnum2 + + G, +>G : LiteralEnum1.A + + H +>H : LiteralEnum1.B +} + +enum R1 { +>R1 : R1 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R1 = 'R1' +>R1 : R1.R1 +>'R1' : "R1" +} + +enum R1 { +>R1 : R1 + + R11 = 'R11' +>R11 : R1.R11 +>'R11' : "R11" +} + +enum R2 { +>R2 : R2 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R2 = 'R2' +>R2 : R2.R2 +>'R2' : "R2" +} + +enum R2 { +>R2 : R2 + + ...LiteralEnum2, +>LiteralEnum2 : typeof LiteralEnum2 + + R22 = 'R22' +>R22 : R2.R22 +>'R22' : "R22" +} + +enum R3 { +>R3 : R3 + + ...R1, +>R1 : typeof R1 + + ...R2, +>R2 : typeof R2 + + R3 = 'R3' +>R3 : R3.R3 +>'R3' : "R3" +} + +LiteralEnum1.A; +>LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1 : typeof LiteralEnum1 +>A : LiteralEnum1.A + +LiteralEnum1.B; +>LiteralEnum1.B : LiteralEnum1.B +>LiteralEnum1 : typeof LiteralEnum1 +>B : LiteralEnum1.B + +LiteralEnum1.C; +>LiteralEnum1.C : LiteralEnum1.A +>LiteralEnum1 : typeof LiteralEnum1 +>C : LiteralEnum1.A + +LiteralEnum1.D; +>LiteralEnum1.D : LiteralEnum1.B +>LiteralEnum1 : typeof LiteralEnum1 +>D : LiteralEnum1.B + +R1.A; +>R1.A : LiteralEnum1.A +>R1 : typeof R1 +>A : LiteralEnum1.A + +R1.B; +>R1.B : LiteralEnum1.B +>R1 : typeof R1 +>B : LiteralEnum1.B + +R1.C; +>R1.C : LiteralEnum1.A +>R1 : typeof R1 +>C : LiteralEnum1.A + +R1.D; +>R1.D : LiteralEnum1.B +>R1 : typeof R1 +>D : LiteralEnum1.B + +R1.R1; +>R1.R1 : R1.R1 +>R1 : typeof R1 +>R1 : R1.R1 + +R1.R11; +>R1.R11 : R1.R11 +>R1 : typeof R1 +>R11 : R1.R11 + +LiteralEnum2.E; +>LiteralEnum2.E : LiteralEnum2.E +>LiteralEnum2 : typeof LiteralEnum2 +>E : LiteralEnum2.E + +LiteralEnum2.F; +>LiteralEnum2.F : LiteralEnum2.F +>LiteralEnum2 : typeof LiteralEnum2 +>F : LiteralEnum2.F + +LiteralEnum2.G; +>LiteralEnum2.G : LiteralEnum2.E +>LiteralEnum2 : typeof LiteralEnum2 +>G : LiteralEnum2.E + +LiteralEnum2.H; +>LiteralEnum2.H : LiteralEnum2.F +>LiteralEnum2 : typeof LiteralEnum2 +>H : LiteralEnum2.F + +R2.A; +>R2.A : LiteralEnum1 +>R2 : typeof R2 +>A : LiteralEnum1 + +R2.B; +>R2.B : LiteralEnum1 +>R2 : typeof R2 +>B : LiteralEnum1 + +R2.C; +>R2.C : LiteralEnum1 +>R2 : typeof R2 +>C : LiteralEnum1 + +R2.D; +>R2.D : LiteralEnum1 +>R2 : typeof R2 +>D : LiteralEnum1 + +R2.E; +>R2.E : LiteralEnum1.A +>R2 : typeof R2 +>E : LiteralEnum1.A + +R2.F; +>R2.F : LiteralEnum1.B +>R2 : typeof R2 +>F : LiteralEnum1.B + +R2.G; +>R2.G : LiteralEnum1.A +>R2 : typeof R2 +>G : LiteralEnum1.A + +R2.H; +>R2.H : LiteralEnum1.B +>R2 : typeof R2 +>H : LiteralEnum1.B + +R2.R2; +>R2.R2 : R2.R2 +>R2 : typeof R2 +>R2 : R2.R2 + +R2.R22 +>R2.R22 : R2.R22 +>R2 : typeof R2 +>R22 : R2.R22 + +R3.A; +>R3.A : LiteralEnum1 +>R3 : typeof R3 +>A : LiteralEnum1 + +R3.B; +>R3.B : LiteralEnum1 +>R3 : typeof R3 +>B : LiteralEnum1 + +R3.C; +>R3.C : LiteralEnum1 +>R3 : typeof R3 +>C : LiteralEnum1 + +R3.D; +>R3.D : LiteralEnum1 +>R3 : typeof R3 +>D : LiteralEnum1 + +R3.E; +>R3.E : LiteralEnum2 +>R3 : typeof R3 +>E : LiteralEnum2 + +R3.F; +>R3.F : LiteralEnum2 +>R3 : typeof R3 +>F : LiteralEnum2 + +R3.G; +>R3.G : LiteralEnum2 +>R3 : typeof R3 +>G : LiteralEnum2 + +R3.H; +>R3.H : LiteralEnum2 +>R3 : typeof R3 +>H : LiteralEnum2 + +R3.R1; +>R3.R1 : R1.R1 +>R3 : typeof R3 +>R1 : R1.R1 + +R3.R11; +>R3.R11 : R1.R11 +>R3 : typeof R3 +>R11 : R1.R11 + +R3.R2; +>R3.R2 : R2.R2 +>R3 : typeof R3 +>R2 : R2.R2 + +R3.R22; +>R3.R22 : R2.R22 +>R3 : typeof R3 +>R22 : R2.R22 + +R3.R3; +>R3.R3 : R3.R3 +>R3 : typeof R3 +>R3 : R3.R3 + diff --git a/tests/baselines/reference/spreadEnum7.errors.txt b/tests/baselines/reference/spreadEnum7.errors.txt new file mode 100644 index 0000000000000..a520fd37367c7 --- /dev/null +++ b/tests/baselines/reference/spreadEnum7.errors.txt @@ -0,0 +1,67 @@ +tests/cases/conformance/enums/spreadEnum7.ts(2,8): error TS2450: Enum 'LiteralEnum1' used before its declaration. +tests/cases/conformance/enums/spreadEnum7.ts(12,8): error TS2450: Enum 'R3' used before its declaration. + + +==== tests/cases/conformance/enums/spreadEnum7.ts (2 errors) ==== + enum R1 { + ...LiteralEnum1, + ~~~~~~~~~~~~ +!!! error TS2450: Enum 'LiteralEnum1' used before its declaration. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:6:6: 'LiteralEnum1' is declared here. + R1 = 'R1' + } + + enum LiteralEnum1 { + A, + B + } + + enum R2 { + ...R3, + ~~ +!!! error TS2450: Enum 'R3' used before its declaration. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:16:6: 'R3' is declared here. + R2 = 'R2' + } + + enum R3 { + ...R2, + R3 = 'R3' + } + + enum R4 { + ...LiteralEnum1, + R4 = 'R4' + } + + enum R5 { + ...LiteralEnum1, + R5 = 'R5' + } + + enum R6 { + ...LiteralEnum1, + ...R4, + ...R5, + R6 = 'R6' + } + + enum PartEnum1 { + A = 'A' + } + + enum RefEnum1 { + ...PartEnum1, + R = 'R' + } + + enum PartEnum1 { + B = 'B' + } + + enum R7 { + B = 'B', + ...LiteralEnum1, + A = 'A' + } + \ No newline at end of file diff --git a/tests/baselines/reference/spreadEnum7.js b/tests/baselines/reference/spreadEnum7.js new file mode 100644 index 0000000000000..3aee207fcb7ac --- /dev/null +++ b/tests/baselines/reference/spreadEnum7.js @@ -0,0 +1,173 @@ +//// [spreadEnum7.ts] +enum R1 { + ...LiteralEnum1, + R1 = 'R1' +} + +enum LiteralEnum1 { + A, + B +} + +enum R2 { + ...R3, + R2 = 'R2' +} + +enum R3 { + ...R2, + R3 = 'R3' +} + +enum R4 { + ...LiteralEnum1, + R4 = 'R4' +} + +enum R5 { + ...LiteralEnum1, + R5 = 'R5' +} + +enum R6 { + ...LiteralEnum1, + ...R4, + ...R5, + R6 = 'R6' +} + +enum PartEnum1 { + A = 'A' +} + +enum RefEnum1 { + ...PartEnum1, + R = 'R' +} + +enum PartEnum1 { + B = 'B' +} + +enum R7 { + B = 'B', + ...LiteralEnum1, + A = 'A' +} + + +//// [spreadEnum7.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var R1; +(function (R1) { + __assign(R1, LiteralEnum1); + R1["R1"] = "R1"; +})(R1 || (R1 = {})); +var LiteralEnum1; +(function (LiteralEnum1) { + LiteralEnum1[LiteralEnum1["A"] = 0] = "A"; + LiteralEnum1[LiteralEnum1["B"] = 1] = "B"; +})(LiteralEnum1 || (LiteralEnum1 = {})); +var R2; +(function (R2) { + __assign(R2, R3); + R2["R2"] = "R2"; +})(R2 || (R2 = {})); +var R3; +(function (R3) { + __assign(R3, R2); + R3["R3"] = "R3"; +})(R3 || (R3 = {})); +var R4; +(function (R4) { + __assign(R4, LiteralEnum1); + R4["R4"] = "R4"; +})(R4 || (R4 = {})); +var R5; +(function (R5) { + __assign(R5, LiteralEnum1); + R5["R5"] = "R5"; +})(R5 || (R5 = {})); +var R6; +(function (R6) { + __assign(R6, LiteralEnum1); + __assign(R6, R4); + __assign(R6, R5); + R6["R6"] = "R6"; +})(R6 || (R6 = {})); +var PartEnum1; +(function (PartEnum1) { + PartEnum1["A"] = "A"; +})(PartEnum1 || (PartEnum1 = {})); +var RefEnum1; +(function (RefEnum1) { + __assign(RefEnum1, PartEnum1); + RefEnum1["R"] = "R"; +})(RefEnum1 || (RefEnum1 = {})); +(function (PartEnum1) { + PartEnum1["B"] = "B"; +})(PartEnum1 || (PartEnum1 = {})); +var R7; +(function (R7) { + R7["B"] = "B"; + __assign(R7, LiteralEnum1); + R7["A"] = "A"; +})(R7 || (R7 = {})); + + +//// [spreadEnum7.d.ts] +declare enum R1 { + ...LiteralEnum1, + R1 = "R1" +} +declare enum LiteralEnum1 { + A = 0, + B = 1 +} +declare enum R2 { + ...R3, + R2 = "R2" +} +declare enum R3 { + ...R2, + R3 = "R3" +} +declare enum R4 { + ...LiteralEnum1, + R4 = "R4" +} +declare enum R5 { + ...LiteralEnum1, + R5 = "R5" +} +declare enum R6 { + ...LiteralEnum1, + ...R4, + ...R5, + R6 = "R6" +} +declare enum PartEnum1 { + A = "A" +} +declare enum RefEnum1 { + ...PartEnum1, + R = "R" +} +declare enum PartEnum1 { + B = "B" +} +declare enum R7 { + B = "B", + ...LiteralEnum1, + A = "A" +} diff --git a/tests/baselines/reference/spreadEnum7.symbols b/tests/baselines/reference/spreadEnum7.symbols new file mode 100644 index 0000000000000..3e63ec7704f4f --- /dev/null +++ b/tests/baselines/reference/spreadEnum7.symbols @@ -0,0 +1,114 @@ +=== tests/cases/conformance/enums/spreadEnum7.ts === +enum R1 { +>R1 : Symbol(R1, Decl(spreadEnum7.ts, 0, 0)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) + + R1 = 'R1' +>R1 : Symbol(R1.R1, Decl(spreadEnum7.ts, 1, 20)) +} + +enum LiteralEnum1 { +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) + + A, +>A : Symbol(LiteralEnum1.A, Decl(spreadEnum7.ts, 5, 19)) + + B +>B : Symbol(LiteralEnum1.B, Decl(spreadEnum7.ts, 6, 6)) +} + +enum R2 { +>R2 : Symbol(R2, Decl(spreadEnum7.ts, 8, 1)) + + ...R3, +>R3 : Symbol(R3, Decl(spreadEnum7.ts, 13, 1)) + + R2 = 'R2' +>R2 : Symbol(R2.R2, Decl(spreadEnum7.ts, 11, 10)) +} + +enum R3 { +>R3 : Symbol(R3, Decl(spreadEnum7.ts, 13, 1)) + + ...R2, +>R2 : Symbol(R2, Decl(spreadEnum7.ts, 8, 1)) + + R3 = 'R3' +>R3 : Symbol(R3.R3, Decl(spreadEnum7.ts, 16, 10)) +} + +enum R4 { +>R4 : Symbol(R4, Decl(spreadEnum7.ts, 18, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) + + R4 = 'R4' +>R4 : Symbol(R4.R4, Decl(spreadEnum7.ts, 21, 20)) +} + +enum R5 { +>R5 : Symbol(R5, Decl(spreadEnum7.ts, 23, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) + + R5 = 'R5' +>R5 : Symbol(R5.R5, Decl(spreadEnum7.ts, 26, 20)) +} + +enum R6 { +>R6 : Symbol(R6, Decl(spreadEnum7.ts, 28, 1)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) + + ...R4, +>R4 : Symbol(R4, Decl(spreadEnum7.ts, 18, 1)) + + ...R5, +>R5 : Symbol(R5, Decl(spreadEnum7.ts, 23, 1)) + + R6 = 'R6' +>R6 : Symbol(R6.R6, Decl(spreadEnum7.ts, 33, 10)) +} + +enum PartEnum1 { +>PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 35, 1), Decl(spreadEnum7.ts, 44, 1)) + + A = 'A' +>A : Symbol(PartEnum1.A, Decl(spreadEnum7.ts, 37, 16)) +} + +enum RefEnum1 { +>RefEnum1 : Symbol(RefEnum1, Decl(spreadEnum7.ts, 39, 1)) + + ...PartEnum1, +>PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 35, 1), Decl(spreadEnum7.ts, 44, 1)) + + R = 'R' +>R : Symbol(RefEnum1.R, Decl(spreadEnum7.ts, 42, 17)) +} + +enum PartEnum1 { +>PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 35, 1), Decl(spreadEnum7.ts, 44, 1)) + + B = 'B' +>B : Symbol(PartEnum1.B, Decl(spreadEnum7.ts, 46, 16)) +} + +enum R7 { +>R7 : Symbol(R7, Decl(spreadEnum7.ts, 48, 1)) + + B = 'B', +>B : Symbol(R7.B, Decl(spreadEnum7.ts, 50, 9)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) + + A = 'A' +>A : Symbol(R7.A, Decl(spreadEnum7.ts, 52, 20)) +} + diff --git a/tests/baselines/reference/spreadEnum7.types b/tests/baselines/reference/spreadEnum7.types new file mode 100644 index 0000000000000..85daad1fc9d73 --- /dev/null +++ b/tests/baselines/reference/spreadEnum7.types @@ -0,0 +1,125 @@ +=== tests/cases/conformance/enums/spreadEnum7.ts === +enum R1 { +>R1 : R1 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R1 = 'R1' +>R1 : R1.R1 +>'R1' : "R1" +} + +enum LiteralEnum1 { +>LiteralEnum1 : LiteralEnum1 + + A, +>A : LiteralEnum1.A + + B +>B : LiteralEnum1.B +} + +enum R2 { +>R2 : R2 + + ...R3, +>R3 : typeof R3 + + R2 = 'R2' +>R2 : R2.R2 +>'R2' : "R2" +} + +enum R3 { +>R3 : R3 + + ...R2, +>R2 : typeof R2 + + R3 = 'R3' +>R3 : R3.R3 +>'R3' : "R3" +} + +enum R4 { +>R4 : R4 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R4 = 'R4' +>R4 : R4.R4 +>'R4' : "R4" +} + +enum R5 { +>R5 : R5 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + R5 = 'R5' +>R5 : R5.R5 +>'R5' : "R5" +} + +enum R6 { +>R6 : R6 + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + ...R4, +>R4 : typeof R4 + + ...R5, +>R5 : typeof R5 + + R6 = 'R6' +>R6 : R6.R6 +>'R6' : "R6" +} + +enum PartEnum1 { +>PartEnum1 : PartEnum1 + + A = 'A' +>A : PartEnum1.A +>'A' : "A" +} + +enum RefEnum1 { +>RefEnum1 : RefEnum1 + + ...PartEnum1, +>PartEnum1 : typeof PartEnum1 + + R = 'R' +>R : RefEnum1.R +>'R' : "R" +} + +enum PartEnum1 { +>PartEnum1 : PartEnum1 + + B = 'B' +>B : PartEnum1.B +>'B' : "B" +} + +enum R7 { +>R7 : R7 + + B = 'B', +>B : R7.B +>'B' : "B" + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 + + A = 'A' +>A : R7.A +>'A' : "A" +} + diff --git a/tests/cases/conformance/enums/spreadEnum6.ts b/tests/cases/conformance/enums/spreadEnum6.ts new file mode 100644 index 0000000000000..07ed3848a7b17 --- /dev/null +++ b/tests/cases/conformance/enums/spreadEnum6.ts @@ -0,0 +1,86 @@ +// @declaration: true + +enum LiteralEnum1 { + A = 0, + B +} + +enum LiteralEnum1 { + C, + D +} + +enum LiteralEnum2 { + E = 0, + F +} + +enum LiteralEnum2 { + G, + H +} + +enum R1 { + ...LiteralEnum1, + R1 = 'R1' +} + +enum R1 { + R11 = 'R11' +} + +enum R2 { + ...LiteralEnum1, + R2 = 'R2' +} + +enum R2 { + ...LiteralEnum2, + R22 = 'R22' +} + +enum R3 { + ...R1, + ...R2, + R3 = 'R3' +} + +LiteralEnum1.A; +LiteralEnum1.B; +LiteralEnum1.C; +LiteralEnum1.D; +R1.A; +R1.B; +R1.C; +R1.D; +R1.R1; +R1.R11; + +LiteralEnum2.E; +LiteralEnum2.F; +LiteralEnum2.G; +LiteralEnum2.H; +R2.A; +R2.B; +R2.C; +R2.D; +R2.E; +R2.F; +R2.G; +R2.H; +R2.R2; +R2.R22 + +R3.A; +R3.B; +R3.C; +R3.D; +R3.E; +R3.F; +R3.G; +R3.H; +R3.R1; +R3.R11; +R3.R2; +R3.R22; +R3.R3; diff --git a/tests/cases/conformance/enums/spreadEnum7.ts b/tests/cases/conformance/enums/spreadEnum7.ts new file mode 100644 index 0000000000000..0684df056b6d2 --- /dev/null +++ b/tests/cases/conformance/enums/spreadEnum7.ts @@ -0,0 +1,57 @@ +// @declaration: true + +enum R1 { + ...LiteralEnum1, + R1 = 'R1' +} + +enum LiteralEnum1 { + A, + B +} + +enum R2 { + ...R3, + R2 = 'R2' +} + +enum R3 { + ...R2, + R3 = 'R3' +} + +enum R4 { + ...LiteralEnum1, + R4 = 'R4' +} + +enum R5 { + ...LiteralEnum1, + R5 = 'R5' +} + +enum R6 { + ...LiteralEnum1, + ...R4, + ...R5, + R6 = 'R6' +} + +enum PartEnum1 { + A = 'A' +} + +enum RefEnum1 { + ...PartEnum1, + R = 'R' +} + +enum PartEnum1 { + B = 'B' +} + +enum R7 { + B = 'B', + ...LiteralEnum1, + A = 'A' +} From 38e46c95a93f259b809200153c0558a7f9efc7fb Mon Sep 17 00:00:00 2001 From: kingwl Date: Mon, 12 Oct 2020 01:26:40 +0800 Subject: [PATCH 17/21] Add more cases --- .../reference/spreadEnum7.errors.txt | 15 +++++++++- tests/baselines/reference/spreadEnum7.js | 28 +++++++++++++++++++ tests/baselines/reference/spreadEnum7.symbols | 20 +++++++++++++ tests/baselines/reference/spreadEnum7.types | 22 +++++++++++++++ tests/cases/conformance/enums/spreadEnum7.ts | 10 +++++++ 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/spreadEnum7.errors.txt b/tests/baselines/reference/spreadEnum7.errors.txt index a520fd37367c7..5e8e9d001b026 100644 --- a/tests/baselines/reference/spreadEnum7.errors.txt +++ b/tests/baselines/reference/spreadEnum7.errors.txt @@ -1,8 +1,9 @@ tests/cases/conformance/enums/spreadEnum7.ts(2,8): error TS2450: Enum 'LiteralEnum1' used before its declaration. tests/cases/conformance/enums/spreadEnum7.ts(12,8): error TS2450: Enum 'R3' used before its declaration. +tests/cases/conformance/enums/spreadEnum7.ts(63,8): error TS1394: Enum expected. -==== tests/cases/conformance/enums/spreadEnum7.ts (2 errors) ==== +==== tests/cases/conformance/enums/spreadEnum7.ts (3 errors) ==== enum R1 { ...LiteralEnum1, ~~~~~~~~~~~~ @@ -64,4 +65,16 @@ tests/cases/conformance/enums/spreadEnum7.ts(12,8): error TS2450: Enum 'R3' used ...LiteralEnum1, A = 'A' } + + enum R8 { + ...R8, + R88 = 'R88' + } + + enum R9 { + ...R9, + ~~ +!!! error TS1394: Enum expected. + R9 = 'R9' + } \ No newline at end of file diff --git a/tests/baselines/reference/spreadEnum7.js b/tests/baselines/reference/spreadEnum7.js index 3aee207fcb7ac..59e5b85c556cd 100644 --- a/tests/baselines/reference/spreadEnum7.js +++ b/tests/baselines/reference/spreadEnum7.js @@ -54,6 +54,16 @@ enum R7 { ...LiteralEnum1, A = 'A' } + +enum R8 { + ...R8, + R88 = 'R88' +} + +enum R9 { + ...R9, + R9 = 'R9' +} //// [spreadEnum7.js] @@ -123,6 +133,16 @@ var R7; __assign(R7, LiteralEnum1); R7["A"] = "A"; })(R7 || (R7 = {})); +var R8; +(function (R8) { + __assign(R8, R8); + R8["R88"] = "R88"; +})(R8 || (R8 = {})); +var R9; +(function (R9) { + __assign(R9, R9); + R9["R9"] = "R9"; +})(R9 || (R9 = {})); //// [spreadEnum7.d.ts] @@ -171,3 +191,11 @@ declare enum R7 { ...LiteralEnum1, A = "A" } +declare enum R8 { + ...R8, + R88 = "R88" +} +declare enum R9 { + ...R9, + R9 = "R9" +} diff --git a/tests/baselines/reference/spreadEnum7.symbols b/tests/baselines/reference/spreadEnum7.symbols index 3e63ec7704f4f..d2071fb5d193a 100644 --- a/tests/baselines/reference/spreadEnum7.symbols +++ b/tests/baselines/reference/spreadEnum7.symbols @@ -112,3 +112,23 @@ enum R7 { >A : Symbol(R7.A, Decl(spreadEnum7.ts, 52, 20)) } +enum R8 { +>R8 : Symbol(R8, Decl(spreadEnum7.ts, 54, 1)) + + ...R8, +>R8 : Symbol(R8, Decl(spreadEnum7.ts, 54, 1)) + + R88 = 'R88' +>R88 : Symbol(R8.R88, Decl(spreadEnum7.ts, 57, 10)) +} + +enum R9 { +>R9 : Symbol(R9, Decl(spreadEnum7.ts, 59, 1)) + + ...R9, +>R9 : Symbol(R9.R9, Decl(spreadEnum7.ts, 62, 10)) + + R9 = 'R9' +>R9 : Symbol(R9.R9, Decl(spreadEnum7.ts, 62, 10)) +} + diff --git a/tests/baselines/reference/spreadEnum7.types b/tests/baselines/reference/spreadEnum7.types index 85daad1fc9d73..ec1c24c647a17 100644 --- a/tests/baselines/reference/spreadEnum7.types +++ b/tests/baselines/reference/spreadEnum7.types @@ -123,3 +123,25 @@ enum R7 { >'A' : "A" } +enum R8 { +>R8 : R8 + + ...R8, +>R8 : typeof R8 + + R88 = 'R88' +>R88 : R8.R88 +>'R88' : "R88" +} + +enum R9 { +>R9 : R9 + + ...R9, +>R9 : R9 + + R9 = 'R9' +>R9 : R9.R9 +>'R9' : "R9" +} + diff --git a/tests/cases/conformance/enums/spreadEnum7.ts b/tests/cases/conformance/enums/spreadEnum7.ts index 0684df056b6d2..84fa8739b9a33 100644 --- a/tests/cases/conformance/enums/spreadEnum7.ts +++ b/tests/cases/conformance/enums/spreadEnum7.ts @@ -55,3 +55,13 @@ enum R7 { ...LiteralEnum1, A = 'A' } + +enum R8 { + ...R8, + R88 = 'R88' +} + +enum R9 { + ...R9, + R9 = 'R9' +} From c45ca710373955b39a9354914204d04b6ee7c7f9 Mon Sep 17 00:00:00 2001 From: kingwl Date: Mon, 12 Oct 2020 14:50:12 +0800 Subject: [PATCH 18/21] Update baseline --- tests/baselines/reference/constEnumErrors.errors.txt | 12 ++++++------ .../reference/constEnumPropertyAccess2.errors.txt | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index abfd41c6faa7c..7c0eb43cf4051 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -6,9 +6,9 @@ tests/cases/compiler/constEnumErrors.ts(15,10): error TS2474: const enum member tests/cases/compiler/constEnumErrors.ts(22,13): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/compiler/constEnumErrors.ts(24,13): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/compiler/constEnumErrors.ts(25,13): error TS2476: A const enum member can only be accessed using a string literal. -tests/cases/compiler/constEnumErrors.ts(27,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. -tests/cases/compiler/constEnumErrors.ts(28,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. -tests/cases/compiler/constEnumErrors.ts(33,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/compiler/constEnumErrors.ts(27,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. +tests/cases/compiler/constEnumErrors.ts(28,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. +tests/cases/compiler/constEnumErrors.ts(33,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. tests/cases/compiler/constEnumErrors.ts(41,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. tests/cases/compiler/constEnumErrors.ts(42,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. tests/cases/compiler/constEnumErrors.ts(43,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'. @@ -59,17 +59,17 @@ tests/cases/compiler/constEnumErrors.ts(43,9): error TS2478: 'const' enum member var x = E2; ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. var y = [E2]; ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. function foo(t: any): void { } foo(E2); ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. const enum NaNOrInfinity { A = 9007199254740992, diff --git a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt index 7de386d886807..7928cdd0e2806 100644 --- a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt +++ b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(14,12): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(16,1): error TS2322: Type 'string' is not assignable to type 'G'. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS2540: Cannot assign to 'B' because it is a read-only property. @@ -19,7 +19,7 @@ tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS25 // Error from referring constant enum in any other context than a property access var z = G; ~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query or spread enum member. var z1 = G[G.A]; ~~~ !!! error TS2476: A const enum member can only be accessed using a string literal. From 8fdd8592d5298eb0464d6b3c615e5d72d29a8aa0 Mon Sep 17 00:00:00 2001 From: kingwl Date: Mon, 12 Oct 2020 16:52:58 +0800 Subject: [PATCH 19/21] Improve diags --- src/compiler/checker.ts | 50 ++++++++++++++----- src/compiler/diagnosticMessages.json | 8 +++ .../reference/spreadEnum6.errors.txt | 28 ++++++----- .../reference/spreadEnum7.errors.txt | 13 ++++- tests/baselines/reference/spreadEnum7.js | 17 +++++++ tests/baselines/reference/spreadEnum7.symbols | 45 +++++++++++------ tests/baselines/reference/spreadEnum7.types | 13 +++++ tests/cases/conformance/enums/spreadEnum7.ts | 6 +++ 8 files changed, 137 insertions(+), 43 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e6b1bcea2c7a8..cf833f83530a5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1340,20 +1340,25 @@ namespace ts { } function addToSymbolTable(target: SymbolTable, source: SymbolTable, message: DiagnosticMessage) { + addToSymbolTableWithDiagnostic(target, source, ({ targetSymbol, id }) => { + forEach(targetSymbol.declarations, addDeclarationDiagnostic(unescapeLeadingUnderscores(id), message)); + }); + + function addDeclarationDiagnostic(id: string, message: DiagnosticMessage) { + return (declaration: Declaration) => diagnostics.add(createDiagnosticForNode(declaration, message, id)); + } + } + + function addToSymbolTableWithDiagnostic(target: SymbolTable, source: SymbolTable, onConflict: (args: { targetSymbol: Symbol, sourceSymbol: Symbol, id: __String }) => void) { source.forEach((sourceSymbol, id) => { const targetSymbol = target.get(id); if (targetSymbol) { - // Error on redeclarations - forEach(targetSymbol.declarations, addDeclarationDiagnostic(unescapeLeadingUnderscores(id), message)); + onConflict({ targetSymbol, sourceSymbol, id }); } else { target.set(id, sourceSymbol); } }); - - function addDeclarationDiagnostic(id: string, message: DiagnosticMessage) { - return (declaration: Declaration) => diagnostics.add(createDiagnosticForNode(declaration, message, id)); - } } function getSymbolLinks(symbol: Symbol): SymbolLinks { @@ -9817,6 +9822,28 @@ namespace ts { return links.resolvedSymbol; } + function lateBindSpreadEnumMember(earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, member: SpreadEnumMember) { + const spreadEnumMemberExports = createSymbolTable(); + const enumMembers = getExportsFromSpreadEnumMember(member); + enumMembers.forEach(enumMember => { + const symbol = getSymbolOfNode(enumMember); + const earlySymbol = earlySymbols?.get(symbol.escapedName); + if (earlySymbol) { + const earlySymbolText = symbolToString(earlySymbol); + const diag = error(member, Diagnostics.Spread_enum_member_has_overlapped_on_0, earlySymbolText); + addRelatedInfo(diag, createDiagnosticForNode(earlySymbol.valueDeclaration, Diagnostics._0_is_declared_here, earlySymbolText)); + } + + const enumSymbol = cloneSymbol(symbol); + spreadEnumMemberExports.set(enumSymbol.escapedName, enumSymbol); + }); + addToSymbolTableWithDiagnostic(lateSymbols, spreadEnumMemberExports, ({ targetSymbol }) => { + const targetSymbolText = symbolToString(targetSymbol); + const diag = error(member, Diagnostics.Spread_enum_member_has_overlapped_on_0, targetSymbolText); + addRelatedInfo(diag, createDiagnosticForNode(targetSymbol.valueDeclaration, Diagnostics._0_is_declared_here, targetSymbolText)); + }); + } + function getResolvedMembersOrExportsOfSymbol(symbol: Symbol, resolutionKind: MembersOrExportsResolutionKind): UnderscoreEscapedMap { const links = getSymbolLinks(symbol); if (!links[resolutionKind]) { @@ -9837,13 +9864,7 @@ namespace ts { if (members) { for (const member of members) { if (isSpreadEnumMember(member)) { - const spreadEnumMemberExports = createSymbolTable(); - const enumMembers = getExportsFromSpreadEnumMember(member); - enumMembers.forEach(enumMember => { - const enumSymbol = cloneSymbol(getSymbolOfNode(enumMember)); - spreadEnumMemberExports.set(enumSymbol.escapedName, enumSymbol); - }); - addToSymbolTable(lateSymbols, spreadEnumMemberExports, Diagnostics.Expression_expected); + lateBindSpreadEnumMember(earlySymbols, lateSymbols, member); } else if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { lateBindMember(symbol, earlySymbols, lateSymbols, member); @@ -35960,6 +35981,9 @@ namespace ts { error(node.name, Diagnostics.Enum_expected); return; } + if (symbol === enumSymbol) { + error(node.name, Diagnostics.Spread_enum_member_cannot_reference_to_itself); + } checkGrammarSpreadEnumMember(enumSymbol, symbol, node); checkExpression(node.name); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 66b9841e2ac88..1a1bc5c792baf 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1216,6 +1216,14 @@ "category": "Error", "code": 1396 }, + "Spread enum member has overlapped on '{0}'.": { + "category": "Error", + "code": 1397 + }, + "Spread enum member cannot reference to itself.": { + "category": "Error", + "code": 1398 + }, "The types of '{0}' are incompatible between these types.": { "category": "Error", diff --git a/tests/baselines/reference/spreadEnum6.errors.txt b/tests/baselines/reference/spreadEnum6.errors.txt index 9c6f00eedfacc..de77513c2b766 100644 --- a/tests/baselines/reference/spreadEnum6.errors.txt +++ b/tests/baselines/reference/spreadEnum6.errors.txt @@ -1,26 +1,18 @@ -tests/cases/conformance/enums/spreadEnum6.ts(2,5): error TS1109: Expression expected. -tests/cases/conformance/enums/spreadEnum6.ts(3,5): error TS1109: Expression expected. -tests/cases/conformance/enums/spreadEnum6.ts(7,5): error TS1109: Expression expected. -tests/cases/conformance/enums/spreadEnum6.ts(8,5): error TS1109: Expression expected. +tests/cases/conformance/enums/spreadEnum6.ts(42,8): error TS1397: Spread enum member has overlapped on 'A'. +tests/cases/conformance/enums/spreadEnum6.ts(42,8): error TS1397: Spread enum member has overlapped on 'B'. +tests/cases/conformance/enums/spreadEnum6.ts(42,8): error TS1397: Spread enum member has overlapped on 'C'. +tests/cases/conformance/enums/spreadEnum6.ts(42,8): error TS1397: Spread enum member has overlapped on 'D'. ==== tests/cases/conformance/enums/spreadEnum6.ts (4 errors) ==== enum LiteralEnum1 { A = 0, - ~ -!!! error TS1109: Expression expected. B - ~ -!!! error TS1109: Expression expected. } enum LiteralEnum1 { C, - ~ -!!! error TS1109: Expression expected. D - ~ -!!! error TS1109: Expression expected. } enum LiteralEnum2 { @@ -55,6 +47,18 @@ tests/cases/conformance/enums/spreadEnum6.ts(8,5): error TS1109: Expression expe enum R3 { ...R1, ...R2, + ~~ +!!! error TS1397: Spread enum member has overlapped on 'A'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum6.ts:2:5: 'A' is declared here. + ~~ +!!! error TS1397: Spread enum member has overlapped on 'B'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum6.ts:3:5: 'B' is declared here. + ~~ +!!! error TS1397: Spread enum member has overlapped on 'C'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum6.ts:7:5: 'C' is declared here. + ~~ +!!! error TS1397: Spread enum member has overlapped on 'D'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum6.ts:8:5: 'D' is declared here. R3 = 'R3' } diff --git a/tests/baselines/reference/spreadEnum7.errors.txt b/tests/baselines/reference/spreadEnum7.errors.txt index 5e8e9d001b026..fd55cf8eece03 100644 --- a/tests/baselines/reference/spreadEnum7.errors.txt +++ b/tests/baselines/reference/spreadEnum7.errors.txt @@ -1,9 +1,10 @@ tests/cases/conformance/enums/spreadEnum7.ts(2,8): error TS2450: Enum 'LiteralEnum1' used before its declaration. tests/cases/conformance/enums/spreadEnum7.ts(12,8): error TS2450: Enum 'R3' used before its declaration. -tests/cases/conformance/enums/spreadEnum7.ts(63,8): error TS1394: Enum expected. +tests/cases/conformance/enums/spreadEnum7.ts(64,8): error TS1398: Spread enum member cannot reference to itself. +tests/cases/conformance/enums/spreadEnum7.ts(69,8): error TS1394: Enum expected. -==== tests/cases/conformance/enums/spreadEnum7.ts (3 errors) ==== +==== tests/cases/conformance/enums/spreadEnum7.ts (4 errors) ==== enum R1 { ...LiteralEnum1, ~~~~~~~~~~~~ @@ -47,6 +48,12 @@ tests/cases/conformance/enums/spreadEnum7.ts(63,8): error TS1394: Enum expected. R6 = 'R6' } + enum R66 { + A, + B, + ...LiteralEnum1, + } + enum PartEnum1 { A = 'A' } @@ -68,6 +75,8 @@ tests/cases/conformance/enums/spreadEnum7.ts(63,8): error TS1394: Enum expected. enum R8 { ...R8, + ~~ +!!! error TS1398: Spread enum member cannot reference to itself. R88 = 'R88' } diff --git a/tests/baselines/reference/spreadEnum7.js b/tests/baselines/reference/spreadEnum7.js index 59e5b85c556cd..5cc6449147e65 100644 --- a/tests/baselines/reference/spreadEnum7.js +++ b/tests/baselines/reference/spreadEnum7.js @@ -36,6 +36,12 @@ enum R6 { R6 = 'R6' } +enum R66 { + A, + B, + ...LiteralEnum1, +} + enum PartEnum1 { A = 'A' } @@ -115,6 +121,12 @@ var R6; __assign(R6, R5); R6["R6"] = "R6"; })(R6 || (R6 = {})); +var R66; +(function (R66) { + R66[R66["A"] = 0] = "A"; + R66[R66["B"] = 1] = "B"; + __assign(R66, LiteralEnum1); +})(R66 || (R66 = {})); var PartEnum1; (function (PartEnum1) { PartEnum1["A"] = "A"; @@ -176,6 +188,11 @@ declare enum R6 { ...R5, R6 = "R6" } +declare enum R66 { + A = 0, + B = 1, + ...LiteralEnum1 +} declare enum PartEnum1 { A = "A" } diff --git a/tests/baselines/reference/spreadEnum7.symbols b/tests/baselines/reference/spreadEnum7.symbols index d2071fb5d193a..612eafb61d5b3 100644 --- a/tests/baselines/reference/spreadEnum7.symbols +++ b/tests/baselines/reference/spreadEnum7.symbols @@ -75,60 +75,73 @@ enum R6 { >R6 : Symbol(R6.R6, Decl(spreadEnum7.ts, 33, 10)) } +enum R66 { +>R66 : Symbol(R66, Decl(spreadEnum7.ts, 35, 1)) + + A, +>A : Symbol(R66.A, Decl(spreadEnum7.ts, 37, 10)) + + B, +>B : Symbol(R66.B, Decl(spreadEnum7.ts, 38, 6)) + + ...LiteralEnum1, +>LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) +} + enum PartEnum1 { ->PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 35, 1), Decl(spreadEnum7.ts, 44, 1)) +>PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 41, 1), Decl(spreadEnum7.ts, 50, 1)) A = 'A' ->A : Symbol(PartEnum1.A, Decl(spreadEnum7.ts, 37, 16)) +>A : Symbol(PartEnum1.A, Decl(spreadEnum7.ts, 43, 16)) } enum RefEnum1 { ->RefEnum1 : Symbol(RefEnum1, Decl(spreadEnum7.ts, 39, 1)) +>RefEnum1 : Symbol(RefEnum1, Decl(spreadEnum7.ts, 45, 1)) ...PartEnum1, ->PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 35, 1), Decl(spreadEnum7.ts, 44, 1)) +>PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 41, 1), Decl(spreadEnum7.ts, 50, 1)) R = 'R' ->R : Symbol(RefEnum1.R, Decl(spreadEnum7.ts, 42, 17)) +>R : Symbol(RefEnum1.R, Decl(spreadEnum7.ts, 48, 17)) } enum PartEnum1 { ->PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 35, 1), Decl(spreadEnum7.ts, 44, 1)) +>PartEnum1 : Symbol(PartEnum1, Decl(spreadEnum7.ts, 41, 1), Decl(spreadEnum7.ts, 50, 1)) B = 'B' ->B : Symbol(PartEnum1.B, Decl(spreadEnum7.ts, 46, 16)) +>B : Symbol(PartEnum1.B, Decl(spreadEnum7.ts, 52, 16)) } enum R7 { ->R7 : Symbol(R7, Decl(spreadEnum7.ts, 48, 1)) +>R7 : Symbol(R7, Decl(spreadEnum7.ts, 54, 1)) B = 'B', ->B : Symbol(R7.B, Decl(spreadEnum7.ts, 50, 9)) +>B : Symbol(R7.B, Decl(spreadEnum7.ts, 56, 9)) ...LiteralEnum1, >LiteralEnum1 : Symbol(LiteralEnum1, Decl(spreadEnum7.ts, 3, 1)) A = 'A' ->A : Symbol(R7.A, Decl(spreadEnum7.ts, 52, 20)) +>A : Symbol(R7.A, Decl(spreadEnum7.ts, 58, 20)) } enum R8 { ->R8 : Symbol(R8, Decl(spreadEnum7.ts, 54, 1)) +>R8 : Symbol(R8, Decl(spreadEnum7.ts, 60, 1)) ...R8, ->R8 : Symbol(R8, Decl(spreadEnum7.ts, 54, 1)) +>R8 : Symbol(R8, Decl(spreadEnum7.ts, 60, 1)) R88 = 'R88' ->R88 : Symbol(R8.R88, Decl(spreadEnum7.ts, 57, 10)) +>R88 : Symbol(R8.R88, Decl(spreadEnum7.ts, 63, 10)) } enum R9 { ->R9 : Symbol(R9, Decl(spreadEnum7.ts, 59, 1)) +>R9 : Symbol(R9, Decl(spreadEnum7.ts, 65, 1)) ...R9, ->R9 : Symbol(R9.R9, Decl(spreadEnum7.ts, 62, 10)) +>R9 : Symbol(R9.R9, Decl(spreadEnum7.ts, 68, 10)) R9 = 'R9' ->R9 : Symbol(R9.R9, Decl(spreadEnum7.ts, 62, 10)) +>R9 : Symbol(R9.R9, Decl(spreadEnum7.ts, 68, 10)) } diff --git a/tests/baselines/reference/spreadEnum7.types b/tests/baselines/reference/spreadEnum7.types index ec1c24c647a17..f688d9e374856 100644 --- a/tests/baselines/reference/spreadEnum7.types +++ b/tests/baselines/reference/spreadEnum7.types @@ -81,6 +81,19 @@ enum R6 { >'R6' : "R6" } +enum R66 { +>R66 : R66 + + A, +>A : R66.A + + B, +>B : R66.B + + ...LiteralEnum1, +>LiteralEnum1 : typeof LiteralEnum1 +} + enum PartEnum1 { >PartEnum1 : PartEnum1 diff --git a/tests/cases/conformance/enums/spreadEnum7.ts b/tests/cases/conformance/enums/spreadEnum7.ts index 84fa8739b9a33..723f19921d018 100644 --- a/tests/cases/conformance/enums/spreadEnum7.ts +++ b/tests/cases/conformance/enums/spreadEnum7.ts @@ -37,6 +37,12 @@ enum R6 { R6 = 'R6' } +enum R66 { + A, + B, + ...LiteralEnum1, +} + enum PartEnum1 { A = 'A' } From 1b4935c381a335a230914829419c377a5d6068ce Mon Sep 17 00:00:00 2001 From: kingwl Date: Mon, 12 Oct 2020 17:33:22 +0800 Subject: [PATCH 20/21] check earlyer --- src/compiler/checker.ts | 1 + tests/baselines/reference/spreadEnum1.types | 40 +++++----- tests/baselines/reference/spreadEnum2.types | 16 ++-- tests/baselines/reference/spreadEnum3.types | 16 ++-- tests/baselines/reference/spreadEnum5.types | 16 ++-- tests/baselines/reference/spreadEnum6.types | 48 ++++++------ .../reference/spreadEnum7.errors.txt | 74 ++++++++++++++++++- 7 files changed, 142 insertions(+), 69 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cf833f83530a5..11ca8d273f8a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35985,6 +35985,7 @@ namespace ts { error(node.name, Diagnostics.Spread_enum_member_cannot_reference_to_itself); } + getExportsOfSymbol(symbol); checkGrammarSpreadEnumMember(enumSymbol, symbol, node); checkExpression(node.name); } diff --git a/tests/baselines/reference/spreadEnum1.types b/tests/baselines/reference/spreadEnum1.types index 65c8a4c3e2c86..0eb4d13f7cf13 100644 --- a/tests/baselines/reference/spreadEnum1.types +++ b/tests/baselines/reference/spreadEnum1.types @@ -3,11 +3,11 @@ enum BasicEvents { >BasicEvents : BasicEvents Start = "Start", ->Start : BasicEvents +>Start : BasicEvents.Start >"Start" : "Start" Finish = "Finish" ->Finish : BasicEvents +>Finish : BasicEvents.Finish >"Finish" : "Finish" } @@ -38,32 +38,32 @@ adv = basic; >basic : BasicEvents basic = BasicEvents.Start; ->basic = BasicEvents.Start : BasicEvents.Start +>basic = BasicEvents.Start : BasicEvents >basic : BasicEvents ->BasicEvents.Start : BasicEvents.Start +>BasicEvents.Start : BasicEvents >BasicEvents : typeof BasicEvents ->Start : BasicEvents.Start +>Start : BasicEvents basic = BasicEvents.Finish; ->basic = BasicEvents.Finish : BasicEvents.Finish +>basic = BasicEvents.Finish : BasicEvents >basic : BasicEvents ->BasicEvents.Finish : BasicEvents.Finish +>BasicEvents.Finish : BasicEvents >BasicEvents : typeof BasicEvents ->Finish : BasicEvents.Finish +>Finish : BasicEvents adv = AdvEvents.Start; ->adv = AdvEvents.Start : BasicEvents +>adv = AdvEvents.Start : BasicEvents.Start >adv : AdvEvents ->AdvEvents.Start : BasicEvents +>AdvEvents.Start : BasicEvents.Start >AdvEvents : typeof AdvEvents ->Start : BasicEvents +>Start : BasicEvents.Start adv = AdvEvents.Finish; ->adv = AdvEvents.Finish : BasicEvents +>adv = AdvEvents.Finish : BasicEvents.Finish >adv : AdvEvents ->AdvEvents.Finish : BasicEvents +>AdvEvents.Finish : BasicEvents.Finish >AdvEvents : typeof AdvEvents ->Finish : BasicEvents +>Finish : BasicEvents.Finish adv = AdvEvents.Pause; >adv = AdvEvents.Pause : AdvEvents.Pause @@ -80,16 +80,16 @@ adv = AdvEvents.Resume; >Resume : AdvEvents.Resume adv = BasicEvents.Start; ->adv = BasicEvents.Start : BasicEvents.Start +>adv = BasicEvents.Start : BasicEvents >adv : AdvEvents ->BasicEvents.Start : BasicEvents.Start +>BasicEvents.Start : BasicEvents >BasicEvents : typeof BasicEvents ->Start : BasicEvents.Start +>Start : BasicEvents adv = BasicEvents.Finish; ->adv = BasicEvents.Finish : BasicEvents.Finish +>adv = BasicEvents.Finish : BasicEvents >adv : AdvEvents ->BasicEvents.Finish : BasicEvents.Finish +>BasicEvents.Finish : BasicEvents >BasicEvents : typeof BasicEvents ->Finish : BasicEvents.Finish +>Finish : BasicEvents diff --git a/tests/baselines/reference/spreadEnum2.types b/tests/baselines/reference/spreadEnum2.types index 406600945377c..0a6f97337206d 100644 --- a/tests/baselines/reference/spreadEnum2.types +++ b/tests/baselines/reference/spreadEnum2.types @@ -56,9 +56,9 @@ enum E { } A.AA; ->A.AA : A.AA +>A.AA : A >A : typeof A ->AA : A.AA +>AA : A B.AA; >B.AA : A.AA @@ -66,9 +66,9 @@ B.AA; >AA : A.AA B.BB; ->B.BB : B.BB +>B.BB : B >B : typeof B ->BB : B.BB +>BB : B C.AA; >C.AA : A @@ -81,9 +81,9 @@ C.BB; >BB : B.BB C.CC; ->C.CC : C.CC +>C.CC : C >C : typeof C ->CC : C.CC +>CC : C D.AA; >D.AA : A @@ -101,9 +101,9 @@ D.CC; >CC : C.CC D.DD; ->D.DD : D.DD +>D.DD : D >D : typeof D ->DD : D.DD +>DD : D E.AA; >E.AA : A diff --git a/tests/baselines/reference/spreadEnum3.types b/tests/baselines/reference/spreadEnum3.types index 9856c8657a52d..b9ac47b364473 100644 --- a/tests/baselines/reference/spreadEnum3.types +++ b/tests/baselines/reference/spreadEnum3.types @@ -71,15 +71,15 @@ enum NumericEnum2 { A = LiteralEnum1.A, >A : NumericEnum2 ->LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1.A : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->A : LiteralEnum1.A +>A : LiteralEnum1 B = LiteralEnum2.B >B : NumericEnum2 ->LiteralEnum2.B : LiteralEnum2.B +>LiteralEnum2.B : LiteralEnum2 >LiteralEnum2 : typeof LiteralEnum2 ->B : LiteralEnum2.B +>B : LiteralEnum2 } enum NumericEnum3 { @@ -88,16 +88,16 @@ enum NumericEnum3 { ['A'] = LiteralEnum1.A, >['A'] : NumericEnum3 >'A' : "A" ->LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1.A : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->A : LiteralEnum1.A +>A : LiteralEnum1 ['B'] = LiteralEnum2.B >['B'] : NumericEnum3 >'B' : "B" ->LiteralEnum2.B : LiteralEnum2.B +>LiteralEnum2.B : LiteralEnum2 >LiteralEnum2 : typeof LiteralEnum2 ->B : LiteralEnum2.B +>B : LiteralEnum2 } const enum ConstEnum { diff --git a/tests/baselines/reference/spreadEnum5.types b/tests/baselines/reference/spreadEnum5.types index 5db60b5b2d8c5..8a4a8fced9e88 100644 --- a/tests/baselines/reference/spreadEnum5.types +++ b/tests/baselines/reference/spreadEnum5.types @@ -55,24 +55,24 @@ const enum R3 { } LiteralEnum1.A; ->LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1.A : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->A : LiteralEnum1.A +>A : LiteralEnum1 LiteralEnum1.B; ->LiteralEnum1.B : LiteralEnum1.B +>LiteralEnum1.B : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->B : LiteralEnum1.B +>B : LiteralEnum1 ConstEnum.A; ->ConstEnum.A : ConstEnum.A +>ConstEnum.A : ConstEnum >ConstEnum : typeof ConstEnum ->A : ConstEnum.A +>A : ConstEnum ConstEnum.B; ->ConstEnum.B : ConstEnum.B +>ConstEnum.B : ConstEnum >ConstEnum : typeof ConstEnum ->B : ConstEnum.B +>B : ConstEnum R1.A; >R1.A : ConstEnum.A diff --git a/tests/baselines/reference/spreadEnum6.types b/tests/baselines/reference/spreadEnum6.types index e5dd09d175435..e1bdb9575ac2a 100644 --- a/tests/baselines/reference/spreadEnum6.types +++ b/tests/baselines/reference/spreadEnum6.types @@ -97,24 +97,24 @@ enum R3 { } LiteralEnum1.A; ->LiteralEnum1.A : LiteralEnum1.A +>LiteralEnum1.A : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->A : LiteralEnum1.A +>A : LiteralEnum1 LiteralEnum1.B; ->LiteralEnum1.B : LiteralEnum1.B +>LiteralEnum1.B : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->B : LiteralEnum1.B +>B : LiteralEnum1 LiteralEnum1.C; ->LiteralEnum1.C : LiteralEnum1.A +>LiteralEnum1.C : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->C : LiteralEnum1.A +>C : LiteralEnum1 LiteralEnum1.D; ->LiteralEnum1.D : LiteralEnum1.B +>LiteralEnum1.D : LiteralEnum1 >LiteralEnum1 : typeof LiteralEnum1 ->D : LiteralEnum1.B +>D : LiteralEnum1 R1.A; >R1.A : LiteralEnum1.A @@ -137,34 +137,34 @@ R1.D; >D : LiteralEnum1.B R1.R1; ->R1.R1 : R1.R1 +>R1.R1 : R1 >R1 : typeof R1 ->R1 : R1.R1 +>R1 : R1 R1.R11; ->R1.R11 : R1.R11 +>R1.R11 : R1 >R1 : typeof R1 ->R11 : R1.R11 +>R11 : R1 LiteralEnum2.E; ->LiteralEnum2.E : LiteralEnum2.E +>LiteralEnum2.E : LiteralEnum2 >LiteralEnum2 : typeof LiteralEnum2 ->E : LiteralEnum2.E +>E : LiteralEnum2 LiteralEnum2.F; ->LiteralEnum2.F : LiteralEnum2.F +>LiteralEnum2.F : LiteralEnum2 >LiteralEnum2 : typeof LiteralEnum2 ->F : LiteralEnum2.F +>F : LiteralEnum2 LiteralEnum2.G; ->LiteralEnum2.G : LiteralEnum2.E +>LiteralEnum2.G : LiteralEnum2 >LiteralEnum2 : typeof LiteralEnum2 ->G : LiteralEnum2.E +>G : LiteralEnum2 LiteralEnum2.H; ->LiteralEnum2.H : LiteralEnum2.F +>LiteralEnum2.H : LiteralEnum2 >LiteralEnum2 : typeof LiteralEnum2 ->H : LiteralEnum2.F +>H : LiteralEnum2 R2.A; >R2.A : LiteralEnum1 @@ -207,14 +207,14 @@ R2.H; >H : LiteralEnum1.B R2.R2; ->R2.R2 : R2.R2 +>R2.R2 : R2 >R2 : typeof R2 ->R2 : R2.R2 +>R2 : R2 R2.R22 ->R2.R22 : R2.R22 +>R2.R22 : R2 >R2 : typeof R2 ->R22 : R2.R22 +>R22 : R2 R3.A; >R3.A : LiteralEnum1 diff --git a/tests/baselines/reference/spreadEnum7.errors.txt b/tests/baselines/reference/spreadEnum7.errors.txt index fd55cf8eece03..d7c8990068088 100644 --- a/tests/baselines/reference/spreadEnum7.errors.txt +++ b/tests/baselines/reference/spreadEnum7.errors.txt @@ -1,10 +1,28 @@ tests/cases/conformance/enums/spreadEnum7.ts(2,8): error TS2450: Enum 'LiteralEnum1' used before its declaration. +tests/cases/conformance/enums/spreadEnum7.ts(7,5): error TS2300: Duplicate identifier 'A'. +tests/cases/conformance/enums/spreadEnum7.ts(8,5): error TS2300: Duplicate identifier 'B'. +tests/cases/conformance/enums/spreadEnum7.ts(12,8): error TS1397: Spread enum member has overlapped on 'R2'. tests/cases/conformance/enums/spreadEnum7.ts(12,8): error TS2450: Enum 'R3' used before its declaration. +tests/cases/conformance/enums/spreadEnum7.ts(13,5): error TS2300: Duplicate identifier 'R2'. +tests/cases/conformance/enums/spreadEnum7.ts(33,8): error TS1397: Spread enum member has overlapped on 'A'. +tests/cases/conformance/enums/spreadEnum7.ts(33,8): error TS1397: Spread enum member has overlapped on 'B'. +tests/cases/conformance/enums/spreadEnum7.ts(34,8): error TS1397: Spread enum member has overlapped on 'A'. +tests/cases/conformance/enums/spreadEnum7.ts(34,8): error TS1397: Spread enum member has overlapped on 'B'. +tests/cases/conformance/enums/spreadEnum7.ts(39,5): error TS2300: Duplicate identifier 'A'. +tests/cases/conformance/enums/spreadEnum7.ts(40,5): error TS2300: Duplicate identifier 'B'. +tests/cases/conformance/enums/spreadEnum7.ts(41,8): error TS1397: Spread enum member has overlapped on 'A'. +tests/cases/conformance/enums/spreadEnum7.ts(41,8): error TS1397: Spread enum member has overlapped on 'B'. +tests/cases/conformance/enums/spreadEnum7.ts(58,5): error TS2300: Duplicate identifier 'B'. +tests/cases/conformance/enums/spreadEnum7.ts(59,8): error TS1397: Spread enum member has overlapped on 'A'. +tests/cases/conformance/enums/spreadEnum7.ts(59,8): error TS1397: Spread enum member has overlapped on 'B'. +tests/cases/conformance/enums/spreadEnum7.ts(60,5): error TS2300: Duplicate identifier 'A'. +tests/cases/conformance/enums/spreadEnum7.ts(64,8): error TS1397: Spread enum member has overlapped on 'R88'. tests/cases/conformance/enums/spreadEnum7.ts(64,8): error TS1398: Spread enum member cannot reference to itself. +tests/cases/conformance/enums/spreadEnum7.ts(65,5): error TS2300: Duplicate identifier 'R88'. tests/cases/conformance/enums/spreadEnum7.ts(69,8): error TS1394: Enum expected. -==== tests/cases/conformance/enums/spreadEnum7.ts (4 errors) ==== +==== tests/cases/conformance/enums/spreadEnum7.ts (22 errors) ==== enum R1 { ...LiteralEnum1, ~~~~~~~~~~~~ @@ -15,15 +33,28 @@ tests/cases/conformance/enums/spreadEnum7.ts(69,8): error TS1394: Enum expected. enum LiteralEnum1 { A, + ~ +!!! error TS2300: Duplicate identifier 'A'. +!!! related TS6203 tests/cases/conformance/enums/spreadEnum7.ts:39:5: 'A' was also declared here. +!!! related TS6204 tests/cases/conformance/enums/spreadEnum7.ts:60:5: and here. B + ~ +!!! error TS2300: Duplicate identifier 'B'. +!!! related TS6203 tests/cases/conformance/enums/spreadEnum7.ts:40:5: 'B' was also declared here. +!!! related TS6204 tests/cases/conformance/enums/spreadEnum7.ts:58:5: and here. } enum R2 { ...R3, ~~ +!!! error TS1397: Spread enum member has overlapped on 'R2'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:13:5: 'R2' is declared here. + ~~ !!! error TS2450: Enum 'R3' used before its declaration. !!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:16:6: 'R3' is declared here. R2 = 'R2' + ~~ +!!! error TS2300: Duplicate identifier 'R2'. } enum R3 { @@ -44,14 +75,38 @@ tests/cases/conformance/enums/spreadEnum7.ts(69,8): error TS1394: Enum expected. enum R6 { ...LiteralEnum1, ...R4, + ~~ +!!! error TS1397: Spread enum member has overlapped on 'A'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:7:5: 'A' is declared here. + ~~ +!!! error TS1397: Spread enum member has overlapped on 'B'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:8:5: 'B' is declared here. ...R5, + ~~ +!!! error TS1397: Spread enum member has overlapped on 'A'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:7:5: 'A' is declared here. + ~~ +!!! error TS1397: Spread enum member has overlapped on 'B'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:8:5: 'B' is declared here. R6 = 'R6' } enum R66 { A, + ~ +!!! error TS2300: Duplicate identifier 'A'. +!!! related TS6203 tests/cases/conformance/enums/spreadEnum7.ts:7:5: 'A' was also declared here. B, + ~ +!!! error TS2300: Duplicate identifier 'B'. +!!! related TS6203 tests/cases/conformance/enums/spreadEnum7.ts:8:5: 'B' was also declared here. ...LiteralEnum1, + ~~~~~~~~~~~~ +!!! error TS1397: Spread enum member has overlapped on 'A'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:39:5: 'A' is declared here. + ~~~~~~~~~~~~ +!!! error TS1397: Spread enum member has overlapped on 'B'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:40:5: 'B' is declared here. } enum PartEnum1 { @@ -69,15 +124,32 @@ tests/cases/conformance/enums/spreadEnum7.ts(69,8): error TS1394: Enum expected. enum R7 { B = 'B', + ~ +!!! error TS2300: Duplicate identifier 'B'. +!!! related TS6203 tests/cases/conformance/enums/spreadEnum7.ts:8:5: 'B' was also declared here. ...LiteralEnum1, + ~~~~~~~~~~~~ +!!! error TS1397: Spread enum member has overlapped on 'A'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:60:5: 'A' is declared here. + ~~~~~~~~~~~~ +!!! error TS1397: Spread enum member has overlapped on 'B'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:58:5: 'B' is declared here. A = 'A' + ~ +!!! error TS2300: Duplicate identifier 'A'. +!!! related TS6203 tests/cases/conformance/enums/spreadEnum7.ts:7:5: 'A' was also declared here. } enum R8 { ...R8, ~~ +!!! error TS1397: Spread enum member has overlapped on 'R88'. +!!! related TS2728 tests/cases/conformance/enums/spreadEnum7.ts:65:5: 'R88' is declared here. + ~~ !!! error TS1398: Spread enum member cannot reference to itself. R88 = 'R88' + ~~~ +!!! error TS2300: Duplicate identifier 'R88'. } enum R9 { From 4aa1fc36453a28ea1a1b8f99d4708993dcbe94fb Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Tue, 13 Oct 2020 12:01:44 +0800 Subject: [PATCH 21/21] Add test again (#5) --- src/compiler/checker.ts | 22 +++++++++++++++++++++- src/compiler/types.ts | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 11ca8d273f8a2..9ddd8384a90b0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3471,8 +3471,28 @@ namespace ts { : getPropertyOfType(type, memberName); } + function isLateBindingContainer(symbol: Symbol): boolean { + if (!(symbol.flags & (SymbolFlags.LateBindingContainer | SymbolFlags.Enum))) { + return false; + } + + if (symbol.flags & SymbolFlags.Enum) { + const links = getSymbolLinks(symbol); + if (links.enumHasLateBoundMember === undefined) { + for (const declaration of symbol.declarations) { + if (isEnumDeclaration(declaration) && some(declaration.members, isSpreadEnumMember)) { + return links.enumHasLateBoundMember = true; + } + } + return links.enumHasLateBoundMember = false; + } + return links.enumHasLateBoundMember; + } + return true; + } + function getExportsOfSymbol(symbol: Symbol): SymbolTable { - return symbol.flags & SymbolFlags.LateBindingContainer ? getResolvedMembersOrExportsOfSymbol(symbol, MembersOrExportsResolutionKind.resolvedExports) : + return isLateBindingContainer(symbol) ? getResolvedMembersOrExportsOfSymbol(symbol, MembersOrExportsResolutionKind.resolvedExports) : symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : symbol.exports || emptySymbols; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6b849cee72ffc..7ab7efdbf7dca 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4642,7 +4642,7 @@ namespace ts { Classifiable = Class | Enum | TypeAlias | Interface | TypeParameter | Module | Alias, /* @internal */ - LateBindingContainer = Class | Interface | TypeLiteral | ObjectLiteral | Function | Enum, + LateBindingContainer = Class | Interface | TypeLiteral | ObjectLiteral | Function, } /* @internal */ @@ -4707,6 +4707,7 @@ namespace ts { typeOnlyDeclaration?: TypeOnlyCompatibleAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label + enumHasLateBoundMember?: boolean // True if enum declaration contains spread enum member } /* @internal */