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

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

Issue 666863002: Support conditional expressions in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer2dart.cps_generator; 5 library analyzer2dart.cps_generator;
6 6
7 import 'package:analyzer/analyzer.dart'; 7 import 'package:analyzer/analyzer.dart';
8 8
9 import 'package:compiler/implementation/elements/elements.dart' as dart2js; 9 import 'package:compiler/implementation/elements/elements.dart' as dart2js;
10 import 'package:analyzer/src/generated/source.dart'; 10 import 'package:analyzer/src/generated/source.dart';
11 import 'package:analyzer/src/generated/element.dart' as analyzer; 11 import 'package:analyzer/src/generated/element.dart' as analyzer;
12 12
13 import 'package:compiler/implementation/dart2jslib.dart' 13 import 'package:compiler/implementation/dart2jslib.dart'
14 show DART_CONSTANT_SYSTEM; 14 show DART_CONSTANT_SYSTEM;
15 import 'package:compiler/implementation/cps_ir/cps_ir_nodes.dart' as ir; 15 import 'package:compiler/implementation/cps_ir/cps_ir_nodes.dart' as ir;
16 import 'package:compiler/implementation/cps_ir/cps_ir_builder.dart'; 16 import 'package:compiler/implementation/cps_ir/cps_ir_builder.dart';
17 import 'package:compiler/implementation/universe/universe.dart'; 17 import 'package:compiler/implementation/universe/universe.dart';
18 18
19 import 'semantic_visitor.dart'; 19 import 'semantic_visitor.dart';
20 import 'element_converter.dart'; 20 import 'element_converter.dart';
21 import 'util.dart'; 21 import 'util.dart';
22 import 'identifier_semantics.dart'; 22 import 'identifier_semantics.dart';
23 23
24 class CpsGeneratingVisitor extends SemanticVisitor<ir.Node> 24 class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
25 with IrBuilderMixin { 25 with IrBuilderMixin<AstNode> {
26 final analyzer.Element element; 26 final analyzer.Element element;
27 final ElementConverter converter; 27 final ElementConverter converter;
28 28
29 CpsGeneratingVisitor(this.converter, this.element); 29 CpsGeneratingVisitor(this.converter, this.element);
30 30
31 Source get currentSource => element.source; 31 Source get currentSource => element.source;
32 32
33 ir.Node visit(AstNode node) => node.accept(this);
34
33 @override 35 @override
34 ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) { 36 ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
35 analyzer.FunctionElement function = node.element; 37 analyzer.FunctionElement function = node.element;
36 dart2js.FunctionElement element = converter.convertElement(function); 38 dart2js.FunctionElement element = converter.convertElement(function);
37 return withBuilder( 39 return withBuilder(
38 new IrBuilder(DART_CONSTANT_SYSTEM, 40 new IrBuilder(DART_CONSTANT_SYSTEM,
39 element, 41 element,
40 // TODO(johnniwinther): Supported closure variables. 42 // TODO(johnniwinther): Supported closure variables.
41 const <dart2js.Local>[]), 43 const <dart2js.Local>[]),
42 () { 44 () {
43 function.parameters.forEach((analyzer.ParameterElement parameter) { 45 function.parameters.forEach((analyzer.ParameterElement parameter) {
44 // TODO(johnniwinther): Support "closure variables", that is variables 46 // TODO(johnniwinther): Support "closure variables", that is variables
45 // accessed from an inner function. 47 // accessed from an inner function.
46 irBuilder.createParameter(converter.convertElement(parameter), 48 irBuilder.createParameter(converter.convertElement(parameter),
47 isClosureVariable: false); 49 isClosureVariable: false);
48 }); 50 });
49 // Visit the body directly to avoid processing the signature as 51 // Visit the body directly to avoid processing the signature as
50 // expressions. 52 // expressions.
51 node.functionExpression.body.accept(this); 53 visit(node.functionExpression.body);
52 return irBuilder.buildFunctionDefinition(element, const []); 54 return irBuilder.buildFunctionDefinition(element, const []);
53 }); 55 });
54 } 56 }
55 57
56 List<ir.Definition> visitArguments(ArgumentList argumentList) { 58 List<ir.Definition> visitArguments(ArgumentList argumentList) {
57 List<ir.Definition> arguments = <ir.Definition>[]; 59 List<ir.Definition> arguments = <ir.Definition>[];
58 for (Expression argument in argumentList.arguments) { 60 for (Expression argument in argumentList.arguments) {
59 ir.Definition value = argument.accept(this); 61 ir.Definition value = build(argument);
60 if (value == null) { 62 if (value == null) {
61 giveUp(argument, 63 giveUp(argument,
62 'Unsupported argument: $argument (${argument.runtimeType}).'); 64 'Unsupported argument: $argument (${argument.runtimeType}).');
63 } 65 }
64 arguments.add(value); 66 arguments.add(value);
65 } 67 }
66 return arguments; 68 return arguments;
67 } 69 }
68 70
69 @override 71 @override
70 ir.Primitive visitDynamicInvocation(MethodInvocation node, 72 ir.Primitive visitDynamicInvocation(MethodInvocation node,
71 AccessSemantics semantics) { 73 AccessSemantics semantics) {
72 // TODO(johnniwinther): Handle implicit `this`. 74 // TODO(johnniwinther): Handle implicit `this`.
73 ir.Primitive receiver = semantics.target.accept(this); 75 ir.Primitive receiver = build(semantics.target);
74 List<ir.Definition> arguments = visitArguments(node.argumentList); 76 List<ir.Definition> arguments = visitArguments(node.argumentList);
75 return irBuilder.buildDynamicInvocation( 77 return irBuilder.buildDynamicInvocation(
76 receiver, 78 receiver,
77 createSelectorFromMethodInvocation(node, node.methodName.name), 79 createSelectorFromMethodInvocation(node, node.methodName.name),
78 arguments); 80 arguments);
79 } 81 }
80 82
81 @override 83 @override
82 ir.Primitive visitStaticMethodInvocation(MethodInvocation node, 84 ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
83 AccessSemantics semantics) { 85 AccessSemantics semantics) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 return irBuilder.buildStringLiteral(node.value); 126 return irBuilder.buildStringLiteral(node.value);
125 } 127 }
126 128
127 @override 129 @override
128 visitStringInterpolation(StringInterpolation node) { 130 visitStringInterpolation(StringInterpolation node) {
129 giveUp(node, "String interpolation."); 131 giveUp(node, "String interpolation.");
130 } 132 }
131 133
132 @override 134 @override
133 visitReturnStatement(ReturnStatement node) { 135 visitReturnStatement(ReturnStatement node) {
134 if (node.expression != null) { 136 irBuilder.buildReturn(build(node.expression));
135 irBuilder.buildReturn(node.expression.accept(this));
136 } else {
137 irBuilder.buildReturn();
138 }
139 } 137 }
140 138
141 @override 139 @override
142 ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) { 140 ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
143 return handleLocalAccess(node, semantics); 141 return handleLocalAccess(node, semantics);
144 } 142 }
145 143
146 @override 144 @override
147 ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) { 145 ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
148 return handleLocalAccess(node, semantics); 146 return handleLocalAccess(node, semantics);
149 } 147 }
150 148
151 @override 149 @override
152 visitVariableDeclaration(VariableDeclaration node) { 150 visitVariableDeclaration(VariableDeclaration node) {
153 // TODO(johnniwinther): Handle constant local variables. 151 // TODO(johnniwinther): Handle constant local variables.
154 ir.Node initialValue; 152 ir.Node initialValue = build(node.initializer);
155 if (node.initializer != null) {
156 initialValue = node.initializer.accept(this);
157 }
158 irBuilder.declareLocalVariable( 153 irBuilder.declareLocalVariable(
159 converter.convertElement(node.element), 154 converter.convertElement(node.element),
160 initialValue: initialValue); 155 initialValue: initialValue);
161 } 156 }
162 157
163 ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) { 158 ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
164 analyzer.Element element = semantics.element; 159 analyzer.Element element = semantics.element;
165 dart2js.Element target = converter.convertElement(element); 160 dart2js.Element target = converter.convertElement(element);
166 assert(invariant(node, target.isLocal, '$target expected to be local.')); 161 assert(invariant(node, target.isLocal, '$target expected to be local.'));
167 return irBuilder.buildLocalGet(target); 162 return irBuilder.buildLocalGet(target);
168 } 163 }
169 164
170 @override 165 @override
171 ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) { 166 ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
172 // TODO(johnniwinther): Handle implicit `this`. 167 // TODO(johnniwinther): Handle implicit `this`.
173 ir.Primitive receiver = semantics.target.accept(this); 168 ir.Primitive receiver = build(semantics.target);
174 return irBuilder.buildDynamicGet(receiver, 169 return irBuilder.buildDynamicGet(receiver,
175 new Selector.getter(semantics.identifier.name, 170 new Selector.getter(semantics.identifier.name,
176 converter.convertElement(element.library))); 171 converter.convertElement(element.library)));
177 } 172 }
178 173
179 @override 174 @override
180 ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) { 175 ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
181 analyzer.Element element = semantics.element; 176 analyzer.Element element = semantics.element;
182 dart2js.Element target = converter.convertElement(element); 177 dart2js.Element target = converter.convertElement(element);
183 // TODO(johnniwinther): Selector information should be computed in the 178 // TODO(johnniwinther): Selector information should be computed in the
184 // [TreeShaker] and shared with the [CpsGeneratingVisitor]. 179 // [TreeShaker] and shared with the [CpsGeneratingVisitor].
185 assert(invariant(node, target.isTopLevel || target.isStatic, 180 assert(invariant(node, target.isTopLevel || target.isStatic,
186 '$target expected to be top-level or static.')); 181 '$target expected to be top-level or static.'));
187 return irBuilder.buildStaticGet(target, 182 return irBuilder.buildStaticGet(target,
188 new Selector.getter(target.name, target.library)); 183 new Selector.getter(target.name, target.library));
189 } 184 }
190 185
191 ir.Primitive handleBinaryExpression(BinaryExpression node, 186 ir.Primitive handleBinaryExpression(BinaryExpression node,
192 String op) { 187 String op) {
193 ir.Primitive left = node.leftOperand.accept(this); 188 ir.Primitive left = build(node.leftOperand);
194 ir.Primitive right = node.rightOperand.accept(this); 189 ir.Primitive right = build(node.rightOperand);
195 Selector selector = new Selector.binaryOperator(op); 190 Selector selector = new Selector.binaryOperator(op);
196 return irBuilder.buildDynamicInvocation( 191 return irBuilder.buildDynamicInvocation(
197 left, selector, <ir.Definition>[right]); 192 left, selector, <ir.Definition>[right]);
198 } 193 }
199 194
200 ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) { 195 ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
201 ir.Primitive left = node.leftOperand.accept(this);
202 ir.Primitive buildRightValue(IrBuilder builder) {
203 return withBuilder(builder, () => node.rightOperand.accept(this));
204 }
205 return irBuilder.buildLogicalOperator( 196 return irBuilder.buildLogicalOperator(
206 left, buildRightValue, isLazyOr: isLazyOr); 197 build(node.leftOperand),
198 subbuild(node.rightOperand),
199 isLazyOr: isLazyOr);
207 } 200 }
208 201
209 @override 202 @override
210 ir.Node visitBinaryExpression(BinaryExpression node) { 203 ir.Node visitBinaryExpression(BinaryExpression node) {
211 // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be 204 // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
212 // available through an enum. 205 // available through an enum.
213 String op = node.operator.lexeme; 206 String op = node.operator.lexeme;
214 switch (op) { 207 switch (op) {
215 case '||': 208 case '||':
216 case '&&': 209 case '&&':
217 return handleLazyOperator(node, isLazyOr: op == '||'); 210 return handleLazyOperator(node, isLazyOr: op == '||');
218 case '!=': 211 case '!=':
219 return irBuilder.buildNegation(handleBinaryExpression(node, '==')); 212 return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
220 default: 213 default:
221 return handleBinaryExpression(node, op); 214 return handleBinaryExpression(node, op);
222 } 215 }
223 } 216 }
224 217
225 @override 218 @override
219 ir.Node visitConditionalExpression(ConditionalExpression node) {
220 return irBuilder.buildConditional(
221 build(node.condition),
222 subbuild(node.thenExpression),
223 subbuild(node.elseExpression));
224 }
225
226 @override
226 visitIfStatement(IfStatement node) { 227 visitIfStatement(IfStatement node) {
227 ir.Primitive condition = node.condition.accept(this); 228 irBuilder.buildIf(
228 229 build(node.condition),
229 void buildThenPart(IrBuilder thenBuilder) { 230 subbuild(node.thenStatement),
230 withBuilder(thenBuilder, () => node.thenStatement.accept(this)); 231 subbuild(node.elseStatement));
231 }
232
233 void buildElsePart(IrBuilder elseBuilder) {
234 if (node.elseStatement != null) {
235 withBuilder(elseBuilder, () => node.elseStatement.accept(this));
236 }
237 }
238
239 irBuilder.buildIf(condition, buildThenPart, buildElsePart);
240 } 232 }
241 } 233 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer2dart/test/end2end_test.dart » ('j') | pkg/analyzer2dart/test/end2end_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698