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 |