diff --git a/src/compiler.ts b/src/compiler.ts index 0dbdccf3ae..0dd2b2b024 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -285,8 +285,8 @@ export class Compiler extends DiagnosticEmitter { currentFlow: Flow; /** Current inline functions stack. */ currentInlineFunctions: Function[] = []; - /** Current enum in compilation. */ - currentEnum: Enum | null = null; + /** Current parent element if not a function, i.e. an enum or namespace. */ + currentParent: Element | null = null; /** Current type in compilation. */ currentType: Type = Type.void; /** Start function statements. */ @@ -987,7 +987,8 @@ export class Compiler extends DiagnosticEmitter { element.set(CommonFlags.COMPILED); var module = this.module; - this.currentEnum = element; + var previousParent = this.currentParent; + this.currentParent = element; var previousValue: EnumValue | null = null; var previousValueIsMut = false; var isInline = element.is(CommonFlags.CONST) || element.hasDecorator(DecoratorFlags.INLINE); @@ -1066,7 +1067,7 @@ export class Compiler extends DiagnosticEmitter { previousValue = val; } } - this.currentEnum = null; + this.currentParent = previousParent; return true; } @@ -1622,9 +1623,6 @@ export class Compiler extends DiagnosticEmitter { // === Statements =============================================================================== compileTopLevelStatement(statement: Statement, body: ExpressionRef[]): void { - if (statement.kind == NodeKind.EXPORTDEFAULT) { - statement = (statement).declaration; - } switch (statement.kind) { case NodeKind.CLASSDECLARATION: { let memberStatements = (statement).members; @@ -1642,9 +1640,16 @@ export class Compiler extends DiagnosticEmitter { break; } case NodeKind.NAMESPACEDECLARATION: { - let memberStatements = (statement).members; - for (let i = 0, k = memberStatements.length; i < k; ++i) { - this.compileTopLevelStatement(memberStatements[i], body); + let element = this.program.getElementByDeclaration(statement); + if (element) { + // any potentiall merged element + let previousParent = this.currentParent; + this.currentParent = element; + let memberStatements = (statement).members; + for (let i = 0, k = memberStatements.length; i < k; ++i) { + this.compileTopLevelStatement(memberStatements[i], body); + } + this.currentParent = previousParent; } break; } @@ -1678,6 +1683,10 @@ export class Compiler extends DiagnosticEmitter { } break; } + case NodeKind.EXPORTDEFAULT: { + this.compileTopLevelStatement((statement).declaration, body); + break; + } case NodeKind.IMPORT: { this.compileFileByPath( (statement).internalPath, @@ -7209,7 +7218,7 @@ export class Compiler extends DiagnosticEmitter { var target = this.resolver.lookupIdentifierExpression( // reports expression, flow, - this.currentEnum || actualFunction + this.currentParent || actualFunction ); if (!target) return module.unreachable(); diff --git a/tests/compiler/features/simd.optimized.wat b/tests/compiler/features/simd.optimized.wat index eefe5781a4..b2f1ecb7ca 100644 --- a/tests/compiler/features/simd.optimized.wat +++ b/tests/compiler/features/simd.optimized.wat @@ -93,7 +93,7 @@ if i32.const 0 i32.const 24 - i32.const 71 + i32.const 70 i32.const 2 call $~lib/builtins/abort unreachable @@ -108,7 +108,7 @@ if i32.const 0 i32.const 24 - i32.const 73 + i32.const 72 i32.const 13 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/features/simd.untouched.wat b/tests/compiler/features/simd.untouched.wat index 69b7e1d2a6..48d7eb9171 100644 --- a/tests/compiler/features/simd.untouched.wat +++ b/tests/compiler/features/simd.untouched.wat @@ -144,7 +144,7 @@ if i32.const 0 i32.const 24 - i32.const 71 + i32.const 70 i32.const 2 call $~lib/builtins/abort unreachable @@ -161,7 +161,7 @@ if i32.const 0 i32.const 24 - i32.const 73 + i32.const 72 i32.const 13 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/namespace.optimized.wat b/tests/compiler/namespace.optimized.wat index e2acb0a3b8..44951b0929 100644 --- a/tests/compiler/namespace.optimized.wat +++ b/tests/compiler/namespace.optimized.wat @@ -1,8 +1,17 @@ (module (type $FUNCSIG$v (func)) (memory $0 0) + (global $namespace/Outer.Inner.anotherVar (mut i32) (i32.const 0)) + (global $namespace/Outer.Inner.evenAnotherVar (mut i32) (i32.const 0)) (export "memory" (memory $0)) + (start $start) (func $start (; 0 ;) (type $FUNCSIG$v) + i32.const 0 + global.set $namespace/Outer.Inner.anotherVar + i32.const 1 + global.set $namespace/Outer.Inner.evenAnotherVar + ) + (func $null (; 1 ;) (type $FUNCSIG$v) nop ) ) diff --git a/tests/compiler/namespace.ts b/tests/compiler/namespace.ts index e23c100a9a..ad3d8493bb 100644 --- a/tests/compiler/namespace.ts +++ b/tests/compiler/namespace.ts @@ -1,6 +1,9 @@ namespace Outer { + export var outerVar: i32 = 1; export namespace Inner { export var aVar: i32 = 0; + export var anotherVar: i32 = aVar; + export var evenAnotherVar: i32 = outerVar; export function aFunc(): i32 { return aVar; } export enum anEnum { ONE = 1, TWO = 2 } export const enum aConstEnum { ONE = 1, TWO = 2 } diff --git a/tests/compiler/namespace.untouched.wat b/tests/compiler/namespace.untouched.wat index 39966a5e53..9893d869ba 100644 --- a/tests/compiler/namespace.untouched.wat +++ b/tests/compiler/namespace.untouched.wat @@ -4,7 +4,10 @@ (memory $0 0) (table $0 1 funcref) (elem (i32.const 0) $null) + (global $namespace/Outer.outerVar (mut i32) (i32.const 1)) (global $namespace/Outer.Inner.aVar (mut i32) (i32.const 0)) + (global $namespace/Outer.Inner.anotherVar (mut i32) (i32.const 0)) + (global $namespace/Outer.Inner.evenAnotherVar (mut i32) (i32.const 0)) (global $namespace/Outer.Inner.anEnum.ONE i32 (i32.const 1)) (global $namespace/Outer.Inner.anEnum.TWO i32 (i32.const 2)) (export "memory" (memory $0)) @@ -16,6 +19,10 @@ i32.const 3 ) (func $start:namespace (; 2 ;) (type $FUNCSIG$v) + global.get $namespace/Outer.Inner.aVar + global.set $namespace/Outer.Inner.anotherVar + global.get $namespace/Outer.outerVar + global.set $namespace/Outer.Inner.evenAnotherVar global.get $namespace/Outer.Inner.aVar drop call $namespace/Outer.Inner.aFunc