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