Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: pkg/compiler/lib/src/ssa/kernel_impact.dart

Issue 2377623002: Handle constructor invocation, is, as, throw, for-in and (a)sync(*) in kernel_impact (Closed)
Patch Set: Remove test line Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 '../dart_types.dart'; 11 import '../dart_types.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../js_backend/backend.dart' show JavaScriptBackend; 13 import '../js_backend/backend.dart' show JavaScriptBackend;
14 import '../kernel/kernel.dart'; 14 import '../kernel/kernel.dart';
15 import '../kernel/kernel_debug.dart'; 15 import '../kernel/kernel_debug.dart';
16 import '../kernel/kernel_visitor.dart'; 16 import '../kernel/kernel_visitor.dart';
17 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; 17 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder;
18 import '../universe/feature.dart'; 18 import '../universe/feature.dart';
19 import '../universe/selector.dart'; 19 import '../universe/selector.dart';
20 import '../universe/use.dart'; 20 import '../universe/use.dart';
21 21
22 import 'kernel_ast_adapter.dart'; 22 import 'kernel_ast_adapter.dart';
23 import '../common/resolution.dart'; 23 import '../common/resolution.dart';
24 24
25 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. 25 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel.
26 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) { 26 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) {
27 AstElement element = resolvedAst.element.implementation; 27 AstElement element = resolvedAst.element;
28 JavaScriptBackend backend = compiler.backend; 28 JavaScriptBackend backend = compiler.backend;
29 Kernel kernel = backend.kernelTask.kernel; 29 Kernel kernel = backend.kernelTask.kernel;
30 KernelImpactBuilder builder = 30 KernelImpactBuilder builder =
31 new KernelImpactBuilder(resolvedAst, compiler, kernel); 31 new KernelImpactBuilder(resolvedAst, compiler, kernel);
32 if (element.isFunction) { 32 if (element.isFunction) {
33 ir.Procedure function = kernel.functions[element]; 33 ir.Procedure function = kernel.functions[element];
34 if (function == null) { 34 if (function == null) {
35 print("FOUND NULL FUNCTION: $element"); 35 print("FOUND NULL FUNCTION: $element");
36 } else { 36 } else {
37 return builder.buildProcedure(function); 37 return builder.buildProcedure(function);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER); 90 impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER);
91 } 91 }
92 return impactBuilder; 92 return impactBuilder;
93 } 93 }
94 94
95 ResolutionImpact buildProcedure(ir.Procedure procedure) { 95 ResolutionImpact buildProcedure(ir.Procedure procedure) {
96 if (procedure.kind == ir.ProcedureKind.Method || 96 if (procedure.kind == ir.ProcedureKind.Method ||
97 procedure.kind == ir.ProcedureKind.Operator) { 97 procedure.kind == ir.ProcedureKind.Operator) {
98 checkFunctionTypes(procedure.function); 98 checkFunctionTypes(procedure.function);
99 visitNode(procedure.function.body); 99 visitNode(procedure.function.body);
100 switch (procedure.function.asyncMarker) {
101 case ir.AsyncMarker.Sync:
102 break;
103 case ir.AsyncMarker.SyncStar:
104 impactBuilder.registerFeature(Feature.SYNC_STAR);
105 break;
106 case ir.AsyncMarker.Async:
107 impactBuilder.registerFeature(Feature.ASYNC);
108 break;
109 case ir.AsyncMarker.AsyncStar:
110 impactBuilder.registerFeature(Feature.ASYNC_STAR);
111 break;
112 case ir.AsyncMarker.SyncYielding:
113 compiler.reporter.internalError(resolvedAst.element,
114 "Unexpected async marker: ${procedure.function.asyncMarker}");
115 }
100 } else { 116 } else {
101 compiler.reporter.internalError( 117 compiler.reporter.internalError(
102 resolvedAst.element, 118 resolvedAst.element,
103 "Unable to compute resolution impact for this kind of Kernel " 119 "Unable to compute resolution impact for this kind of Kernel "
104 "procedure: ${procedure.kind}"); 120 "procedure: ${procedure.kind}");
105 } 121 }
106 return impactBuilder; 122 return impactBuilder;
107 } 123 }
108 124
109 void visitNode(ir.Node node) => node?.accept(this); 125 void visitNode(ir.Node node) => node?.accept(this);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 visitNode(entry.key); 208 visitNode(entry.key);
193 visitNode(entry.value); 209 visitNode(entry.value);
194 } 210 }
195 211
196 void _visitArguments(ir.Arguments arguments) { 212 void _visitArguments(ir.Arguments arguments) {
197 arguments.positional.forEach(visitNode); 213 arguments.positional.forEach(visitNode);
198 arguments.named.forEach(visitNode); 214 arguments.named.forEach(visitNode);
199 } 215 }
200 216
201 @override 217 @override
202 void visitStaticInvocation(ir.StaticInvocation invocation) { 218 void visitConstructorInvocation(ir.ConstructorInvocation node) {
203 _visitArguments(invocation.arguments); 219 handleNew(node, node.target);
204 Element target = astAdapter.getElement(invocation.target).declaration; 220 }
221
222 void handleNew(ir.InvocationExpression node, ir.Member target) {
223 _visitArguments(node.arguments);
224 Element element = astAdapter.getElement(target).declaration;
225 impactBuilder.registerStaticUse(new StaticUse.constructorInvoke(
226 element, astAdapter.getCallStructure(node.arguments)));
227 ClassElement cls = astAdapter.getElement(target.enclosingClass);
228 List<DartType> typeArguments =
229 astAdapter.getDartTypes(node.arguments.types);
230 impactBuilder.registerTypeUse(
231 new TypeUse.instantiation(new InterfaceType(cls, typeArguments)));
232 if (typeArguments.any((DartType type) => !type.isDynamic)) {
233 impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
234 }
235 }
236
237 @override
238 void visitStaticInvocation(ir.StaticInvocation node) {
239 Element target = astAdapter.getElement(node.target).declaration;
205 if (target.isFactoryConstructor) { 240 if (target.isFactoryConstructor) {
206 impactBuilder.registerStaticUse(new StaticUse.constructorInvoke(
207 target, astAdapter.getCallStructure(invocation.arguments)));
208 // TODO(johnniwinther): We should not mark the type as instantiated but 241 // TODO(johnniwinther): We should not mark the type as instantiated but
209 // rather follow the type arguments directly. 242 // rather follow the type arguments directly.
210 // 243 //
211 // Consider this: 244 // Consider this:
212 // 245 //
213 // abstract class A<T> { 246 // abstract class A<T> {
214 // factory A.regular() => new B<T>(); 247 // factory A.regular() => new B<T>();
215 // factory A.redirect() = B<T>; 248 // factory A.redirect() = B<T>;
216 // } 249 // }
217 // 250 //
218 // class B<T> implements A<T> {} 251 // class B<T> implements A<T> {}
219 // 252 //
220 // main() { 253 // main() {
221 // print(new A<int>.regular() is B<int>); 254 // print(new A<int>.regular() is B<int>);
222 // print(new A<String>.redirect() is B<String>); 255 // print(new A<String>.redirect() is B<String>);
223 // } 256 // }
224 // 257 //
225 // To track that B is actually instantiated as B<int> and B<String> we 258 // To track that B is actually instantiated as B<int> and B<String> we
226 // need to follow the type arguments passed to A.regular and A.redirect 259 // need to follow the type arguments passed to A.regular and A.redirect
227 // to B. Currently, we only do this soundly if we register A<int> and 260 // to B. Currently, we only do this soundly if we register A<int> and
228 // A<String> as instantiated. We should instead register that A.T is 261 // A<String> as instantiated. We should instead register that A.T is
229 // instantiated as int and String. 262 // instantiated as int and String.
230 ClassElement cls = 263 handleNew(node, node.target);
231 astAdapter.getElement(invocation.target.enclosingClass);
232 List<DartType> typeArguments =
233 astAdapter.getDartTypes(invocation.arguments.types);
234 impactBuilder.registerTypeUse(
235 new TypeUse.instantiation(new InterfaceType(cls, typeArguments)));
236 if (typeArguments.any((DartType type) => !type.isDynamic)) {
237 impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
238 }
239 } else { 264 } else {
265 _visitArguments(node.arguments);
240 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( 266 impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
241 target, astAdapter.getCallStructure(invocation.arguments))); 267 target, astAdapter.getCallStructure(node.arguments)));
242 } 268 }
243 } 269 }
244 270
245 @override 271 @override
246 void visitStaticGet(ir.StaticGet node) { 272 void visitStaticGet(ir.StaticGet node) {
247 ir.Member target = node.target; 273 ir.Member target = node.target;
248 Element element = astAdapter.getElement(target).declaration; 274 Element element = astAdapter.getElement(target).declaration;
249 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { 275 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) {
250 impactBuilder.registerStaticUse(new StaticUse.staticTearOff(element)); 276 impactBuilder.registerStaticUse(new StaticUse.staticTearOff(element));
251 } else { 277 } else {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 @override 343 @override
318 void visitVariableDeclaration(ir.VariableDeclaration node) { 344 void visitVariableDeclaration(ir.VariableDeclaration node) {
319 checkType(node.type); 345 checkType(node.type);
320 if (node.initializer != null) { 346 if (node.initializer != null) {
321 visitNode(node.initializer); 347 visitNode(node.initializer);
322 } else { 348 } else {
323 impactBuilder.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER); 349 impactBuilder.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER);
324 } 350 }
325 } 351 }
326 352
353 @override
354 void visitIsExpression(ir.IsExpression node) {
355 impactBuilder.registerTypeUse(
356 new TypeUse.isCheck(astAdapter.getDartType(node.type)));
357 }
358
359 @override
360 void visitAsExpression(ir.AsExpression node) {
361 impactBuilder
362 .registerTypeUse(new TypeUse.asCast(astAdapter.getDartType(node.type)));
363 }
364
365 @override
366 void visitThrow(ir.Throw node) {
367 impactBuilder.registerFeature(Feature.THROW_EXPRESSION);
368 visitNode(node.expression);
369 }
370
371 @override
372 void visitForInStatement(ir.ForInStatement node) {
373 visitNode(node.variable);
374 visitNode(node.iterable);
375 visitNode(node.body);
376 if (node.isAsync) {
377 impactBuilder.registerFeature(Feature.ASYNC_FOR_IN);
378 } else {
379 impactBuilder.registerFeature(Feature.SYNC_FOR_IN);
380 impactBuilder
381 .registerDynamicUse(new DynamicUse(Selectors.iterator, null));
382 }
383 impactBuilder.registerDynamicUse(new DynamicUse(Selectors.current, null));
384 impactBuilder.registerDynamicUse(new DynamicUse(Selectors.moveNext, null));
385 }
386
327 // TODO(johnniwinther): Make this throw and visit child nodes explicitly 387 // TODO(johnniwinther): Make this throw and visit child nodes explicitly
328 // instead to ensure that we don't visit unwanted parts of the ir. 388 // instead to ensure that we don't visit unwanted parts of the ir.
329 @override 389 @override
330 void defaultNode(ir.Node node) => node.visitChildren(this); 390 void defaultNode(ir.Node node) => node.visitChildren(this);
331 } 391 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/members.dart ('k') | tests/compiler/dart2js/kernel/impact_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698