-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor the lifting system to work on expressions instead of references and merge lifting and capturing into a unified model. *Lifting* is the concept of referencing a preflight expression from an inflight scope, while *capturing* is the concept of referencing an object defined in a parent scope (albeit not another phase). The mechanism works like this: we now have another "lifting" phase which runs immediately after type checking. This phase does the following: 1. **Lifting**: for inflight methods, it scans all the expressions. If it finds an expression marked as a preflight expression, it uses the jsifier to render it's preflight code and obtains a *token* from a lifts registry that's maintained at the class *type* level. 2. **Capturing**: for each expression that is a reference (both type refs and object refs), it checks looks up in which symbol environment it is defined. It then checks if that environment is a parent of the current method environment. If it is, is adds it to the lifts registry as well. For each class, the lifting phase returns a new class object with the lift registry updated. So `class.lifts` has all the information about lifting and capturing for this class, later to be used downstream. Now we move to the jsification phase. For each expression, the jsifier checks the `lifts` registry and if there's a token for this expression (by id), it emits the token instead (only in inflight of course). The token registry is also consulted when the class machinery is jsified in order to emit the code that lifts expressions from preflight to inflight (both at the object level and at the type level) and binds them for access management. When jsifying inflight base classes, we need to resolve the base class type and extract the lifting tokens from it. ## Misc * The simulator failed to start certain test apps due to unresolvable attributes. This is because there was no mechanism to handle implicit dependencies on startup. A popular solution to this problem is to use an *init queue*. We basically pop a resource from the queue and try to start it. If we can't resolve a reference to other resources, we retry by returning it to the queue. An attempt count is decremented to avoid an infinite loop in case of a dependency cycle or unresolvable attribute (cc @Chriscbr). * Additionally, the simulator did not call `cleanup()` during the shutdown sequence. This resulted in leaking ports in the `cloud.Api` resource that prevented the program from exiting (not exactly sure how this have worked). @tsuf239, any idea? ## Fixes * #1878 is fixed because now we are able to lift complete expressions. So `bucket.bucketArn` is a simple string and there is no need to lift the bucket. * #2729 is fixed with the following error: `Unable to reassign a captured variable` * #3253 This is the 3rd attempt at this refactor, and hopefully the last for now. It supersedes #3125 and #2909. ## Follow ups * #3244 * #3249 * #3189 ## Checklist - [x] Title matches [Winglang's style guide](https://docs.winglang.io/contributing/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [x] Tests added (always) - [x] Docs updated (only required for features) - [x] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Monada Contribution License](https://docs.winglang.io/terms-and-policies/contribution-license.html)*.
- Loading branch information
Showing
326 changed files
with
22,161 additions
and
7,224 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,25 @@ | ||
let y = "hello"; | ||
let y = "h"; | ||
|
||
inflight () => { | ||
() => { | ||
log("hello"); | ||
log(y); | ||
// ^ Cannot capture symbol "y" because it is shadowed by another symbol with the same name | ||
let y = "world"; | ||
let y = "y"; | ||
}; | ||
|
||
inflight () => { | ||
let y = "hi"; | ||
|
||
inflight () => { | ||
log(y); | ||
// ^ Cannot capture symbol "y" because it is shadowed by another symbol with the same name | ||
let y = "world"; | ||
}; | ||
}; | ||
|
||
// TODO: https://github.com/winglang/wing/issues/2753 | ||
// let x = "hi"; | ||
// if true { | ||
// log(x); | ||
// let x = "world"; | ||
// } | ||
let x = "hi"; | ||
if true { | ||
log(x); | ||
// ^ Cannot capture symbol "x" because it is shadowed by another symbol with the same name | ||
let x = "world"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
class Foo { | ||
static inflight foo(): num { return 1; } | ||
static inflight bar(): num { return Foo.foo(); } | ||
|
||
inflight callThis(): num { | ||
return Foo.bar(); | ||
} | ||
|
||
} | ||
|
||
inflight class Bar { | ||
static bar(): num { return 2; } | ||
|
||
callThis(): num { | ||
return Bar.bar(); | ||
} | ||
} | ||
|
||
let foo = new Foo(); | ||
|
||
test "test" { | ||
class Zoo { | ||
static zoo(): num { return 3; } | ||
} | ||
|
||
let bar = new Bar(); | ||
|
||
assert(Foo.foo() == 1); | ||
assert(Bar.bar() == 2); | ||
assert(Zoo.zoo() == 3); | ||
assert(foo.callThis() == 1); | ||
assert(bar.callThis() == 2); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
bring cloud; | ||
|
||
class Foo { | ||
inflight1: inflight (): num; | ||
init() { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
class MyClosure { | ||
inflight another(): str { | ||
return "hello"; | ||
} | ||
|
||
inflight handle(): num { | ||
return 42; | ||
} | ||
} | ||
|
||
let fn = new MyClosure(); | ||
|
||
test "test" { | ||
assert(fn() == 42); | ||
assert(fn.another() == "hello"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
bring cloud; | ||
|
||
let initCount = new cloud.Counter(); | ||
|
||
class Foo { | ||
inflight init() { | ||
initCount.inc(); | ||
} | ||
|
||
inflight method() { } | ||
} | ||
|
||
class Bar { | ||
foo: Foo; | ||
init() { | ||
this.foo = new Foo(); | ||
} | ||
|
||
inflight callFoo() { | ||
this.foo.method(); | ||
} | ||
} | ||
|
||
let bar = new Bar(); | ||
|
||
test "hello" { | ||
bar.callFoo(); | ||
bar.foo.method(); | ||
|
||
// TODO: https://github.com/winglang/wing/issues/3244 | ||
assert(initCount.peek() == /*1*/ 2); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class Foo { | ||
value: str; | ||
init() { this.value = "hello"; } | ||
} | ||
|
||
let foo_this = new Foo(); | ||
test "test" { | ||
assert(foo_this.value == "hello"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
let y = "hello"; | ||
|
||
test "test" { | ||
assert(y == "hello"); | ||
let y = "z"; | ||
assert(y == "z"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
class Foo { | ||
inflight x: num; | ||
inflight init() { | ||
this.x = 42; | ||
} | ||
inflight bar(): num { | ||
return this.x; | ||
} | ||
inflight foo(): num { | ||
return this.bar() / 2; | ||
} | ||
} | ||
|
||
let f = new Foo(); | ||
|
||
test "test" { | ||
assert(f.foo() == 21); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
bring cloud; | ||
|
||
let bucket2 = new cloud.Bucket(); | ||
|
||
let fn = inflight () => { | ||
bucket2.put("hello", "world"); | ||
}; | ||
|
||
class MyClosure { | ||
bucket: cloud.Bucket; | ||
|
||
init() { | ||
this.bucket = new cloud.Bucket(); | ||
} | ||
|
||
inflight handle() { | ||
log("handle called"); | ||
this.putFile(); | ||
} | ||
|
||
inflight putFile() { | ||
log("putFile called"); | ||
this.bucket.put("hello", "world"); | ||
} | ||
|
||
inflight listFiles(): Array<str> { | ||
bucket2.put("b2", "world"); | ||
return this.bucket.list(); | ||
} | ||
} | ||
|
||
let fn2 = new MyClosure(); | ||
|
||
test "call synthetic closure class as a function" { | ||
fn(); | ||
} | ||
|
||
test "call non-synthetic closure as a function" { | ||
fn2(); | ||
assert(fn2.bucket.get("hello") == "world"); | ||
assert(fn2.listFiles().length == 1); | ||
assert(bucket2.get("b2") == "world"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
bring cloud; | ||
|
||
class MyClosure { | ||
q: cloud.Queue; | ||
init() { | ||
this.q = new cloud.Queue(); | ||
} | ||
|
||
inflight handle() { | ||
this.q.push("hello"); | ||
} | ||
} | ||
|
||
let fn = new MyClosure(); | ||
|
||
test "test" { | ||
fn(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.