diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index f835afff31f..b571530c5d9 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -26,7 +26,7 @@ namespace ts { return ModuleInstanceState.NonInstantiated; // 2. const enum declarations case SyntaxKind.EnumDeclaration: - if (isConst(node)) { + if (isEnumConst(node as EnumDeclaration)) { return ModuleInstanceState.ConstEnumOnly; } break; @@ -2611,7 +2611,7 @@ namespace ts { } function bindEnumDeclaration(node: EnumDeclaration) { - return isConst(node) + return isEnumConst(node) ? bindBlockScopedDeclaration(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) : bindBlockScopedDeclaration(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); } @@ -2768,7 +2768,7 @@ namespace ts { // report error on instantiated modules or const-enums only modules if preserveConstEnums is set (node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node)) || // report error on regular enums and const enums if preserveConstEnums is set - (node.kind === SyntaxKind.EnumDeclaration && (!isConstEnumDeclaration(node) || options.preserveConstEnums)); + (isEnumDeclaration(node) && (!isEnumConst(node) || options.preserveConstEnums)); if (reportError) { currentFlow = reportedUnreachableFlow; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 95103c1518e..b4651d711ee 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25185,7 +25185,7 @@ namespace ts { } // In ambient enum declarations that specify no const modifier, enum member declarations that omit // a value are considered computed members (as opposed to having auto-incremented values). - if (member.parent.flags & NodeFlags.Ambient && !isConst(member.parent)) { + if (member.parent.flags & NodeFlags.Ambient && !isEnumConst(member.parent)) { return undefined; } // If the member declaration specifies no value, the member is considered a constant enum member. @@ -25201,7 +25201,7 @@ namespace ts { function computeConstantValue(member: EnumMember): string | number | undefined { const enumKind = getEnumKind(getSymbolOfNode(member.parent)); - const isConstEnum = isConst(member.parent); + const isConstEnum = isEnumConst(member.parent); const initializer = member.initializer!; const value = enumKind === EnumKind.Literal && !isLiteralEnumMember(member) ? undefined : evaluate(initializer); if (value !== undefined) { @@ -25336,7 +25336,7 @@ namespace ts { computeEnumMemberValues(node); - const enumIsConst = isConst(node); + const enumIsConst = isEnumConst(node); if (compilerOptions.isolatedModules && enumIsConst && node.flags & NodeFlags.Ambient) { error(node.name, Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } @@ -25353,7 +25353,7 @@ namespace ts { if (enumSymbol.declarations.length > 1) { // check that const is placed\omitted on all enum declarations forEach(enumSymbol.declarations, decl => { - if (isConstEnumDeclaration(decl) !== enumIsConst) { + if (isEnumDeclaration(decl) && isEnumConst(decl) !== enumIsConst) { error(getNameOfDeclaration(decl), Diagnostics.Enum_declarations_must_all_be_const_or_non_const); } }); @@ -27217,8 +27217,9 @@ namespace ts { const symbol = getNodeLinks(node).resolvedSymbol; if (symbol && (symbol.flags & SymbolFlags.EnumMember)) { // inline property\index accesses only for const enums - if (isConstEnumDeclaration(symbol.valueDeclaration.parent)) { - return getEnumMemberValue(symbol.valueDeclaration); + const member = symbol.valueDeclaration as EnumMember; + if (isEnumConst(member.parent)) { + return getEnumMemberValue(member); } } @@ -27372,7 +27373,7 @@ namespace ts { } function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean { - if (isConst(node)) { + if (isVariableDeclaration(node) && isVarConst(node)) { const type = getTypeOfSymbol(getSymbolOfNode(node)); return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral); } @@ -28677,7 +28678,7 @@ namespace ts { if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) { if (node.flags & NodeFlags.Ambient) { if (node.initializer) { - if (isConst(node) && !node.type) { + if (isVarConst(node) && !node.type) { if (!isStringOrNumberLiteralExpression(node.initializer)) { return grammarErrorOnNode(node.initializer, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal); } @@ -28688,7 +28689,7 @@ namespace ts { return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } } - if (node.initializer && !(isConst(node) && isStringOrNumberLiteralExpression(node.initializer))) { + if (node.initializer && !(isVarConst(node) && isStringOrNumberLiteralExpression(node.initializer))) { // Error on equals token which immediate precedes the initializer const equalsTokenLength = "=".length; return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); @@ -28698,7 +28699,7 @@ namespace ts { if (isBindingPattern(node.name) && !isBindingPattern(node.parent)) { return grammarErrorOnNode(node, Diagnostics.A_destructuring_declaration_must_have_an_initializer); } - if (isConst(node)) { + if (isVarConst(node)) { return grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); } } @@ -28713,7 +28714,7 @@ namespace ts { checkESModuleMarker(node.name); } - const checkLetConstNames = (isLet(node) || isConst(node)); + const checkLetConstNames = (isLet(node) || isVarConst(node)); // 1. LexicalDeclaration : LetOrConst BindingList ; // It is a Syntax Error if the BoundNames of BindingList contains "let". @@ -28793,7 +28794,7 @@ namespace ts { if (isLet(node.declarationList)) { return grammarErrorOnNode(node, Diagnostics.let_declarations_can_only_be_declared_inside_a_block); } - else if (isConst(node.declarationList)) { + else if (isVarConst(node.declarationList)) { return grammarErrorOnNode(node, Diagnostics.const_declarations_can_only_be_declared_inside_a_block); } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6e9e747d19f..4d4c0130f69 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1983,7 +1983,7 @@ namespace ts { } function emitVariableDeclarationList(node: VariableDeclarationList) { - writeKeyword(isLet(node) ? "let" : isConst(node) ? "const" : "var"); + writeKeyword(isLet(node) ? "let" : isVarConst(node) ? "const" : "var"); writeSpace(); emitList(node, node.declarations, ListFormat.VariableDeclarationList); } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index e9507d6c8ff..a0d941f1def 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2602,7 +2602,7 @@ namespace ts { * @param node The enum declaration node. */ function shouldEmitEnumDeclaration(node: EnumDeclaration) { - return !isConst(node) + return !isEnumConst(node) || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 40cb2cc96e8..192e718f8e0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -897,13 +897,12 @@ namespace ts { return file.scriptKind === ScriptKind.JSON; } - export function isConstEnumDeclaration(node: Node): boolean { - return node.kind === SyntaxKind.EnumDeclaration && isConst(node); + export function isEnumConst(node: EnumDeclaration): boolean { + return !!(getCombinedModifierFlags(node) & ModifierFlags.Const); } - export function isConst(node: Node): boolean { - return !!(getCombinedNodeFlags(node) & NodeFlags.Const) - || !!(isDeclaration(node) && getCombinedModifierFlags(node) & ModifierFlags.Const); + export function isVarConst(node: VariableDeclaration | VariableDeclarationList): boolean { + return !!(getCombinedNodeFlags(node) & NodeFlags.Const); } export function isLet(node: Node): boolean { @@ -1184,7 +1183,7 @@ namespace ts { } export function isValidESSymbolDeclaration(node: Node): node is VariableDeclaration | PropertyDeclaration | SignatureDeclaration { - return isVariableDeclaration(node) ? isConst(node) && isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) : + return isVariableDeclaration(node) ? isVarConst(node) && isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) : isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) : isPropertySignature(node) && hasReadonlyModifier(node); } diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 5eb26dc21d6..018d4836807 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -49,7 +49,7 @@ namespace ts.SymbolDisplay { if (isFirstDeclarationOfSymbolParameter(symbol)) { return ScriptElementKind.parameterElement; } - else if (symbol.valueDeclaration && isConst(symbol.valueDeclaration)) { + else if (symbol.valueDeclaration && isVarConst(symbol.valueDeclaration as VariableDeclaration)) { return ScriptElementKind.constElement; } else if (forEach(symbol.declarations, isLet)) { @@ -298,7 +298,7 @@ namespace ts.SymbolDisplay { } if (symbolFlags & SymbolFlags.Enum) { prefixNextMeaning(); - if (forEach(symbol.declarations, isConstEnumDeclaration)) { + if (some(symbol.declarations, d => isEnumDeclaration(d) && isEnumConst(d))) { displayParts.push(keywordPart(SyntaxKind.ConstKeyword)); displayParts.push(spacePart()); } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 300a1a0a2e0..6e78adc1436 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -380,7 +380,7 @@ namespace ts { } function getKindOfVariableDeclaration(v: VariableDeclaration): ScriptElementKind { - return isConst(v) + return isVarConst(v) ? ScriptElementKind.constElement : isLet(v) ? ScriptElementKind.letElement diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1783064f309..1a2806cfacb 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6171,8 +6171,8 @@ declare namespace ts { function getErrorSpanForNode(sourceFile: SourceFile, node: Node): TextSpan; function isExternalOrCommonJsModule(file: SourceFile): boolean; function isJsonSourceFile(file: SourceFile): file is JsonSourceFile; - function isConstEnumDeclaration(node: Node): boolean; - function isConst(node: Node): boolean; + function isEnumConst(node: EnumDeclaration): boolean; + function isVarConst(node: VariableDeclaration | VariableDeclarationList): boolean; function isLet(node: Node): boolean; function isSuperCall(n: Node): n is SuperCall; function isImportCall(n: Node): n is ImportCall;