5
5
6
6
module ts {
7
7
8
- export function isInstantiated ( node : Node ) : boolean {
8
+ export const enum ModuleInstanceState {
9
+ NonInstantiated = 0 ,
10
+ Instantiated = 1 ,
11
+ ConstEnumOnly = 2
12
+ }
13
+
14
+ export function getModuleInstanceState ( node : Node ) : ModuleInstanceState {
9
15
// A module is uninstantiated if it contains only
10
16
// 1. interface declarations
11
17
if ( node . kind === SyntaxKind . InterfaceDeclaration ) {
12
- return false ;
18
+ return ModuleInstanceState . NonInstantiated ;
13
19
}
14
- // 2. non - exported import declarations
20
+ // 2. const enum declarations don't make module instantiated
21
+ else if ( node . kind === SyntaxKind . EnumDeclaration && isConstEnumDeclaration ( < EnumDeclaration > node ) ) {
22
+ return ModuleInstanceState . ConstEnumOnly ;
23
+ }
24
+ // 3. non - exported import declarations
15
25
else if ( node . kind === SyntaxKind . ImportDeclaration && ! ( node . flags & NodeFlags . Export ) ) {
16
- return false ;
26
+ return ModuleInstanceState . NonInstantiated ;
17
27
}
18
- // 3. other uninstantiated module declarations.
19
- else if ( node . kind === SyntaxKind . ModuleBlock && ! forEachChild ( node , isInstantiated ) ) {
20
- return false ;
28
+ // 4. other uninstantiated module declarations.
29
+ else if ( node . kind === SyntaxKind . ModuleBlock ) {
30
+ var state = ModuleInstanceState . NonInstantiated ;
31
+ forEachChild ( node , n => {
32
+ switch ( getModuleInstanceState ( n ) ) {
33
+ case ModuleInstanceState . NonInstantiated :
34
+ // child is non-instantiated - continue searching
35
+ return false ;
36
+ case ModuleInstanceState . ConstEnumOnly :
37
+ // child is const enum only - record state and continue searching
38
+ state = ModuleInstanceState . ConstEnumOnly ;
39
+ return false ;
40
+ case ModuleInstanceState . Instantiated :
41
+ // child is instantiated - record state and stop
42
+ state = ModuleInstanceState . Instantiated ;
43
+ return true ;
44
+ }
45
+ } ) ;
46
+ return state ;
21
47
}
22
- else if ( node . kind === SyntaxKind . ModuleDeclaration && ! isInstantiated ( ( < ModuleDeclaration > node ) . body ) ) {
23
- return false ;
48
+ else if ( node . kind === SyntaxKind . ModuleDeclaration ) {
49
+ return getModuleInstanceState ( ( < ModuleDeclaration > node ) . body ) ;
24
50
}
25
51
else {
26
- return true ;
52
+ return ModuleInstanceState . Instantiated ;
27
53
}
28
54
}
29
55
@@ -58,12 +84,13 @@ module ts {
58
84
if ( symbolKind & SymbolFlags . Value && ! symbol . valueDeclaration ) symbol . valueDeclaration = node ;
59
85
}
60
86
87
+ // TODO(jfreeman): Implement getDeclarationName for property name
61
88
function getDeclarationName ( node : Declaration ) : string {
62
89
if ( node . name ) {
63
90
if ( node . kind === SyntaxKind . ModuleDeclaration && node . name . kind === SyntaxKind . StringLiteral ) {
64
- return '"' + node . name . text + '"' ;
91
+ return '"' + ( < LiteralExpression > node . name ) . text + '"' ;
65
92
}
66
- return node . name . text ;
93
+ return ( < Identifier > node . name ) . text ;
67
94
}
68
95
switch ( node . kind ) {
69
96
case SyntaxKind . Constructor : return "__constructor" ;
@@ -74,7 +101,7 @@ module ts {
74
101
}
75
102
76
103
function getDisplayName ( node : Declaration ) : string {
77
- return node . name ? identifierToString ( node . name ) : getDeclarationName ( node ) ;
104
+ return node . name ? declarationNameToString ( node . name ) : getDeclarationName ( node ) ;
78
105
}
79
106
80
107
function declareSymbol ( symbols : SymbolTable , parent : Symbol , node : Declaration , includes : SymbolFlags , excludes : SymbolFlags ) : Symbol {
@@ -248,11 +275,22 @@ module ts {
248
275
if ( node . name . kind === SyntaxKind . StringLiteral ) {
249
276
bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
250
277
}
251
- else if ( isInstantiated ( node ) ) {
252
- bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
253
- }
254
278
else {
255
- bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes , /*isBlockScopeContainer*/ true ) ;
279
+ var state = getModuleInstanceState ( node ) ;
280
+ if ( state === ModuleInstanceState . NonInstantiated ) {
281
+ bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes , /*isBlockScopeContainer*/ true ) ;
282
+ }
283
+ else {
284
+ bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
285
+ if ( state === ModuleInstanceState . ConstEnumOnly ) {
286
+ // mark value module as module that contains only enums
287
+ node . symbol . constEnumOnlyModule = true ;
288
+ }
289
+ else if ( node . symbol . constEnumOnlyModule ) {
290
+ // const only value module was merged with instantiated module - reset flag
291
+ node . symbol . constEnumOnlyModule = false ;
292
+ }
293
+ }
256
294
}
257
295
}
258
296
@@ -360,8 +398,16 @@ module ts {
360
398
case SyntaxKind . InterfaceDeclaration :
361
399
bindDeclaration ( < Declaration > node , SymbolFlags . Interface , SymbolFlags . InterfaceExcludes , /*isBlockScopeContainer*/ false ) ;
362
400
break ;
401
+ case SyntaxKind . TypeAliasDeclaration :
402
+ bindDeclaration ( < Declaration > node , SymbolFlags . TypeAlias , SymbolFlags . TypeAliasExcludes , /*isBlockScopeContainer*/ false ) ;
403
+ break ;
363
404
case SyntaxKind . EnumDeclaration :
364
- bindDeclaration ( < Declaration > node , SymbolFlags . Enum , SymbolFlags . EnumExcludes , /*isBlockScopeContainer*/ false ) ;
405
+ if ( isConstEnumDeclaration ( < EnumDeclaration > node ) ) {
406
+ bindDeclaration ( < Declaration > node , SymbolFlags . ConstEnum , SymbolFlags . ConstEnumExcludes , /*isBlockScopeContainer*/ false ) ;
407
+ }
408
+ else {
409
+ bindDeclaration ( < Declaration > node , SymbolFlags . RegularEnum , SymbolFlags . RegularEnumExcludes , /*isBlockScopeContainer*/ false ) ;
410
+ }
365
411
break ;
366
412
case SyntaxKind . ModuleDeclaration :
367
413
bindModuleDeclaration ( < ModuleDeclaration > node ) ;
0 commit comments