| 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 '../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 '../elements/resolution_types.dart'; | 11 import '../elements/types.dart'; |
| 12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart' show AstElement, ResolvedAst; |
| 13 import '../elements/entities.dart'; |
| 13 import '../js_backend/backend.dart' show JavaScriptBackend; | 14 import '../js_backend/backend.dart' show JavaScriptBackend; |
| 14 import '../kernel/kernel.dart'; | 15 import '../kernel/kernel.dart'; |
| 15 import '../kernel/kernel_debug.dart'; | 16 import '../kernel/kernel_debug.dart'; |
| 16 import '../kernel/kernel_visitor.dart'; | |
| 17 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; | 17 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; |
| 18 import '../universe/call_structure.dart'; | 18 import '../universe/call_structure.dart'; |
| 19 import '../universe/feature.dart'; | 19 import '../universe/feature.dart'; |
| 20 import '../universe/selector.dart'; | 20 import '../universe/selector.dart'; |
| 21 import '../universe/use.dart'; | 21 import '../universe/use.dart'; |
| 22 | 22 |
| 23 import 'kernel_ast_adapter.dart'; | 23 import 'kernel_ast_adapter.dart'; |
| 24 import '../common/resolution.dart'; | 24 import '../common/resolution.dart'; |
| 25 | 25 |
| 26 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. | 26 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 KernelAstAdapter astAdapter; | 71 KernelAstAdapter astAdapter; |
| 72 | 72 |
| 73 KernelImpactBuilder(this.resolvedAst, this.compiler, Kernel kernel) { | 73 KernelImpactBuilder(this.resolvedAst, this.compiler, Kernel kernel) { |
| 74 this.impactBuilder = | 74 this.impactBuilder = |
| 75 new ResolutionWorldImpactBuilder('${resolvedAst.element}'); | 75 new ResolutionWorldImpactBuilder('${resolvedAst.element}'); |
| 76 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, | 76 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, |
| 77 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); | 77 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); |
| 78 } | 78 } |
| 79 | 79 |
| 80 /// Add a checked-mode type use of [type] if it is not `dynamic`. | 80 /// Add a checked-mode type use of [type] if it is not `dynamic`. |
| 81 ResolutionDartType checkType(ir.DartType irType) { | 81 DartType checkType(ir.DartType irType) { |
| 82 ResolutionDartType type = astAdapter.getDartType(irType); | 82 DartType type = astAdapter.getDartType(irType); |
| 83 if (!type.isDynamic) { | 83 if (!type.isDynamic) { |
| 84 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); | 84 impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type)); |
| 85 } | 85 } |
| 86 return type; | 86 return type; |
| 87 } | 87 } |
| 88 | 88 |
| 89 /// Add checked-mode type use for the parameter type and constant for the | 89 /// Add checked-mode type use for the parameter type and constant for the |
| 90 /// default value of [parameter]. | 90 /// default value of [parameter]. |
| 91 void handleParameter(ir.VariableDeclaration parameter) { | 91 void handleParameter(ir.VariableDeclaration parameter) { |
| 92 checkType(parameter.type); | 92 checkType(parameter.type); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 } | 212 } |
| 213 | 213 |
| 214 @override | 214 @override |
| 215 void visitNullLiteral(ir.NullLiteral literal) { | 215 void visitNullLiteral(ir.NullLiteral literal) { |
| 216 impactBuilder.registerConstantLiteral(new NullConstantExpression()); | 216 impactBuilder.registerConstantLiteral(new NullConstantExpression()); |
| 217 } | 217 } |
| 218 | 218 |
| 219 @override | 219 @override |
| 220 void visitListLiteral(ir.ListLiteral literal) { | 220 void visitListLiteral(ir.ListLiteral literal) { |
| 221 visitNodes(literal.expressions); | 221 visitNodes(literal.expressions); |
| 222 ResolutionDartType elementType = checkType(literal.typeArgument); | 222 DartType elementType = checkType(literal.typeArgument); |
| 223 | 223 |
| 224 impactBuilder.registerListLiteral(new ListLiteralUse( | 224 impactBuilder.registerListLiteral(new ListLiteralUse( |
| 225 compiler.commonElements.listType(elementType), | 225 compiler.commonElements.listType(elementType), |
| 226 isConstant: literal.isConst, | 226 isConstant: literal.isConst, |
| 227 isEmpty: literal.expressions.isEmpty)); | 227 isEmpty: literal.expressions.isEmpty)); |
| 228 } | 228 } |
| 229 | 229 |
| 230 @override | 230 @override |
| 231 void visitMapLiteral(ir.MapLiteral literal) { | 231 void visitMapLiteral(ir.MapLiteral literal) { |
| 232 visitNodes(literal.entries); | 232 visitNodes(literal.entries); |
| 233 ResolutionDartType keyType = checkType(literal.keyType); | 233 DartType keyType = checkType(literal.keyType); |
| 234 ResolutionDartType valueType = checkType(literal.valueType); | 234 DartType valueType = checkType(literal.valueType); |
| 235 impactBuilder.registerMapLiteral(new MapLiteralUse( | 235 impactBuilder.registerMapLiteral(new MapLiteralUse( |
| 236 compiler.commonElements.mapType(keyType, valueType), | 236 compiler.commonElements.mapType(keyType, valueType), |
| 237 isConstant: literal.isConst, | 237 isConstant: literal.isConst, |
| 238 isEmpty: literal.entries.isEmpty)); | 238 isEmpty: literal.entries.isEmpty)); |
| 239 } | 239 } |
| 240 | 240 |
| 241 void visitMapEntry(ir.MapEntry entry) { | 241 void visitMapEntry(ir.MapEntry entry) { |
| 242 visitNode(entry.key); | 242 visitNode(entry.key); |
| 243 visitNode(entry.value); | 243 visitNode(entry.value); |
| 244 } | 244 } |
| 245 | 245 |
| 246 void _visitArguments(ir.Arguments arguments) { | 246 void _visitArguments(ir.Arguments arguments) { |
| 247 arguments.positional.forEach(visitNode); | 247 arguments.positional.forEach(visitNode); |
| 248 arguments.named.forEach(visitNode); | 248 arguments.named.forEach(visitNode); |
| 249 } | 249 } |
| 250 | 250 |
| 251 @override | 251 @override |
| 252 void visitConstructorInvocation(ir.ConstructorInvocation node) { | 252 void visitConstructorInvocation(ir.ConstructorInvocation node) { |
| 253 handleNew(node, node.target, isConst: node.isConst); | 253 handleNew(node, node.target, isConst: node.isConst); |
| 254 } | 254 } |
| 255 | 255 |
| 256 void handleNew(ir.InvocationExpression node, ir.Member target, | 256 void handleNew(ir.InvocationExpression node, ir.Member target, |
| 257 {bool isConst: false}) { | 257 {bool isConst: false}) { |
| 258 _visitArguments(node.arguments); | 258 _visitArguments(node.arguments); |
| 259 ConstructorElement constructor = astAdapter.getConstructor(target); | 259 FunctionEntity constructor = astAdapter.getConstructor(target); |
| 260 ClassElement cls = astAdapter.getClass(target.enclosingClass); | 260 ClassEntity cls = astAdapter.getClass(target.enclosingClass); |
| 261 List<ResolutionDartType> typeArguments = | 261 List<DartType> typeArguments = |
| 262 astAdapter.getDartTypes(node.arguments.types); | 262 astAdapter.getDartTypes(node.arguments.types); |
| 263 ResolutionInterfaceType type = | 263 InterfaceType type = astAdapter.createInterfaceType(cls, typeArguments); |
| 264 new ResolutionInterfaceType(cls, typeArguments); | |
| 265 CallStructure callStructure = astAdapter.getCallStructure(node.arguments); | 264 CallStructure callStructure = astAdapter.getCallStructure(node.arguments); |
| 266 impactBuilder.registerStaticUse(isConst | 265 impactBuilder.registerStaticUse(isConst |
| 267 ? new StaticUse.constConstructorInvoke(constructor, callStructure, type) | 266 ? new StaticUse.constConstructorInvoke(constructor, callStructure, type) |
| 268 : new StaticUse.typedConstructorInvoke( | 267 : new StaticUse.typedConstructorInvoke( |
| 269 constructor, callStructure, type)); | 268 constructor, callStructure, type)); |
| 270 if (typeArguments.any((ResolutionDartType type) => !type.isDynamic)) { | 269 if (typeArguments.any((DartType type) => !type.isDynamic)) { |
| 271 impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK); | 270 impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK); |
| 272 } | 271 } |
| 273 } | 272 } |
| 274 | 273 |
| 275 @override | 274 @override |
| 276 void visitSuperInitializer(ir.SuperInitializer node) { | 275 void visitSuperInitializer(ir.SuperInitializer node) { |
| 277 ConstructorElement target = astAdapter.getConstructor(node.target); | 276 FunctionEntity target = astAdapter.getConstructor(node.target); |
| 278 _visitArguments(node.arguments); | 277 _visitArguments(node.arguments); |
| 279 impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke( | 278 impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke( |
| 280 target, astAdapter.getCallStructure(node.arguments))); | 279 target, astAdapter.getCallStructure(node.arguments))); |
| 281 } | 280 } |
| 282 | 281 |
| 283 @override | 282 @override |
| 284 void visitStaticInvocation(ir.StaticInvocation node) { | 283 void visitStaticInvocation(ir.StaticInvocation node) { |
| 285 MethodElement target = astAdapter.getMethod(node.target); | 284 FunctionEntity target = astAdapter.getMethod(node.target); |
| 286 if (target.isFactoryConstructor) { | 285 if (node.target.kind == ir.ProcedureKind.Factory) { |
| 287 // TODO(johnniwinther): We should not mark the type as instantiated but | 286 // TODO(johnniwinther): We should not mark the type as instantiated but |
| 288 // rather follow the type arguments directly. | 287 // rather follow the type arguments directly. |
| 289 // | 288 // |
| 290 // Consider this: | 289 // Consider this: |
| 291 // | 290 // |
| 292 // abstract class A<T> { | 291 // abstract class A<T> { |
| 293 // factory A.regular() => new B<T>(); | 292 // factory A.regular() => new B<T>(); |
| 294 // factory A.redirect() = B<T>; | 293 // factory A.redirect() = B<T>; |
| 295 // } | 294 // } |
| 296 // | 295 // |
| (...skipping 29 matching lines...) Expand all Loading... |
| 326 astAdapter.getNativeBehaviorForJsEmbeddedGlobalCall(node)); | 325 astAdapter.getNativeBehaviorForJsEmbeddedGlobalCall(node)); |
| 327 break; | 326 break; |
| 328 case ForeignKind.JS_INTERCEPTOR_CONSTANT: | 327 case ForeignKind.JS_INTERCEPTOR_CONSTANT: |
| 329 if (node.arguments.positional.length != 1 || | 328 if (node.arguments.positional.length != 1 || |
| 330 node.arguments.named.isNotEmpty) { | 329 node.arguments.named.isNotEmpty) { |
| 331 astAdapter.reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE, | 330 astAdapter.reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE, |
| 332 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 331 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
| 333 } | 332 } |
| 334 ir.Node argument = node.arguments.positional.first; | 333 ir.Node argument = node.arguments.positional.first; |
| 335 if (argument is ir.TypeLiteral && argument.type is ir.InterfaceType) { | 334 if (argument is ir.TypeLiteral && argument.type is ir.InterfaceType) { |
| 336 ResolutionInterfaceType type = astAdapter.getDartType(argument.type); | 335 InterfaceType type = astAdapter.getInterfaceType(argument.type); |
| 337 impactBuilder.registerTypeUse(new TypeUse.instantiation(type)); | 336 impactBuilder.registerTypeUse(new TypeUse.instantiation(type)); |
| 338 } | 337 } |
| 339 break; | 338 break; |
| 340 case ForeignKind.NONE: | 339 case ForeignKind.NONE: |
| 341 break; | 340 break; |
| 342 } | 341 } |
| 343 } | 342 } |
| 344 | 343 |
| 345 @override | 344 @override |
| 346 void visitStaticGet(ir.StaticGet node) { | 345 void visitStaticGet(ir.StaticGet node) { |
| 347 ir.Member target = node.target; | 346 ir.Member target = node.target; |
| 348 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { | 347 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { |
| 349 MethodElement method = astAdapter.getMethod(target); | 348 FunctionEntity method = astAdapter.getMethod(target); |
| 350 impactBuilder.registerStaticUse(new StaticUse.staticTearOff(method)); | 349 impactBuilder.registerStaticUse(new StaticUse.staticTearOff(method)); |
| 351 } else { | 350 } else { |
| 352 MemberElement member = astAdapter.getMember(target); | 351 MemberEntity member = astAdapter.getMember(target); |
| 353 impactBuilder.registerStaticUse(new StaticUse.staticGet(member)); | 352 impactBuilder.registerStaticUse(new StaticUse.staticGet(member)); |
| 354 } | 353 } |
| 355 } | 354 } |
| 356 | 355 |
| 357 @override | 356 @override |
| 358 void visitStaticSet(ir.StaticSet node) { | 357 void visitStaticSet(ir.StaticSet node) { |
| 359 visitNode(node.value); | 358 visitNode(node.value); |
| 360 MemberElement member = astAdapter.getMember(node.target); | 359 MemberEntity member = astAdapter.getMember(node.target); |
| 361 impactBuilder.registerStaticUse(new StaticUse.staticSet(member)); | 360 impactBuilder.registerStaticUse(new StaticUse.staticSet(member)); |
| 362 } | 361 } |
| 363 | 362 |
| 364 void handleSuperInvocation(ir.Node target, ir.Node arguments) { | 363 void handleSuperInvocation(ir.Node target, ir.Node arguments) { |
| 365 MethodElement method = astAdapter.getMethod(target); | 364 FunctionEntity method = astAdapter.getMethod(target); |
| 366 _visitArguments(arguments); | 365 _visitArguments(arguments); |
| 367 impactBuilder.registerStaticUse(new StaticUse.superInvoke( | 366 impactBuilder.registerStaticUse(new StaticUse.superInvoke( |
| 368 method, astAdapter.getCallStructure(arguments))); | 367 method, astAdapter.getCallStructure(arguments))); |
| 369 } | 368 } |
| 370 | 369 |
| 371 @override | 370 @override |
| 372 void visitDirectMethodInvocation(ir.DirectMethodInvocation node) { | 371 void visitDirectMethodInvocation(ir.DirectMethodInvocation node) { |
| 373 handleSuperInvocation(node.target, node.arguments); | 372 handleSuperInvocation(node.target, node.arguments); |
| 374 } | 373 } |
| 375 | 374 |
| 376 @override | 375 @override |
| 377 void visitSuperMethodInvocation(ir.SuperMethodInvocation node) { | 376 void visitSuperMethodInvocation(ir.SuperMethodInvocation node) { |
| 378 // TODO(johnniwinther): Should we support this or always use the | 377 // TODO(johnniwinther): Should we support this or always use the |
| 379 // [MixinFullResolution] transformer? | 378 // [MixinFullResolution] transformer? |
| 380 handleSuperInvocation(node.interfaceTarget, node.arguments); | 379 handleSuperInvocation(node.interfaceTarget, node.arguments); |
| 381 } | 380 } |
| 382 | 381 |
| 383 void handleSuperGet(ir.Member target) { | 382 void handleSuperGet(ir.Member target) { |
| 384 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { | 383 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { |
| 385 MethodElement method = astAdapter.getMethod(target); | 384 FunctionEntity method = astAdapter.getMethod(target); |
| 386 impactBuilder.registerStaticUse(new StaticUse.superTearOff(method)); | 385 impactBuilder.registerStaticUse(new StaticUse.superTearOff(method)); |
| 387 } else { | 386 } else { |
| 388 MemberElement member = astAdapter.getMember(target); | 387 MemberEntity member = astAdapter.getMember(target); |
| 389 impactBuilder.registerStaticUse(new StaticUse.superGet(member)); | 388 impactBuilder.registerStaticUse(new StaticUse.superGet(member)); |
| 390 } | 389 } |
| 391 } | 390 } |
| 392 | 391 |
| 393 @override | 392 @override |
| 394 void visitDirectGet(ir.StaticGet node) { | 393 void visitDirectGet(ir.StaticGet node) { |
| 395 handleSuperGet(node.target); | 394 handleSuperGet(node.target); |
| 396 } | 395 } |
| 397 | 396 |
| 398 @override | 397 @override |
| 399 void visitSuperPropertyGet(ir.SuperPropertyGet node) { | 398 void visitSuperPropertyGet(ir.SuperPropertyGet node) { |
| 400 handleSuperGet(node.interfaceTarget); | 399 handleSuperGet(node.interfaceTarget); |
| 401 } | 400 } |
| 402 | 401 |
| 403 void handleSuperSet(ir.Node target, ir.Node value) { | 402 void handleSuperSet(ir.Node target, ir.Node value) { |
| 404 visitNode(value); | 403 visitNode(value); |
| 405 if (target is ir.Field) { | 404 if (target is ir.Field) { |
| 406 FieldElement field = astAdapter.getField(target); | 405 FieldEntity field = astAdapter.getField(target); |
| 407 impactBuilder.registerStaticUse(new StaticUse.superFieldSet(field)); | 406 impactBuilder.registerStaticUse(new StaticUse.superFieldSet(field)); |
| 408 } else { | 407 } else { |
| 409 MethodElement method = astAdapter.getMethod(target); | 408 FunctionEntity method = astAdapter.getMethod(target); |
| 410 impactBuilder.registerStaticUse(new StaticUse.superSetterSet(method)); | 409 impactBuilder.registerStaticUse(new StaticUse.superSetterSet(method)); |
| 411 } | 410 } |
| 412 } | 411 } |
| 413 | 412 |
| 414 @override | 413 @override |
| 415 void visitDirectPropertySet(ir.DirectPropertySet node) { | 414 void visitDirectPropertySet(ir.DirectPropertySet node) { |
| 416 handleSuperSet(node.target, node.value); | 415 handleSuperSet(node.target, node.value); |
| 417 } | 416 } |
| 418 | 417 |
| 419 @override | 418 @override |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 @override | 561 @override |
| 563 void visitFieldInitializer(ir.FieldInitializer node) { | 562 void visitFieldInitializer(ir.FieldInitializer node) { |
| 564 impactBuilder.registerStaticUse( | 563 impactBuilder.registerStaticUse( |
| 565 new StaticUse.fieldInit(astAdapter.getField(node.field))); | 564 new StaticUse.fieldInit(astAdapter.getField(node.field))); |
| 566 visitNode(node.value); | 565 visitNode(node.value); |
| 567 } | 566 } |
| 568 | 567 |
| 569 @override | 568 @override |
| 570 void visitRedirectingInitializer(ir.RedirectingInitializer node) { | 569 void visitRedirectingInitializer(ir.RedirectingInitializer node) { |
| 571 _visitArguments(node.arguments); | 570 _visitArguments(node.arguments); |
| 572 Element target = astAdapter.getElement(node.target).declaration; | 571 FunctionEntity target = astAdapter.getConstructor(node.target); |
| 573 impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke( | 572 impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke( |
| 574 target, astAdapter.getCallStructure(node.arguments))); | 573 target, astAdapter.getCallStructure(node.arguments))); |
| 575 } | 574 } |
| 576 | 575 |
| 577 // TODO(johnniwinther): Make this throw and visit child nodes explicitly | 576 // TODO(johnniwinther): Make this throw and visit child nodes explicitly |
| 578 // instead to ensure that we don't visit unwanted parts of the ir. | 577 // instead to ensure that we don't visit unwanted parts of the ir. |
| 579 @override | 578 @override |
| 580 void defaultNode(ir.Node node) => node.visitChildren(this); | 579 void defaultNode(ir.Node node) => node.visitChildren(this); |
| 581 } | 580 } |
| OLD | NEW |