Transform object literal expressions

This commit is contained in:
joeduffy 2017-01-12 13:38:54 -08:00
parent 1572816861
commit 24c4f48b81
3 changed files with 64 additions and 23 deletions

View file

@ -44,7 +44,7 @@ export interface StringLiteral extends Literal {
export const stringLiteralKind = "StringLiteral";
export type StringLiteralKind = "StringLiteral";
// A array literal (`new` and/or initialization).
// A array literal plus optional initialization.
export interface ArrayLiteral extends Literal {
kind: ArrayLiteralKind;
type: symbols.TypeToken; // the type of array to produce.
@ -54,24 +54,23 @@ export interface ArrayLiteral extends Literal {
export const arrayLiteralKind = "ArrayLiteral";
export type ArrayLiteralKind = "ArrayLiteral";
// An object literal (`new` and/or initialization).
// An object literal plus optional initialization.
export interface ObjectLiteral extends Literal {
kind: ObjectLiteralKind;
type: symbols.TypeToken; // the type of object to produce.
initializers?: ObjectLiteralInitializer[]; // an optional array of property initializers.
arguments?: Expression[]; // an optional set of arguments for the constructor.
kind: ObjectLiteralKind;
type: symbols.TypeToken; // the type of object to produce.
properties?: ObjectLiteralProperty[]; // an optional array of property initializers.
}
export const objectLiteralKind = "ObjectLiteral";
export type ObjectLiteralKind = "ObjectLiteral";
// An object literal property initializer.
export interface ObjectLiteralInitializer extends Node {
kind: ObjectLiteralInitializerKind;
property: symbols.VariableToken; // the property being initialized.
value: Expression; // the expression value to store into the property.
export interface ObjectLiteralProperty extends Node {
kind: ObjectLiteralPropertyKind;
name: Identifier; // the property being initialized.
value: Expression; // the expression value to store into the property.
}
export const objectLiteralInitializerKind = "ObjectLiteralInitializer";
export type ObjectLiteralInitializerKind = "ObjectLiteralInitializer";
export const objectLiteralPropertyKind = "ObjectLiteralProperty";
export type ObjectLiteralPropertyKind = "ObjectLiteralProperty";
/** Loads **/

View file

@ -49,7 +49,7 @@ export type NodeKind =
expressions.StringLiteralKind |
expressions.ArrayLiteralKind |
expressions.ObjectLiteralKind |
expressions.ObjectLiteralInitializerKind |
expressions.ObjectLiteralPropertyKind |
expressions.LoadLocationExpressionKind |
expressions.LoadDynamicExpressionKind |
expressions.NewExpressionKind |

View file

@ -1178,7 +1178,7 @@ export class Transformer {
}
}
private transformArrayLiteralExpression(node: ts.ArrayLiteralExpression): ast.Expression {
private transformArrayLiteralExpression(node: ts.ArrayLiteralExpression): ast.ArrayLiteral {
return this.withLocation(node, <ast.ArrayLiteral>{
kind: ast.arrayLiteralKind,
type: this.transformTypeNode(undefined),
@ -1293,21 +1293,63 @@ export class Transformer {
return contract.fail("NYI");
}
private transformObjectLiteralExpression(node: ts.ObjectLiteralExpression): ast.Expression {
return contract.fail("NYI");
private transformObjectLiteralExpression(node: ts.ObjectLiteralExpression): ast.ObjectLiteral {
// TODO[marapongo/mu#46]: because TypeScript object literals are untyped, it's not clear what MuIL type this
// expression should produce. It's common for a TypeScript literal to be enclosed in a cast, for example,
// `<SomeType>{ literal }`, in which case, perhaps we could detect `<SomeType>`. Alternatively, MuIL could
// just automatically dynamically coerce `any` to the target type, similar to TypeScript, when necessary.
// I had envisioned requiring explicit dynamic casts for this, in which case, perhaps this expression should
// always be encased in something that prepares it for dynamic cast in the consuming expression.
return this.withLocation(node, <ast.ObjectLiteral>{
kind: ast.objectLiteralKind,
type: this.transformTypeNode(undefined),
properties: node.properties.map(
(prop: ts.ObjectLiteralElement) => this.transformObjectLiteralElement(prop)),
});
}
private transformObjectLiteralElement(node: ts.ObjectLiteralElement): ast.Expression {
return contract.fail("NYI");
private transformObjectLiteralElement(node: ts.ObjectLiteralElement): ast.ObjectLiteralProperty {
switch (node.kind) {
case ts.SyntaxKind.PropertyAssignment:
return this.transformObjectLiteralPropertyAssignment(<ts.PropertyAssignment>node);
case ts.SyntaxKind.ShorthandPropertyAssignment:
return this.transformObjectLiteralShorthandPropertyAssignment(<ts.ShorthandPropertyAssignment>node);
case ts.SyntaxKind.GetAccessor:
return this.transformObjectLiteralFunctionLikeElement(<ts.GetAccessorDeclaration>node);
case ts.SyntaxKind.SetAccessor:
return this.transformObjectLiteralFunctionLikeElement(<ts.SetAccessorDeclaration>node);
case ts.SyntaxKind.MethodDeclaration:
return this.transformObjectLiteralFunctionLikeElement(<ts.MethodDeclaration>node);
default:
return contract.fail(`Unrecognized object literal element kind ${ts.SyntaxKind[node.kind]}`);
}
}
private transformObjectLiteralPropertyElement(
node: ts.PropertyAssignment | ts.ShorthandPropertyAssignment): ast.Expression {
return contract.fail("NYI");
private transformObjectLiteralPropertyAssignment(node: ts.PropertyAssignment): ast.ObjectLiteralProperty {
return this.withLocation(node, <ast.ObjectLiteralProperty>{
kind: ast.objectLiteralPropertyKind,
name: this.transformPropertyName(node.name),
value: this.transformExpression(node.initializer),
});
}
private transformObjectLiteralFunctionLikeElement(
node: ts.AccessorDeclaration | ts.MethodDeclaration): ast.Expression {
private transformObjectLiteralShorthandPropertyAssignment(
node: ts.ShorthandPropertyAssignment): ast.ObjectLiteralProperty {
let name: ast.Identifier = this.transformIdentifier(node.name);
return this.withLocation(node, <ast.ObjectLiteralProperty>{
kind: ast.objectLiteralPropertyKind,
name: name,
value: this.withLocation(node.name, <ast.LoadLocationExpression>{
kind: ast.loadLocationExpressionKind,
name: name,
}),
});
}
private transformObjectLiteralFunctionLikeElement(node: ts.FunctionLikeDeclaration): ast.ObjectLiteralProperty {
// TODO: turn these into lambdas.
return contract.fail("NYI");
}