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

Side by Side Diff: pkg/analyzer2dart/lib/src/cps_generator.dart

Issue 2037123002: Cleanup: remove package "analyzer2dart". (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer2dart.cps_generator;
6
7 import 'package:analyzer/analyzer.dart';
8
9 import 'package:compiler/src/dart_types.dart' as dart2js;
10 import 'package:compiler/src/elements/elements.dart' as dart2js;
11 import 'package:analyzer/src/generated/source.dart';
12 import 'package:analyzer/src/generated/element.dart' as analyzer;
13
14 import 'package:compiler/src/constant_system_dart.dart'
15 show DART_CONSTANT_SYSTEM;
16 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
17 import 'package:compiler/src/cps_ir/cps_ir_builder.dart';
18 import 'package:compiler/src/universe/universe.dart';
19
20 import 'semantic_visitor.dart';
21 import 'element_converter.dart';
22 import 'util.dart';
23 import 'identifier_semantics.dart';
24
25 /// Visitor that converts the AST node of an analyzer element into a CPS ir
26 /// node.
27 class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {
28 final ElementConverter converter;
29 final AstNode node;
30
31 CpsElementVisitor(this.converter, this.node);
32
33 @override
34 ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {
35 CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
36 FunctionDeclaration functionDeclaration = node;
37 return visitor.handleFunctionDeclaration(
38 element, functionDeclaration.functionExpression.body);
39 }
40
41 @override
42 ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {
43 CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
44 MethodDeclaration methodDeclaration = node;
45 return visitor.handleFunctionDeclaration(element, methodDeclaration.body);
46 }
47
48 @override
49 ir.FieldDefinition visitTopLevelVariableElement(
50 analyzer.TopLevelVariableElement element) {
51 CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
52 VariableDeclaration variableDeclaration = node;
53 return visitor.handleFieldDeclaration(element, variableDeclaration);
54 }
55
56 @override
57 ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {
58 CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
59 if (!element.isFactory) {
60 ConstructorDeclaration constructorDeclaration = node;
61 FunctionBody body;
62 if (constructorDeclaration != null) {
63 body = constructorDeclaration.body;
64 } else {
65 assert(element.isSynthetic);
66 }
67 return visitor.handleConstructorDeclaration(element, body);
68 }
69 // TODO(johnniwinther): Support factory constructors.
70 return null;
71 }
72 }
73
74 /// Visitor that converts analyzer AST nodes into CPS ir nodes.
75 class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
76 with IrBuilderMixin<AstNode> {
77 /// Promote the type of [irBuilder] to [DartIrBuilder].
78 /// The JS backend requires closure conversion which we do not support yet.
79 DartIrBuilder get irBuilder => super.irBuilder;
80 final analyzer.Element element;
81 final ElementConverter converter;
82
83 CpsGeneratingVisitor(this.converter, this.element);
84
85 Source get currentSource => element.source;
86
87 analyzer.LibraryElement get currentLibrary => element.library;
88
89 ir.Node visit(AstNode node) => node.accept(this);
90
91 ir.ConstructorDefinition handleConstructorDeclaration(
92 analyzer.ConstructorElement constructor, FunctionBody body) {
93 dart2js.ConstructorElement element = converter.convertElement(constructor);
94 return withBuilder(
95 new DartIrBuilder(DART_CONSTANT_SYSTEM,
96 element,
97 // TODO(johnniwinther): Support closure variables.
98 new Set<dart2js.Local>()),
99 () {
100 irBuilder.buildFunctionHeader(
101 constructor.parameters.map(converter.convertElement));
102 // Visit the body directly to avoid processing the signature as
103 // expressions.
104 // Call to allow for `body == null` in case of synthesized constructors.
105 build(body);
106 return irBuilder.makeConstructorDefinition(const [], const []);
107 });
108 }
109
110 ir.FieldDefinition handleFieldDeclaration(
111 analyzer.PropertyInducingElement field, VariableDeclaration node) {
112 dart2js.FieldElement element = converter.convertElement(field);
113 return withBuilder(
114 new DartIrBuilder(DART_CONSTANT_SYSTEM,
115 element,
116 // TODO(johnniwinther): Support closure variables.
117 new Set<dart2js.Local>()),
118 () {
119 irBuilder.buildFieldInitializerHeader();
120 ir.Primitive initializer = build(node.initializer);
121 return irBuilder.makeFieldDefinition(initializer);
122 });
123 }
124
125 ir.FunctionDefinition handleFunctionDeclaration(
126 analyzer.ExecutableElement function, FunctionBody body) {
127 dart2js.FunctionElement element = converter.convertElement(function);
128 return withBuilder(
129 new DartIrBuilder(DART_CONSTANT_SYSTEM,
130 element,
131 // TODO(johnniwinther): Support closure variables.
132 new Set<dart2js.Local>()),
133 () {
134 irBuilder.buildFunctionHeader(
135 function.parameters.map(converter.convertElement));
136 // Visit the body directly to avoid processing the signature as
137 // expressions.
138 visit(body);
139 return irBuilder.makeFunctionDefinition(const []);
140 });
141 }
142
143 @override
144 ir.Primitive visitFunctionExpression(FunctionExpression node) {
145 return irBuilder.buildFunctionExpression(
146 handleFunctionDeclaration(node.element, node.body));
147 }
148
149 @override
150 ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
151 return handleFunctionDeclaration(
152 node.element, node.functionExpression.body);
153 }
154
155 @override
156 visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
157 FunctionDeclaration functionDeclaration = node.functionDeclaration;
158 analyzer.FunctionElement function = functionDeclaration.element;
159 dart2js.FunctionElement element = converter.convertElement(function);
160 ir.FunctionDefinition definition = handleFunctionDeclaration(
161 function, functionDeclaration.functionExpression.body);
162 irBuilder.declareLocalFunction(element, definition);
163 }
164
165 List<ir.Primitive> visitArguments(ArgumentList argumentList) {
166 List<ir.Primitive> arguments = <ir.Primitive>[];
167 for (Expression argument in argumentList.arguments) {
168 ir.Primitive value = build(argument);
169 if (value == null) {
170 giveUp(argument,
171 'Unsupported argument: $argument (${argument.runtimeType}).');
172 }
173 arguments.add(value);
174 }
175 return arguments;
176 }
177
178 @override
179 ir.Node visitMethodInvocation(MethodInvocation node) {
180 // Overridden to avoid eager visits of the receiver and arguments.
181 return handleMethodInvocation(node);
182 }
183
184 @override
185 ir.Primitive visitDynamicInvocation(MethodInvocation node,
186 AccessSemantics semantics) {
187 // TODO(johnniwinther): Handle implicit `this`.
188 ir.Primitive receiver = build(semantics.target);
189 List<ir.Primitive> arguments = visitArguments(node.argumentList);
190 return irBuilder.buildDynamicInvocation(
191 receiver,
192 createSelectorFromMethodInvocation(
193 node.argumentList, node.methodName.name),
194 arguments);
195 }
196
197 @override
198 ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
199 AccessSemantics semantics) {
200 analyzer.Element staticElement = semantics.element;
201 dart2js.Element element = converter.convertElement(staticElement);
202 List<ir.Primitive> arguments = visitArguments(node.argumentList);
203 return irBuilder.buildStaticFunctionInvocation(
204 element,
205 createCallStructureFromMethodInvocation(node.argumentList),
206 arguments);
207 }
208
209 @override
210 ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
211 return handleLocalAccess(node, semantics);
212 }
213
214 ir.Primitive handleLocalInvocation(MethodInvocation node,
215 AccessSemantics semantics) {
216 analyzer.Element staticElement = semantics.element;
217 dart2js.Element element = converter.convertElement(staticElement);
218 List<ir.Definition> arguments = visitArguments(node.argumentList);
219 CallStructure callStructure = createCallStructureFromMethodInvocation(
220 node.argumentList);
221 if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
222 return irBuilder.buildLocalFunctionInvocation(
223 element, callStructure, arguments);
224 } else {
225 return irBuilder.buildLocalVariableInvocation(
226 element, callStructure, arguments);
227 }
228 }
229
230 @override
231 ir.Node visitLocalVariableInvocation(MethodInvocation node,
232 AccessSemantics semantics) {
233 return handleLocalInvocation(node, semantics);
234 }
235
236 @override
237 ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,
238 AccessSemantics semantics) {
239 return handleLocalInvocation(node, semantics);
240 }
241
242 @override
243 ir.Primitive visitFunctionExpressionInvocation(
244 FunctionExpressionInvocation node) {
245 ir.Primitive target = build(node.function);
246 List<ir.Definition> arguments = visitArguments(node.argumentList);
247 return irBuilder.buildCallInvocation(
248 target,
249 createCallStructureFromMethodInvocation(node.argumentList),
250 arguments);
251 }
252
253 @override
254 ir.Primitive visitInstanceCreationExpression(
255 InstanceCreationExpression node) {
256 analyzer.Element staticElement = node.staticElement;
257 if (staticElement != null) {
258 dart2js.Element element = converter.convertElement(staticElement);
259 dart2js.DartType type = converter.convertType(node.staticType);
260 List<ir.Primitive> arguments = visitArguments(node.argumentList);
261 return irBuilder.buildConstructorInvocation(
262 element,
263 createCallStructureFromMethodInvocation(node.argumentList),
264 type,
265 arguments);
266 }
267 return giveUp(node, "Unresolved constructor invocation.");
268 }
269
270 @override
271 ir.Constant visitNullLiteral(NullLiteral node) {
272 return irBuilder.buildNullConstant();
273 }
274
275 @override
276 ir.Constant visitBooleanLiteral(BooleanLiteral node) {
277 return irBuilder.buildBooleanConstant(node.value);
278 }
279
280 @override
281 ir.Constant visitDoubleLiteral(DoubleLiteral node) {
282 return irBuilder.buildDoubleConstant(node.value);
283 }
284
285 @override
286 ir.Constant visitIntegerLiteral(IntegerLiteral node) {
287 return irBuilder.buildIntegerConstant(node.value);
288 }
289
290 @override
291 visitAdjacentStrings(AdjacentStrings node) {
292 String value = node.stringValue;
293 if (value != null) {
294 return irBuilder.buildStringConstant(value);
295 }
296 giveUp(node, "Non constant adjacent strings.");
297 }
298
299 @override
300 ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {
301 return irBuilder.buildStringConstant(node.value);
302 }
303
304 @override
305 visitStringInterpolation(StringInterpolation node) {
306 giveUp(node, "String interpolation.");
307 }
308
309 @override
310 visitReturnStatement(ReturnStatement node) {
311 irBuilder.buildReturn(build(node.expression));
312 }
313
314 @override
315 ir.Node visitPropertyAccess(PropertyAccess node) {
316 // Overridden to avoid eager visits of the receiver.
317 return handlePropertyAccess(node);
318 }
319
320 @override
321 ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
322 return handleLocalAccess(node, semantics);
323 }
324
325 @override
326 ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
327 return handleLocalAccess(node, semantics);
328 }
329
330 @override
331 visitVariableDeclaration(VariableDeclaration node) {
332 // TODO(johnniwinther): Handle constant local variables.
333 ir.Node initialValue = build(node.initializer);
334 irBuilder.declareLocalVariable(
335 converter.convertElement(node.element),
336 initialValue: initialValue);
337 }
338
339 dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {
340 analyzer.Element element = semantics.element;
341 dart2js.Element target = converter.convertElement(element);
342 assert(invariant(node, target.isLocal, '$target expected to be local.'));
343 return target;
344 }
345
346 ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
347 dart2js.Element local = getLocal(node, semantics);
348 if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
349 return irBuilder.buildLocalFunctionGet(local);
350 } else {
351 return irBuilder.buildLocalVariableGet(local);
352 }
353 }
354
355 ir.Primitive handleLocalAssignment(AssignmentExpression node,
356 AccessSemantics semantics) {
357 if (node.operator.lexeme != '=') {
358 return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
359 }
360 return irBuilder.buildLocalVariableSet(
361 getLocal(node, semantics),
362 build(node.rightHandSide));
363 }
364
365 @override
366 ir.Node visitAssignmentExpression(AssignmentExpression node) {
367 // Avoid eager visiting of left and right hand side.
368 return handleAssignmentExpression(node);
369 }
370
371 @override
372 ir.Node visitLocalVariableAssignment(AssignmentExpression node,
373 AccessSemantics semantics) {
374 return handleLocalAssignment(node, semantics);
375 }
376
377 @override
378 ir.Node visitParameterAssignment(AssignmentExpression node,
379 AccessSemantics semantics) {
380 return handleLocalAssignment(node, semantics);
381 }
382
383 @override
384 ir.Node visitStaticFieldAssignment(AssignmentExpression node,
385 AccessSemantics semantics) {
386 if (node.operator.lexeme != '=') {
387 return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
388 }
389 analyzer.Element element = semantics.element;
390 dart2js.Element target = converter.convertElement(element);
391 // TODO(johnniwinther): Selector information should be computed in the
392 // [TreeShaker] and shared with the [CpsGeneratingVisitor].
393 assert(invariant(node, target.isTopLevel || target.isStatic,
394 '$target expected to be top-level or static.'));
395 return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));
396 }
397
398 @override
399 ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
400 // TODO(johnniwinther): Handle implicit `this`.
401 ir.Primitive receiver = build(semantics.target);
402 return irBuilder.buildDynamicGet(receiver,
403 new Selector.getter(semantics.identifier.name,
404 converter.convertElement(element.library)));
405 }
406
407 @override
408 ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
409 analyzer.Element element = semantics.element;
410 dart2js.Element target = converter.convertElement(element);
411 // TODO(johnniwinther): Selector information should be computed in the
412 // [TreeShaker] and shared with the [CpsGeneratingVisitor].
413 assert(invariant(node, target.isTopLevel || target.isStatic,
414 '$target expected to be top-level or static.'));
415 return irBuilder.buildStaticFieldLazyGet(target, null);
416 }
417
418 ir.Primitive handleBinaryExpression(BinaryExpression node,
419 String op) {
420 ir.Primitive left = build(node.leftOperand);
421 ir.Primitive right = build(node.rightOperand);
422 Selector selector = new Selector.binaryOperator(op);
423 return irBuilder.buildDynamicInvocation(
424 left, selector, <ir.Primitive>[right]);
425 }
426
427 ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
428 return irBuilder.buildLogicalOperator(
429 build(node.leftOperand),
430 subbuild(node.rightOperand),
431 isLazyOr: isLazyOr);
432 }
433
434 @override
435 ir.Node visitBinaryExpression(BinaryExpression node) {
436 // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
437 // available through an enum.
438 String op = node.operator.lexeme;
439 switch (op) {
440 case '||':
441 case '&&':
442 return handleLazyOperator(node, isLazyOr: op == '||');
443 case '!=':
444 return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
445 default:
446 return handleBinaryExpression(node, op);
447 }
448 }
449
450 @override
451 ir.Node visitConditionalExpression(ConditionalExpression node) {
452 return irBuilder.buildConditional(
453 build(node.condition),
454 subbuild(node.thenExpression),
455 subbuild(node.elseExpression));
456 }
457
458 @override
459 visitIfStatement(IfStatement node) {
460 irBuilder.buildIf(
461 build(node.condition),
462 subbuild(node.thenStatement),
463 subbuild(node.elseStatement));
464 }
465
466 @override
467 visitBlock(Block node) {
468 irBuilder.buildBlock(node.statements, build);
469 }
470
471 @override
472 ir.Node visitListLiteral(ListLiteral node) {
473 dart2js.InterfaceType type = converter.convertType(node.staticType);
474 // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue
475 // 18630 has been resolved.
476 Iterable<ir.Primitive> values = node.elements.map((e) => build(e));
477 return irBuilder.buildListLiteral(type, values);
478 }
479
480 @override
481 ir.Node visitMapLiteral(MapLiteral node) {
482 dart2js.InterfaceType type = converter.convertType(node.staticType);
483 return irBuilder.buildMapLiteral(
484 type,
485 node.entries.map((e) => e.key),
486 node.entries.map((e) => e.value),
487 build);
488 }
489
490 @override
491 visitForStatement(ForStatement node) {
492 // TODO(johnniwinther): Support `for` as a jump target.
493 List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];
494 SubbuildFunction buildInitializer;
495 if (node.variables != null) {
496 buildInitializer = subbuild(node.variables);
497 for (VariableDeclaration variable in node.variables.variables) {
498 loopVariables.add(converter.convertElement(variable.element));
499 }
500 } else {
501 buildInitializer = subbuild(node.initialization);
502 }
503 irBuilder.buildFor(buildInitializer: buildInitializer,
504 buildCondition: subbuild(node.condition),
505 buildBody: subbuild(node.body),
506 buildUpdate: subbuildSequence(node.updaters),
507 loopVariables: loopVariables);
508 }
509
510 @override
511 visitWhileStatement(WhileStatement node) {
512 // TODO(johnniwinther): Support `while` as a jump target.
513 irBuilder.buildWhile(buildCondition: subbuild(node.condition),
514 buildBody: subbuild(node.body));
515 }
516
517 @override
518 visitDeclaredIdentifier(DeclaredIdentifier node) {
519 giveUp(node, "Unexpected node: DeclaredIdentifier");
520 }
521
522 @override
523 visitForEachStatement(ForEachStatement node) {
524 SubbuildFunction buildVariableDeclaration;
525 dart2js.Element variableElement;
526 Selector variableSelector;
527 if (node.identifier != null) {
528 AccessSemantics accessSemantics =
529 node.identifier.accept(ACCESS_SEMANTICS_VISITOR);
530 if (accessSemantics.kind == AccessKind.DYNAMIC) {
531 variableSelector = new Selector.setter(
532 node.identifier.name, converter.convertElement(currentLibrary));
533 } else if (accessSemantics.element != null) {
534 variableElement = converter.convertElement(accessSemantics.element);
535 variableSelector = new Selector.setter(
536 variableElement.name,
537 converter.convertElement(accessSemantics.element.library));
538 } else {
539 giveUp(node, 'For-in of unresolved variable: $accessSemantics');
540 }
541 } else {
542 assert(invariant(
543 node, node.loopVariable != null, "Loop variable expected"));
544 variableElement = converter.convertElement(node.loopVariable.element);
545 buildVariableDeclaration = (IrBuilder builder) {
546 builder.declareLocalVariable(variableElement);
547 };
548 }
549 // TODO(johnniwinther): Support `for-in` as a jump target.
550 irBuilder.buildForIn(
551 buildExpression: subbuild(node.iterable),
552 buildVariableDeclaration: buildVariableDeclaration,
553 variableElement: variableElement,
554 variableSelector: variableSelector,
555 buildBody: subbuild(node.body));
556 }
557 @override
558 ir.Primitive visitIsExpression(IsExpression node) {
559 return irBuilder.buildTypeOperator(
560 visit(node.expression),
561 converter.convertType(node.type.type),
562 isTypeTest: true,
563 isNotCheck: node.notOperator != null);
564 }
565
566 @override
567 ir.Primitive visitAsExpression(AsExpression node) {
568 return irBuilder.buildTypeOperator(
569 visit(node.expression),
570 converter.convertType(node.type.type),
571 isTypeTest: false);
572 }
573
574 @override
575 visitTryStatement(TryStatement node) {
576 List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
577 for (CatchClause catchClause in node.catchClauses) {
578 catchClauseInfos.add(new CatchClauseInfo(
579 exceptionVariable: converter.convertElement(
580 catchClause.exceptionParameter.staticElement),
581 buildCatchBlock: subbuild(catchClause.body)));
582
583 }
584 irBuilder.buildTry(
585 tryStatementInfo: new TryStatementInfo(),
586 buildTryBlock: subbuild(node.body),
587 catchClauseInfos: catchClauseInfos);
588 }
589 }
OLDNEW
« no previous file with comments | « pkg/analyzer2dart/lib/src/converted_world.dart ('k') | pkg/analyzer2dart/lib/src/dart_backend.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698