From 908522aa0fb42d80fb4ab102b2760141a18d9df8 Mon Sep 17 00:00:00 2001 From: joeduffy Date: Mon, 16 Jan 2017 10:01:11 -0800 Subject: [PATCH] Fix a problem with identifiers as expressions MuIL doesn't support identifiers as expressions; instead, an explicit LoadLocationExpression is required. There was a problem in the current MuJS translation process -- masked by TypeScript silently duck typing from Identifier to Expression -- but our Mu decoding library discovered it. This fixes the problem by wrapping Identifiers used in Expression positions in a proper LoadLocationExpression node. --- tools/mujs/lib/compiler/transform.ts | 13 ++-- .../tests/output/scenarios/point/Mu.out.json | 72 ++++++++++++++++--- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/tools/mujs/lib/compiler/transform.ts b/tools/mujs/lib/compiler/transform.ts index c80dc2199..ccaada8bd 100644 --- a/tools/mujs/lib/compiler/transform.ts +++ b/tools/mujs/lib/compiler/transform.ts @@ -379,7 +379,7 @@ export class Transformer { return symbols.anyType; } - + // transformIdentifier takes a TypeScript identifier node and yields a true MuIL identifier. private transformIdentifier(node: ts.Identifier): ast.Identifier { return this.withLocation(node, ident(node.text)); } @@ -872,7 +872,7 @@ export class Transformer { private transformDeclarationIdentifier(node: ts.DeclarationName): ast.Identifier { switch (node.kind) { case ts.SyntaxKind.Identifier: - return this.transformIdentifierExpression(node); + return this.transformIdentifier(node); default: return contract.fail(`Unrecognized declaration identifier: ${ts.SyntaxKind[node.kind]}`); } @@ -1866,8 +1866,13 @@ export class Transformer { return notYetImplemented(node); } - private transformIdentifierExpression(node: ts.Identifier): ast.Identifier { - return this.withLocation(node, ident(node.text)); + // transformIdentifierExpression takes a TypeScript identifier node and yields a MuIL expression. This expression, + // when evaluated, will load the value of the target identifier, so that it's suitable as an expression node. + private transformIdentifierExpression(node: ts.Identifier): ast.Expression { + return this.withLocation(node, { + kind: ast.loadLocationExpressionKind, + name: this.transformIdentifier(node), + }); } private transformObjectBindingPattern(node: ts.ObjectBindingPattern): ast.Expression { diff --git a/tools/mujs/tests/output/scenarios/point/Mu.out.json b/tools/mujs/tests/output/scenarios/point/Mu.out.json index 9ebcdff52..5f1de53b1 100644 --- a/tools/mujs/tests/output/scenarios/point/Mu.out.json +++ b/tools/mujs/tests/output/scenarios/point/Mu.out.json @@ -130,8 +130,22 @@ } }, "right": { - "kind": "Identifier", - "ident": "x", + "kind": "LoadLocationExpression", + "name": { + "kind": "Identifier", + "ident": "x", + "loc": { + "file": "index.ts", + "start": { + "line": 9, + "column": 17 + }, + "end": { + "line": 9, + "column": 18 + } + } + }, "loc": { "file": "index.ts", "start": { @@ -221,8 +235,22 @@ } }, "right": { - "kind": "Identifier", - "ident": "y", + "kind": "LoadLocationExpression", + "name": { + "kind": "Identifier", + "ident": "y", + "loc": { + "file": "index.ts", + "start": { + "line": 10, + "column": 17 + }, + "end": { + "line": 10, + "column": 18 + } + } + }, "loc": { "file": "index.ts", "start": { @@ -402,8 +430,22 @@ "right": { "kind": "LoadLocationExpression", "object": { - "kind": "Identifier", - "ident": "other", + "kind": "LoadLocationExpression", + "name": { + "kind": "Identifier", + "ident": "other", + "loc": { + "file": "index.ts", + "start": { + "line": 14, + "column": 34 + }, + "end": { + "line": 14, + "column": 39 + } + } + }, "loc": { "file": "index.ts", "start": { @@ -508,8 +550,22 @@ "right": { "kind": "LoadLocationExpression", "object": { - "kind": "Identifier", - "ident": "other", + "kind": "LoadLocationExpression", + "name": { + "kind": "Identifier", + "ident": "other", + "loc": { + "file": "index.ts", + "start": { + "line": 14, + "column": 52 + }, + "end": { + "line": 14, + "column": 57 + } + } + }, "loc": { "file": "index.ts", "start": {