|
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