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 |