| 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 library dart2js.kernel.impact_test; | 5 library dart2js.kernel.impact_test; |
| 6 | 6 |
| 7 import 'package:async_helper/async_helper.dart'; | 7 import 'package:async_helper/async_helper.dart'; |
| 8 import 'package:compiler/src/commandline_options.dart'; | |
| 9 import 'package:compiler/src/common.dart'; | 8 import 'package:compiler/src/common.dart'; |
| 9 import 'package:compiler/src/common_elements.dart'; |
| 10 import 'package:compiler/src/common/names.dart'; | 10 import 'package:compiler/src/common/names.dart'; |
| 11 import 'package:compiler/src/common/resolution.dart'; | 11 import 'package:compiler/src/common/resolution.dart'; |
| 12 import 'package:compiler/src/compiler.dart'; | 12 import 'package:compiler/src/compiler.dart'; |
| 13 import 'package:compiler/src/constants/expressions.dart'; | 13 import 'package:compiler/src/constants/expressions.dart'; |
| 14 import 'package:compiler/src/elements/elements.dart'; | 14 import 'package:compiler/src/elements/elements.dart'; |
| 15 import 'package:compiler/src/elements/entities.dart'; | 15 import 'package:compiler/src/elements/entities.dart'; |
| 16 import 'package:compiler/src/elements/resolution_types.dart'; | 16 import 'package:compiler/src/elements/resolution_types.dart'; |
| 17 import 'package:compiler/src/js_backend/backend.dart'; | |
| 18 import 'package:compiler/src/kernel/element_map.dart'; | |
| 19 import 'package:compiler/src/kernel/element_map_impl.dart'; | 17 import 'package:compiler/src/kernel/element_map_impl.dart'; |
| 18 import 'package:compiler/src/kernel/kernel_strategy.dart'; |
| 20 import 'package:compiler/src/resolution/registry.dart'; | 19 import 'package:compiler/src/resolution/registry.dart'; |
| 21 import 'package:compiler/src/resolution/tree_elements.dart'; | 20 import 'package:compiler/src/resolution/tree_elements.dart'; |
| 22 import 'package:compiler/src/ssa/kernel_impact.dart'; | |
| 23 import 'package:compiler/src/serialization/equivalence.dart'; | 21 import 'package:compiler/src/serialization/equivalence.dart'; |
| 24 import 'package:compiler/src/universe/call_structure.dart'; | 22 import 'package:compiler/src/universe/call_structure.dart'; |
| 25 import 'package:compiler/src/universe/feature.dart'; | 23 import 'package:compiler/src/universe/feature.dart'; |
| 26 import 'package:compiler/src/universe/use.dart'; | 24 import 'package:compiler/src/universe/use.dart'; |
| 27 import 'package:expect/expect.dart'; | 25 import 'package:compiler/src/util/util.dart'; |
| 28 import 'package:kernel/ast.dart' as ir; | |
| 29 import '../memory_compiler.dart'; | |
| 30 import '../equivalence/check_helpers.dart'; | 26 import '../equivalence/check_helpers.dart'; |
| 27 import 'compiler_helper.dart'; |
| 31 import 'test_helpers.dart'; | 28 import 'test_helpers.dart'; |
| 32 | 29 |
| 33 const Map<String, String> SOURCE = const <String, String>{ | 30 const Map<String, String> SOURCE = const <String, String>{ |
| 34 // Pretend this is a dart2js_native test to allow use of 'native' keyword. | 31 // Pretend this is a dart2js_native test to allow use of 'native' keyword. |
| 35 'sdk/tests/compiler/dart2js_native/main.dart': r''' | 32 'sdk/tests/compiler/dart2js_native/main.dart': r''' |
| 36 import 'dart:_foreign_helper'; | 33 import 'dart:_foreign_helper'; |
| 37 import 'dart:_js_helper'; | 34 import 'dart:_js_helper'; |
| 38 import 'dart:_interceptors'; | 35 import 'dart:_interceptors'; |
| 39 import 'dart:_native_typed_data'; | 36 import 'dart:_native_typed_data'; |
| 40 import 'dart:indexed_db'; | 37 import 'dart:indexed_db'; |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 with GenericMixin1<X5, Y5>, GenericMixin2<X5, Y5>; | 724 with GenericMixin1<X5, Y5>, GenericMixin2<X5, Y5>; |
| 728 ''', | 725 ''', |
| 729 }; | 726 }; |
| 730 | 727 |
| 731 main(List<String> args) { | 728 main(List<String> args) { |
| 732 bool fullTest = args.contains('--full'); | 729 bool fullTest = args.contains('--full'); |
| 733 asyncTest(() async { | 730 asyncTest(() async { |
| 734 enableDebugMode(); | 731 enableDebugMode(); |
| 735 Uri entryPoint = | 732 Uri entryPoint = |
| 736 Uri.parse('memory:sdk/tests/compiler/dart2js_native/main.dart'); | 733 Uri.parse('memory:sdk/tests/compiler/dart2js_native/main.dart'); |
| 737 Compiler compiler = compilerFor( | |
| 738 entryPoint: entryPoint, | |
| 739 memorySourceFiles: SOURCE, | |
| 740 options: [ | |
| 741 fullTest ? Flags.analyzeAll : Flags.analyzeOnly, | |
| 742 Flags.useKernelInSsa, | |
| 743 Flags.enableAssertMessage | |
| 744 ]); | |
| 745 compiler.resolution.retainCachesForTesting = true; | |
| 746 Expect.isTrue(await compiler.run(entryPoint)); | |
| 747 JavaScriptBackend backend = compiler.backend; | |
| 748 KernelToElementMapForImpact kernelElementMap = | |
| 749 new KernelToElementMapForImpactImpl( | |
| 750 compiler.reporter, compiler.environment, compiler.frontendStrategy); | |
| 751 kernelElementMap.addProgram(backend.kernelTask.program); | |
| 752 | 734 |
| 753 LibraryElement mainApp = | 735 Pair<Compiler, Compiler> pair = |
| 754 compiler.frontendStrategy.elementEnvironment.mainLibrary; | 736 await analyzeOnly(entryPoint, SOURCE, printSteps: true); |
| 755 checkLibrary(compiler, kernelElementMap, mainApp, fullTest: fullTest); | 737 Compiler compiler1 = pair.a; |
| 756 compiler.libraryLoader.libraries.forEach((LibraryEntity library) { | 738 Compiler compiler2 = pair.b; |
| 757 if (library == mainApp) return; | 739 ElementEnvironment elementEnvironment1 = |
| 758 checkLibrary(compiler, kernelElementMap, library, fullTest: fullTest); | 740 compiler1.frontendStrategy.elementEnvironment; |
| 741 ElementEnvironment elementEnvironment2 = |
| 742 compiler2.frontendStrategy.elementEnvironment; |
| 743 KernelFrontEndStrategy kernelStrategy = compiler2.frontendStrategy; |
| 744 KernelToElementMapForImpactImpl elementMap = kernelStrategy.elementMap; |
| 745 KernelEquivalence equivalence = new KernelEquivalence(elementMap); |
| 746 |
| 747 void checkMembers(MemberEntity member1, MemberEntity member2) { |
| 748 if (!fullTest && !compiler1.resolution.hasResolutionImpact(member1)) { |
| 749 print('Skipping member without impact: $member1'); |
| 750 return; |
| 751 } |
| 752 compiler1.reporter.withCurrentElement(member1, () { |
| 753 ResolutionImpact astImpact = |
| 754 compiler1.resolution.getResolutionImpact(member1); |
| 755 astImpact = laxImpact(compiler1, member1, astImpact); |
| 756 ResolutionImpact kernelImpact = elementMap.computeWorldImpact(member2); |
| 757 testResolutionImpactEquivalence(astImpact, kernelImpact, |
| 758 strategy: new CheckStrategy( |
| 759 elementEquivalence: equivalence.entityEquivalence, |
| 760 typeEquivalence: equivalence.typeEquivalence)); |
| 761 }); |
| 762 } |
| 763 |
| 764 void checkLibraries(LibraryEntity library1, LibraryEntity library2) { |
| 765 if (!fullTest && library1.canonicalUri.scheme == 'dart') { |
| 766 print('Skipping library: $library1'); |
| 767 return; |
| 768 } |
| 769 elementEnvironment1.forEachClass(library1, (ClassEntity cls1) { |
| 770 ClassEntity cls2 = elementEnvironment2.lookupClass(library2, cls1.name); |
| 771 elementEnvironment1.forEachClassMember(cls1, |
| 772 (ClassEntity declarer, MemberEntity member1) { |
| 773 if (declarer != cls1) return; |
| 774 MemberEntity member2 = elementEnvironment2 |
| 775 .lookupClassMember(cls2, member1.name, setter: member1.isSetter); |
| 776 checkMembers(member1, member2); |
| 777 }); |
| 778 elementEnvironment1.forEachConstructor(cls1, |
| 779 (ConstructorEntity constructor1) { |
| 780 ConstructorEntity constructor2 = |
| 781 elementEnvironment2.lookupConstructor(cls2, constructor1.name); |
| 782 checkMembers(constructor1, constructor2); |
| 783 }); |
| 784 }); |
| 785 |
| 786 elementEnvironment1.forEachLibraryMember(library1, |
| 787 (MemberEntity member1) { |
| 788 MemberEntity member2 = elementEnvironment2.lookupLibraryMember( |
| 789 library2, member1.name, |
| 790 setter: member1.isSetter); |
| 791 checkMembers(member1, member2); |
| 792 }); |
| 793 } |
| 794 |
| 795 checkLibraries( |
| 796 elementEnvironment1.mainLibrary, elementEnvironment2.mainLibrary); |
| 797 elementEnvironment1.libraries.forEach((LibraryEntity library1) { |
| 798 if (library1 == elementEnvironment1.mainLibrary) return; |
| 799 LibraryEntity library2 = |
| 800 elementEnvironment2.lookupLibrary(library1.canonicalUri); |
| 801 checkLibraries(library1, library2); |
| 759 }); | 802 }); |
| 760 }); | 803 }); |
| 761 } | 804 } |
| 762 | 805 |
| 763 void checkLibrary(Compiler compiler, KernelToElementMapForImpact elementMap, | |
| 764 LibraryElement library, | |
| 765 {bool fullTest: false}) { | |
| 766 library.forEachLocalMember((_element) { | |
| 767 AstElement element = _element; | |
| 768 if (element.isClass) { | |
| 769 ClassElement cls = element; | |
| 770 cls.forEachLocalMember((_member) { | |
| 771 AstElement member = _member; | |
| 772 checkElement(compiler, elementMap, member, fullTest: fullTest); | |
| 773 }); | |
| 774 } else if (element.isTypedef) { | |
| 775 // Skip typedefs. | |
| 776 } else { | |
| 777 checkElement(compiler, elementMap, element, fullTest: fullTest); | |
| 778 } | |
| 779 }); | |
| 780 } | |
| 781 | |
| 782 void checkElement(Compiler compiler, KernelToElementMapForImpact elementMap, | |
| 783 AstElement element, | |
| 784 {bool fullTest: false}) { | |
| 785 if (!fullTest && element.library.isPlatformLibrary) { | |
| 786 return; | |
| 787 } | |
| 788 if (element.isConstructor) { | |
| 789 ConstructorElement constructor = element; | |
| 790 if (constructor.isRedirectingFactory) { | |
| 791 // Skip redirecting constructors for now; they might not be supported. | |
| 792 return; | |
| 793 } | |
| 794 } | |
| 795 if (!fullTest && !compiler.resolution.hasResolutionImpact(element)) { | |
| 796 return; | |
| 797 } | |
| 798 compiler.reporter.withCurrentElement(element.implementation, () { | |
| 799 ResolutionImpact astImpact = | |
| 800 compiler.resolution.getResolutionImpact(element); | |
| 801 astImpact = laxImpact(compiler, element, astImpact); | |
| 802 ResolutionImpact kernelImpact1 = build(compiler, element.resolvedAst); | |
| 803 ir.Member member = getIrMember(compiler, element.resolvedAst); | |
| 804 Expect.isNotNull(kernelImpact1, 'No impact computed for $element'); | |
| 805 ResolutionImpact kernelImpact2 = buildKernelImpact(member, elementMap); | |
| 806 Expect.isNotNull(kernelImpact2, 'No impact computed for $member'); | |
| 807 testResolutionImpactEquivalence(astImpact, kernelImpact1, | |
| 808 strategy: const CheckStrategy()); | |
| 809 KernelEquivalence equivalence = new KernelEquivalence(elementMap); | |
| 810 testResolutionImpactEquivalence(astImpact, kernelImpact2, | |
| 811 strategy: new CheckStrategy( | |
| 812 elementEquivalence: equivalence.entityEquivalence, | |
| 813 typeEquivalence: equivalence.typeEquivalence)); | |
| 814 }); | |
| 815 } | |
| 816 | |
| 817 /// Lax the precision of [impact] to meet expectancy of the corresponding impact | 806 /// Lax the precision of [impact] to meet expectancy of the corresponding impact |
| 818 /// generated from kernel. | 807 /// generated from kernel. |
| 819 ResolutionImpact laxImpact( | 808 ResolutionImpact laxImpact( |
| 820 Compiler compiler, AstElement element, ResolutionImpact impact) { | 809 Compiler compiler, MemberElement element, ResolutionImpact impact) { |
| 821 ResolutionWorldImpactBuilder builder = | 810 ResolutionWorldImpactBuilder builder = |
| 822 new ResolutionWorldImpactBuilder('Lax impact of ${element}'); | 811 new ResolutionWorldImpactBuilder('Lax impact of ${element}'); |
| 823 for (StaticUse staticUse in impact.staticUses) { | 812 for (StaticUse staticUse in impact.staticUses) { |
| 824 switch (staticUse.kind) { | 813 switch (staticUse.kind) { |
| 825 case StaticUseKind.CONSTRUCTOR_INVOKE: | 814 case StaticUseKind.CONSTRUCTOR_INVOKE: |
| 826 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 815 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 827 ConstructorElement constructor = staticUse.element; | 816 ConstructorElement constructor = staticUse.element; |
| 828 ConstructorElement effectiveTarget = constructor.effectiveTarget; | 817 ConstructorElement effectiveTarget = constructor.effectiveTarget; |
| 829 ResolutionDartType effectiveTargetType = | 818 ResolutionDartType effectiveTargetType = |
| 830 constructor.computeEffectiveTargetType(staticUse.type); | 819 constructor.computeEffectiveTargetType(staticUse.type); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 builder.registerFeature(Feature.THROW_EXPRESSION); | 892 builder.registerFeature(Feature.THROW_EXPRESSION); |
| 904 break; | 893 break; |
| 905 default: | 894 default: |
| 906 builder.registerFeature(feature); | 895 builder.registerFeature(feature); |
| 907 break; | 896 break; |
| 908 } | 897 } |
| 909 } | 898 } |
| 910 impact.nativeData.forEach(builder.registerNativeData); | 899 impact.nativeData.forEach(builder.registerNativeData); |
| 911 return builder; | 900 return builder; |
| 912 } | 901 } |
| OLD | NEW |