Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/names.dart'; | 8 import '../common/names.dart'; |
| 9 import '../compiler.dart'; | 9 import '../compiler.dart'; |
| 10 import '../constants/expressions.dart'; | 10 import '../constants/expressions.dart'; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 | 65 |
| 66 /// Add a checked-mode type use of [type] if it is not `dynamic`. | 66 /// Add a checked-mode type use of [type] if it is not `dynamic`. |
| 67 DartType checkType(ir.DartType irType) { | 67 DartType checkType(ir.DartType irType) { |
| 68 DartType type = astAdapter.getDartType(irType); | 68 DartType type = astAdapter.getDartType(irType); |
| 69 if (!type.isDynamic) { | 69 if (!type.isDynamic) { |
| 70 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); | 70 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); |
| 71 } | 71 } |
| 72 return type; | 72 return type; |
| 73 } | 73 } |
| 74 | 74 |
| 75 /// Add a checked-mode type use of return type and parameters of [node]. | |
| 76 void checkFunctionTypes(ir.FunctionNode node) { | |
| 77 checkType(node.returnType); | |
| 78 node.positionalParameters.forEach((v) => checkType(v.type)); | |
| 79 node.namedParameters.forEach((v) => checkType(v.type)); | |
| 80 } | |
| 81 | |
| 75 ResolutionImpact buildField(ir.Field field) { | 82 ResolutionImpact buildField(ir.Field field) { |
| 76 checkType(field.type); | 83 checkType(field.type); |
| 77 if (field.initializer != null) { | 84 if (field.initializer != null) { |
| 78 field.initializer.accept(this); | 85 field.initializer.accept(this); |
| 79 } else { | 86 } else { |
| 80 impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER); | 87 impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER); |
| 81 } | 88 } |
| 82 return impactBuilder; | 89 return impactBuilder; |
| 83 } | 90 } |
| 84 | 91 |
| 85 ResolutionImpact buildProcedure(ir.Procedure procedure) { | 92 ResolutionImpact buildProcedure(ir.Procedure procedure) { |
| 86 if (procedure.kind == ir.ProcedureKind.Method || | 93 if (procedure.kind == ir.ProcedureKind.Method || |
| 87 procedure.kind == ir.ProcedureKind.Operator) { | 94 procedure.kind == ir.ProcedureKind.Operator) { |
| 88 checkType(procedure.function.returnType); | 95 checkFunctionTypes(procedure.function); |
| 89 procedure.function.positionalParameters.forEach((v) => checkType(v.type)); | |
| 90 procedure.function.namedParameters.forEach((v) => checkType(v.type)); | |
| 91 procedure.function.body.accept(this); | 96 procedure.function.body.accept(this); |
| 92 } else { | 97 } else { |
| 93 compiler.reporter.internalError( | 98 compiler.reporter.internalError( |
| 94 resolvedAst.element, | 99 resolvedAst.element, |
| 95 "Unable to compute resolution impact for this kind of Kernel " | 100 "Unable to compute resolution impact for this kind of Kernel " |
| 96 "procedure: ${procedure.kind}"); | 101 "procedure: ${procedure.kind}"); |
| 97 } | 102 } |
| 98 return impactBuilder; | 103 return impactBuilder; |
| 99 } | 104 } |
| 100 | 105 |
| 106 void visitNode(ir.Node node) => node?.accept(this); | |
|
Harry Terkelsen
2016/09/22 19:20:15
if you have this, you should use it consistently t
Johnni Winther
2016/09/23 09:01:50
I thought I had ;) - Done.
| |
| 107 | |
| 101 void visitNodes(Iterable<ir.Node> nodes) { | 108 void visitNodes(Iterable<ir.Node> nodes) { |
| 102 nodes.forEach((ir.Node node) => node.accept(this)); | 109 nodes.forEach((ir.Node node) => node.accept(this)); |
| 103 } | 110 } |
| 104 | 111 |
| 105 @override | 112 @override |
| 106 void visitBlock(ir.Block block) => visitNodes(block.statements); | 113 void visitBlock(ir.Block block) => visitNodes(block.statements); |
| 107 | 114 |
| 108 @override | 115 @override |
| 109 void visitExpressionStatement(ir.ExpressionStatement exprStatement) { | 116 void visitExpressionStatement(ir.ExpressionStatement exprStatement) { |
| 110 exprStatement.expression.accept(this); | 117 exprStatement.expression.accept(this); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK); | 238 impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK); |
| 232 } | 239 } |
| 233 } else { | 240 } else { |
| 234 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 241 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 235 target, astAdapter.getCallStructure(invocation.arguments))); | 242 target, astAdapter.getCallStructure(invocation.arguments))); |
| 236 } | 243 } |
| 237 } | 244 } |
| 238 | 245 |
| 239 @override | 246 @override |
| 240 void visitStaticGet(ir.StaticGet node) { | 247 void visitStaticGet(ir.StaticGet node) { |
| 241 Element target = astAdapter.getElement(node.target).declaration; | 248 ir.Member target = node.target; |
| 242 impactBuilder.registerStaticUse(new StaticUse.staticGet(target)); | 249 Element element = astAdapter.getElement(target).declaration; |
| 250 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { | |
| 251 impactBuilder.registerStaticUse(new StaticUse.staticTearOff(element)); | |
| 252 } else { | |
| 253 impactBuilder.registerStaticUse(new StaticUse.staticGet(element)); | |
| 254 } | |
| 243 } | 255 } |
| 244 | 256 |
| 245 @override | 257 @override |
| 246 void visitMethodInvocation(ir.MethodInvocation invocation) { | 258 void visitMethodInvocation(ir.MethodInvocation invocation) { |
| 247 var receiver = invocation.receiver; | 259 var receiver = invocation.receiver; |
| 248 if (receiver is ir.VariableGet && | 260 if (receiver is ir.VariableGet && |
| 249 receiver.variable.isFinal && | 261 receiver.variable.isFinal && |
| 250 receiver.variable.parent is ir.FunctionDeclaration) { | 262 receiver.variable.parent is ir.FunctionDeclaration) { |
| 251 // Invocation of a local function. No need for dynamic use. | 263 // Invocation of a local function. No need for dynamic use. |
| 252 } else { | 264 } else { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 269 node.receiver.accept(this); | 281 node.receiver.accept(this); |
| 270 node.value.accept(this); | 282 node.value.accept(this); |
| 271 impactBuilder.registerDynamicUse(new DynamicUse( | 283 impactBuilder.registerDynamicUse(new DynamicUse( |
| 272 new Selector.setter(astAdapter.getName(node.name)), null)); | 284 new Selector.setter(astAdapter.getName(node.name)), null)); |
| 273 } | 285 } |
| 274 | 286 |
| 275 @override | 287 @override |
| 276 void visitAssertStatement(ir.AssertStatement node) { | 288 void visitAssertStatement(ir.AssertStatement node) { |
| 277 impactBuilder.registerFeature( | 289 impactBuilder.registerFeature( |
| 278 node.message != null ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT); | 290 node.message != null ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT); |
| 279 node.visitChildren(this); | 291 visitNode(node.condition); |
| 292 visitNode(node.message); | |
| 280 } | 293 } |
| 281 | 294 |
| 282 @override | 295 @override |
| 283 void visitStringConcatenation(ir.StringConcatenation node) { | 296 void visitStringConcatenation(ir.StringConcatenation node) { |
| 284 impactBuilder.registerFeature(Feature.STRING_INTERPOLATION); | 297 impactBuilder.registerFeature(Feature.STRING_INTERPOLATION); |
| 285 impactBuilder.registerFeature(Feature.STRING_JUXTAPOSITION); | 298 impactBuilder.registerFeature(Feature.STRING_JUXTAPOSITION); |
| 286 node.visitChildren(this); | 299 visitNodes(node.expressions); |
| 287 } | 300 } |
| 288 | 301 |
| 289 @override | 302 @override |
| 290 void visitFunctionDeclaration(ir.FunctionDeclaration node) { | 303 void visitFunctionDeclaration(ir.FunctionDeclaration node) { |
| 291 impactBuilder | 304 impactBuilder |
| 292 .registerStaticUse(new StaticUse.closure(astAdapter.getElement(node))); | 305 .registerStaticUse(new StaticUse.closure(astAdapter.getElement(node))); |
| 293 node.visitChildren(this); | 306 checkFunctionTypes(node.function); |
| 307 visitNode(node.function.body); | |
| 294 } | 308 } |
| 295 | 309 |
| 296 @override | 310 @override |
| 311 void visitFunctionExpression(ir.FunctionExpression node) { | |
| 312 impactBuilder | |
| 313 .registerStaticUse(new StaticUse.closure(astAdapter.getElement(node))); | |
| 314 checkFunctionTypes(node.function); | |
| 315 visitNode(node.function.body); | |
| 316 } | |
| 317 | |
| 318 @override | |
| 319 void visitVariableDeclaration(ir.VariableDeclaration node) { | |
| 320 checkType(node.type); | |
| 321 if (node.initializer != null) { | |
| 322 visitNode(node.initializer); | |
| 323 } else { | |
| 324 impactBuilder.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER); | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 // TODO(johnniwinther): Make this throw and visit child nodes explicitly | |
| 329 // instead to ensure that we don't visit unwanted parts of the ir. | |
| 330 @override | |
| 297 void defaultNode(ir.Node node) => node.visitChildren(this); | 331 void defaultNode(ir.Node node) => node.visitChildren(this); |
| 298 } | 332 } |
| OLD | NEW |