Fix enum tag circular references (#27161)

* Fix enum tag circular references

Also, don't try to resolve enum tag types in Typescript.

* Improve comment
This commit is contained in:
Nathan Shively-Sanders
2018-09-17 16:06:17 -07:00
committed by GitHub
parent e3026b0eb3
commit 59e4770a51
7 changed files with 50 additions and 3 deletions

View File

@@ -640,7 +640,7 @@ namespace ts {
const identityRelation = createMap<RelationComparisonResult>();
const enumRelation = createMap<RelationComparisonResult>();
type TypeSystemEntity = Symbol | Type | Signature;
type TypeSystemEntity = Node | Symbol | Type | Signature;
const enum TypeSystemPropertyName {
Type,
@@ -648,6 +648,7 @@ namespace ts {
DeclaredType,
ResolvedReturnType,
ImmediateBaseConstraint,
EnumTagType,
}
const enum CheckMode {
@@ -4475,6 +4476,8 @@ namespace ts {
switch (propertyName) {
case TypeSystemPropertyName.Type:
return !!getSymbolLinks(<Symbol>target).type;
case TypeSystemPropertyName.EnumTagType:
return !!(getNodeLinks(target as JSDocEnumTag).resolvedEnumType);
case TypeSystemPropertyName.DeclaredType:
return !!getSymbolLinks(<Symbol>target).declaredType;
case TypeSystemPropertyName.ResolvedBaseConstructorType:
@@ -8252,9 +8255,18 @@ namespace ts {
}
// JS are 'string' or 'number', not an enum type.
const enumTag = symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
const enumTag = isInJSFile(node) && symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
if (enumTag) {
return enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
const links = getNodeLinks(enumTag);
if (!pushTypeResolution(enumTag, TypeSystemPropertyName.EnumTagType)) {
return errorType;
}
let type = enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
if (!popTypeResolution()) {
type = errorType;
error(node, Diagnostics.Enum_type_0_circularly_references_itself, symbolToString(symbol));
}
return (links.resolvedEnumType = type);
}
// Get type from reference to named type that cannot be generic (enum or type parameter)

View File

@@ -2112,6 +2112,10 @@
"category": "Error",
"code": 2585
},
"Enum type '{0}' circularly references itself.": {
"category": "Error",
"code": 2586
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600

View File

@@ -3676,6 +3676,7 @@ namespace ts {
export interface NodeLinks {
flags: NodeCheckFlags; // Set of flags specific to Node
resolvedType?: Type; // Cached type of type node
resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag
resolvedSignature?: Signature; // Cached signature of signature node or call expression
resolvedSignatures?: Map<Signature[]>; // Cached signatures of jsx node
resolvedSymbol?: Symbol; // Cached name resolution result

View File

@@ -0,0 +1,9 @@
tests/cases/conformance/jsdoc/bug27142.js(1,12): error TS2586: Enum type 'E' circularly references itself.
==== tests/cases/conformance/jsdoc/bug27142.js (1 errors) ====
/** @enum {E} */
~
!!! error TS2586: Enum type 'E' circularly references itself.
const E = { x: 0 };

View File

@@ -0,0 +1,6 @@
=== tests/cases/conformance/jsdoc/bug27142.js ===
/** @enum {E} */
const E = { x: 0 };
>E : Symbol(E, Decl(bug27142.js, 1, 5))
>x : Symbol(x, Decl(bug27142.js, 1, 11))

View File

@@ -0,0 +1,8 @@
=== tests/cases/conformance/jsdoc/bug27142.js ===
/** @enum {E} */
const E = { x: 0 };
>E : { x: number; }
>{ x: 0 } : { x: number; }
>x : number
>0 : 0

View File

@@ -0,0 +1,7 @@
// @noEmit: true
// @allowJs: true
// @checkJs: true
// @Filename: bug27142.js
/** @enum {E} */
const E = { x: 0 };