From 2b7e30db66f402198ed5691cbae97618c6363859 Mon Sep 17 00:00:00 2001 From: dcode Date: Mon, 23 Sep 2019 15:42:14 +0200 Subject: [PATCH 1/3] Add resolve-propertyaccess test --- src/resolver.ts | 3 +- tests/compiler/resolve-propertyaccess.json | 5 + .../resolve-propertyaccess.optimized.wat | 397 ++++++++++ tests/compiler/resolve-propertyaccess.ts | 61 ++ .../resolve-propertyaccess.untouched.wat | 706 ++++++++++++++++++ 5 files changed, 1171 insertions(+), 1 deletion(-) create mode 100644 tests/compiler/resolve-propertyaccess.json create mode 100644 tests/compiler/resolve-propertyaccess.optimized.wat create mode 100644 tests/compiler/resolve-propertyaccess.ts create mode 100644 tests/compiler/resolve-propertyaccess.untouched.wat diff --git a/src/resolver.ts b/src/resolver.ts index 790345a48c..5239848576 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -1175,7 +1175,8 @@ export class Resolver extends DiagnosticEmitter { switch (target.kind) { case ElementKind.GLOBAL: if (!this.ensureResolvedLazyGlobal(target, reportMode)) return null; case ElementKind.LOCAL: - case ElementKind.FIELD: { // someVar.prop + case ElementKind.FIELD: + case ElementKind.ENUMVALUE: { // someVar.prop let type = (target).type; assert(type != Type.void); let classReference = type.classReference; if (!classReference) { diff --git a/tests/compiler/resolve-propertyaccess.json b/tests/compiler/resolve-propertyaccess.json new file mode 100644 index 0000000000..b1da366ff4 --- /dev/null +++ b/tests/compiler/resolve-propertyaccess.json @@ -0,0 +1,5 @@ +{ + "asc_flags": [ + "--runtime none" + ] +} \ No newline at end of file diff --git a/tests/compiler/resolve-propertyaccess.optimized.wat b/tests/compiler/resolve-propertyaccess.optimized.wat new file mode 100644 index 0000000000..a61a5bc68c --- /dev/null +++ b/tests/compiler/resolve-propertyaccess.optimized.wat @@ -0,0 +1,397 @@ +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (memory $0 1) + (data (i32.const 8) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\000") + (data (i32.const 32) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\001") + (data (i32.const 56) "2\00\00\00\01\00\00\00\01\00\00\002\00\00\00r\00e\00s\00o\00l\00v\00e\00-\00p\00r\00o\00p\00e\00r\00t\00y\00a\00c\00c\00e\00s\00s\00.\00t\00s") + (data (i32.const 128) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\002") + (data (i32.const 152) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\003") + (data (i32.const 176) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\004") + (data (i32.const 200) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\005") + (data (i32.const 224) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\006") + (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) + (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) + (export "memory" (memory $0)) + (start $start) + (func $~lib/util/number/decimalCount32 (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + i32.const 1 + i32.const 2 + local.get $0 + i32.const 10 + i32.lt_u + select + i32.const 3 + i32.const 4 + i32.const 5 + local.get $0 + i32.const 10000 + i32.lt_u + select + local.get $0 + i32.const 1000 + i32.lt_u + select + local.get $0 + i32.const 100 + i32.lt_u + select + i32.const 6 + i32.const 7 + local.get $0 + i32.const 1000000 + i32.lt_u + select + i32.const 8 + i32.const 9 + i32.const 10 + local.get $0 + i32.const 1000000000 + i32.lt_u + select + local.get $0 + i32.const 100000000 + i32.lt_u + select + local.get $0 + i32.const 10000000 + i32.lt_u + select + local.get $0 + i32.const 100000 + i32.lt_u + select + ) + (func $~lib/rt/stub/maybeGrowMemory (; 2 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + (local $2 i32) + local.get $0 + memory.size + local.tee $2 + i32.const 16 + i32.shl + local.tee $1 + i32.gt_u + if + local.get $2 + local.get $0 + local.get $1 + i32.sub + i32.const 65535 + i32.add + i32.const -65536 + i32.and + i32.const 16 + i32.shr_u + local.tee $1 + local.get $2 + local.get $1 + i32.gt_s + select + memory.grow + i32.const 0 + i32.lt_s + if + local.get $1 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + end + local.get $0 + global.set $~lib/rt/stub/offset + ) + (func $~lib/rt/stub/__alloc (; 3 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + local.get $0 + i32.const 1073741808 + i32.gt_u + if + unreachable + end + global.get $~lib/rt/stub/offset + i32.const 16 + i32.add + local.tee $3 + local.get $0 + i32.const 15 + i32.add + i32.const -16 + i32.and + local.tee $2 + i32.const 16 + local.get $2 + i32.const 16 + i32.gt_u + select + local.tee $4 + i32.add + call $~lib/rt/stub/maybeGrowMemory + local.get $3 + i32.const 16 + i32.sub + local.tee $2 + local.get $4 + i32.store + local.get $2 + i32.const -1 + i32.store offset=4 + local.get $2 + local.get $1 + i32.store offset=8 + local.get $2 + local.get $0 + i32.store offset=12 + local.get $3 + ) + (func $~lib/util/number/utoa_simple (; 4 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + loop $continue|0 + local.get $1 + i32.const 10 + i32.rem_u + local.set $3 + local.get $1 + i32.const 10 + i32.div_u + local.set $1 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.const 1 + i32.shl + local.get $0 + i32.add + local.get $3 + i32.const 48 + i32.add + i32.store16 + local.get $1 + br_if $continue|0 + end + ) + (func $~lib/util/number/itoa32 (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + local.get $0 + i32.eqz + if + i32.const 24 + return + end + local.get $0 + i32.const 0 + i32.lt_s + local.tee $1 + if + i32.const 0 + local.get $0 + i32.sub + local.set $0 + end + local.get $0 + call $~lib/util/number/decimalCount32 + local.get $1 + i32.add + local.tee $3 + i32.const 1 + i32.shl + i32.const 1 + call $~lib/rt/stub/__alloc + local.tee $2 + local.get $0 + local.get $3 + call $~lib/util/number/utoa_simple + local.get $1 + if + local.get $2 + i32.const 45 + i32.store16 + end + local.get $2 + ) + (func $~lib/string/String#get:length (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 + i32.const 16 + i32.sub + i32.load offset=12 + i32.const 1 + i32.shr_u + ) + (func $~lib/util/string/compareImpl (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + loop $continue|0 + local.get $2 + if (result i32) + local.get $0 + i32.load16_u + local.get $1 + i32.load16_u + i32.sub + local.tee $3 + i32.eqz + else + i32.const 0 + end + if + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + i32.const 2 + i32.add + local.set $0 + local.get $1 + i32.const 2 + i32.add + local.set $1 + br $continue|0 + end + end + local.get $3 + ) + (func $~lib/string/String.__eq (; 8 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + local.get $0 + local.get $1 + i32.eq + if + i32.const 1 + return + end + block $folding-inner0 + local.get $1 + i32.eqz + i32.const 1 + local.get $0 + select + br_if $folding-inner0 + local.get $0 + call $~lib/string/String#get:length + local.tee $2 + local.get $1 + call $~lib/string/String#get:length + i32.ne + br_if $folding-inner0 + local.get $0 + local.get $1 + local.get $2 + call $~lib/util/string/compareImpl + i32.eqz + return + end + i32.const 0 + ) + (func $start:resolve-propertyaccess (; 9 ;) (type $FUNCSIG$v) + (local $0 i32) + i32.const 256 + global.set $~lib/rt/stub/startOffset + i32.const 256 + global.set $~lib/rt/stub/offset + i32.const 1 + call $~lib/util/number/itoa32 + i32.const 48 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 5 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $~lib/util/number/itoa32 + i32.const 144 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 16 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $~lib/util/number/itoa32 + i32.const 168 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 27 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + call $~lib/util/number/itoa32 + i32.const 192 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 37 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 5 + call $~lib/util/number/itoa32 + i32.const 216 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 48 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + i32.const 3 + call $~lib/rt/stub/__alloc + local.tee $0 + i32.const 6 + i32.store + local.get $0 + i32.load + call $~lib/util/number/itoa32 + i32.const 240 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 56 + i32.const 2 + call $~lib/builtins/abort + unreachable + end + ) + (func $start (; 10 ;) (type $FUNCSIG$v) + call $start:resolve-propertyaccess + ) + (func $null (; 11 ;) (type $FUNCSIG$v) + nop + ) +) diff --git a/tests/compiler/resolve-propertyaccess.ts b/tests/compiler/resolve-propertyaccess.ts new file mode 100644 index 0000000000..6bd3dde775 --- /dev/null +++ b/tests/compiler/resolve-propertyaccess.ts @@ -0,0 +1,61 @@ +namespace Namespace { + export const member = 1; +} + +assert( + (Namespace.member).toString() + == + "1" +); + +function MergedNamespace(): i32 { return 0; } +namespace MergedNamespace { + export const member = 2; +} + +assert( + (MergedNamespace.member).toString() + == + "2" +); + +namespace TypedNamespace { + export const member = 3; +} +type TypedNamespace = string; + +assert( + (TypedNamespace.member).toString() + == + "3" +); + +enum Enum { + VALUE = 4 +} + +assert( + (Enum.VALUE).toString() + == + "4" +); + +class Class { + static staticField: i32 = 5; + instanceField: i32 = 6; +} + +assert( + (Class.staticField).toString() + == + "5" +); + +{ + let instance = new Class(); + assert( + (instance.instanceField).toString() + == + "6" + ); +} diff --git a/tests/compiler/resolve-propertyaccess.untouched.wat b/tests/compiler/resolve-propertyaccess.untouched.wat new file mode 100644 index 0000000000..395ee56717 --- /dev/null +++ b/tests/compiler/resolve-propertyaccess.untouched.wat @@ -0,0 +1,706 @@ +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$iiiiii (func (param i32 i32 i32 i32 i32) (result i32))) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$v (func)) + (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (memory $0 1) + (data (i32.const 8) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\000\00") + (data (i32.const 32) "\90\01\00\00\01\00\00\00\00\00\00\00\90\01\00\000\000\000\001\000\002\000\003\000\004\000\005\000\006\000\007\000\008\000\009\001\000\001\001\001\002\001\003\001\004\001\005\001\006\001\007\001\008\001\009\002\000\002\001\002\002\002\003\002\004\002\005\002\006\002\007\002\008\002\009\003\000\003\001\003\002\003\003\003\004\003\005\003\006\003\007\003\008\003\009\004\000\004\001\004\002\004\003\004\004\004\005\004\006\004\007\004\008\004\009\005\000\005\001\005\002\005\003\005\004\005\005\005\006\005\007\005\008\005\009\006\000\006\001\006\002\006\003\006\004\006\005\006\006\006\007\006\008\006\009\007\000\007\001\007\002\007\003\007\004\007\005\007\006\007\007\007\008\007\009\008\000\008\001\008\002\008\003\008\004\008\005\008\006\008\007\008\008\008\009\009\000\009\001\009\002\009\003\009\004\009\005\009\006\009\007\009\008\009\009\00") + (data (i32.const 448) "\10\00\00\00\01\00\00\00\03\00\00\00\10\00\00\000\00\00\000\00\00\00\90\01\00\00d\00\00\00") + (data (i32.const 480) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\001\00") + (data (i32.const 504) "2\00\00\00\01\00\00\00\01\00\00\002\00\00\00r\00e\00s\00o\00l\00v\00e\00-\00p\00r\00o\00p\00e\00r\00t\00y\00a\00c\00c\00e\00s\00s\00.\00t\00s\00") + (data (i32.const 576) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\002\00") + (data (i32.const 600) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\003\00") + (data (i32.const 624) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\004\00") + (data (i32.const 648) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\005\00") + (data (i32.const 672) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\006\00") + (table $0 1 funcref) + (elem (i32.const 0) $null) + (global $resolve-propertyaccess/Namespace.member i32 (i32.const 1)) + (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) + (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) + (global $~lib/ASC_SHRINK_LEVEL i32 (i32.const 0)) + (global $resolve-propertyaccess/MergedNamespace.member i32 (i32.const 2)) + (global $resolve-propertyaccess/TypedNamespace.member i32 (i32.const 3)) + (global $resolve-propertyaccess/Enum.VALUE i32 (i32.const 4)) + (global $resolve-propertyaccess/Class.staticField (mut i32) (i32.const 5)) + (global $~lib/heap/__heap_base i32 (i32.const 692)) + (export "memory" (memory $0)) + (start $start) + (func $~lib/rt/stub/__retain (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 + ) + (func $~lib/util/number/decimalCount32 (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + local.get $0 + i32.const 100000 + i32.lt_u + if + local.get $0 + i32.const 100 + i32.lt_u + if + i32.const 1 + i32.const 2 + local.get $0 + i32.const 10 + i32.lt_u + select + return + else + i32.const 4 + i32.const 5 + local.get $0 + i32.const 10000 + i32.lt_u + select + local.set $1 + i32.const 3 + local.get $1 + local.get $0 + i32.const 1000 + i32.lt_u + select + return + end + unreachable + else + local.get $0 + i32.const 10000000 + i32.lt_u + if + i32.const 6 + i32.const 7 + local.get $0 + i32.const 1000000 + i32.lt_u + select + return + else + i32.const 9 + i32.const 10 + local.get $0 + i32.const 1000000000 + i32.lt_u + select + local.set $1 + i32.const 8 + local.get $1 + local.get $0 + i32.const 100000000 + i32.lt_u + select + return + end + unreachable + end + unreachable + ) + (func $~lib/rt/stub/maybeGrowMemory (; 3 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + memory.size + local.set $1 + local.get $1 + i32.const 16 + i32.shl + local.set $2 + local.get $0 + local.get $2 + i32.gt_u + if + local.get $0 + local.get $2 + i32.sub + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $3 + local.get $1 + local.tee $4 + local.get $3 + local.tee $5 + local.get $4 + local.get $5 + i32.gt_s + select + local.set $4 + local.get $4 + memory.grow + i32.const 0 + i32.lt_s + if + local.get $3 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + end + local.get $0 + global.set $~lib/rt/stub/offset + ) + (func $~lib/rt/stub/__alloc (; 4 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + local.get $0 + i32.const 1073741808 + i32.gt_u + if + unreachable + end + global.get $~lib/rt/stub/offset + i32.const 16 + i32.add + local.set $2 + local.get $0 + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.tee $3 + i32.const 16 + local.tee $4 + local.get $3 + local.get $4 + i32.gt_u + select + local.set $5 + local.get $2 + local.get $5 + i32.add + call $~lib/rt/stub/maybeGrowMemory + local.get $2 + i32.const 16 + i32.sub + local.set $6 + local.get $6 + local.get $5 + i32.store + local.get $6 + i32.const -1 + i32.store offset=4 + local.get $6 + local.get $1 + i32.store offset=8 + local.get $6 + local.get $0 + i32.store offset=12 + local.get $2 + ) + (func $~lib/util/number/utoa32_lut (; 5 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i64) + (local $9 i64) + i32.const 464 + i32.load offset=4 + local.set $3 + block $break|0 + loop $continue|0 + local.get $1 + i32.const 10000 + i32.ge_u + i32.eqz + br_if $break|0 + local.get $1 + i32.const 10000 + i32.div_u + local.set $4 + local.get $1 + i32.const 10000 + i32.rem_u + local.set $5 + local.get $4 + local.set $1 + local.get $5 + i32.const 100 + i32.div_u + local.set $6 + local.get $5 + i32.const 100 + i32.rem_u + local.set $7 + local.get $3 + local.get $6 + i32.const 2 + i32.shl + i32.add + i64.load32_u + local.set $8 + local.get $3 + local.get $7 + i32.const 2 + i32.shl + i32.add + i64.load32_u + local.set $9 + local.get $2 + i32.const 4 + i32.sub + local.set $2 + local.get $0 + local.get $2 + i32.const 1 + i32.shl + i32.add + local.get $8 + local.get $9 + i64.const 32 + i64.shl + i64.or + i64.store + br $continue|0 + end + unreachable + end + local.get $1 + i32.const 100 + i32.ge_u + if + local.get $1 + i32.const 100 + i32.div_u + local.set $7 + local.get $1 + i32.const 100 + i32.rem_u + local.set $6 + local.get $7 + local.set $1 + local.get $2 + i32.const 2 + i32.sub + local.set $2 + local.get $3 + local.get $6 + i32.const 2 + i32.shl + i32.add + i32.load + local.set $5 + local.get $0 + local.get $2 + i32.const 1 + i32.shl + i32.add + local.get $5 + i32.store + end + local.get $1 + i32.const 10 + i32.ge_u + if + local.get $2 + i32.const 2 + i32.sub + local.set $2 + local.get $3 + local.get $1 + i32.const 2 + i32.shl + i32.add + i32.load + local.set $5 + local.get $0 + local.get $2 + i32.const 1 + i32.shl + i32.add + local.get $5 + i32.store + else + local.get $2 + i32.const 1 + i32.sub + local.set $2 + i32.const 48 + local.get $1 + i32.add + local.set $5 + local.get $0 + local.get $2 + i32.const 1 + i32.shl + i32.add + local.get $5 + i32.store16 + end + ) + (func $~lib/util/number/itoa32 (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + local.get $0 + i32.eqz + if + i32.const 24 + call $~lib/rt/stub/__retain + return + end + local.get $0 + i32.const 0 + i32.lt_s + local.set $1 + local.get $1 + if + i32.const 0 + local.get $0 + i32.sub + local.set $0 + end + local.get $0 + call $~lib/util/number/decimalCount32 + local.get $1 + i32.add + local.set $2 + local.get $2 + i32.const 1 + i32.shl + i32.const 1 + call $~lib/rt/stub/__alloc + local.set $3 + local.get $3 + local.set $6 + local.get $0 + local.set $5 + local.get $2 + local.set $4 + local.get $6 + local.get $5 + local.get $4 + call $~lib/util/number/utoa32_lut + local.get $1 + if + local.get $3 + i32.const 45 + i32.store16 + end + local.get $3 + call $~lib/rt/stub/__retain + ) + (func $~lib/util/number/itoa (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 + call $~lib/util/number/itoa32 + return + ) + (func $~lib/number/I32#toString (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 + call $~lib/util/number/itoa + ) + (func $~lib/rt/stub/__release (; 9 ;) (type $FUNCSIG$vi) (param $0 i32) + nop + ) + (func $~lib/string/String#get:length (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 + i32.const 16 + i32.sub + i32.load offset=12 + i32.const 1 + i32.shr_u + ) + (func $~lib/util/string/compareImpl (; 11 ;) (type $FUNCSIG$iiiiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + local.get $0 + call $~lib/rt/stub/__retain + drop + local.get $2 + call $~lib/rt/stub/__retain + drop + i32.const 0 + local.set $5 + local.get $0 + local.get $1 + i32.const 1 + i32.shl + i32.add + local.set $6 + local.get $2 + local.get $3 + i32.const 1 + i32.shl + i32.add + local.set $7 + block $break|0 + loop $continue|0 + local.get $4 + if (result i32) + local.get $6 + i32.load16_u + local.get $7 + i32.load16_u + i32.sub + local.tee $5 + i32.eqz + else + i32.const 0 + end + i32.eqz + br_if $break|0 + local.get $4 + i32.const 1 + i32.sub + local.set $4 + local.get $6 + i32.const 2 + i32.add + local.set $6 + local.get $7 + i32.const 2 + i32.add + local.set $7 + br $continue|0 + end + unreachable + end + local.get $5 + local.set $8 + local.get $0 + call $~lib/rt/stub/__release + local.get $2 + call $~lib/rt/stub/__release + local.get $8 + ) + (func $~lib/string/String.__eq (; 12 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + local.get $0 + call $~lib/rt/stub/__retain + drop + local.get $1 + call $~lib/rt/stub/__retain + drop + local.get $0 + local.get $1 + i32.eq + if + i32.const 1 + local.set $2 + local.get $0 + call $~lib/rt/stub/__release + local.get $1 + call $~lib/rt/stub/__release + local.get $2 + return + end + local.get $0 + i32.const 0 + i32.eq + if (result i32) + i32.const 1 + else + local.get $1 + i32.const 0 + i32.eq + end + if + i32.const 0 + local.set $2 + local.get $0 + call $~lib/rt/stub/__release + local.get $1 + call $~lib/rt/stub/__release + local.get $2 + return + end + local.get $0 + call $~lib/string/String#get:length + local.set $3 + local.get $3 + local.get $1 + call $~lib/string/String#get:length + i32.ne + if + i32.const 0 + local.set $2 + local.get $0 + call $~lib/rt/stub/__release + local.get $1 + call $~lib/rt/stub/__release + local.get $2 + return + end + local.get $0 + i32.const 0 + local.get $1 + i32.const 0 + local.get $3 + call $~lib/util/string/compareImpl + i32.eqz + local.set $2 + local.get $0 + call $~lib/rt/stub/__release + local.get $1 + call $~lib/rt/stub/__release + local.get $2 + ) + (func $resolve-propertyaccess/Class#constructor (; 13 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 + i32.eqz + if + i32.const 4 + i32.const 4 + call $~lib/rt/stub/__alloc + call $~lib/rt/stub/__retain + local.set $0 + end + local.get $0 + i32.const 6 + i32.store + local.get $0 + ) + (func $start:resolve-propertyaccess (; 14 ;) (type $FUNCSIG$v) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + global.get $~lib/heap/__heap_base + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + global.set $~lib/rt/stub/startOffset + global.get $~lib/rt/stub/startOffset + global.set $~lib/rt/stub/offset + i32.const 1 + call $~lib/number/I32#toString + local.tee $0 + i32.const 496 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 5 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $~lib/number/I32#toString + local.tee $1 + i32.const 592 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 16 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $~lib/number/I32#toString + local.tee $2 + i32.const 616 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 27 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + call $~lib/number/I32#toString + local.tee $3 + i32.const 640 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 37 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + global.get $resolve-propertyaccess/Class.staticField + call $~lib/number/I32#toString + local.tee $4 + i32.const 664 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 48 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $resolve-propertyaccess/Class#constructor + local.set $5 + local.get $5 + i32.load + call $~lib/number/I32#toString + local.tee $6 + i32.const 688 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 56 + i32.const 2 + call $~lib/builtins/abort + unreachable + end + local.get $5 + call $~lib/rt/stub/__release + local.get $6 + call $~lib/rt/stub/__release + local.get $0 + call $~lib/rt/stub/__release + local.get $1 + call $~lib/rt/stub/__release + local.get $2 + call $~lib/rt/stub/__release + local.get $3 + call $~lib/rt/stub/__release + local.get $4 + call $~lib/rt/stub/__release + ) + (func $start (; 15 ;) (type $FUNCSIG$v) + call $start:resolve-propertyaccess + ) + (func $null (; 16 ;) (type $FUNCSIG$v) + ) +) From a9f28f5bbcf9c363e9531b974261c1d333c1a5f5 Mon Sep 17 00:00:00 2001 From: dcode Date: Mon, 23 Sep 2019 16:04:04 +0200 Subject: [PATCH 2/3] fix lazy --- src/resolver.ts | 25 ++-- .../resolve-propertyaccess.optimized.wat | 90 ++++++++++--- tests/compiler/resolve-propertyaccess.ts | 28 +++++ .../resolve-propertyaccess.untouched.wat | 118 ++++++++++++++---- 4 files changed, 209 insertions(+), 52 deletions(-) diff --git a/src/resolver.ts b/src/resolver.ts index 5239848576..ecedcb954c 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -771,11 +771,9 @@ export class Resolver extends DiagnosticEmitter { /** Gets the concrete type of an element. */ getTypeOfElement(element: Element): Type | null { var kind = element.kind; - if (kind == ElementKind.GLOBAL) { - if (!this.ensureResolvedLazyGlobal(element, ReportMode.SWALLOW)) return null; - } if (isTypedElement(kind)) { let type = (element).type; + assert(type != Type.void); let classReference = type.classReference; if (classReference) { let wrappedType = classReference.wrappedType; @@ -1140,16 +1138,15 @@ export class Resolver extends DiagnosticEmitter { } /** Resolves a lazily compiled global, i.e. a static class field or annotated `@lazy`. */ - private ensureResolvedLazyGlobal(global: Global, reportMode: ReportMode = ReportMode.REPORT): bool { + private ensureResolvedLazyGlobal(global: Global, ctxFlow: Flow, reportMode: ReportMode = ReportMode.REPORT): bool { if (global.is(CommonFlags.RESOLVED)) return true; + var type: Type | null; var typeNode = global.typeNode; - if (!typeNode) return false; - var type = this.resolveType( // reports - typeNode, - global.parent, - null, - reportMode - ); + if (typeNode) { + type = this.resolveType(typeNode, global.parent, null, reportMode); + } else { + type = this.resolveExpression(assert(global.initializerNode), ctxFlow, Type.auto, reportMode); + } if (!type) return false; global.setType(type); // also sets resolved return true; @@ -1173,10 +1170,10 @@ export class Resolver extends DiagnosticEmitter { // Resolve variable-likes to their class type first switch (target.kind) { - case ElementKind.GLOBAL: if (!this.ensureResolvedLazyGlobal(target, reportMode)) return null; + case ElementKind.GLOBAL: if (!this.ensureResolvedLazyGlobal(target, ctxFlow, reportMode)) return null; + case ElementKind.ENUMVALUE: case ElementKind.LOCAL: - case ElementKind.FIELD: - case ElementKind.ENUMVALUE: { // someVar.prop + case ElementKind.FIELD: { // someVar.prop let type = (target).type; assert(type != Type.void); let classReference = type.classReference; if (!classReference) { diff --git a/tests/compiler/resolve-propertyaccess.optimized.wat b/tests/compiler/resolve-propertyaccess.optimized.wat index a61a5bc68c..c491a4b1f9 100644 --- a/tests/compiler/resolve-propertyaccess.optimized.wat +++ b/tests/compiler/resolve-propertyaccess.optimized.wat @@ -11,11 +11,15 @@ (data (i32.const 8) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\000") (data (i32.const 32) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\001") (data (i32.const 56) "2\00\00\00\01\00\00\00\01\00\00\002\00\00\00r\00e\00s\00o\00l\00v\00e\00-\00p\00r\00o\00p\00e\00r\00t\00y\00a\00c\00c\00e\00s\00s\00.\00t\00s") - (data (i32.const 128) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\002") - (data (i32.const 152) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\003") - (data (i32.const 176) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\004") - (data (i32.const 200) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\005") - (data (i32.const 224) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\006") + (data (i32.const 128) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\001\001") + (data (i32.const 152) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\002") + (data (i32.const 176) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\002\002") + (data (i32.const 200) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\003") + (data (i32.const 224) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\003\003") + (data (i32.const 248) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\004") + (data (i32.const 272) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\005") + (data (i32.const 296) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\005\005") + (data (i32.const 320) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\006") (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) (export "memory" (memory $0)) @@ -298,9 +302,9 @@ ) (func $start:resolve-propertyaccess (; 9 ;) (type $FUNCSIG$v) (local $0 i32) - i32.const 256 + i32.const 352 global.set $~lib/rt/stub/startOffset - i32.const 256 + i32.const 352 global.set $~lib/rt/stub/offset i32.const 1 call $~lib/util/number/itoa32 @@ -310,12 +314,12 @@ if i32.const 0 i32.const 72 - i32.const 5 + i32.const 6 i32.const 0 call $~lib/builtins/abort unreachable end - i32.const 2 + i32.const 11 call $~lib/util/number/itoa32 i32.const 144 call $~lib/string/String.__eq @@ -323,12 +327,12 @@ if i32.const 0 i32.const 72 - i32.const 16 + i32.const 12 i32.const 0 call $~lib/builtins/abort unreachable end - i32.const 3 + i32.const 2 call $~lib/util/number/itoa32 i32.const 168 call $~lib/string/String.__eq @@ -336,12 +340,12 @@ if i32.const 0 i32.const 72 - i32.const 27 + i32.const 24 i32.const 0 call $~lib/builtins/abort unreachable end - i32.const 4 + i32.const 22 call $~lib/util/number/itoa32 i32.const 192 call $~lib/string/String.__eq @@ -349,16 +353,29 @@ if i32.const 0 i32.const 72 - i32.const 37 + i32.const 30 i32.const 0 call $~lib/builtins/abort unreachable end - i32.const 5 + i32.const 3 call $~lib/util/number/itoa32 i32.const 216 call $~lib/string/String.__eq i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 42 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 33 + call $~lib/util/number/itoa32 + i32.const 240 + call $~lib/string/String.__eq + i32.eqz if i32.const 0 i32.const 72 @@ -368,6 +385,45 @@ unreachable end i32.const 4 + call $~lib/util/number/itoa32 + i32.const 264 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 58 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 5 + call $~lib/util/number/itoa32 + i32.const 288 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 70 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 55 + call $~lib/util/number/itoa32 + i32.const 312 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 72 + i32.const 76 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 4 i32.const 3 call $~lib/rt/stub/__alloc local.tee $0 @@ -376,13 +432,13 @@ local.get $0 i32.load call $~lib/util/number/itoa32 - i32.const 240 + i32.const 336 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 72 - i32.const 56 + i32.const 84 i32.const 2 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/resolve-propertyaccess.ts b/tests/compiler/resolve-propertyaccess.ts index 6bd3dde775..c8ca701a02 100644 --- a/tests/compiler/resolve-propertyaccess.ts +++ b/tests/compiler/resolve-propertyaccess.ts @@ -1,5 +1,6 @@ namespace Namespace { export const member = 1; + @lazy export const lazyMember = 11; } assert( @@ -8,9 +9,16 @@ assert( "1" ); +assert( + (Namespace.lazyMember).toString() + == + "11" +); + function MergedNamespace(): i32 { return 0; } namespace MergedNamespace { export const member = 2; + @lazy export const lazyMember = 22; } assert( @@ -19,8 +27,15 @@ assert( "2" ); +assert( + (MergedNamespace.lazyMember).toString() + == + "22" +); + namespace TypedNamespace { export const member = 3; + @lazy export const lazyMember = 33; } type TypedNamespace = string; @@ -30,6 +45,12 @@ assert( "3" ); +assert( + (TypedNamespace.lazyMember).toString() + == + "33" +); + enum Enum { VALUE = 4 } @@ -42,6 +63,7 @@ assert( class Class { static staticField: i32 = 5; + @lazy static lazyStaticField: i32 = 55; instanceField: i32 = 6; } @@ -51,6 +73,12 @@ assert( "5" ); +assert( + (Class.lazyStaticField).toString() + == + "55" +); + { let instance = new Class(); assert( diff --git a/tests/compiler/resolve-propertyaccess.untouched.wat b/tests/compiler/resolve-propertyaccess.untouched.wat index 395ee56717..56b94b0437 100644 --- a/tests/compiler/resolve-propertyaccess.untouched.wat +++ b/tests/compiler/resolve-propertyaccess.untouched.wat @@ -13,22 +13,30 @@ (data (i32.const 448) "\10\00\00\00\01\00\00\00\03\00\00\00\10\00\00\000\00\00\000\00\00\00\90\01\00\00d\00\00\00") (data (i32.const 480) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\001\00") (data (i32.const 504) "2\00\00\00\01\00\00\00\01\00\00\002\00\00\00r\00e\00s\00o\00l\00v\00e\00-\00p\00r\00o\00p\00e\00r\00t\00y\00a\00c\00c\00e\00s\00s\00.\00t\00s\00") - (data (i32.const 576) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\002\00") - (data (i32.const 600) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\003\00") - (data (i32.const 624) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\004\00") - (data (i32.const 648) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\005\00") - (data (i32.const 672) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\006\00") + (data (i32.const 576) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\001\001\00") + (data (i32.const 600) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\002\00") + (data (i32.const 624) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\002\002\00") + (data (i32.const 648) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\003\00") + (data (i32.const 672) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\003\003\00") + (data (i32.const 696) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\004\00") + (data (i32.const 720) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\005\00") + (data (i32.const 744) "\04\00\00\00\01\00\00\00\01\00\00\00\04\00\00\005\005\00") + (data (i32.const 768) "\02\00\00\00\01\00\00\00\01\00\00\00\02\00\00\006\00") (table $0 1 funcref) (elem (i32.const 0) $null) (global $resolve-propertyaccess/Namespace.member i32 (i32.const 1)) (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) (global $~lib/ASC_SHRINK_LEVEL i32 (i32.const 0)) + (global $resolve-propertyaccess/Namespace.lazyMember i32 (i32.const 11)) (global $resolve-propertyaccess/MergedNamespace.member i32 (i32.const 2)) + (global $resolve-propertyaccess/MergedNamespace.lazyMember i32 (i32.const 22)) (global $resolve-propertyaccess/TypedNamespace.member i32 (i32.const 3)) + (global $resolve-propertyaccess/TypedNamespace.lazyMember i32 (i32.const 33)) (global $resolve-propertyaccess/Enum.VALUE i32 (i32.const 4)) (global $resolve-propertyaccess/Class.staticField (mut i32) (i32.const 5)) - (global $~lib/heap/__heap_base i32 (i32.const 692)) + (global $resolve-propertyaccess/Class.lazyStaticField (mut i32) (i32.const 55)) + (global $~lib/heap/__heap_base i32 (i32.const 788)) (export "memory" (memory $0)) (start $start) (func $~lib/rt/stub/__retain (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) @@ -585,6 +593,10 @@ (local $4 i32) (local $5 i32) (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) global.get $~lib/heap/__heap_base i32.const 15 i32.add @@ -604,12 +616,12 @@ if i32.const 0 i32.const 520 - i32.const 5 + i32.const 6 i32.const 0 call $~lib/builtins/abort unreachable end - i32.const 2 + i32.const 11 call $~lib/number/I32#toString local.tee $1 i32.const 592 @@ -618,12 +630,12 @@ if i32.const 0 i32.const 520 - i32.const 16 + i32.const 12 i32.const 0 call $~lib/builtins/abort unreachable end - i32.const 3 + i32.const 2 call $~lib/number/I32#toString local.tee $2 i32.const 616 @@ -632,12 +644,12 @@ if i32.const 0 i32.const 520 - i32.const 27 + i32.const 24 i32.const 0 call $~lib/builtins/abort unreachable end - i32.const 4 + i32.const 22 call $~lib/number/I32#toString local.tee $3 i32.const 640 @@ -646,17 +658,31 @@ if i32.const 0 i32.const 520 - i32.const 37 + i32.const 30 i32.const 0 call $~lib/builtins/abort unreachable end - global.get $resolve-propertyaccess/Class.staticField + i32.const 3 call $~lib/number/I32#toString local.tee $4 i32.const 664 call $~lib/string/String.__eq i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 42 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 33 + call $~lib/number/I32#toString + local.tee $5 + i32.const 688 + call $~lib/string/String.__eq + i32.eqz if i32.const 0 i32.const 520 @@ -665,27 +691,69 @@ call $~lib/builtins/abort unreachable end + i32.const 4 + call $~lib/number/I32#toString + local.tee $6 + i32.const 712 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 58 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + global.get $resolve-propertyaccess/Class.staticField + call $~lib/number/I32#toString + local.tee $7 + i32.const 736 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 70 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + global.get $resolve-propertyaccess/Class.lazyStaticField + call $~lib/number/I32#toString + local.tee $8 + i32.const 760 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 520 + i32.const 76 + i32.const 0 + call $~lib/builtins/abort + unreachable + end i32.const 0 call $resolve-propertyaccess/Class#constructor - local.set $5 - local.get $5 + local.set $9 + local.get $9 i32.load call $~lib/number/I32#toString - local.tee $6 - i32.const 688 + local.tee $10 + i32.const 784 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 520 - i32.const 56 + i32.const 84 i32.const 2 call $~lib/builtins/abort unreachable end - local.get $5 + local.get $9 call $~lib/rt/stub/__release - local.get $6 + local.get $10 call $~lib/rt/stub/__release local.get $0 call $~lib/rt/stub/__release @@ -697,6 +765,14 @@ call $~lib/rt/stub/__release local.get $4 call $~lib/rt/stub/__release + local.get $5 + call $~lib/rt/stub/__release + local.get $6 + call $~lib/rt/stub/__release + local.get $7 + call $~lib/rt/stub/__release + local.get $8 + call $~lib/rt/stub/__release ) (func $start (; 15 ;) (type $FUNCSIG$v) call $start:resolve-propertyaccess From 1941dc5f2e862c4dac88256eded80e333a92e143 Mon Sep 17 00:00:00 2001 From: dcode Date: Mon, 23 Sep 2019 16:31:35 +0200 Subject: [PATCH 3/3] fix the fix --- src/resolver.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/resolver.ts b/src/resolver.ts index ecedcb954c..3b7b8827df 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -771,6 +771,9 @@ export class Resolver extends DiagnosticEmitter { /** Gets the concrete type of an element. */ getTypeOfElement(element: Element): Type | null { var kind = element.kind; + if (kind == ElementKind.GLOBAL) { + if (!this.ensureResolvedLazyGlobal(element, ReportMode.SWALLOW)) return null; + } if (isTypedElement(kind)) { let type = (element).type; assert(type != Type.void); @@ -1138,14 +1141,14 @@ export class Resolver extends DiagnosticEmitter { } /** Resolves a lazily compiled global, i.e. a static class field or annotated `@lazy`. */ - private ensureResolvedLazyGlobal(global: Global, ctxFlow: Flow, reportMode: ReportMode = ReportMode.REPORT): bool { + private ensureResolvedLazyGlobal(global: Global, reportMode: ReportMode = ReportMode.REPORT): bool { if (global.is(CommonFlags.RESOLVED)) return true; var type: Type | null; var typeNode = global.typeNode; if (typeNode) { type = this.resolveType(typeNode, global.parent, null, reportMode); } else { - type = this.resolveExpression(assert(global.initializerNode), ctxFlow, Type.auto, reportMode); + type = this.resolveExpression(assert(global.initializerNode), global.file.startFunction.flow, Type.auto, reportMode); } if (!type) return false; global.setType(type); // also sets resolved @@ -1170,7 +1173,7 @@ export class Resolver extends DiagnosticEmitter { // Resolve variable-likes to their class type first switch (target.kind) { - case ElementKind.GLOBAL: if (!this.ensureResolvedLazyGlobal(target, ctxFlow, reportMode)) return null; + case ElementKind.GLOBAL: if (!this.ensureResolvedLazyGlobal(target, reportMode)) return null; case ElementKind.ENUMVALUE: case ElementKind.LOCAL: case ElementKind.FIELD: { // someVar.prop