Skip to content

Commit

Permalink
feat: nodeof built-in function (#5411)
Browse files Browse the repository at this point in the history
Closes #2027

This PR adds a `nodeof()` function, a handy built-in for reflecting on the application tree (aka construct tree) in preflight.

## Checklist

- [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted)
- [x] Description explains motivation and solution
- [x] Tests added (always)
- [ ] Docs updated (only required for features)
- [ ] 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 [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
  • Loading branch information
Chriscbr authored Jan 3, 2024
1 parent 6437741 commit c52cca6
Show file tree
Hide file tree
Showing 184 changed files with 605 additions and 371 deletions.
1 change: 1 addition & 0 deletions docs/docs/03-language-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ log("UTC: {t1.utc.toIso())}"); // output: 2023-02-09T06:21:03.000Z
| `log` | logs str |
| `assert` | checks a condition and _throws_ if evaluated to false |
| `unsafeCast` | cast a value into a different type |
| `nodeof` | obtain the [tree node](./02-concepts/02-application-tree.md) of a preflight object |
> ```TS
> log("Hello {name}");
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/07-examples/80-singletons.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ bring cloud;
class SingletonBucket {
pub static of(scope: std.IResource): cloud.Bucket {
let uid = "SingletonBucket";
let root = std.Node.of(scope).root;
let rootNode = std.Node.of(root);
let root = nodeof(scope).root;
let rootNode = nodeof(root);
return unsafeCast(rootNode.tryFindChild(uid)) ?? new cloud.Bucket() as uid in root;
}
}
Expand All @@ -35,4 +35,4 @@ Now, in order to access our bucket from anywhere within the app, I can just use:
let bucket = SingletonBucket.of(this);
```
And we will always get the same bucket.
And we will always get the same bucket.
17 changes: 17 additions & 0 deletions examples/tests/invalid/global_symbols.test.w
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
let log = "hi";
// ^Error: Symbol "log" already defined in this scope
let assert = "there";
// ^Error: Symbol "assert" already defined in this scope
let unsafeCast = "wingnuts";
// ^Error: Symbol "unsafeCast" already defined in this scope
let nodeof = "!";
// ^Error: Symbol "nodeof" already defined in this scope

log = "hi";
// ^Error: Variable is not reassignable
assert = "there";
// ^Error: Variable is not reassignable
unsafeCast = "wingnuts";
// ^Error: Variable is not reassignable
nodeof = "!";
// ^Error: Variable is not reassignable
6 changes: 3 additions & 3 deletions examples/tests/sdk_tests/std/node.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ bring cloud;
bring expect;

let bucket = new cloud.Bucket();
let app = std.Node.of(bucket).app;
let app = nodeof(bucket).app;
assert(app.workdir.endsWith(".wing"));
assert(app.entrypointDir.endsWith("/sdk_tests/std") || app.entrypointDir.endsWith("\\sdk_tests\\std"));
app.isTestEnvironment; // don't care if it's true or false, just that it compiles

class SingletonBucket {
pub static of(scope: std.IResource): cloud.Bucket {
let uid = "SingletonBucket";
let root = std.Node.of(scope).root;
let root_node = std.Node.of(root);
let root = nodeof(scope).root;
let root_node = nodeof(root);
return unsafeCast(root_node.tryFindChild(uid)) ?? new cloud.Bucket() as uid in root;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/tests/valid/construct-base.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ let getPath = (c: cx.Construct): str => {
};

let getDisplayName = (r: std.Resource): str? => {
return std.Node.of(r).title;
return nodeof(r).title;
};

let q = new aws.sqsQueue.SqsQueue();
Expand Down
3 changes: 3 additions & 0 deletions libs/wingc/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ pub enum UtilityFunctions {
Log,
Assert,
UnsafeCast,
Nodeof,
}

impl UtilityFunctions {
Expand All @@ -318,6 +319,7 @@ impl UtilityFunctions {
UtilityFunctions::Log,
UtilityFunctions::Assert,
UtilityFunctions::UnsafeCast,
UtilityFunctions::Nodeof,
]
}
}
Expand All @@ -328,6 +330,7 @@ impl Display for UtilityFunctions {
UtilityFunctions::Log => write!(f, "log"),
UtilityFunctions::Assert => write!(f, "assert"),
UtilityFunctions::UnsafeCast => write!(f, "unsafeCast"),
UtilityFunctions::Nodeof => write!(f, "nodeof"),
}
}
}
Expand Down
14 changes: 5 additions & 9 deletions libs/wingc/src/closure_transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,15 @@ impl Fold for ClosureTransformer {

// class_init_body :=
// ```
// std.Node.of(this).hidden = true;
// nodeof(this).hidden = true;
// ```
let std_display_of_this = Expr::new(
ExprKind::Call {
callee: CalleeKind::Expr(Box::new(Expr::new(
ExprKind::Reference(Reference::TypeMember {
type_name: UserDefinedType {
root: Symbol::new("std", WingSpan::for_file(file_id)),
fields: vec![Symbol::new("Node", WingSpan::for_file(file_id))],
span: WingSpan::for_file(file_id),
},
property: Symbol::new("of", WingSpan::for_file(file_id)),
}),
ExprKind::Reference(Reference::Identifier(Symbol::new(
"nodeof",
WingSpan::for_file(file_id),
))),
WingSpan::for_file(file_id),
))),
arg_list: ArgList {
Expand Down
2 changes: 1 addition & 1 deletion libs/wingc/src/jsify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ impl<'a> JSifier<'a> {
BinaryOperator::Less => "<",
BinaryOperator::LessOrEqual => "<=",
BinaryOperator::Equal => return new_code!(expr_span, "$helpers.eq(", js_left, ", ", js_right, ")"),
BinaryOperator::NotEqual => return new_code!(expr_span, "!$helpers.eq(", js_left, ", ", js_right, ")"),
BinaryOperator::NotEqual => return new_code!(expr_span, "$helpers.neq(", js_left, ", ", js_right, ")"),
BinaryOperator::LogicalAnd => "&&",
BinaryOperator::LogicalOr => "||",
BinaryOperator::UnwrapOr => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
2 changes: 1 addition & 1 deletion libs/wingc/src/jsify/snapshots/builtins.snap
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand All @@ -97,7 +97,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
2 changes: 1 addition & 1 deletion libs/wingc/src/jsify/snapshots/capture_token.snap
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
4 changes: 2 additions & 2 deletions libs/wingc/src/jsify/snapshots/closure_field.snap
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down Expand Up @@ -184,7 +184,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
4 changes: 2 additions & 2 deletions libs/wingc/src/jsify/snapshots/enum_value.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = function({ $MyEnum, $x }) {
return $obj;
}
async handle() {
$helpers.assert(!$helpers.eq($MyEnum.B, $MyEnum.C), "MyEnum.B != MyEnum.C");
$helpers.assert($helpers.neq($MyEnum.B, $MyEnum.C), "MyEnum.B != MyEnum.C");
$helpers.assert($helpers.eq($x, $MyEnum.C), "x == MyEnum.C");
}
}
Expand All @@ -54,7 +54,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
2 changes: 1 addition & 1 deletion libs/wingc/src/jsify/snapshots/func_returns_func.snap
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class $Root extends $stdlib.std.Resource {
_hash = require('crypto').createHash('md5').update(this._toInflight()).digest('hex');
constructor($scope, $id, ) {
super($scope, $id);
(std.Node.of(this)).hidden = true;
$helpers.nodeof(this).hidden = true;
}
static _toInflightType() {
return `
Expand Down
Loading

0 comments on commit c52cca6

Please sign in to comment.