Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: lib/call.ts

Issue 2225953002: Strip more unused features. (Closed) Base URL: git@github.com:dart-lang/js_facade_gen.git@master
Patch Set: Fix types Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/base.ts ('k') | lib/dart_libraries_for_browser_types.ts » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 import ts = require('typescript');
2 import base = require('./base');
3 import ts2dart = require('./main');
4 import {FacadeConverter} from './facade_converter';
5
6 export default class CallTranspiler extends base.TranspilerBase {
7 constructor(tr: ts2dart.Transpiler, private fc: FacadeConverter) { super(tr); }
8
9 visitNode(node: ts.Node): boolean {
10 switch (node.kind) {
11 case ts.SyntaxKind.Block:
12 // This is a bit ugly: to separate Declarations from Calls, this code ha s to special case
13 // blocks that are actually constructor bodies.
14 if (node.parent && node.parent.kind === ts.SyntaxKind.Constructor) {
15 return this.visitConstructorBody(<ts.ConstructorDeclaration>node.paren t);
16 }
17 return false;
18 case ts.SyntaxKind.NewExpression:
19 let newExpr = <ts.NewExpression>node;
20 if (this.hasAncestor(node, ts.SyntaxKind.Decorator)) {
21 // Constructor calls in annotations must be const constructor calls.
22 this.emit('const');
23 } else if (this.fc.isInsideConstExpr(node)) {
24 this.emit('const');
25 } else {
26 // Some implementations can replace the `new` keyword.
27 if (this.fc.shouldEmitNew(newExpr)) {
28 this.emit('new');
29 }
30 }
31 if (this.fc.maybeHandleCall(newExpr)) break;
32 this.visitCall(newExpr);
33 break;
34 case ts.SyntaxKind.CallExpression:
35 let callExpr = <ts.CallExpression>node;
36 if (this.fc.maybeHandleCall(callExpr)) break;
37 if (this.maybeHandleSuperCall(callExpr)) break;
38 this.visitCall(callExpr);
39 break;
40 case ts.SyntaxKind.SuperKeyword:
41 this.emit('super');
42 break;
43 default:
44 return false;
45 }
46 return true;
47 }
48
49 private visitCall(c: ts.CallExpression) {
50 if (c.expression.kind === ts.SyntaxKind.Identifier) {
51 this.fc.visitTypeName(<ts.Identifier>c.expression);
52 } else {
53 this.visit(c.expression);
54 }
55 if (c.typeArguments) {
56 // For DDC, emit generic method arguments in /* block comments */
57 // NB: Surprisingly, whitespace within the comment is significant here :-(
58 // TODO(martinprobst): Remove once Dart natively supports generic methods.
59 if (c.kind !== ts.SyntaxKind.NewExpression) this.emit('/*');
60 this.maybeVisitTypeArguments(c);
61 if (c.kind !== ts.SyntaxKind.NewExpression) this.emitNoSpace('*/');
62 }
63 this.emit('(');
64 if (c.arguments && !this.handleNamedParamsCall(c)) {
65 this.visitList(c.arguments);
66 }
67 this.emit(')');
68 }
69
70 private handleNamedParamsCall(c: ts.CallExpression): boolean {
71 // Preamble: This is all committed in the name of backwards compat with the traceur transpiler.
72
73 // Terrible hack: transform foo(a, b, {c: d}) into foo(a, b, c: d), which is Dart's calling
74 // syntax for named/optional parameters. An alternative would be to transfor m the method
75 // declaration to take a plain object literal and destructure in the method, but then client
76 // code written against Dart wouldn't get nice named parameters.
77 if (c.arguments.length === 0) return false;
78 let last = c.arguments[c.arguments.length - 1];
79 if (last.kind !== ts.SyntaxKind.ObjectLiteralExpression) return false;
80 let objLit = <ts.ObjectLiteralExpression>last;
81 if (objLit.properties.length === 0) return false;
82 // Even worse: foo(a, b, {'c': d}) is considered to *not* be a named paramet ers call.
83 let hasNonPropAssignments = objLit.properties.some(
84 (p) =>
85 (p.kind !== ts.SyntaxKind.PropertyAssignment ||
86 (<ts.PropertyAssignment>p).name.kind !== ts.SyntaxKind.Identifier)) ;
87 if (hasNonPropAssignments) return false;
88
89 let len = c.arguments.length - 1;
90 this.visitList(c.arguments.slice(0, len));
91 if (len) this.emit(',');
92 let props = objLit.properties;
93 for (let i = 0; i < props.length; i++) {
94 let prop = <ts.PropertyAssignment>props[i];
95 this.emit(base.ident(prop.name));
96 this.emit(':');
97 this.visit(prop.initializer);
98 if (i < objLit.properties.length - 1) this.emit(',');
99 }
100 return true;
101 }
102
103 /**
104 * Handles constructor initializer lists and bodies.
105 *
106 * <p>Dart's super() ctor calls have to be moved to the constructors initializ er list, and `const`
107 * constructors must be completely empty, only assigning into fields through t he initializer list.
108 * The code below finds super() calls and handles const constructors, marked w ith the special
109 * `@CONST` annotation on the class.
110 *
111 * <p>Not emitting super() calls when traversing the ctor body is handled by m aybeHandleSuperCall
112 * below.
113 */
114 private visitConstructorBody(ctor: ts.ConstructorDeclaration): boolean {
115 let body = ctor.body;
116 if (!body) return false;
117
118 let errorAssignmentsSuper = 'const constructors can only contain assignments and super calls';
119 let errorThisAssignment = 'assignments in const constructors must assign int o this.';
120
121 let parent = <base.ClassLike>ctor.parent;
122 let parentIsConst = this.isConst(parent);
123 let superCall: ts.CallExpression;
124 let expressions: ts.Expression[] = [];
125 // Find super() calls and (if in a const ctor) collect assignment expression s (not statements!)
126 body.statements.forEach((stmt) => {
127 if (stmt.kind !== ts.SyntaxKind.ExpressionStatement) {
128 if (parentIsConst) this.reportError(stmt, errorAssignmentsSuper);
129 return;
130 }
131 let nestedExpr = (<ts.ExpressionStatement>stmt).expression;
132
133 // super() call?
134 if (nestedExpr.kind === ts.SyntaxKind.CallExpression) {
135 let callExpr = <ts.CallExpression>nestedExpr;
136 if (callExpr.expression.kind !== ts.SyntaxKind.SuperKeyword) {
137 if (parentIsConst) this.reportError(stmt, errorAssignmentsSuper);
138 return;
139 }
140 superCall = callExpr;
141 return;
142 }
143
144 // this.x assignment?
145 if (parentIsConst) {
146 // Check for assignment.
147 if (nestedExpr.kind !== ts.SyntaxKind.BinaryExpression) {
148 this.reportError(nestedExpr, errorAssignmentsSuper);
149 return;
150 }
151 let binExpr = <ts.BinaryExpression>nestedExpr;
152 if (binExpr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) {
153 this.reportError(binExpr, errorAssignmentsSuper);
154 return;
155 }
156 // Check for 'this.'
157 if (binExpr.left.kind !== ts.SyntaxKind.PropertyAccessExpression) {
158 this.reportError(binExpr, errorThisAssignment);
159 return;
160 }
161 let lhs = <ts.PropertyAccessExpression>binExpr.left;
162 if (lhs.expression.kind !== ts.SyntaxKind.ThisKeyword) {
163 this.reportError(binExpr, errorThisAssignment);
164 return;
165 }
166 let ident = lhs.name;
167 binExpr.left = ident;
168 expressions.push(nestedExpr);
169 }
170 });
171
172 let hasInitializerExpr = expressions.length > 0;
173 if (hasInitializerExpr) {
174 // Write out the assignments.
175 this.emit(':');
176 this.visitList(expressions);
177 }
178 if (superCall) {
179 this.emit(hasInitializerExpr ? ',' : ':');
180 this.emit('super (');
181 if (!this.handleNamedParamsCall(superCall)) {
182 this.visitList(superCall.arguments);
183 }
184 this.emit(')');
185 }
186 if (parentIsConst) {
187 // Const ctors don't have bodies.
188 this.emit(';');
189 return true; // completely handled.
190 } else {
191 return false;
192 }
193 }
194
195 /**
196 * Checks whether `callExpr` is a super() call that should be ignored because it was already
197 * handled by `maybeEmitSuperInitializer` above.
198 */
199 private maybeHandleSuperCall(callExpr: ts.CallExpression): boolean {
200 if (callExpr.expression.kind !== ts.SyntaxKind.SuperKeyword) return false;
201 // Sanity check that there was indeed a ctor directly above this call.
202 let exprStmt = callExpr.parent;
203 let ctorBody = exprStmt.parent;
204 let ctor = ctorBody.parent;
205 if (ctor.kind !== ts.SyntaxKind.Constructor) {
206 this.reportError(callExpr, 'super calls must be immediate children of thei r constructors');
207 return false;
208 }
209 this.emit('/* super call moved to initializer */');
210 return true;
211 }
212 }
OLDNEW
« no previous file with comments | « lib/base.ts ('k') | lib/dart_libraries_for_browser_types.ts » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698