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

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: Visit conditionally. 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
« no previous file with comments | « no previous file | pkg/analyzer2dart/test/end2end_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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';
(...skipping 12 matching lines...) Expand all
23 23
24 class CpsGeneratingVisitor extends SemanticVisitor<ir.Node> 24 class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
25 with IrBuilderMixin { 25 with IrBuilderMixin {
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 != null ? node.accept(this) : null;
sigurdm 2014/10/20 10:48:32 This is not what I expect "visit" to do - it shoul
Johnni Winther 2014/10/20 12:25:13 Done.
34
35 /// Returns a closure that takes an [IrBuilder] and visits [node] in its
36 /// context.
37 build(AstNode node) {
sigurdm 2014/10/20 10:48:32 I don't really like the name - the function does n
Johnni Winther 2014/10/20 12:25:13 Done.
38 return (IrBuilder builder) => withBuilder(builder, () => visit(node));
39 }
40
33 @override 41 @override
34 ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) { 42 ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
35 analyzer.FunctionElement function = node.element; 43 analyzer.FunctionElement function = node.element;
36 dart2js.FunctionElement element = converter.convertElement(function); 44 dart2js.FunctionElement element = converter.convertElement(function);
37 return withBuilder( 45 return withBuilder(
38 new IrBuilder(DART_CONSTANT_SYSTEM, 46 new IrBuilder(DART_CONSTANT_SYSTEM,
39 element, 47 element,
40 // TODO(johnniwinther): Supported closure variables. 48 // TODO(johnniwinther): Supported closure variables.
41 const <dart2js.Local>[]), 49 const <dart2js.Local>[]),
42 () { 50 () {
43 function.parameters.forEach((analyzer.ParameterElement parameter) { 51 function.parameters.forEach((analyzer.ParameterElement parameter) {
44 // TODO(johnniwinther): Support "closure variables", that is variables 52 // TODO(johnniwinther): Support "closure variables", that is variables
45 // accessed from an inner function. 53 // accessed from an inner function.
46 irBuilder.createParameter(converter.convertElement(parameter), 54 irBuilder.createParameter(converter.convertElement(parameter),
47 isClosureVariable: false); 55 isClosureVariable: false);
48 }); 56 });
49 // Visit the body directly to avoid processing the signature as 57 // Visit the body directly to avoid processing the signature as
50 // expressions. 58 // expressions.
51 node.functionExpression.body.accept(this); 59 visit(node.functionExpression.body);
52 return irBuilder.buildFunctionDefinition(element, const []); 60 return irBuilder.buildFunctionDefinition(element, const []);
53 }); 61 });
54 } 62 }
55 63
56 List<ir.Definition> visitArguments(ArgumentList argumentList) { 64 List<ir.Definition> visitArguments(ArgumentList argumentList) {
57 List<ir.Definition> arguments = <ir.Definition>[]; 65 List<ir.Definition> arguments = <ir.Definition>[];
58 for (Expression argument in argumentList.arguments) { 66 for (Expression argument in argumentList.arguments) {
59 ir.Definition value = argument.accept(this); 67 ir.Definition value = visit(argument);
60 if (value == null) { 68 if (value == null) {
61 giveUp(argument, 69 giveUp(argument,
62 'Unsupported argument: $argument (${argument.runtimeType}).'); 70 'Unsupported argument: $argument (${argument.runtimeType}).');
63 } 71 }
64 arguments.add(value); 72 arguments.add(value);
65 } 73 }
66 return arguments; 74 return arguments;
67 } 75 }
68 76
69 @override 77 @override
70 ir.Primitive visitDynamicInvocation(MethodInvocation node, 78 ir.Primitive visitDynamicInvocation(MethodInvocation node,
71 AccessSemantics semantics) { 79 AccessSemantics semantics) {
72 // TODO(johnniwinther): Handle implicit `this`. 80 // TODO(johnniwinther): Handle implicit `this`.
73 ir.Primitive receiver = semantics.target.accept(this); 81 ir.Primitive receiver = visit(semantics.target);
74 List<ir.Definition> arguments = visitArguments(node.argumentList); 82 List<ir.Definition> arguments = visitArguments(node.argumentList);
75 return irBuilder.buildDynamicInvocation( 83 return irBuilder.buildDynamicInvocation(
76 receiver, 84 receiver,
77 createSelectorFromMethodInvocation(node, node.methodName.name), 85 createSelectorFromMethodInvocation(node, node.methodName.name),
78 arguments); 86 arguments);
79 } 87 }
80 88
81 @override 89 @override
82 ir.Primitive visitStaticMethodInvocation(MethodInvocation node, 90 ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
83 AccessSemantics semantics) { 91 AccessSemantics semantics) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 return irBuilder.buildStringLiteral(node.value); 132 return irBuilder.buildStringLiteral(node.value);
125 } 133 }
126 134
127 @override 135 @override
128 visitStringInterpolation(StringInterpolation node) { 136 visitStringInterpolation(StringInterpolation node) {
129 giveUp(node, "String interpolation."); 137 giveUp(node, "String interpolation.");
130 } 138 }
131 139
132 @override 140 @override
133 visitReturnStatement(ReturnStatement node) { 141 visitReturnStatement(ReturnStatement node) {
134 if (node.expression != null) { 142 irBuilder.buildReturn(visit(node.expression));
135 irBuilder.buildReturn(node.expression.accept(this));
136 } else {
137 irBuilder.buildReturn();
138 }
139 } 143 }
140 144
141 @override 145 @override
142 ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) { 146 ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
143 return handleLocalAccess(node, semantics); 147 return handleLocalAccess(node, semantics);
144 } 148 }
145 149
146 @override 150 @override
147 ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) { 151 ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
148 return handleLocalAccess(node, semantics); 152 return handleLocalAccess(node, semantics);
149 } 153 }
150 154
151 @override 155 @override
152 visitVariableDeclaration(VariableDeclaration node) { 156 visitVariableDeclaration(VariableDeclaration node) {
153 // TODO(johnniwinther): Handle constant local variables. 157 // TODO(johnniwinther): Handle constant local variables.
154 ir.Node initialValue; 158 ir.Node initialValue = visit(node.initializer);
155 if (node.initializer != null) {
156 initialValue = node.initializer.accept(this);
157 }
158 irBuilder.declareLocalVariable( 159 irBuilder.declareLocalVariable(
159 converter.convertElement(node.element), 160 converter.convertElement(node.element),
160 initialValue: initialValue); 161 initialValue: initialValue);
161 } 162 }
162 163
163 ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) { 164 ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
164 analyzer.Element element = semantics.element; 165 analyzer.Element element = semantics.element;
165 dart2js.Element target = converter.convertElement(element); 166 dart2js.Element target = converter.convertElement(element);
166 assert(invariant(node, target.isLocal, '$target expected to be local.')); 167 assert(invariant(node, target.isLocal, '$target expected to be local.'));
167 return irBuilder.buildLocalGet(target); 168 return irBuilder.buildLocalGet(target);
168 } 169 }
169 170
170 @override 171 @override
171 ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) { 172 ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
172 // TODO(johnniwinther): Handle implicit `this`. 173 // TODO(johnniwinther): Handle implicit `this`.
173 ir.Primitive receiver = semantics.target.accept(this); 174 ir.Primitive receiver = visit(semantics.target);
174 return irBuilder.buildDynamicGet(receiver, 175 return irBuilder.buildDynamicGet(receiver,
175 new Selector.getter(semantics.identifier.name, 176 new Selector.getter(semantics.identifier.name,
176 converter.convertElement(element.library))); 177 converter.convertElement(element.library)));
177 } 178 }
178 179
179 @override 180 @override
180 ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) { 181 ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
181 analyzer.Element element = semantics.element; 182 analyzer.Element element = semantics.element;
182 dart2js.Element target = converter.convertElement(element); 183 dart2js.Element target = converter.convertElement(element);
183 // TODO(johnniwinther): Selector information should be computed in the 184 // TODO(johnniwinther): Selector information should be computed in the
184 // [TreeShaker] and shared with the [CpsGeneratingVisitor]. 185 // [TreeShaker] and shared with the [CpsGeneratingVisitor].
185 assert(invariant(node, target.isTopLevel || target.isStatic, 186 assert(invariant(node, target.isTopLevel || target.isStatic,
186 '$target expected to be top-level or static.')); 187 '$target expected to be top-level or static.'));
187 return irBuilder.buildStaticGet(target, 188 return irBuilder.buildStaticGet(target,
188 new Selector.getter(target.name, target.library)); 189 new Selector.getter(target.name, target.library));
189 } 190 }
190 191
191 ir.Primitive handleBinaryExpression(BinaryExpression node, 192 ir.Primitive handleBinaryExpression(BinaryExpression node,
192 String op) { 193 String op) {
193 ir.Primitive left = node.leftOperand.accept(this); 194 ir.Primitive left = visit(node.leftOperand);
194 ir.Primitive right = node.rightOperand.accept(this); 195 ir.Primitive right = visit(node.rightOperand);
195 Selector selector = new Selector.binaryOperator(op); 196 Selector selector = new Selector.binaryOperator(op);
196 return irBuilder.buildDynamicInvocation( 197 return irBuilder.buildDynamicInvocation(
197 left, selector, <ir.Definition>[right]); 198 left, selector, <ir.Definition>[right]);
198 } 199 }
199 200
200 ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) { 201 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( 202 return irBuilder.buildLogicalOperator(
206 left, buildRightValue, isLazyOr: isLazyOr); 203 visit(node.leftOperand),
204 build(node.rightOperand),
205 isLazyOr: isLazyOr);
207 } 206 }
208 207
209 @override 208 @override
210 ir.Node visitBinaryExpression(BinaryExpression node) { 209 ir.Node visitBinaryExpression(BinaryExpression node) {
211 // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be 210 // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
212 // available through an enum. 211 // available through an enum.
213 String op = node.operator.lexeme; 212 String op = node.operator.lexeme;
214 switch (op) { 213 switch (op) {
215 case '||': 214 case '||':
216 case '&&': 215 case '&&':
217 return handleLazyOperator(node, isLazyOr: op == '||'); 216 return handleLazyOperator(node, isLazyOr: op == '||');
218 case '!=': 217 case '!=':
219 return irBuilder.buildNegation(handleBinaryExpression(node, '==')); 218 return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
220 default: 219 default:
221 return handleBinaryExpression(node, op); 220 return handleBinaryExpression(node, op);
222 } 221 }
223 } 222 }
224 223
225 @override 224 @override
225 ir.Node visitConditionalExpression(ConditionalExpression node) {
226 return irBuilder.buildConditional(
227 visit(node.condition),
228 build(node.thenExpression),
229 build(node.elseExpression));
230 }
231
232 @override
226 visitIfStatement(IfStatement node) { 233 visitIfStatement(IfStatement node) {
227 ir.Primitive condition = node.condition.accept(this); 234 irBuilder.buildIf(
228 235 visit(node.condition),
229 void buildThenPart(IrBuilder thenBuilder) { 236 build(node.thenStatement),
230 withBuilder(thenBuilder, () => node.thenStatement.accept(this)); 237 build(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 } 238 }
241 } 239 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer2dart/test/end2end_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698