Merge branch 'gometalinter' of https://github.com/bforsyth927/lumi into bforsyth927-gometalinter

This commit is contained in:
Luke Hoban 2017-06-13 16:15:12 -07:00
commit cdd5471cfe
35 changed files with 570 additions and 282 deletions

View file

@ -30,8 +30,6 @@ install:
.PHONY: lint .PHONY: lint
lint: lint:
@echo "\033[0;32mLINT:\033[0m" @echo "\033[0;32mLINT:\033[0m"
@gometalinter pkg/... @gometalinter pkg/...
@gometalinter cmd/lumi/... @gometalinter cmd/lumi/...
@gometalinter cmd/lumidl/... @gometalinter cmd/lumidl/...

View file

@ -1023,11 +1023,14 @@ export class Transformer {
contract.assert(!!idsym, `Expected an ID symbol for '${id.ident}', but it is missing`); contract.assert(!!idsym, `Expected an ID symbol for '${id.ident}', but it is missing`);
tok = await this.resolveTokenFromSymbol(idsym); tok = await this.resolveTokenFromSymbol(idsym);
// note that we intentionally leave object blank, since the token is fully qualified. // 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 (isDynamic) {
// If the target type is `dynamic`, we cannot perform static lookups; devolve into a dynamic load. // 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>{ return this.withLocation(node, <ast.TryLoadDynamicExpression>{
kind: ast.tryLoadDynamicExpressionKind, kind: ast.tryLoadDynamicExpressionKind,
object: object, object: object,

View file

@ -1215,10 +1215,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a2", "value": "a2",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1303,10 +1303,10 @@
"left": { "left": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a2", "value": "a2",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1436,10 +1436,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a2", "value": "a2",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1524,10 +1524,10 @@
"left": { "left": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a2", "value": "a2",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1657,10 +1657,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a2", "value": "a2",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1745,10 +1745,10 @@
"left": { "left": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a2", "value": "a2",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2004,10 +2004,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a3", "value": "a3",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2121,10 +2121,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a3", "value": "a3",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2238,10 +2238,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a3", "value": "a3",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2859,10 +2859,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2978,10 +2978,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -3125,10 +3125,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -3272,10 +3272,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -3417,10 +3417,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -3536,10 +3536,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -3683,10 +3683,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -3830,10 +3830,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -4189,10 +4189,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -4308,10 +4308,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -4455,10 +4455,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -4602,10 +4602,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -4747,10 +4747,10 @@
"right": { "right": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -4866,10 +4866,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -5013,10 +5013,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -5160,10 +5160,10 @@
"object": { "object": {
"kind": "TryLoadDynamicExpression", "kind": "TryLoadDynamicExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/arrays:index:a6", "value": "a6",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {

View file

@ -942,10 +942,10 @@
"expression": { "expression": {
"kind": "InvokeFunctionExpression", "kind": "InvokeFunctionExpression",
"function": { "function": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/undefined:index:f", "value": "f",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1237,10 +1237,10 @@
"expression": { "expression": {
"kind": "InvokeFunctionExpression", "kind": "InvokeFunctionExpression",
"function": { "function": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/undefined:index:g", "value": "g",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {

View file

@ -1023,10 +1023,10 @@
}, },
"operator": "=", "operator": "=",
"right": { "right": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:modprop", "value": "modprop",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1256,10 +1256,10 @@
"kind": "BinaryOperatorExpression", "kind": "BinaryOperatorExpression",
"operator": "!=", "operator": "!=",
"left": { "left": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:c", "value": "c",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1389,10 +1389,10 @@
"right": { "right": {
"kind": "LoadLocationExpression", "kind": "LoadLocationExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:c", "value": "c",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1568,10 +1568,10 @@
"tok": "f" "tok": "f"
}, },
"value": { "value": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:modprop", "value": "modprop",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1664,10 +1664,10 @@
"value": { "value": {
"kind": "LoadLocationExpression", "kind": "LoadLocationExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:c", "value": "c",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1770,10 +1770,10 @@
"property": { "property": {
"kind": "InvokeFunctionExpression", "kind": "InvokeFunctionExpression",
"function": { "function": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:j", "value": "j",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1965,10 +1965,10 @@
"right": { "right": {
"kind": "LoadLocationExpression", "kind": "LoadLocationExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:c", "value": "c",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2065,10 +2065,10 @@
"left": { "left": {
"kind": "LoadLocationExpression", "kind": "LoadLocationExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/props:index:c", "value": "c",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {

View file

@ -1164,10 +1164,10 @@
"function": { "function": {
"kind": "LoadLocationExpression", "kind": "LoadLocationExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:b", "value": "b",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1262,10 +1262,10 @@
"kind": "BinaryOperatorExpression", "kind": "BinaryOperatorExpression",
"operator": "!=", "operator": "!=",
"left": { "left": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:bgx", "value": "bgx",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1363,10 +1363,10 @@
} }
}, },
"right": { "right": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:bgx", "value": "bgx",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1581,10 +1581,10 @@
"function": { "function": {
"kind": "LoadLocationExpression", "kind": "LoadLocationExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:c", "value": "c",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1679,10 +1679,10 @@
"kind": "BinaryOperatorExpression", "kind": "BinaryOperatorExpression",
"operator": "!=", "operator": "!=",
"left": { "left": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:cgx", "value": "cgx",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1780,10 +1780,10 @@
} }
}, },
"right": { "right": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:cgx", "value": "cgx",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -1910,10 +1910,10 @@
"function": { "function": {
"kind": "LoadLocationExpression", "kind": "LoadLocationExpression",
"object": { "object": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:c", "value": "c",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2008,10 +2008,10 @@
"kind": "BinaryOperatorExpression", "kind": "BinaryOperatorExpression",
"operator": "!=", "operator": "!=",
"left": { "left": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:cgy", "value": "cgy",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {
@ -2109,10 +2109,10 @@
} }
}, },
"right": { "right": {
"kind": "LoadLocationExpression", "kind": "TryLoadDynamicExpression",
"name": { "name": {
"kind": "Token", "kind": "StringLiteral",
"tok": "basic/super:index:cgy", "value": "cgy",
"loc": { "loc": {
"file": "index.ts", "file": "index.ts",
"start": { "start": {

View file

@ -2,5 +2,6 @@ name: serverless
description: Basic example of a serverless AWS application. description: Basic example of a serverless AWS application.
dependencies: dependencies:
lumi: "*" lumi: "*"
lumijs: "*"
aws: "*" aws: "*"

View file

@ -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 let hello = "Hello, world!"
// by runtime code, we'll declare variables that should be available on the global scope of the lambda to keep let lambda = new aws.serverless.Function(
// TypeScript type checking happy. "mylambda",
let console: any [aws.iam.AWSLambdaFullAccess],
(event, context, callback) => {
function createLambda() { console.log(hello);
// TODO[pulumi/lumi#175] Currently, we can only capture local variables, not module scope variables, console.log("Music table hash key is: " + music.hashKey);
// so we keep this inside a helper function. console.log("Invoked function: " + context.invokedFunctionArn);
let hello = "Hello, world!" callback(null, "Succeeed with " + context.getRemainingTimeInMillis() + "ms remaining.");
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 api = new aws.serverless.API("frontend") let api = new aws.serverless.API("frontend")
api.route("GET", "/bambam", lambda) api.route("GET", "/bambam", lambda)

View file

@ -9,6 +9,7 @@
"typescript": "^2.1.4" "typescript": "^2.1.4"
}, },
"peerDependencies": { "peerDependencies": {
"@lumi/lumi": "*",
"@lumi/aws": "*" "@lumi/aws": "*"
} }
} }

View file

@ -13,11 +13,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable: ordered-imports */ import * as slack from "@slack/client";
import {builders, providers} from "./cicd"; import {builders, providers} from "./cicd";
import * as github from "./github"; import * as github from "./github";
import * as slack from "@slack/client";
// On pushes or PR merges, // On pushes or PR merges,
// - In master, build and deploy the bits to production. // - In master, build and deploy the bits to production.

View file

@ -78,7 +78,7 @@ function createPathSpec(lambdaARN: string): SwaggerOperation {
} }
function createSourceARN(region: string, account: string, apiid: string, functionName: string): string { 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. // API is a higher level abstraction for working with AWS APIGateway reources.
@ -117,9 +117,8 @@ export class API {
default: default:
throw new Error("Method not supported: " + method); throw new Error("Method not supported: " + method);
} }
<<<<<<< HEAD
let apiName = ""; let apiName = "";
if(this.api.apiName !== undefined) { if (this.api.apiName !== undefined) {
apiName = this.api.apiName; apiName = this.api.apiName;
} }
let invokePermission = new Permission(this.apiName + "_invoke_" + sha1hash(method + path), { 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"), 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
=======
// 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. // to constructing this apigateway lambda invocation uri.
// this.swaggerSpec.paths[path][swaggerMethod] = createPathSpec(lambda.lambda.arn); // this.swaggerSpec.paths[path][swaggerMethod] = createPathSpec(lambda.lambda.arn);
this.swaggerSpec.paths[path][swaggerMethod] = createPathSpec( this.swaggerSpec.paths[path][swaggerMethod] = createPathSpec(

View file

@ -13,12 +13,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable: ordered-imports align*/
import { AssetArchive, String } from "@lumi/lumi/asset"; 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 { Function as LambdaFunction } from "../lambda/function";
import { ARN } from "../types"; import { ARN } from "../types";
import { Role } from "../iam/role";
// Context is the shape of the context object passed to a Function callback. // Context is the shape of the context object passed to a Function callback.
export interface Context { export interface Context {
@ -56,7 +55,7 @@ export class Function {
public role: Role; public role: Role;
constructor(name: string, policies: ARN[], 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) { if (name === undefined) {
throw new Error("Missing required resource name"); throw new Error("Missing required resource name");

View file

@ -13,12 +13,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable:no-empty */
// Asset represents a blob of text or data that is managed as a first class entity. // Asset represents a blob of text or data that is managed as a first class entity.
export abstract class Asset { export abstract class Asset {
constructor() {
}
} }
// Blob is a kind of asset produced from an in-memory blob represented as a byte array. // Blob is a kind of asset produced from an in-memory blob represented as a byte array.

View file

@ -12,10 +12,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable:no-empty*/
// Resource represents a class whose CRUD operations are implemented by a provider plugin. // Resource represents a class whose CRUD operations are implemented by a provider plugin.
export abstract class Resource { export abstract class Resource {
constructor() {
}
} }

View file

@ -1,3 +1,5 @@
name: lumijs name: lumijs
description: The LumiJS runtime library. description: The LumiJS runtime library.
dependencies:
lumi: "*"

25
lib/lumijs/lib/console.ts Normal file
View 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();

View file

@ -17,4 +17,5 @@
export * from "./errors"; export * from "./errors";
export * from "./types"; export * from "./types";
export * from "./console";

View file

@ -13,12 +13,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable: variable-name */
// The available cloud providers. // The available cloud providers.
export const AWS = "aws"; // Amazon Web Services. export const aws = "aws"; // Amazon Web Services.
export const GCP = "gcp"; // Google Cloud Platform. export const gcp = "gcp"; // Google Cloud Platform.
export const Azure = "azure"; // Microsoft Azure. export const azure = "azure"; // Microsoft Azure.
export const VMWare = "vmware"; // VMWare vSphere, etc. export const vmware = "vmware"; // VMWare vSphere, etc.

View file

@ -13,12 +13,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable:ordered-imports */
export * from "./arch"; export * from "./arch";
import * as clouds from "./clouds"; import * as clouds from "./clouds";
import * as schedulers from "./schedulers";
import * as runtimes from "./runtimes"; import * as runtimes from "./runtimes";
import * as schedulers from "./schedulers";
export {clouds, schedulers, runtimes}; export {clouds, schedulers, runtimes};

View file

@ -13,15 +13,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable:variable-name */
// The available language runtimes. // The available language runtimes.
export const nodejs = "nodejs";
export const NodeJS = "nodejs"; export const python = "python";
export const Python = "python";
export let ext: {[lang: string]: string} = { export let ext: {[lang: string]: string} = {
NodeJS: ".js", nodejs: ".js",
Python: ".py", python: ".py",
}; };

View file

@ -13,14 +13,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* tslint:disable:variable-name */
// The available container scheduler/runtimes. // The available container scheduler/runtimes.
export const swarm = "swarm"; // Docker Swarm.
export const Swarm = "swarm"; // Docker Swarm. export const kubernetes = "kubernetes"; // Kubernetes.
export const Kubernetes = "kubernetes"; // Kubernetes. export const mesos = "mesos"; // Apache Mesos.
export const Mesos = "mesos"; // Apache Mesos. export const ecs = "ecs"; // Amazon Elastic Container Service (only valid for AWS clouds).
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 GKE = "gke"; // Google Container Engine (only valid for GCP clouds). export const acs = "acs"; // Microsoft Azure Container Service (only valid for Azure).
export const ACS = "acs"; // Microsoft Azure Container Service (only valid for Azure).

View file

@ -13,14 +13,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 aws from "@lumi/aws";
import * as kubefission from "@lumi/kubefission"; import * as kubefission from "@lumi/kubefission";
import {asset} from "@lumi/lumi"; 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. // 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, // 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. // initCloudResources sets up the right resources for the given cloud and scheduler target.
private initCloudResources(): any { private initCloudResources(): any {
let target: arch.Arch = config.requireArch(); let target: arch.Arch = config.requireArch();
if (target.scheduler === arch.schedulers.Kubernetes) { if (target.scheduler === arch.schedulers.kubernetes) {
return this.initKubernetesResources(); return this.initKubernetesResources();
} }
else { else {
switch (target.cloud) { switch (target.cloud) {
case arch.clouds.AWS: case arch.clouds.aws:
return this.initAWSResources(); return this.initAWSResources();
case arch.clouds.GCP: case arch.clouds.gcp:
return this.initGCPResources(); return this.initGCPResources();
case arch.clouds.Azure: case arch.clouds.azure:
return this.initAzureResources(); return this.initAzureResources();
default: default:
throw new Error("Unsupported target cloud: " + target.cloud); throw new Error("Unsupported target cloud: " + target.cloud);

View 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))
}

View 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")
}

View file

@ -1730,22 +1730,23 @@ func (e *evaluator) evalLoadDynamicCore(node ast.Node, objexpr *ast.Expression,
}, nil }, nil
} }
func (e *evaluator) getDynamicNameAddr(key tokens.Name, lval bool) *rt.Pointer { func getDynamicNameAddrCore(locals rt.Environment, globals *rt.Object, key tokens.Name) *rt.Pointer {
var pv *rt.Pointer if loc := locals.Lookup(key); loc != nil {
return locals.GetValueAddr(loc, true) // create a slot, we know the declaration exists.
// 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.
} }
// 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 pv == nil && lval {
if e.fnc != nil && e.fnc.SpecialModInit() && e.locals.Activation() { if e.fnc != nil && e.fnc.SpecialModInit() && e.locals.Activation() {
pkey := rt.PropertyKey(key)
pv = globals.Properties().GetInitAddr(pkey) pv = globals.Properties().GetInitAddr(pkey)
} else { } else {
loc := symbols.NewSpecialVariableSym(key, types.Dynamic) 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 // 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. // capture the current environment, including the this variable.
sig := e.ctx.RequireType(node).(*symbols.FunctionType) 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 return obj, nil
} }

View file

@ -19,14 +19,15 @@ import (
"crypto/sha1" "crypto/sha1"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"sort"
"strconv" "strconv"
"strings" "strings"
"github.com/pulumi/lumi/pkg/compiler/ast" "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/symbols"
"github.com/pulumi/lumi/pkg/compiler/types" "github.com/pulumi/lumi/pkg/compiler/types"
"github.com/pulumi/lumi/pkg/eval/rt" "github.com/pulumi/lumi/pkg/eval/rt"
"github.com/pulumi/lumi/pkg/tokens"
"github.com/pulumi/lumi/pkg/util/contract" "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.") 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 // Insert environment variables into a PropertyMap with stable ordering
envPropMap := rt.NewPropertyMap() envPropMap := rt.NewPropertyMap()
slots := stub.Env.Slots() for _, tok := range binder.FreeVars(stub.Func) {
var keys []*symbols.LocalVariable var name tokens.Name
for key := range slots { contract.Assertf(tok.Simple() || (tok.HasModule() && tok.HasModuleMember() && !tok.HasClassMember()),
keys = append(keys, key) "Expected free variable to be simple name or reference to top-level module name")
} if tok.Simple() {
sort.SliceStable(keys, func(i, j int) bool { name = tok.Name()
return keys[i].Name() < keys[j].Name() } else {
}) name = tokens.Name(tok.ModuleMember().Name())
for _, key := range keys { }
envPropMap.Set(rt.PropertyKey(key.Name()), slots[key].Obj()) 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) envObj := e.alloc.New(intrin.Tree(), types.Dynamic, envPropMap, nil)

View file

@ -452,21 +452,23 @@ func NewFunctionObjectFromSymbol(fnc symbols.Function, this *Object) *Object {
} }
// NewFunctionObjectFromLambda creates a new function object with very specific underlying parts. // 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{ return NewFunctionObject(FuncStub{
Func: fnc, Func: fnc,
Sig: sig, Sig: sig,
Env: env, Env: env,
Module: module,
}) })
} }
// FuncStub is a stub that captures a symbol plus an optional instance 'this' object. // FuncStub is a stub that captures a symbol plus an optional instance 'this' object.
type FuncStub struct { type FuncStub struct {
Func ast.Function // the function whose body AST to evaluate. Func ast.Function // the function whose body AST to evaluate.
Sym symbols.Function // an optional function symbol that this AST belongs to. Sym symbols.Function // an optional function symbol that this AST belongs to.
Sig *symbols.FunctionType // the function type representing this function's signature. Sig *symbols.FunctionType // the function type representing this function's signature.
This *Object // an optional "this" pointer to bind when invoking this function. This *Object // an optional "this" pointer to bind when invoking this function.
Env Environment // an optional environment to evaluate this function inside. 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. // 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() stub := value.FunctionValue()
contract.Assert(stub.This == parent) contract.Assert(stub.This == parent)
value = NewFunctionObject(FuncStub{ value = NewFunctionObject(FuncStub{
Func: stub.Func, Func: stub.Func,
Sym: stub.Sym, Sym: stub.Sym,
Sig: stub.Sig, Sig: stub.Sig,
This: this, This: this,
Env: stub.Env, Env: stub.Env,
Module: stub.Module,
}) })
prop = NewPointer(value, prop.Readonly(), prop.Getter(), prop.Setter()) prop = NewPointer(value, prop.Readonly(), prop.Getter(), prop.Setter())
case *symbols.ComputedType: 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) Tree() diag.Diagable { return intrin.node }
func (intrin *Intrinsic) Function() ast.Function { return intrin.node } func (intrin *Intrinsic) Function() ast.Function { return intrin.node }
func (intrin *Intrinsic) Signature() *symbols.FunctionType { return intrin.sig } 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 } func (intrin *Intrinsic) UnderlyingSymbol() symbols.Function { return intrin.fnc }

View file

@ -28,8 +28,8 @@ import (
"github.com/pulumi/lumi/pkg/util/contract" "github.com/pulumi/lumi/pkg/util/contract"
) )
// Print prints a LumiGL graph.
func Print(g graph.Graph, w io.Writer) error { func Print(g graph.Graph, w io.Writer) error {
var err error var err error
// Allocate a new writer. In general, we will ignore write errors throughout this function, for simplicity, opting // 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. // instead to return the result of flushing the buffer at the end, which is generally latching.

View file

@ -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 // 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 // the underlying streaming capabilities offered by assets and archives, but can be used in a pinch to interact with
// APIs that demand []bytes. // APIs that demand []bytes.
func (a Archive) Bytes(format ArchiveFormat) []byte { func (a Archive) Bytes(format ArchiveFormat) ([]byte, error) {
var data bytes.Buffer var data bytes.Buffer
err := a.Archive(format, &data) var err error
contract.Assert(err == nil) err = a.Archive(format, &data)
return data.Bytes(), err
return data.Bytes()
} }
// Archive produces a single archive stream in the desired format. It prefers to return the archive with as little // Archive produces a single archive stream in the desired format. It prefers to return the archive with as little

View file

@ -95,13 +95,13 @@ func newPlugin(ctx *Context, bins []string, prefix string) (*plugin, error) {
var port string var port string
b := make([]byte, 1) b := make([]byte, 1)
for { for {
n, stderr := plug.Stdout.Read(b) n, readerr := plug.Stdout.Read(b)
if stderr != nil { if readerr != nil {
plug.Proc.Kill() plug.Proc.Kill()
if port == "" { 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' { if n > 0 && b[0] == '\n' {
break break

View file

@ -37,7 +37,6 @@ func writefmtln(w *bufio.Writer, msg string, args ...interface{}) {
func emitHeaderWarning(w *bufio.Writer) { func emitHeaderWarning(w *bufio.Writer) {
writefmtln(w, "// *** WARNING: this file was generated by the Lumi IDL Compiler (LUMIDL). ***") 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, "// *** 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, "") writefmtln(w, "")
} }

View file

@ -126,6 +126,7 @@ func (g *PackGenerator) emitFileContents(file string, body string) error {
// Emit a header into the file. // Emit a header into the file.
emitHeaderWarning(w) emitHeaderWarning(w)
writefmtln(w, "/* tslint:disable:ordered-imports variable-name */")
// If there are any resources, import the Lumi package. // If there are any resources, import the Lumi package.
if g.FileHadRes { if g.FileHadRes {

View file

@ -38,15 +38,10 @@ func InitLogging(logToStderr bool, verbose int, logFlow bool) {
flag.Parse() flag.Parse()
if logToStderr { if logToStderr {
err := flag.Lookup("logtostderr").Value.Set("true") err := flag.Lookup("logtostderr").Value.Set("true")
if err != nil { contract.Assert(err != nil)
contract.Assert(err != nil)
}
} }
if verbose > 0 { if verbose > 0 {
err := flag.Lookup("v").Value.Set(strconv.Itoa(verbose)) err := flag.Lookup("v").Value.Set(strconv.Itoa(verbose))
if err != nil { contract.Assert(err != nil)
contract.Assert(err != nil)
}
} }
} }

View file

@ -178,11 +178,6 @@ func (w *workspace) DepCandidates(dep pack.PackageURL) []string {
return cands 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. // qnamePath just cleans a name and makes sure it's appropriate to use as a path.
func qnamePath(nm tokens.QName) string { func qnamePath(nm tokens.QName) string {
return stringNamePath(string(nm)) return stringNamePath(string(nm))

View file

@ -120,5 +120,6 @@
"check-separator", "check-separator",
"check-type" "check-type"
] ]
} }
} }