| Index: lib/call.ts
|
| diff --git a/lib/call.ts b/lib/call.ts
|
| deleted file mode 100644
|
| index 86aa01b4b027794b460b56e85b8ed9fb755abc79..0000000000000000000000000000000000000000
|
| --- a/lib/call.ts
|
| +++ /dev/null
|
| @@ -1,212 +0,0 @@
|
| -import ts = require('typescript');
|
| -import base = require('./base');
|
| -import ts2dart = require('./main');
|
| -import {FacadeConverter} from './facade_converter';
|
| -
|
| -export default class CallTranspiler extends base.TranspilerBase {
|
| - constructor(tr: ts2dart.Transpiler, private fc: FacadeConverter) { super(tr); }
|
| -
|
| - visitNode(node: ts.Node): boolean {
|
| - switch (node.kind) {
|
| - case ts.SyntaxKind.Block:
|
| - // This is a bit ugly: to separate Declarations from Calls, this code has to special case
|
| - // blocks that are actually constructor bodies.
|
| - if (node.parent && node.parent.kind === ts.SyntaxKind.Constructor) {
|
| - return this.visitConstructorBody(<ts.ConstructorDeclaration>node.parent);
|
| - }
|
| - return false;
|
| - case ts.SyntaxKind.NewExpression:
|
| - let newExpr = <ts.NewExpression>node;
|
| - if (this.hasAncestor(node, ts.SyntaxKind.Decorator)) {
|
| - // Constructor calls in annotations must be const constructor calls.
|
| - this.emit('const');
|
| - } else if (this.fc.isInsideConstExpr(node)) {
|
| - this.emit('const');
|
| - } else {
|
| - // Some implementations can replace the `new` keyword.
|
| - if (this.fc.shouldEmitNew(newExpr)) {
|
| - this.emit('new');
|
| - }
|
| - }
|
| - if (this.fc.maybeHandleCall(newExpr)) break;
|
| - this.visitCall(newExpr);
|
| - break;
|
| - case ts.SyntaxKind.CallExpression:
|
| - let callExpr = <ts.CallExpression>node;
|
| - if (this.fc.maybeHandleCall(callExpr)) break;
|
| - if (this.maybeHandleSuperCall(callExpr)) break;
|
| - this.visitCall(callExpr);
|
| - break;
|
| - case ts.SyntaxKind.SuperKeyword:
|
| - this.emit('super');
|
| - break;
|
| - default:
|
| - return false;
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - private visitCall(c: ts.CallExpression) {
|
| - if (c.expression.kind === ts.SyntaxKind.Identifier) {
|
| - this.fc.visitTypeName(<ts.Identifier>c.expression);
|
| - } else {
|
| - this.visit(c.expression);
|
| - }
|
| - if (c.typeArguments) {
|
| - // For DDC, emit generic method arguments in /* block comments */
|
| - // NB: Surprisingly, whitespace within the comment is significant here :-(
|
| - // TODO(martinprobst): Remove once Dart natively supports generic methods.
|
| - if (c.kind !== ts.SyntaxKind.NewExpression) this.emit('/*');
|
| - this.maybeVisitTypeArguments(c);
|
| - if (c.kind !== ts.SyntaxKind.NewExpression) this.emitNoSpace('*/');
|
| - }
|
| - this.emit('(');
|
| - if (c.arguments && !this.handleNamedParamsCall(c)) {
|
| - this.visitList(c.arguments);
|
| - }
|
| - this.emit(')');
|
| - }
|
| -
|
| - private handleNamedParamsCall(c: ts.CallExpression): boolean {
|
| - // Preamble: This is all committed in the name of backwards compat with the traceur transpiler.
|
| -
|
| - // Terrible hack: transform foo(a, b, {c: d}) into foo(a, b, c: d), which is Dart's calling
|
| - // syntax for named/optional parameters. An alternative would be to transform the method
|
| - // declaration to take a plain object literal and destructure in the method, but then client
|
| - // code written against Dart wouldn't get nice named parameters.
|
| - if (c.arguments.length === 0) return false;
|
| - let last = c.arguments[c.arguments.length - 1];
|
| - if (last.kind !== ts.SyntaxKind.ObjectLiteralExpression) return false;
|
| - let objLit = <ts.ObjectLiteralExpression>last;
|
| - if (objLit.properties.length === 0) return false;
|
| - // Even worse: foo(a, b, {'c': d}) is considered to *not* be a named parameters call.
|
| - let hasNonPropAssignments = objLit.properties.some(
|
| - (p) =>
|
| - (p.kind !== ts.SyntaxKind.PropertyAssignment ||
|
| - (<ts.PropertyAssignment>p).name.kind !== ts.SyntaxKind.Identifier));
|
| - if (hasNonPropAssignments) return false;
|
| -
|
| - let len = c.arguments.length - 1;
|
| - this.visitList(c.arguments.slice(0, len));
|
| - if (len) this.emit(',');
|
| - let props = objLit.properties;
|
| - for (let i = 0; i < props.length; i++) {
|
| - let prop = <ts.PropertyAssignment>props[i];
|
| - this.emit(base.ident(prop.name));
|
| - this.emit(':');
|
| - this.visit(prop.initializer);
|
| - if (i < objLit.properties.length - 1) this.emit(',');
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - /**
|
| - * Handles constructor initializer lists and bodies.
|
| - *
|
| - * <p>Dart's super() ctor calls have to be moved to the constructors initializer list, and `const`
|
| - * constructors must be completely empty, only assigning into fields through the initializer list.
|
| - * The code below finds super() calls and handles const constructors, marked with the special
|
| - * `@CONST` annotation on the class.
|
| - *
|
| - * <p>Not emitting super() calls when traversing the ctor body is handled by maybeHandleSuperCall
|
| - * below.
|
| - */
|
| - private visitConstructorBody(ctor: ts.ConstructorDeclaration): boolean {
|
| - let body = ctor.body;
|
| - if (!body) return false;
|
| -
|
| - let errorAssignmentsSuper = 'const constructors can only contain assignments and super calls';
|
| - let errorThisAssignment = 'assignments in const constructors must assign into this.';
|
| -
|
| - let parent = <base.ClassLike>ctor.parent;
|
| - let parentIsConst = this.isConst(parent);
|
| - let superCall: ts.CallExpression;
|
| - let expressions: ts.Expression[] = [];
|
| - // Find super() calls and (if in a const ctor) collect assignment expressions (not statements!)
|
| - body.statements.forEach((stmt) => {
|
| - if (stmt.kind !== ts.SyntaxKind.ExpressionStatement) {
|
| - if (parentIsConst) this.reportError(stmt, errorAssignmentsSuper);
|
| - return;
|
| - }
|
| - let nestedExpr = (<ts.ExpressionStatement>stmt).expression;
|
| -
|
| - // super() call?
|
| - if (nestedExpr.kind === ts.SyntaxKind.CallExpression) {
|
| - let callExpr = <ts.CallExpression>nestedExpr;
|
| - if (callExpr.expression.kind !== ts.SyntaxKind.SuperKeyword) {
|
| - if (parentIsConst) this.reportError(stmt, errorAssignmentsSuper);
|
| - return;
|
| - }
|
| - superCall = callExpr;
|
| - return;
|
| - }
|
| -
|
| - // this.x assignment?
|
| - if (parentIsConst) {
|
| - // Check for assignment.
|
| - if (nestedExpr.kind !== ts.SyntaxKind.BinaryExpression) {
|
| - this.reportError(nestedExpr, errorAssignmentsSuper);
|
| - return;
|
| - }
|
| - let binExpr = <ts.BinaryExpression>nestedExpr;
|
| - if (binExpr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) {
|
| - this.reportError(binExpr, errorAssignmentsSuper);
|
| - return;
|
| - }
|
| - // Check for 'this.'
|
| - if (binExpr.left.kind !== ts.SyntaxKind.PropertyAccessExpression) {
|
| - this.reportError(binExpr, errorThisAssignment);
|
| - return;
|
| - }
|
| - let lhs = <ts.PropertyAccessExpression>binExpr.left;
|
| - if (lhs.expression.kind !== ts.SyntaxKind.ThisKeyword) {
|
| - this.reportError(binExpr, errorThisAssignment);
|
| - return;
|
| - }
|
| - let ident = lhs.name;
|
| - binExpr.left = ident;
|
| - expressions.push(nestedExpr);
|
| - }
|
| - });
|
| -
|
| - let hasInitializerExpr = expressions.length > 0;
|
| - if (hasInitializerExpr) {
|
| - // Write out the assignments.
|
| - this.emit(':');
|
| - this.visitList(expressions);
|
| - }
|
| - if (superCall) {
|
| - this.emit(hasInitializerExpr ? ',' : ':');
|
| - this.emit('super (');
|
| - if (!this.handleNamedParamsCall(superCall)) {
|
| - this.visitList(superCall.arguments);
|
| - }
|
| - this.emit(')');
|
| - }
|
| - if (parentIsConst) {
|
| - // Const ctors don't have bodies.
|
| - this.emit(';');
|
| - return true; // completely handled.
|
| - } else {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Checks whether `callExpr` is a super() call that should be ignored because it was already
|
| - * handled by `maybeEmitSuperInitializer` above.
|
| - */
|
| - private maybeHandleSuperCall(callExpr: ts.CallExpression): boolean {
|
| - if (callExpr.expression.kind !== ts.SyntaxKind.SuperKeyword) return false;
|
| - // Sanity check that there was indeed a ctor directly above this call.
|
| - let exprStmt = callExpr.parent;
|
| - let ctorBody = exprStmt.parent;
|
| - let ctor = ctorBody.parent;
|
| - if (ctor.kind !== ts.SyntaxKind.Constructor) {
|
| - this.reportError(callExpr, 'super calls must be immediate children of their constructors');
|
| - return false;
|
| - }
|
| - this.emit('/* super call moved to initializer */');
|
| - return true;
|
| - }
|
| -}
|
|
|