| 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'; |
| 11 import '../core_types.dart'; |
| 11 import '../elements/types.dart'; | 12 import '../elements/types.dart'; |
| 12 import '../elements/elements.dart' show AstElement, ResolvedAst; | 13 import '../elements/elements.dart' show AstElement, ResolvedAst; |
| 13 import '../elements/entities.dart'; | 14 import '../elements/entities.dart'; |
| 14 import '../js_backend/backend.dart' show JavaScriptBackend; | 15 import '../js_backend/backend.dart' show JavaScriptBackend; |
| 15 import '../kernel/kernel.dart'; | 16 import '../kernel/kernel.dart'; |
| 16 import '../kernel/kernel_debug.dart'; | 17 import '../kernel/kernel_debug.dart'; |
| 17 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; | 18 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; |
| 18 import '../universe/call_structure.dart'; | 19 import '../universe/call_structure.dart'; |
| 19 import '../universe/feature.dart'; | 20 import '../universe/feature.dart'; |
| 20 import '../universe/selector.dart'; | 21 import '../universe/selector.dart'; |
| 21 import '../universe/use.dart'; | 22 import '../universe/use.dart'; |
| 22 | 23 |
| 23 import 'kernel_ast_adapter.dart'; | 24 import 'kernel_ast_adapter.dart'; |
| 24 import '../common/resolution.dart'; | 25 import '../common/resolution.dart'; |
| 25 | 26 |
| 26 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. | 27 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. |
| 27 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) { | 28 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) { |
| 28 AstElement element = resolvedAst.element; | 29 AstElement element = resolvedAst.element; |
| 29 return compiler.reporter.withCurrentElement(element.implementation, () { | 30 return compiler.reporter.withCurrentElement(element.implementation, () { |
| 30 JavaScriptBackend backend = compiler.backend; | 31 JavaScriptBackend backend = compiler.backend; |
| 31 Kernel kernel = backend.kernelTask.kernel; | 32 Kernel kernel = backend.kernelTask.kernel; |
| 32 KernelImpactBuilder builder = | 33 KernelAstAdapter astAdapter = new KernelAstAdapter(kernel, compiler.backend, |
| 33 new KernelImpactBuilder(resolvedAst, compiler, kernel); | 34 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); |
| 35 KernelImpactBuilder builder = new KernelImpactBuilder( |
| 36 '${resolvedAst.element}', astAdapter, compiler.commonElements); |
| 34 if (element.isFunction || | 37 if (element.isFunction || |
| 35 element.isGetter || | 38 element.isGetter || |
| 36 element.isSetter || | 39 element.isSetter || |
| 37 element.isFactoryConstructor) { | 40 element.isFactoryConstructor) { |
| 38 ir.Procedure function = kernel.functions[element]; | 41 ir.Procedure function = kernel.functions[element]; |
| 39 if (function == null) { | 42 if (function == null) { |
| 40 throw "FOUND NULL FUNCTION: $element"; | 43 throw "FOUND NULL FUNCTION: $element"; |
| 41 } else { | 44 } else { |
| 42 return builder.buildProcedure(function); | 45 return builder.buildProcedure(function); |
| 43 } | 46 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 55 } else { | 58 } else { |
| 56 return builder.buildField(field); | 59 return builder.buildField(field); |
| 57 } | 60 } |
| 58 } else { | 61 } else { |
| 59 throw new UnsupportedError("Unsupported element: $element"); | 62 throw new UnsupportedError("Unsupported element: $element"); |
| 60 } | 63 } |
| 61 }); | 64 }); |
| 62 } | 65 } |
| 63 | 66 |
| 64 class KernelImpactBuilder extends ir.Visitor { | 67 class KernelImpactBuilder extends ir.Visitor { |
| 65 final ResolvedAst resolvedAst; | 68 final ResolutionWorldImpactBuilder impactBuilder; |
| 66 final Compiler compiler; | 69 final KernelWorldBuilder astAdapter; |
| 70 final CommonElements commonElements; |
| 67 | 71 |
| 68 JavaScriptBackend get backend => compiler.backend; | 72 KernelImpactBuilder(String name, this.astAdapter, this.commonElements) |
| 69 | 73 : this.impactBuilder = new ResolutionWorldImpactBuilder(name); |
| 70 ResolutionWorldImpactBuilder impactBuilder; | |
| 71 KernelWorldBuilder astAdapter; | |
| 72 | |
| 73 KernelImpactBuilder(this.resolvedAst, this.compiler, Kernel kernel) { | |
| 74 this.impactBuilder = | |
| 75 new ResolutionWorldImpactBuilder('${resolvedAst.element}'); | |
| 76 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, | |
| 77 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); | |
| 78 } | |
| 79 | 74 |
| 80 /// Add a checked-mode type use of [type] if it is not `dynamic`. | 75 /// Add a checked-mode type use of [type] if it is not `dynamic`. |
| 81 DartType checkType(ir.DartType irType) { | 76 DartType checkType(ir.DartType irType) { |
| 82 DartType type = astAdapter.getDartType(irType); | 77 DartType type = astAdapter.getDartType(irType); |
| 83 if (!type.isDynamic) { | 78 if (!type.isDynamic) { |
| 84 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); | 79 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); |
| 85 } | 80 } |
| 86 return type; | 81 return type; |
| 87 } | 82 } |
| 88 | 83 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 case ir.AsyncMarker.SyncStar: | 134 case ir.AsyncMarker.SyncStar: |
| 140 impactBuilder.registerFeature(Feature.SYNC_STAR); | 135 impactBuilder.registerFeature(Feature.SYNC_STAR); |
| 141 break; | 136 break; |
| 142 case ir.AsyncMarker.Async: | 137 case ir.AsyncMarker.Async: |
| 143 impactBuilder.registerFeature(Feature.ASYNC); | 138 impactBuilder.registerFeature(Feature.ASYNC); |
| 144 break; | 139 break; |
| 145 case ir.AsyncMarker.AsyncStar: | 140 case ir.AsyncMarker.AsyncStar: |
| 146 impactBuilder.registerFeature(Feature.ASYNC_STAR); | 141 impactBuilder.registerFeature(Feature.ASYNC_STAR); |
| 147 break; | 142 break; |
| 148 case ir.AsyncMarker.SyncYielding: | 143 case ir.AsyncMarker.SyncYielding: |
| 149 compiler.reporter.internalError(resolvedAst.element, | 144 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE, |
| 150 "Unexpected async marker: ${procedure.function.asyncMarker}"); | 145 "Unexpected async marker: ${procedure.function.asyncMarker}"); |
| 151 } | 146 } |
| 152 if (procedure.isExternal && | 147 if (procedure.isExternal && |
| 153 !astAdapter.isForeignLibrary(procedure.enclosingLibrary)) { | 148 !astAdapter.isForeignLibrary(procedure.enclosingLibrary)) { |
| 154 impactBuilder | 149 impactBuilder |
| 155 .registerNativeData(astAdapter.getNativeBehaviorForMethod(procedure)); | 150 .registerNativeData(astAdapter.getNativeBehaviorForMethod(procedure)); |
| 156 } | 151 } |
| 157 return impactBuilder; | 152 return impactBuilder; |
| 158 } | 153 } |
| 159 | 154 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 void visitNullLiteral(ir.NullLiteral literal) { | 211 void visitNullLiteral(ir.NullLiteral literal) { |
| 217 impactBuilder.registerConstantLiteral(new NullConstantExpression()); | 212 impactBuilder.registerConstantLiteral(new NullConstantExpression()); |
| 218 } | 213 } |
| 219 | 214 |
| 220 @override | 215 @override |
| 221 void visitListLiteral(ir.ListLiteral literal) { | 216 void visitListLiteral(ir.ListLiteral literal) { |
| 222 visitNodes(literal.expressions); | 217 visitNodes(literal.expressions); |
| 223 DartType elementType = checkType(literal.typeArgument); | 218 DartType elementType = checkType(literal.typeArgument); |
| 224 | 219 |
| 225 impactBuilder.registerListLiteral(new ListLiteralUse( | 220 impactBuilder.registerListLiteral(new ListLiteralUse( |
| 226 compiler.commonElements.listType(elementType), | 221 commonElements.listType(elementType), |
| 227 isConstant: literal.isConst, | 222 isConstant: literal.isConst, |
| 228 isEmpty: literal.expressions.isEmpty)); | 223 isEmpty: literal.expressions.isEmpty)); |
| 229 } | 224 } |
| 230 | 225 |
| 231 @override | 226 @override |
| 232 void visitMapLiteral(ir.MapLiteral literal) { | 227 void visitMapLiteral(ir.MapLiteral literal) { |
| 233 visitNodes(literal.entries); | 228 visitNodes(literal.entries); |
| 234 DartType keyType = checkType(literal.keyType); | 229 DartType keyType = checkType(literal.keyType); |
| 235 DartType valueType = checkType(literal.valueType); | 230 DartType valueType = checkType(literal.valueType); |
| 236 impactBuilder.registerMapLiteral(new MapLiteralUse( | 231 impactBuilder.registerMapLiteral(new MapLiteralUse( |
| 237 compiler.commonElements.mapType(keyType, valueType), | 232 commonElements.mapType(keyType, valueType), |
| 238 isConstant: literal.isConst, | 233 isConstant: literal.isConst, |
| 239 isEmpty: literal.entries.isEmpty)); | 234 isEmpty: literal.entries.isEmpty)); |
| 240 } | 235 } |
| 241 | 236 |
| 242 void visitMapEntry(ir.MapEntry entry) { | 237 void visitMapEntry(ir.MapEntry entry) { |
| 243 visitNode(entry.key); | 238 visitNode(entry.key); |
| 244 visitNode(entry.value); | 239 visitNode(entry.value); |
| 245 } | 240 } |
| 246 | 241 |
| 247 void _visitArguments(ir.Arguments arguments) { | 242 void _visitArguments(ir.Arguments arguments) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { | 372 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { |
| 378 FunctionEntity method = astAdapter.getMethod(target); | 373 FunctionEntity method = astAdapter.getMethod(target); |
| 379 impactBuilder.registerStaticUse(new StaticUse.superTearOff(method)); | 374 impactBuilder.registerStaticUse(new StaticUse.superTearOff(method)); |
| 380 } else { | 375 } else { |
| 381 MemberEntity member = astAdapter.getMember(target); | 376 MemberEntity member = astAdapter.getMember(target); |
| 382 impactBuilder.registerStaticUse(new StaticUse.superGet(member)); | 377 impactBuilder.registerStaticUse(new StaticUse.superGet(member)); |
| 383 } | 378 } |
| 384 } | 379 } |
| 385 | 380 |
| 386 @override | 381 @override |
| 387 void visitDirectGet(ir.StaticGet node) { | 382 void visitDirectPropertyGet(ir.DirectPropertyGet node) { |
| 388 handleSuperGet(node.target); | 383 handleSuperGet(node.target); |
| 389 } | 384 } |
| 390 | 385 |
| 391 @override | 386 @override |
| 392 void visitSuperPropertyGet(ir.SuperPropertyGet node) { | 387 void visitSuperPropertyGet(ir.SuperPropertyGet node) { |
| 393 handleSuperGet(node.interfaceTarget); | 388 handleSuperGet(node.interfaceTarget); |
| 394 } | 389 } |
| 395 | 390 |
| 396 void handleSuperSet(ir.Node target, ir.Node value) { | 391 void handleSuperSet(ir.Node target, ir.Node value) { |
| 397 visitNode(value); | 392 visitNode(value); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 FunctionEntity target = astAdapter.getConstructor(node.target); | 560 FunctionEntity target = astAdapter.getConstructor(node.target); |
| 566 impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke( | 561 impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke( |
| 567 target, astAdapter.getCallStructure(node.arguments))); | 562 target, astAdapter.getCallStructure(node.arguments))); |
| 568 } | 563 } |
| 569 | 564 |
| 570 // TODO(johnniwinther): Make this throw and visit child nodes explicitly | 565 // TODO(johnniwinther): Make this throw and visit child nodes explicitly |
| 571 // instead to ensure that we don't visit unwanted parts of the ir. | 566 // instead to ensure that we don't visit unwanted parts of the ir. |
| 572 @override | 567 @override |
| 573 void defaultNode(ir.Node node) => node.visitChildren(this); | 568 void defaultNode(ir.Node node) => node.visitChildren(this); |
| 574 } | 569 } |
| OLD | NEW |