| 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 '../compiler.dart'; | 8 import '../compiler.dart'; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| 11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import '../js_backend/backend.dart' show JavaScriptBackend; | 12 import '../js_backend/backend.dart' show JavaScriptBackend; |
| 13 import '../kernel/kernel.dart'; | 13 import '../kernel/kernel.dart'; |
| 14 import '../kernel/kernel_visitor.dart'; | 14 import '../kernel/kernel_visitor.dart'; |
| 15 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; | 15 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; |
| 16 import '../universe/feature.dart'; | 16 import '../universe/feature.dart'; |
| 17 import '../universe/use.dart'; | 17 import '../universe/use.dart'; |
| 18 | 18 |
| 19 import 'kernel_ast_adapter.dart'; | 19 import 'kernel_ast_adapter.dart'; |
| 20 import '../common/resolution.dart'; | 20 import '../common/resolution.dart'; |
| 21 | 21 |
| 22 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. | 22 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. |
| 23 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) { | 23 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) { |
| 24 AstElement element = resolvedAst.element.implementation; | 24 AstElement element = resolvedAst.element.implementation; |
| 25 JavaScriptBackend backend = compiler.backend; | 25 JavaScriptBackend backend = compiler.backend; |
| 26 Kernel kernel = backend.kernelTask.kernel; | 26 Kernel kernel = backend.kernelTask.kernel; |
| 27 ir.Procedure function = kernel.functions[element]; | 27 KernelImpactBuilder builder = |
| 28 if (function == null) { | 28 new KernelImpactBuilder(resolvedAst, compiler, kernel); |
| 29 print("FOUND NULL FUNCTION: $element"); | 29 if (element.isFunction) { |
| 30 print(kernel.functions); | 30 ir.Procedure function = kernel.functions[element]; |
| 31 if (function == null) { |
| 32 print("FOUND NULL FUNCTION: $element"); |
| 33 } else { |
| 34 return builder.buildProcedure(function); |
| 35 } |
| 36 } else { |
| 37 ir.Field field = kernel.fields[element]; |
| 38 if (field == null) { |
| 39 print("FOUND NULL FUNCTION: $element"); |
| 40 } else { |
| 41 return builder.buildField(field); |
| 42 } |
| 31 } | 43 } |
| 32 KernelImpactBuilder builder = | 44 return null; |
| 33 new KernelImpactBuilder(function, element, resolvedAst, compiler, kernel); | |
| 34 return builder.build(); | |
| 35 } | 45 } |
| 36 | 46 |
| 37 class KernelImpactBuilder extends ir.Visitor { | 47 class KernelImpactBuilder extends ir.Visitor { |
| 38 final ir.Procedure function; | |
| 39 final FunctionElement functionElement; | |
| 40 final ResolvedAst resolvedAst; | 48 final ResolvedAst resolvedAst; |
| 41 final Compiler compiler; | 49 final Compiler compiler; |
| 42 | 50 |
| 43 JavaScriptBackend get backend => compiler.backend; | 51 JavaScriptBackend get backend => compiler.backend; |
| 44 | 52 |
| 45 ResolutionWorldImpactBuilder impactBuilder; | 53 ResolutionWorldImpactBuilder impactBuilder; |
| 46 KernelAstAdapter astAdapter; | 54 KernelAstAdapter astAdapter; |
| 47 | 55 |
| 48 KernelImpactBuilder(this.function, this.functionElement, this.resolvedAst, | 56 KernelImpactBuilder(this.resolvedAst, this.compiler, Kernel kernel) { |
| 49 this.compiler, Kernel kernel) { | 57 this.impactBuilder = |
| 50 this.impactBuilder = new ResolutionWorldImpactBuilder('$functionElement'); | 58 new ResolutionWorldImpactBuilder('${resolvedAst.element}'); |
| 51 this.astAdapter = new KernelAstAdapter( | 59 this.astAdapter = new KernelAstAdapter( |
| 52 compiler.backend, | 60 compiler.backend, |
| 53 resolvedAst, | 61 resolvedAst, |
| 54 kernel.nodeToAst, | 62 kernel.nodeToAst, |
| 55 kernel.nodeToElement, | 63 kernel.nodeToElement, |
| 56 kernel.functions, | 64 kernel.functions, |
| 65 kernel.fields, |
| 57 kernel.classes, | 66 kernel.classes, |
| 58 kernel.libraries); | 67 kernel.libraries); |
| 59 } | 68 } |
| 60 | 69 |
| 61 ResolutionImpact build() { | |
| 62 if (function.kind == ir.ProcedureKind.Method || | |
| 63 function.kind == ir.ProcedureKind.Operator) { | |
| 64 buildMethod(function); | |
| 65 } else { | |
| 66 compiler.reporter.internalError( | |
| 67 functionElement, | |
| 68 "Unable to compute resolution impact for this kind of Kernel " | |
| 69 "procedure: ${function.kind}"); | |
| 70 } | |
| 71 return impactBuilder; | |
| 72 } | |
| 73 | |
| 74 /// Add a checked-mode type use of [type] if it is not `dynamic`. | 70 /// Add a checked-mode type use of [type] if it is not `dynamic`. |
| 75 DartType checkType(DartType type) { | 71 DartType checkType(ir.DartType irType) { |
| 72 DartType type = astAdapter.getDartType(irType); |
| 76 if (!type.isDynamic) { | 73 if (!type.isDynamic) { |
| 77 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); | 74 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); |
| 78 } | 75 } |
| 79 return type; | 76 return type; |
| 80 } | 77 } |
| 81 | 78 |
| 82 void buildMethod(ir.Procedure method) { | 79 ResolutionImpact buildField(ir.Field field) { |
| 83 method.function.body.accept(this); | 80 checkType(field.type); |
| 81 if (field.initializer != null) { |
| 82 field.initializer.accept(this); |
| 83 } else { |
| 84 impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER); |
| 85 } |
| 86 return impactBuilder; |
| 87 } |
| 88 |
| 89 ResolutionImpact buildProcedure(ir.Procedure procedure) { |
| 90 if (procedure.kind == ir.ProcedureKind.Method || |
| 91 procedure.kind == ir.ProcedureKind.Operator) { |
| 92 checkType(procedure.function.returnType); |
| 93 procedure.function.positionalParameters.forEach((v) => checkType(v.type)); |
| 94 procedure.function.namedParameters.forEach((v) => checkType(v.type)); |
| 95 procedure.function.body.accept(this); |
| 96 } else { |
| 97 compiler.reporter.internalError( |
| 98 resolvedAst.element, |
| 99 "Unable to compute resolution impact for this kind of Kernel " |
| 100 "procedure: ${procedure.kind}"); |
| 101 } |
| 102 return impactBuilder; |
| 84 } | 103 } |
| 85 | 104 |
| 86 void visitNodes(Iterable<ir.Node> nodes) { | 105 void visitNodes(Iterable<ir.Node> nodes) { |
| 87 nodes.forEach((ir.Node node) => node.accept(this)); | 106 nodes.forEach((ir.Node node) => node.accept(this)); |
| 88 } | 107 } |
| 89 | 108 |
| 90 @override | 109 @override |
| 91 void visitBlock(ir.Block block) => visitNodes(block.statements); | 110 void visitBlock(ir.Block block) => visitNodes(block.statements); |
| 92 | 111 |
| 93 @override | 112 @override |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 } | 156 } |
| 138 | 157 |
| 139 @override | 158 @override |
| 140 void visitNullLiteral(ir.NullLiteral literal) { | 159 void visitNullLiteral(ir.NullLiteral literal) { |
| 141 impactBuilder.registerConstantLiteral(new NullConstantExpression()); | 160 impactBuilder.registerConstantLiteral(new NullConstantExpression()); |
| 142 } | 161 } |
| 143 | 162 |
| 144 @override | 163 @override |
| 145 void visitListLiteral(ir.ListLiteral literal) { | 164 void visitListLiteral(ir.ListLiteral literal) { |
| 146 visitNodes(literal.expressions); | 165 visitNodes(literal.expressions); |
| 147 DartType elementType = | 166 DartType elementType = checkType(literal.typeArgument); |
| 148 checkType(astAdapter.getDartType(literal.typeArgument)); | |
| 149 | 167 |
| 150 impactBuilder.registerListLiteral(new ListLiteralUse( | 168 impactBuilder.registerListLiteral(new ListLiteralUse( |
| 151 compiler.coreTypes.listType(elementType), | 169 compiler.coreTypes.listType(elementType), |
| 152 isConstant: literal.isConst, | 170 isConstant: literal.isConst, |
| 153 isEmpty: literal.expressions.isEmpty)); | 171 isEmpty: literal.expressions.isEmpty)); |
| 154 } | 172 } |
| 155 | 173 |
| 156 @override | 174 @override |
| 157 void visitMapLiteral(ir.MapLiteral literal) { | 175 void visitMapLiteral(ir.MapLiteral literal) { |
| 158 visitNodes(literal.entries); | 176 visitNodes(literal.entries); |
| 159 DartType keyType = checkType(astAdapter.getDartType(literal.keyType)); | 177 DartType keyType = checkType(literal.keyType); |
| 160 DartType valueType = checkType(astAdapter.getDartType(literal.valueType)); | 178 DartType valueType = checkType(literal.valueType); |
| 161 impactBuilder.registerMapLiteral(new MapLiteralUse( | 179 impactBuilder.registerMapLiteral(new MapLiteralUse( |
| 162 compiler.coreTypes.mapType(keyType, valueType), | 180 compiler.coreTypes.mapType(keyType, valueType), |
| 163 isConstant: literal.isConst, | 181 isConstant: literal.isConst, |
| 164 isEmpty: literal.entries.isEmpty)); | 182 isEmpty: literal.entries.isEmpty)); |
| 165 } | 183 } |
| 166 | 184 |
| 167 void visitMapEntry(ir.MapEntry entry) { | 185 void visitMapEntry(ir.MapEntry entry) { |
| 168 entry.key.accept(this); | 186 entry.key.accept(this); |
| 169 entry.value.accept(this); | 187 entry.value.accept(this); |
| 170 } | 188 } |
| 171 | 189 |
| 172 void _visitArguments(ir.Arguments arguments) { | 190 void _visitArguments(ir.Arguments arguments) { |
| 173 for (ir.Expression argument in arguments.positional) { | 191 for (ir.Expression argument in arguments.positional) { |
| 174 argument.accept(this); | 192 argument.accept(this); |
| 175 } | 193 } |
| 176 for (ir.NamedExpression argument in arguments.named) { | 194 for (ir.NamedExpression argument in arguments.named) { |
| 177 argument.value.accept(this); | 195 argument.value.accept(this); |
| 178 } | 196 } |
| 179 } | 197 } |
| 180 | 198 |
| 181 @override | 199 @override |
| 182 void visitStaticInvocation(ir.StaticInvocation invocation) { | 200 void visitStaticInvocation(ir.StaticInvocation invocation) { |
| 183 _visitArguments(invocation.arguments); | 201 _visitArguments(invocation.arguments); |
| 184 Element target = astAdapter.getElement(invocation.target).declaration; | 202 Element target = astAdapter.getElement(invocation.target).declaration; |
| 185 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 203 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 186 target, astAdapter.getCallStructure(invocation.arguments))); | 204 target, astAdapter.getCallStructure(invocation.arguments))); |
| 187 } | 205 } |
| 188 | 206 |
| 189 @override | 207 @override |
| 208 void visitStaticGet(ir.StaticGet node) { |
| 209 Element target = astAdapter.getElement(node.target).declaration; |
| 210 impactBuilder.registerStaticUse(new StaticUse.staticGet(target)); |
| 211 } |
| 212 |
| 213 @override |
| 190 void visitMethodInvocation(ir.MethodInvocation invocation) { | 214 void visitMethodInvocation(ir.MethodInvocation invocation) { |
| 191 invocation.receiver.accept(this); | 215 invocation.receiver.accept(this); |
| 192 _visitArguments(invocation.arguments); | 216 _visitArguments(invocation.arguments); |
| 193 impactBuilder.registerDynamicUse( | 217 impactBuilder.registerDynamicUse( |
| 194 new DynamicUse(astAdapter.getSelector(invocation), null)); | 218 new DynamicUse(astAdapter.getSelector(invocation), null)); |
| 195 } | 219 } |
| 196 | 220 |
| 197 @override | 221 @override |
| 198 void visitNot(ir.Not not) { | 222 void visitNot(ir.Not not) { |
| 199 not.operand.accept(this); | 223 not.operand.accept(this); |
| 200 } | 224 } |
| 201 } | 225 } |
| OLD | NEW |