Skip to content

Const enums #970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Nov 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0d171ca
initial implementation of constant folding
vladima Oct 26, 2014
97460f5
handle non-qualified names, add 'propagateEnumConstants' command line…
vladima Oct 26, 2014
ce336bc
added folding for references to enum members in enum member initializ…
vladima Oct 26, 2014
365587f
addressed CR feedback, added support for indexed access
vladima Oct 27, 2014
cb472eb
move code around to consolidate checks in one place
vladima Oct 27, 2014
03cb645
dropped redundand type assertion, added mising check
vladima Oct 27, 2014
329d6e2
merge with master
vladima Oct 28, 2014
2dd9511
'const enum' iteration 0. TODO: allow and track const enums in import…
vladima Oct 28, 2014
6f4ea86
merge with master
vladima Oct 29, 2014
e949eda
const enums, iteration 1: const enums can be used in imports, const e…
vladima Oct 29, 2014
4aa4ea7
allow arithmetic operations in constant expressions, handle infinity\…
vladima Oct 30, 2014
270d187
addressed CR feedback
vladima Oct 30, 2014
dd57c6c
added .d.ts generation tests
vladima Oct 31, 2014
ac54fbf
set 'earlyError' bit to 'non-constant expression in constant enum ini…
vladima Oct 31, 2014
7d80b71
do not treat module that contains only const enums as instantiated
vladima Nov 1, 2014
8662c68
add test for 'preserveConstEnums' command line argument
vladima Nov 1, 2014
0b738e8
merge with master
vladima Nov 1, 2014
2d94030
inline enum constant values for indexed access when index is string l…
vladima Nov 2, 2014
4d354c0
addressed CR feedback: adjusted text of error messages, added descrip…
vladima Nov 3, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 57 additions & 15 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,51 @@

module ts {

export function isInstantiated(node: Node): boolean {
export enum ModuleInstanceState {
NonInstantiated = 0,
Instantiated = 1,
ConstEnumOnly = 2
}

export function getModuleInstanceState(node: Node): ModuleInstanceState {
// A module is uninstantiated if it contains only
// 1. interface declarations
if (node.kind === SyntaxKind.InterfaceDeclaration) {
return false;
return ModuleInstanceState.NonInstantiated;
}
// 2. non - exported import declarations
// 2. const enum declarations don't make module instantiated
else if (node.kind === SyntaxKind.EnumDeclaration && isConstEnumDeclaration(<EnumDeclaration>node)) {
return ModuleInstanceState.ConstEnumOnly;
}
// 3. non - exported import declarations
else if (node.kind === SyntaxKind.ImportDeclaration && !(node.flags & NodeFlags.Export)) {
return false;
return ModuleInstanceState.NonInstantiated;
}
// 3. other uninstantiated module declarations.
else if (node.kind === SyntaxKind.ModuleBlock && !forEachChild(node, isInstantiated)) {
return false;
// 4. other uninstantiated module declarations.
else if (node.kind === SyntaxKind.ModuleBlock) {
var state = ModuleInstanceState.NonInstantiated;
forEachChild(node, n => {
switch (getModuleInstanceState(n)) {
case ModuleInstanceState.NonInstantiated:
// child is non-instantiated - continue searching
return false;
case ModuleInstanceState.ConstEnumOnly:
// child is const enum only - record state and continue searching
state = ModuleInstanceState.ConstEnumOnly;
return false;
case ModuleInstanceState.Instantiated:
// child is instantiated - record state and stop
state = ModuleInstanceState.Instantiated;
return true;
}
});
return state;
}
else if (node.kind === SyntaxKind.ModuleDeclaration && !isInstantiated((<ModuleDeclaration>node).body)) {
return false;
else if (node.kind === SyntaxKind.ModuleDeclaration) {
return getModuleInstanceState((<ModuleDeclaration>node).body);
}
else {
return true;
return ModuleInstanceState.Instantiated;
}
}

Expand Down Expand Up @@ -248,11 +274,22 @@ module ts {
if (node.name.kind === SyntaxKind.StringLiteral) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
}
else if (isInstantiated(node)) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
}
else {
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true);
var state = getModuleInstanceState(node);
if (state === ModuleInstanceState.NonInstantiated) {
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true);
}
else {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
if (state === ModuleInstanceState.ConstEnumOnly) {
// mark value module as module that contains only enums
node.symbol.constEnumOnlyModule = true;
}
else if (node.symbol.constEnumOnlyModule) {
// const only value module was merged with instantiated module - reset flag
node.symbol.constEnumOnlyModule = false;
}
}
}
}

Expand Down Expand Up @@ -364,7 +401,12 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.EnumDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Enum, SymbolFlags.EnumExcludes, /*isBlockScopeContainer*/ false);
if (isConstEnumDeclaration(<EnumDeclaration>node)) {
bindDeclaration(<Declaration>node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes, /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes, /*isBlockScopeContainer*/ false);
}
break;
case SyntaxKind.ModuleDeclaration:
bindModuleDeclaration(<ModuleDeclaration>node);
Expand Down
Loading