Merge branch 'gometalinter' of https://github.com/bforsyth927/lumi into bforsyth927-gometalinter
This commit is contained in:
commit
cdd5471cfe
2
Makefile
2
Makefile
|
@ -30,8 +30,6 @@ install:
|
|||
.PHONY: lint
|
||||
lint:
|
||||
@echo "\033[0;32mLINT:\033[0m"
|
||||
|
||||
|
||||
@gometalinter pkg/...
|
||||
@gometalinter cmd/lumi/...
|
||||
@gometalinter cmd/lumidl/...
|
||||
|
|
|
@ -1023,11 +1023,14 @@ export class Transformer {
|
|||
contract.assert(!!idsym, `Expected an ID symbol for '${id.ident}', but it is missing`);
|
||||
tok = await this.resolveTokenFromSymbol(idsym);
|
||||
// note that we intentionally leave object blank, since the token is fully qualified.
|
||||
if ((idsym.flags & ts.SymbolFlags.Alias) === 0) {
|
||||
// Mark as dynamic unless this is an alias to a module import.
|
||||
isDynamic = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDynamic) {
|
||||
// If the target type is `dynamic`, we cannot perform static lookups; devolve into a dynamic load.
|
||||
contract.assert(!!object);
|
||||
return this.withLocation(node, <ast.TryLoadDynamicExpression>{
|
||||
kind: ast.tryLoadDynamicExpressionKind,
|
||||
object: object,
|
||||
|
|
|
@ -1215,10 +1215,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a2",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a2",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1303,10 +1303,10 @@
|
|||
"left": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a2",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a2",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1436,10 +1436,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a2",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a2",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1524,10 +1524,10 @@
|
|||
"left": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a2",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a2",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1657,10 +1657,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a2",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a2",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1745,10 +1745,10 @@
|
|||
"left": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a2",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a2",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2004,10 +2004,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a3",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a3",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2121,10 +2121,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a3",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a3",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2238,10 +2238,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a3",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a3",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2859,10 +2859,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2978,10 +2978,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -3125,10 +3125,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -3272,10 +3272,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -3417,10 +3417,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -3536,10 +3536,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -3683,10 +3683,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -3830,10 +3830,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -4189,10 +4189,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -4308,10 +4308,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -4455,10 +4455,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -4602,10 +4602,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -4747,10 +4747,10 @@
|
|||
"right": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -4866,10 +4866,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -5013,10 +5013,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -5160,10 +5160,10 @@
|
|||
"object": {
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/arrays:index:a6",
|
||||
"kind": "StringLiteral",
|
||||
"value": "a6",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
|
|
@ -942,10 +942,10 @@
|
|||
"expression": {
|
||||
"kind": "InvokeFunctionExpression",
|
||||
"function": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/undefined:index:f",
|
||||
"kind": "StringLiteral",
|
||||
"value": "f",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1237,10 +1237,10 @@
|
|||
"expression": {
|
||||
"kind": "InvokeFunctionExpression",
|
||||
"function": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/undefined:index:g",
|
||||
"kind": "StringLiteral",
|
||||
"value": "g",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
|
|
@ -1023,10 +1023,10 @@
|
|||
},
|
||||
"operator": "=",
|
||||
"right": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:modprop",
|
||||
"kind": "StringLiteral",
|
||||
"value": "modprop",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1256,10 +1256,10 @@
|
|||
"kind": "BinaryOperatorExpression",
|
||||
"operator": "!=",
|
||||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:c",
|
||||
"kind": "StringLiteral",
|
||||
"value": "c",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1389,10 +1389,10 @@
|
|||
"right": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:c",
|
||||
"kind": "StringLiteral",
|
||||
"value": "c",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1568,10 +1568,10 @@
|
|||
"tok": "f"
|
||||
},
|
||||
"value": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:modprop",
|
||||
"kind": "StringLiteral",
|
||||
"value": "modprop",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1664,10 +1664,10 @@
|
|||
"value": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:c",
|
||||
"kind": "StringLiteral",
|
||||
"value": "c",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1770,10 +1770,10 @@
|
|||
"property": {
|
||||
"kind": "InvokeFunctionExpression",
|
||||
"function": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:j",
|
||||
"kind": "StringLiteral",
|
||||
"value": "j",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1965,10 +1965,10 @@
|
|||
"right": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:c",
|
||||
"kind": "StringLiteral",
|
||||
"value": "c",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2065,10 +2065,10 @@
|
|||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/props:index:c",
|
||||
"kind": "StringLiteral",
|
||||
"value": "c",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
|
|
@ -1164,10 +1164,10 @@
|
|||
"function": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:b",
|
||||
"kind": "StringLiteral",
|
||||
"value": "b",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1262,10 +1262,10 @@
|
|||
"kind": "BinaryOperatorExpression",
|
||||
"operator": "!=",
|
||||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:bgx",
|
||||
"kind": "StringLiteral",
|
||||
"value": "bgx",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1363,10 +1363,10 @@
|
|||
}
|
||||
},
|
||||
"right": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:bgx",
|
||||
"kind": "StringLiteral",
|
||||
"value": "bgx",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1581,10 +1581,10 @@
|
|||
"function": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:c",
|
||||
"kind": "StringLiteral",
|
||||
"value": "c",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1679,10 +1679,10 @@
|
|||
"kind": "BinaryOperatorExpression",
|
||||
"operator": "!=",
|
||||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:cgx",
|
||||
"kind": "StringLiteral",
|
||||
"value": "cgx",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1780,10 +1780,10 @@
|
|||
}
|
||||
},
|
||||
"right": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:cgx",
|
||||
"kind": "StringLiteral",
|
||||
"value": "cgx",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -1910,10 +1910,10 @@
|
|||
"function": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"object": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:c",
|
||||
"kind": "StringLiteral",
|
||||
"value": "c",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2008,10 +2008,10 @@
|
|||
"kind": "BinaryOperatorExpression",
|
||||
"operator": "!=",
|
||||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:cgy",
|
||||
"kind": "StringLiteral",
|
||||
"value": "cgy",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
@ -2109,10 +2109,10 @@
|
|||
}
|
||||
},
|
||||
"right": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"kind": "TryLoadDynamicExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "basic/super:index:cgy",
|
||||
"kind": "StringLiteral",
|
||||
"value": "cgy",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
|
|
|
@ -2,5 +2,6 @@ name: serverless
|
|||
description: Basic example of a serverless AWS application.
|
||||
dependencies:
|
||||
lumi: "*"
|
||||
lumijs: "*"
|
||||
aws: "*"
|
||||
|
||||
|
|
|
@ -49,34 +49,17 @@ let music = new aws.dynamodb.Table("music", {
|
|||
],
|
||||
})
|
||||
|
||||
// TODO[pulumi/lumi#174] Until we have global definitions available in Lumi for these APIs that are expected
|
||||
// by runtime code, we'll declare variables that should be available on the global scope of the lambda to keep
|
||||
// TypeScript type checking happy.
|
||||
let console: any
|
||||
|
||||
function createLambda() {
|
||||
// TODO[pulumi/lumi#175] Currently, we can only capture local variables, not module scope variables,
|
||||
// so we keep this inside a helper function.
|
||||
let hello = "Hello, world!"
|
||||
let num = 3
|
||||
let obj = { x: 42 }
|
||||
let mus = music
|
||||
|
||||
let lambda = new aws.serverless.Function(
|
||||
"mylambda",
|
||||
[aws.iam.AWSLambdaFullAccess],
|
||||
(event, context, callback) => {
|
||||
console.log(hello);
|
||||
console.log(obj.x);
|
||||
console.log("Music table hash key is: " + mus.hashKey);
|
||||
console.log("Invoked function: " + context.invokedFunctionArn);
|
||||
callback(null, "Succeeed with " + context.getRemainingTimeInMillis() + "ms remaining.");
|
||||
}
|
||||
);
|
||||
return lambda;
|
||||
}
|
||||
|
||||
let lambda = createLambda();
|
||||
let hello = "Hello, world!"
|
||||
let lambda = new aws.serverless.Function(
|
||||
"mylambda",
|
||||
[aws.iam.AWSLambdaFullAccess],
|
||||
(event, context, callback) => {
|
||||
console.log(hello);
|
||||
console.log("Music table hash key is: " + music.hashKey);
|
||||
console.log("Invoked function: " + context.invokedFunctionArn);
|
||||
callback(null, "Succeeed with " + context.getRemainingTimeInMillis() + "ms remaining.");
|
||||
}
|
||||
);
|
||||
|
||||
let api = new aws.serverless.API("frontend")
|
||||
api.route("GET", "/bambam", lambda)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"typescript": "^2.1.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@lumi/lumi": "*",
|
||||
"@lumi/aws": "*"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable: ordered-imports */
|
||||
|
||||
import * as slack from "@slack/client";
|
||||
import {builders, providers} from "./cicd";
|
||||
import * as github from "./github";
|
||||
import * as slack from "@slack/client";
|
||||
|
||||
// On pushes or PR merges,
|
||||
// - In master, build and deploy the bits to production.
|
||||
|
|
|
@ -78,7 +78,7 @@ function createPathSpec(lambdaARN: string): SwaggerOperation {
|
|||
}
|
||||
|
||||
function createSourceARN(region: string, account: string, apiid: string, functionName: string): string {
|
||||
return "arn:aws:execute-api:"+region+":"+account+":"+apiid+"/*/*/"+ functionName;
|
||||
return "arn:aws:execute-api:" + region + ":" + account + ":" + apiid + "/*/*/" + functionName;
|
||||
}
|
||||
|
||||
// API is a higher level abstraction for working with AWS APIGateway reources.
|
||||
|
@ -117,9 +117,8 @@ export class API {
|
|||
default:
|
||||
throw new Error("Method not supported: " + method);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
let apiName = "";
|
||||
if(this.api.apiName !== undefined) {
|
||||
if (this.api.apiName !== undefined) {
|
||||
apiName = this.api.apiName;
|
||||
}
|
||||
let invokePermission = new Permission(this.apiName + "_invoke_" + sha1hash(method + path), {
|
||||
|
@ -129,9 +128,6 @@ export class API {
|
|||
sourceARN: createSourceARN("us-east-1", "490047557317", apiName, "webapi-test-func"),
|
||||
});
|
||||
// TODO[pulumi/lumi#90]: Once we suport output properties, we can use `lambda.lambda.arn` as input
|
||||
=======
|
||||
// TODO[pulumi/lumi#90]: Once we suport output properties, we can use `lambda.lambda.arn` as input
|
||||
>>>>>>> 13dbcdbafc96be49e509c618194cd649ba6d0817
|
||||
// to constructing this apigateway lambda invocation uri.
|
||||
// this.swaggerSpec.paths[path][swaggerMethod] = createPathSpec(lambda.lambda.arn);
|
||||
this.swaggerSpec.paths[path][swaggerMethod] = createPathSpec(
|
||||
|
|
|
@ -13,12 +13,11 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable: ordered-imports align*/
|
||||
import { AssetArchive, String } from "@lumi/lumi/asset";
|
||||
import { serializeClosure, jsonStringify } from "@lumi/lumi/runtime";
|
||||
import { jsonStringify, serializeClosure} from "@lumi/lumi/runtime";
|
||||
import { Role } from "../iam/role";
|
||||
import { Function as LambdaFunction } from "../lambda/function";
|
||||
import { ARN } from "../types";
|
||||
import { Role } from "../iam/role";
|
||||
|
||||
// Context is the shape of the context object passed to a Function callback.
|
||||
export interface Context {
|
||||
|
@ -56,7 +55,7 @@ export class Function {
|
|||
public role: Role;
|
||||
|
||||
constructor(name: string, policies: ARN[],
|
||||
func: (event: any, context: Context, callback: (error: any, result: any) => void) => any) {
|
||||
func: (event: any, context: Context, callback: (error: any, result: any) => void) => any) {
|
||||
|
||||
if (name === undefined) {
|
||||
throw new Error("Missing required resource name");
|
||||
|
|
|
@ -13,12 +13,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable:no-empty */
|
||||
|
||||
// Asset represents a blob of text or data that is managed as a first class entity.
|
||||
export abstract class Asset {
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
|
||||
// Blob is a kind of asset produced from an in-memory blob represented as a byte array.
|
||||
|
|
|
@ -12,10 +12,8 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/* tslint:disable:no-empty*/
|
||||
|
||||
// Resource represents a class whose CRUD operations are implemented by a provider plugin.
|
||||
export abstract class Resource {
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
name: lumijs
|
||||
description: The LumiJS runtime library.
|
||||
dependencies:
|
||||
lumi: "*"
|
||||
|
||||
|
|
25
lib/lumijs/lib/console.ts
Normal file
25
lib/lumijs/lib/console.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Licensed to Pulumi Corporation ("Pulumi") under one or more
|
||||
// contributor license agreements. See the NOTICE file distributed with
|
||||
// this work for additional information regarding copyright ownership.
|
||||
// Pulumi licenses this file to You under the Apache License, Version 2.0
|
||||
// (the "License"); you may not use this file except in compliance with
|
||||
// the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { printf } from "@lumi/lumi/runtime"
|
||||
|
||||
export class Console {
|
||||
log(message: any) {
|
||||
printf(message);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
export let console = new Console();
|
|
@ -17,4 +17,5 @@
|
|||
|
||||
export * from "./errors";
|
||||
export * from "./types";
|
||||
export * from "./console";
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable: variable-name */
|
||||
|
||||
|
||||
// The available cloud providers.
|
||||
|
||||
export const AWS = "aws"; // Amazon Web Services.
|
||||
export const GCP = "gcp"; // Google Cloud Platform.
|
||||
export const Azure = "azure"; // Microsoft Azure.
|
||||
export const VMWare = "vmware"; // VMWare vSphere, etc.
|
||||
export const aws = "aws"; // Amazon Web Services.
|
||||
export const gcp = "gcp"; // Google Cloud Platform.
|
||||
export const azure = "azure"; // Microsoft Azure.
|
||||
export const vmware = "vmware"; // VMWare vSphere, etc.
|
||||
|
||||
|
|
|
@ -13,12 +13,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable:ordered-imports */
|
||||
|
||||
export * from "./arch";
|
||||
|
||||
import * as clouds from "./clouds";
|
||||
import * as schedulers from "./schedulers";
|
||||
import * as runtimes from "./runtimes";
|
||||
import * as schedulers from "./schedulers";
|
||||
export {clouds, schedulers, runtimes};
|
||||
|
||||
|
|
|
@ -13,15 +13,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable:variable-name */
|
||||
|
||||
// The available language runtimes.
|
||||
|
||||
export const NodeJS = "nodejs";
|
||||
export const Python = "python";
|
||||
export const nodejs = "nodejs";
|
||||
export const python = "python";
|
||||
|
||||
export let ext: {[lang: string]: string} = {
|
||||
NodeJS: ".js",
|
||||
Python: ".py",
|
||||
nodejs: ".js",
|
||||
python: ".py",
|
||||
};
|
||||
|
||||
|
|
|
@ -13,14 +13,11 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable:variable-name */
|
||||
|
||||
// The available container scheduler/runtimes.
|
||||
|
||||
export const Swarm = "swarm"; // Docker Swarm.
|
||||
export const Kubernetes = "kubernetes"; // Kubernetes.
|
||||
export const Mesos = "mesos"; // Apache Mesos.
|
||||
export const ECS = "ecs"; // Amazon Elastic Container Service (only valid for AWS clouds).
|
||||
export const GKE = "gke"; // Google Container Engine (only valid for GCP clouds).
|
||||
export const ACS = "acs"; // Microsoft Azure Container Service (only valid for Azure).
|
||||
export const swarm = "swarm"; // Docker Swarm.
|
||||
export const kubernetes = "kubernetes"; // Kubernetes.
|
||||
export const mesos = "mesos"; // Apache Mesos.
|
||||
export const ecs = "ecs"; // Amazon Elastic Container Service (only valid for AWS clouds).
|
||||
export const gke = "gke"; // Google Container Engine (only valid for GCP clouds).
|
||||
export const acs = "acs"; // Microsoft Azure Container Service (only valid for Azure).
|
||||
|
||||
|
|
|
@ -13,14 +13,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/* tslint:disable:ordered-imports */
|
||||
|
||||
import * as arch from "../arch";
|
||||
import * as config from "../config";
|
||||
import * as runtime from "../runtime";
|
||||
import * as aws from "@lumi/aws";
|
||||
import * as kubefission from "@lumi/kubefission";
|
||||
import {asset} from "@lumi/lumi";
|
||||
import * as arch from "../arch";
|
||||
import * as config from "../config";
|
||||
import * as runtime from "../runtime";
|
||||
|
||||
// Function is a cross-cloud function abstraction whose source code is taken from a string, file, or network asset.
|
||||
// For example, `https://gist.github.com/pulumi/fe8a5ae322ffe63fac90535eb554237f` will use a Gist published on GitHub,
|
||||
|
@ -48,16 +46,16 @@ export class Function {
|
|||
// initCloudResources sets up the right resources for the given cloud and scheduler target.
|
||||
private initCloudResources(): any {
|
||||
let target: arch.Arch = config.requireArch();
|
||||
if (target.scheduler === arch.schedulers.Kubernetes) {
|
||||
if (target.scheduler === arch.schedulers.kubernetes) {
|
||||
return this.initKubernetesResources();
|
||||
}
|
||||
else {
|
||||
switch (target.cloud) {
|
||||
case arch.clouds.AWS:
|
||||
case arch.clouds.aws:
|
||||
return this.initAWSResources();
|
||||
case arch.clouds.GCP:
|
||||
case arch.clouds.gcp:
|
||||
return this.initGCPResources();
|
||||
case arch.clouds.Azure:
|
||||
case arch.clouds.azure:
|
||||
return this.initAzureResources();
|
||||
default:
|
||||
throw new Error("Unsupported target cloud: " + target.cloud);
|
||||
|
|
107
pkg/compiler/binder/freevars.go
Normal file
107
pkg/compiler/binder/freevars.go
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Licensed to Pulumi Corporation ("Pulumi") under one or more
|
||||
// contributor license agreements. See the NOTICE file distributed with
|
||||
// this work for additional information regarding copyright ownership.
|
||||
// Pulumi licenses this file to You under the Apache License, Version 2.0
|
||||
// (the "License"); you may not use this file except in compliance with
|
||||
// the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package binder
|
||||
|
||||
import (
|
||||
"github.com/pulumi/lumi/pkg/compiler/ast"
|
||||
"github.com/pulumi/lumi/pkg/tokens"
|
||||
"github.com/pulumi/lumi/pkg/util/contract"
|
||||
)
|
||||
|
||||
// FreeVars computes the free variables referenced inside a function body.
|
||||
// The free variables for a function will be either simple identifier tokens or tokens
|
||||
// referencing module-scope variables.
|
||||
func FreeVars(fnc ast.Function) []tokens.Token {
|
||||
visitor := &freeVarsVisitor{
|
||||
freeVars: map[tokens.Token]bool{},
|
||||
}
|
||||
|
||||
ast.Walk(visitor, fnc)
|
||||
|
||||
params := fnc.GetParameters()
|
||||
if params != nil {
|
||||
for _, lv := range *params {
|
||||
visitor.removeLocalVariable(lv)
|
||||
}
|
||||
}
|
||||
|
||||
var vars []tokens.Token
|
||||
for k := range visitor.freeVars {
|
||||
vars = append(vars, k)
|
||||
}
|
||||
return vars
|
||||
}
|
||||
|
||||
type freeVarsVisitor struct {
|
||||
freeVars map[tokens.Token]bool
|
||||
}
|
||||
|
||||
var _ ast.Visitor = (*freeVarsVisitor)(nil)
|
||||
|
||||
func (visitor *freeVarsVisitor) Visit(node ast.Node) ast.Visitor {
|
||||
return visitor
|
||||
}
|
||||
|
||||
// We walk the AST and process each node after visiting it in depth first order. There are two cases we care about:
|
||||
// 1) After visiting a leaf node which is a reference to a local variable (`n.Object == nil``), we add it to our set.
|
||||
// 2) After visiting a LocalVariableDeclaration or a Lambda, we remove the declared variables from our set.
|
||||
func (visitor *freeVarsVisitor) After(node ast.Node) {
|
||||
switch n := node.(type) {
|
||||
case *ast.LoadLocationExpression:
|
||||
if n.Object == nil {
|
||||
visitor.addToken(n.Name.Tok)
|
||||
}
|
||||
case *ast.LoadDynamicExpression:
|
||||
if n.Object == nil {
|
||||
switch e := n.Name.(type) {
|
||||
case *ast.StringLiteral:
|
||||
visitor.addToken(tokens.Token(e.Value))
|
||||
default:
|
||||
contract.Failf("expected LoadDynamicExpression with Object == nil to have a StringLiteral expression")
|
||||
}
|
||||
}
|
||||
case *ast.TryLoadDynamicExpression:
|
||||
if n.Object == nil {
|
||||
switch e := n.Name.(type) {
|
||||
case *ast.StringLiteral:
|
||||
visitor.addToken(tokens.Token(e.Value))
|
||||
default:
|
||||
contract.Failf("expected LoadDynamicExpression with Object == nil to have a StringLiteral expression")
|
||||
}
|
||||
}
|
||||
case *ast.LambdaExpression:
|
||||
if n.Parameters != nil {
|
||||
for _, param := range *n.Parameters {
|
||||
visitor.removeLocalVariable(param)
|
||||
}
|
||||
}
|
||||
case *ast.Block:
|
||||
for _, stmt := range n.Statements {
|
||||
switch s := stmt.(type) {
|
||||
case *ast.LocalVariableDeclaration:
|
||||
visitor.removeLocalVariable(s.Local)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (visitor *freeVarsVisitor) addToken(tok tokens.Token) {
|
||||
visitor.freeVars[tok] = true
|
||||
}
|
||||
|
||||
func (visitor *freeVarsVisitor) removeLocalVariable(lv *ast.LocalVariable) {
|
||||
delete(visitor.freeVars, tokens.Token(lv.Name.Ident))
|
||||
}
|
192
pkg/compiler/binder/freevars_test.go
Normal file
192
pkg/compiler/binder/freevars_test.go
Normal file
|
@ -0,0 +1,192 @@
|
|||
// Licensed to Pulumi Corporation ("Pulumi") under one or more
|
||||
// contributor license agreements. See the NOTICE file distributed with
|
||||
// this work for additional information regarding copyright ownership.
|
||||
// Pulumi licenses this file to You under the Apache License, Version 2.0
|
||||
// (the "License"); you may not use this file except in compliance with
|
||||
// the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package binder
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pulumi/lumi/pkg/compiler/ast"
|
||||
"github.com/pulumi/lumi/pkg/compiler/types"
|
||||
"github.com/pulumi/lumi/pkg/tokens"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func makeLocalVariable(name string) *ast.LocalVariable {
|
||||
return &ast.LocalVariable{
|
||||
DefinitionNode: ast.DefinitionNode{
|
||||
Name: &ast.Identifier{
|
||||
Ident: tokens.Name(name),
|
||||
},
|
||||
},
|
||||
VariableNode: ast.VariableNode{
|
||||
Type: &ast.TypeToken{
|
||||
Tok: types.Object.TypeToken(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func expressionRef(expr ast.Expression) *ast.Expression {
|
||||
return &expr
|
||||
}
|
||||
|
||||
func TestFreeVars_Parameter(t *testing.T) {
|
||||
// function(foo) foo
|
||||
fun := ast.ModuleMethod{
|
||||
FunctionNode: ast.FunctionNode{
|
||||
Parameters: &[]*ast.LocalVariable{
|
||||
makeLocalVariable("foo"),
|
||||
},
|
||||
Body: &ast.ExpressionStatement{
|
||||
Expression: &ast.LoadLocationExpression{
|
||||
Name: &ast.Token{
|
||||
Tok: tokens.Token("foo"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
freeVars := FreeVars(&fun)
|
||||
assert.Len(t, freeVars, 0, "expected no free variables")
|
||||
}
|
||||
|
||||
func TestFreeVars_Dynamic(t *testing.T) {
|
||||
// function(foo) foo
|
||||
fun := ast.ModuleMethod{
|
||||
FunctionNode: ast.FunctionNode{
|
||||
Parameters: &[]*ast.LocalVariable{},
|
||||
Body: &ast.ExpressionStatement{
|
||||
Expression: &ast.LoadDynamicExpression{
|
||||
Name: &ast.StringLiteral{
|
||||
Value: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
freeVars := FreeVars(&fun)
|
||||
assert.Len(t, freeVars, 1, "expected one free variable")
|
||||
assert.Equal(t, tokens.Name("foo"), freeVars[0].Name())
|
||||
}
|
||||
|
||||
func TestFreeVars_LocalVariable(t *testing.T) {
|
||||
// function(foo) { var bar; foo; bar; baz; }
|
||||
fun := ast.ModuleMethod{
|
||||
FunctionNode: ast.FunctionNode{
|
||||
Parameters: &[]*ast.LocalVariable{
|
||||
makeLocalVariable("foo"),
|
||||
},
|
||||
Body: &ast.Block{
|
||||
Statements: []ast.Statement{
|
||||
&ast.LocalVariableDeclaration{
|
||||
Local: makeLocalVariable("bar"),
|
||||
},
|
||||
&ast.ExpressionStatement{
|
||||
Expression: &ast.LoadLocationExpression{
|
||||
Name: &ast.Token{
|
||||
Tok: tokens.Token("foo"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.ExpressionStatement{
|
||||
Expression: &ast.LoadLocationExpression{
|
||||
Name: &ast.Token{
|
||||
Tok: tokens.Token("bar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.ExpressionStatement{
|
||||
Expression: &ast.TryLoadDynamicExpression{
|
||||
Name: &ast.StringLiteral{
|
||||
Value: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
freeVars := FreeVars(&fun)
|
||||
assert.Len(t, freeVars, 1, "expected one free variable")
|
||||
assert.Equal(t, tokens.Name("baz"), freeVars[0].Name())
|
||||
}
|
||||
|
||||
func TestFreeVars_Member(t *testing.T) {
|
||||
// function(foo) foo.bar
|
||||
fun := ast.ModuleMethod{
|
||||
FunctionNode: ast.FunctionNode{
|
||||
Parameters: &[]*ast.LocalVariable{
|
||||
makeLocalVariable("foo"),
|
||||
},
|
||||
Body: &ast.ExpressionStatement{
|
||||
Expression: &ast.LoadLocationExpression{
|
||||
Object: expressionRef(&ast.LoadLocationExpression{
|
||||
Name: &ast.Token{
|
||||
Tok: tokens.Token("foo"),
|
||||
},
|
||||
}),
|
||||
Name: &ast.Token{
|
||||
Tok: tokens.Token("bar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
freeVars := FreeVars(&fun)
|
||||
assert.Len(t, freeVars, 0, "expected no free variables")
|
||||
}
|
||||
|
||||
func TestFreeVars_Lambda(t *testing.T) {
|
||||
// function(foo) ((bar) => bar)(foo)
|
||||
fun := ast.ModuleMethod{
|
||||
FunctionNode: ast.FunctionNode{
|
||||
Parameters: &[]*ast.LocalVariable{
|
||||
makeLocalVariable("foo"),
|
||||
},
|
||||
Body: &ast.ExpressionStatement{
|
||||
Expression: &ast.InvokeFunctionExpression{
|
||||
Function: &ast.LambdaExpression{
|
||||
FunctionNode: ast.FunctionNode{
|
||||
Parameters: &[]*ast.LocalVariable{
|
||||
makeLocalVariable("bar"),
|
||||
},
|
||||
Body: &ast.ExpressionStatement{
|
||||
Expression: &ast.LoadLocationExpression{
|
||||
Name: &ast.Token{
|
||||
Tok: tokens.Token("bar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
CallExpressionNode: ast.CallExpressionNode{
|
||||
Arguments: &[]*ast.CallArgument{
|
||||
&ast.CallArgument{
|
||||
Expr: &ast.LoadLocationExpression{
|
||||
Name: &ast.Token{
|
||||
Tok: tokens.Token("foo"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
freeVars := FreeVars(&fun)
|
||||
assert.Len(t, freeVars, 0, "expected no free variables")
|
||||
}
|
|
@ -1730,22 +1730,23 @@ func (e *evaluator) evalLoadDynamicCore(node ast.Node, objexpr *ast.Expression,
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (e *evaluator) getDynamicNameAddr(key tokens.Name, lval bool) *rt.Pointer {
|
||||
var pv *rt.Pointer
|
||||
|
||||
// If there's no object, look in the current localsment.
|
||||
pkey := rt.PropertyKey(key)
|
||||
globals := e.getModuleGlobals(e.ctx.Currmodule)
|
||||
if loc := e.locals.Lookup(key); loc != nil {
|
||||
pv = e.locals.GetValueAddr(loc, true) // create a slot, we know the declaration exists.
|
||||
} else {
|
||||
// If it didn't exist in the lexical scope, check the module's globals.
|
||||
pv = globals.Properties().GetAddr(pkey) // look for a global by this name, but don't allocate one.
|
||||
func getDynamicNameAddrCore(locals rt.Environment, globals *rt.Object, key tokens.Name) *rt.Pointer {
|
||||
if loc := locals.Lookup(key); loc != nil {
|
||||
return locals.GetValueAddr(loc, true) // create a slot, we know the declaration exists.
|
||||
}
|
||||
// If it didn't exist in the lexical scope, check the module's globals.
|
||||
pkey := rt.PropertyKey(key)
|
||||
return globals.Properties().GetAddr(pkey) // look for a global by this name, but don't allocate one.
|
||||
}
|
||||
|
||||
// Finally, if neither of those existed, and this is the target of a load, allocate a slot.
|
||||
func (e *evaluator) getDynamicNameAddr(key tokens.Name, lval bool) *rt.Pointer {
|
||||
globals := e.getModuleGlobals(e.ctx.Currmodule)
|
||||
pv := getDynamicNameAddrCore(e.locals, globals, key)
|
||||
|
||||
// If not found and this is the target of a load, allocate a slot.
|
||||
if pv == nil && lval {
|
||||
if e.fnc != nil && e.fnc.SpecialModInit() && e.locals.Activation() {
|
||||
pkey := rt.PropertyKey(key)
|
||||
pv = globals.Properties().GetInitAddr(pkey)
|
||||
} else {
|
||||
loc := symbols.NewSpecialVariableSym(key, types.Dynamic)
|
||||
|
@ -1870,7 +1871,8 @@ func (e *evaluator) evalLambdaExpression(node *ast.LambdaExpression) (*rt.Object
|
|||
// To create a lambda object we will simply produce a function object that can invoke it. Lambdas also uniquely
|
||||
// capture the current environment, including the this variable.
|
||||
sig := e.ctx.RequireType(node).(*symbols.FunctionType)
|
||||
obj := rt.NewFunctionObjectFromLambda(node, sig, e.locals)
|
||||
moduleObject := e.getModuleGlobals(e.ctx.Currmodule)
|
||||
obj := rt.NewFunctionObjectFromLambda(node, sig, e.locals, moduleObject)
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -19,14 +19,15 @@ import (
|
|||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pulumi/lumi/pkg/compiler/ast"
|
||||
"github.com/pulumi/lumi/pkg/compiler/binder"
|
||||
"github.com/pulumi/lumi/pkg/compiler/symbols"
|
||||
"github.com/pulumi/lumi/pkg/compiler/types"
|
||||
"github.com/pulumi/lumi/pkg/eval/rt"
|
||||
"github.com/pulumi/lumi/pkg/tokens"
|
||||
"github.com/pulumi/lumi/pkg/util/contract"
|
||||
)
|
||||
|
||||
|
@ -108,21 +109,24 @@ func serializeClosure(intrin *rt.Intrinsic, e *evaluator, this *rt.Object, args
|
|||
return e.NewException(intrin.Tree(), "Expected argument 'func' to be a lambda expression.")
|
||||
}
|
||||
|
||||
// TODO[pulumi/lumi#177]: We are using the full environment available at execution time here, we should
|
||||
// instead capture only the free variables referenced in the function itself.
|
||||
|
||||
// Insert environment variables into a PropertyMap with stable ordering
|
||||
envPropMap := rt.NewPropertyMap()
|
||||
slots := stub.Env.Slots()
|
||||
var keys []*symbols.LocalVariable
|
||||
for key := range slots {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.SliceStable(keys, func(i, j int) bool {
|
||||
return keys[i].Name() < keys[j].Name()
|
||||
})
|
||||
for _, key := range keys {
|
||||
envPropMap.Set(rt.PropertyKey(key.Name()), slots[key].Obj())
|
||||
for _, tok := range binder.FreeVars(stub.Func) {
|
||||
var name tokens.Name
|
||||
contract.Assertf(tok.Simple() || (tok.HasModule() && tok.HasModuleMember() && !tok.HasClassMember()),
|
||||
"Expected free variable to be simple name or reference to top-level module name")
|
||||
if tok.Simple() {
|
||||
name = tok.Name()
|
||||
} else {
|
||||
name = tokens.Name(tok.ModuleMember().Name())
|
||||
}
|
||||
pv := getDynamicNameAddrCore(stub.Env, stub.Module, name)
|
||||
if pv != nil {
|
||||
envPropMap.Set(rt.PropertyKey(name), pv.Obj())
|
||||
}
|
||||
// Else the variable was not found, so we skip serializing it.
|
||||
// This will be true for references to globals which are not known to Lumi but
|
||||
// will be available within the runtime environment.
|
||||
}
|
||||
envObj := e.alloc.New(intrin.Tree(), types.Dynamic, envPropMap, nil)
|
||||
|
||||
|
|
|
@ -452,21 +452,23 @@ func NewFunctionObjectFromSymbol(fnc symbols.Function, this *Object) *Object {
|
|||
}
|
||||
|
||||
// NewFunctionObjectFromLambda creates a new function object with very specific underlying parts.
|
||||
func NewFunctionObjectFromLambda(fnc ast.Function, sig *symbols.FunctionType, env Environment) *Object {
|
||||
func NewFunctionObjectFromLambda(fnc ast.Function, sig *symbols.FunctionType, env Environment, module *Object) *Object {
|
||||
return NewFunctionObject(FuncStub{
|
||||
Func: fnc,
|
||||
Sig: sig,
|
||||
Env: env,
|
||||
Func: fnc,
|
||||
Sig: sig,
|
||||
Env: env,
|
||||
Module: module,
|
||||
})
|
||||
}
|
||||
|
||||
// FuncStub is a stub that captures a symbol plus an optional instance 'this' object.
|
||||
type FuncStub struct {
|
||||
Func ast.Function // the function whose body AST to evaluate.
|
||||
Sym symbols.Function // an optional function symbol that this AST belongs to.
|
||||
Sig *symbols.FunctionType // the function type representing this function's signature.
|
||||
This *Object // an optional "this" pointer to bind when invoking this function.
|
||||
Env Environment // an optional environment to evaluate this function inside.
|
||||
Func ast.Function // the function whose body AST to evaluate.
|
||||
Sym symbols.Function // an optional function symbol that this AST belongs to.
|
||||
Sig *symbols.FunctionType // the function type representing this function's signature.
|
||||
This *Object // an optional "this" pointer to bind when invoking this function.
|
||||
Env Environment // an optional environment to evaluate this function inside.
|
||||
Module *Object // an optional module object to use for module variable lookups inside this function.
|
||||
}
|
||||
|
||||
// NewPointerObject allocates a new pointer-like object that wraps the given reference.
|
||||
|
@ -641,11 +643,12 @@ func adjustPointerForThis(parent *Object, this *Object, prop *Pointer) *Pointer
|
|||
stub := value.FunctionValue()
|
||||
contract.Assert(stub.This == parent)
|
||||
value = NewFunctionObject(FuncStub{
|
||||
Func: stub.Func,
|
||||
Sym: stub.Sym,
|
||||
Sig: stub.Sig,
|
||||
This: this,
|
||||
Env: stub.Env,
|
||||
Func: stub.Func,
|
||||
Sym: stub.Sym,
|
||||
Sig: stub.Sig,
|
||||
This: this,
|
||||
Env: stub.Env,
|
||||
Module: stub.Module,
|
||||
})
|
||||
prop = NewPointer(value, prop.Readonly(), prop.Getter(), prop.Setter())
|
||||
case *symbols.ComputedType:
|
||||
|
@ -684,7 +687,7 @@ func (intrin *Intrinsic) SpecialModInit() bool { return false }
|
|||
func (intrin *Intrinsic) Tree() diag.Diagable { return intrin.node }
|
||||
func (intrin *Intrinsic) Function() ast.Function { return intrin.node }
|
||||
func (intrin *Intrinsic) Signature() *symbols.FunctionType { return intrin.sig }
|
||||
func (intrin *Intrinsic) String() string { return string(intrin.Name()) }
|
||||
func (intrin *Intrinsic) String() string { return string(intrin.Token()) }
|
||||
|
||||
func (intrin *Intrinsic) UnderlyingSymbol() symbols.Function { return intrin.fnc }
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ import (
|
|||
"github.com/pulumi/lumi/pkg/util/contract"
|
||||
)
|
||||
|
||||
// Print prints a LumiGL graph.
|
||||
func Print(g graph.Graph, w io.Writer) error {
|
||||
|
||||
var err error
|
||||
// Allocate a new writer. In general, we will ignore write errors throughout this function, for simplicity, opting
|
||||
// instead to return the result of flushing the buffer at the end, which is generally latching.
|
||||
|
|
|
@ -346,12 +346,11 @@ func (a Archive) openURLStream(url *url.URL) (io.ReadCloser, error) {
|
|||
// Bytes fetches the archive contents as a byte slices. This is almost certainly the least efficient way to deal with
|
||||
// the underlying streaming capabilities offered by assets and archives, but can be used in a pinch to interact with
|
||||
// APIs that demand []bytes.
|
||||
func (a Archive) Bytes(format ArchiveFormat) []byte {
|
||||
func (a Archive) Bytes(format ArchiveFormat) ([]byte, error) {
|
||||
var data bytes.Buffer
|
||||
err := a.Archive(format, &data)
|
||||
contract.Assert(err == nil)
|
||||
|
||||
return data.Bytes()
|
||||
var err error
|
||||
err = a.Archive(format, &data)
|
||||
return data.Bytes(), err
|
||||
}
|
||||
|
||||
// Archive produces a single archive stream in the desired format. It prefers to return the archive with as little
|
||||
|
|
|
@ -95,13 +95,13 @@ func newPlugin(ctx *Context, bins []string, prefix string) (*plugin, error) {
|
|||
var port string
|
||||
b := make([]byte, 1)
|
||||
for {
|
||||
n, stderr := plug.Stdout.Read(b)
|
||||
if stderr != nil {
|
||||
n, readerr := plug.Stdout.Read(b)
|
||||
if readerr != nil {
|
||||
plug.Proc.Kill()
|
||||
if port == "" {
|
||||
return nil, errors.Wrapf(stderr, "could not read plugin [%v] stdout", foundbin)
|
||||
return nil, errors.Wrapf(readerr, "could not read plugin [%v] stdout", foundbin)
|
||||
}
|
||||
return nil, errors.Wrapf(stderr, "failure reading plugin [%v] stdout (read '%v')", foundbin, port)
|
||||
return nil, errors.Wrapf(readerr, "failure reading plugin [%v] stdout (read '%v')", foundbin, port)
|
||||
}
|
||||
if n > 0 && b[0] == '\n' {
|
||||
break
|
||||
|
|
|
@ -37,7 +37,6 @@ func writefmtln(w *bufio.Writer, msg string, args ...interface{}) {
|
|||
func emitHeaderWarning(w *bufio.Writer) {
|
||||
writefmtln(w, "// *** WARNING: this file was generated by the Lumi IDL Compiler (LUMIDL). ***")
|
||||
writefmtln(w, "// *** Do not edit by hand unless you're certain you know what you are doing! ***")
|
||||
writefmtln(w, "/* tslint:disable:ordered-imports variable-name */")
|
||||
writefmtln(w, "")
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ func (g *PackGenerator) emitFileContents(file string, body string) error {
|
|||
|
||||
// Emit a header into the file.
|
||||
emitHeaderWarning(w)
|
||||
writefmtln(w, "/* tslint:disable:ordered-imports variable-name */")
|
||||
|
||||
// If there are any resources, import the Lumi package.
|
||||
if g.FileHadRes {
|
||||
|
|
|
@ -38,15 +38,10 @@ func InitLogging(logToStderr bool, verbose int, logFlow bool) {
|
|||
flag.Parse()
|
||||
if logToStderr {
|
||||
err := flag.Lookup("logtostderr").Value.Set("true")
|
||||
if err != nil {
|
||||
contract.Assert(err != nil)
|
||||
}
|
||||
|
||||
contract.Assert(err != nil)
|
||||
}
|
||||
if verbose > 0 {
|
||||
err := flag.Lookup("v").Value.Set(strconv.Itoa(verbose))
|
||||
if err != nil {
|
||||
contract.Assert(err != nil)
|
||||
}
|
||||
contract.Assert(err != nil)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,11 +178,6 @@ func (w *workspace) DepCandidates(dep pack.PackageURL) []string {
|
|||
return cands
|
||||
}
|
||||
|
||||
// namePath just cleans a name and makes sure it's appropriate to use as a path.
|
||||
func namePath(nm tokens.Name) string { //nolint
|
||||
return stringNamePath(string(nm))
|
||||
}
|
||||
|
||||
// qnamePath just cleans a name and makes sure it's appropriate to use as a path.
|
||||
func qnamePath(nm tokens.QName) string {
|
||||
return stringNamePath(string(nm))
|
||||
|
|
|
@ -120,5 +120,6 @@
|
|||
"check-separator",
|
||||
"check-type"
|
||||
]
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue