|
3 | 3 | * @license Apache-2.0 |
4 | 4 | */ |
5 | 5 |
|
| 6 | +// helper globals used by mangleImportName |
| 7 | +let mangleImportName_moduleName: string = ""; |
| 8 | +let mangleImportName_elementName: string = ""; |
| 9 | + |
6 | 10 | import { |
7 | 11 | BuiltinNames, |
8 | 12 | BuiltinFunctionContext, |
@@ -1097,6 +1101,20 @@ export class Compiler extends DiagnosticEmitter { |
1097 | 1101 |
|
1098 | 1102 | // === Globals ================================================================================== |
1099 | 1103 |
|
| 1104 | + /** Tries to compile a global variable lazily. */ |
| 1105 | + compileGlobalLazy(global: Global, reportNode: Node): bool { |
| 1106 | + if (global.is(CommonFlags.Compiled)) return !global.is(CommonFlags.Errored); |
| 1107 | + if (global.hasAnyDecorator(DecoratorFlags.Lazy | DecoratorFlags.Builtin) || global.is(CommonFlags.Ambient)) { |
| 1108 | + return this.compileGlobal(global); // compile now |
| 1109 | + } |
| 1110 | + // Otherwise the global is used before its initializer executes |
| 1111 | + this.errorRelated( |
| 1112 | + DiagnosticCode.Variable_0_used_before_its_declaration, |
| 1113 | + reportNode.range, global.identifierNode.range, global.internalName |
| 1114 | + ); |
| 1115 | + return false; |
| 1116 | + } |
| 1117 | + |
1100 | 1118 | /** Compiles a global variable. */ |
1101 | 1119 | compileGlobal(global: Global): bool { |
1102 | 1120 | if (global.is(CommonFlags.Compiled)) return !global.is(CommonFlags.Errored); |
@@ -5548,8 +5566,9 @@ export class Compiler extends DiagnosticEmitter { |
5548 | 5566 | let targetType: Type; |
5549 | 5567 | switch (target.kind) { |
5550 | 5568 | case ElementKind.Global: { |
5551 | | - // not yet compiled if a static field compiled as a global |
5552 | | - if (!this.compileGlobal(<Global>target)) return this.module.unreachable(); // reports |
| 5569 | + if (!this.compileGlobalLazy(<Global>target, expression)) { |
| 5570 | + return this.module.unreachable(); |
| 5571 | + } |
5553 | 5572 | // fall-through |
5554 | 5573 | } |
5555 | 5574 | case ElementKind.Local: { |
@@ -5691,7 +5710,9 @@ export class Compiler extends DiagnosticEmitter { |
5691 | 5710 | } |
5692 | 5711 | case ElementKind.Global: { |
5693 | 5712 | let global = <Global>target; |
5694 | | - if (!this.compileGlobal(global)) return module.unreachable(); |
| 5713 | + if (!this.compileGlobalLazy(global, valueExpression)) { |
| 5714 | + return module.unreachable(); |
| 5715 | + } |
5695 | 5716 | if (target.isAny(CommonFlags.Const | CommonFlags.Readonly)) { |
5696 | 5717 | this.error( |
5697 | 5718 | DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, |
@@ -6766,7 +6787,7 @@ export class Compiler extends DiagnosticEmitter { |
6766 | 6787 | let resolved = this.resolver.lookupExpression(initializer, instance.flow, parameterTypes[i], ReportMode.Swallow); |
6767 | 6788 | if (resolved && resolved.kind == ElementKind.Global) { |
6768 | 6789 | let global = <Global>resolved; |
6769 | | - if (this.compileGlobal(global) && global.is(CommonFlags.Inlined)) { |
| 6790 | + if (this.compileGlobalLazy(global, initializer) && global.is(CommonFlags.Inlined)) { |
6770 | 6791 | operands.push( |
6771 | 6792 | this.compileInlineConstant(global, parameterTypes[i], Constraints.ConvImplicit) |
6772 | 6793 | ); |
@@ -7329,7 +7350,7 @@ export class Compiler extends DiagnosticEmitter { |
7329 | 7350 | } |
7330 | 7351 | case ElementKind.Global: { |
7331 | 7352 | let global = <Global>target; |
7332 | | - if (!this.compileGlobal(global)) { // reports; not yet compiled if a static field |
| 7353 | + if (!this.compileGlobalLazy(global, expression)) { |
7333 | 7354 | return module.unreachable(); |
7334 | 7355 | } |
7335 | 7356 | let globalType = global.type; |
@@ -8895,7 +8916,9 @@ export class Compiler extends DiagnosticEmitter { |
8895 | 8916 | switch (target.kind) { |
8896 | 8917 | case ElementKind.Global: { // static field |
8897 | 8918 | let global = <Global>target; |
8898 | | - if (!this.compileGlobal(global)) return module.unreachable(); // reports |
| 8919 | + if (!this.compileGlobalLazy(global, expression)) { |
| 8920 | + return module.unreachable(); |
| 8921 | + } |
8899 | 8922 | let globalType = global.type; |
8900 | 8923 | assert(globalType != Type.void); |
8901 | 8924 | if (this.pendingElements.has(global)) { |
@@ -10388,6 +10411,7 @@ export class Compiler extends DiagnosticEmitter { |
10388 | 10411 | } |
10389 | 10412 |
|
10390 | 10413 | // helpers |
| 10414 | + |
10391 | 10415 | function mangleImportName( |
10392 | 10416 | element: Element, |
10393 | 10417 | declaration: DeclarationStatement |
@@ -10444,6 +10468,3 @@ function mangleImportName( |
10444 | 10468 | ); |
10445 | 10469 | } |
10446 | 10470 | } |
10447 | | - |
10448 | | -let mangleImportName_moduleName: string = ""; |
10449 | | -let mangleImportName_elementName: string = ""; |
|
0 commit comments