| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file | 
|  | 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. | 
|  | 4 | 
|  | 5 // Test that the optimized algorithm for mixin applications matches the mixins | 
|  | 6 // generated by fasta. | 
|  | 7 library dart2js.kernel.mixins_test; | 
|  | 8 | 
|  | 9 import 'package:async_helper/async_helper.dart'; | 
|  | 10 import 'package:compiler/src/commandline_options.dart'; | 
|  | 11 import 'package:compiler/src/common_elements.dart'; | 
|  | 12 import 'package:compiler/src/compiler.dart'; | 
|  | 13 import 'package:compiler/src/elements/entities.dart'; | 
|  | 14 import 'package:compiler/src/elements/types.dart'; | 
|  | 15 import 'package:compiler/src/kernel/kernel_strategy.dart'; | 
|  | 16 import 'package:compiler/src/resolution/class_hierarchy.dart'; | 
|  | 17 import 'package:compiler/src/universe/class_set.dart'; | 
|  | 18 import 'package:compiler/src/world.dart'; | 
|  | 19 import 'package:expect/expect.dart'; | 
|  | 20 import '../memory_compiler.dart'; | 
|  | 21 import '../equivalence/check_helpers.dart'; | 
|  | 22 import 'test_helpers.dart'; | 
|  | 23 import 'compiler_helper.dart'; | 
|  | 24 | 
|  | 25 const SOURCE = const { | 
|  | 26   'main.dart': ''' | 
|  | 27 | 
|  | 28 class Super {} | 
|  | 29 class Mixin1 {} | 
|  | 30 class Mixin2 {} | 
|  | 31 class Sub1 extends Super with Mixin1 {} | 
|  | 32 class Sub2 extends Super with Mixin1, Mixin2 {} | 
|  | 33 class NamedSub1 = Super with Mixin1; | 
|  | 34 class NamedSub2 = Super with Mixin1, Mixin2; | 
|  | 35 | 
|  | 36 | 
|  | 37 class GenericSuper<T> {} | 
|  | 38 class GenericMixin1<T> {} | 
|  | 39 class GenericMixin2<T> {} | 
|  | 40 class GenericSub1<T> extends GenericSuper<T> with GenericMixin1<T> {} | 
|  | 41 class GenericSub2<T> extends GenericSuper<T> | 
|  | 42     with GenericMixin1<T>, GenericMixin2<T> {} | 
|  | 43 class GenericNamedSub1<T> = GenericSuper<T> with GenericMixin1<T>; | 
|  | 44 class GenericNamedSub2<T> = GenericSuper<T> | 
|  | 45     with GenericMixin1<T>, GenericMixin2<T>; | 
|  | 46 | 
|  | 47 class FixedSub1a extends GenericSuper<int> with GenericMixin1<int> {} | 
|  | 48 class FixedSub1b extends GenericSuper<int> with GenericMixin1<double> {} | 
|  | 49 class FixedSub2a extends GenericSuper<int> | 
|  | 50     with GenericMixin1<int>, GenericMixin2<int> {} | 
|  | 51 class FixedSub2b extends GenericSuper<double> | 
|  | 52     with GenericMixin1<double>, GenericMixin2<double> {} | 
|  | 53 | 
|  | 54 | 
|  | 55 main() { | 
|  | 56   new Super(); | 
|  | 57   new Mixin1(); | 
|  | 58   new Mixin2(); | 
|  | 59   new Sub1(); | 
|  | 60   new Sub2(); | 
|  | 61   new NamedSub1(); | 
|  | 62   new NamedSub2(); | 
|  | 63 | 
|  | 64   new GenericSuper<int>(); | 
|  | 65   new GenericMixin1<int>(); | 
|  | 66   new GenericMixin2<int>(); | 
|  | 67   new GenericSub1<int>(); | 
|  | 68   new GenericSub2<int>(); | 
|  | 69   new GenericNamedSub1<int>(); | 
|  | 70   new GenericNamedSub2<int>(); | 
|  | 71 | 
|  | 72   new FixedSub1a(); | 
|  | 73   new FixedSub1b(); | 
|  | 74   new FixedSub2a(); | 
|  | 75   new FixedSub2b(); | 
|  | 76 } | 
|  | 77 ''' | 
|  | 78 }; | 
|  | 79 | 
|  | 80 Map<ClassEntity, String> generateClassEnv( | 
|  | 81     ElementEnvironment env, DartTypes types) { | 
|  | 82   Map<ClassEntity, String> classEnv = <ClassEntity, String>{}; | 
|  | 83 | 
|  | 84   void createEnv(ClassEntity cls) { | 
|  | 85     classEnv.putIfAbsent(cls, () { | 
|  | 86       InterfaceType thisType = env.getThisType(cls); | 
|  | 87       StringBuffer sb = new StringBuffer(); | 
|  | 88       sb.write('class '); | 
|  | 89       sb.write(env.getThisType(cls)); | 
|  | 90       ClassEntity superclass = env.getSuperClass(cls); | 
|  | 91       if (superclass != null) { | 
|  | 92         createEnv(superclass); | 
|  | 93         sb.write(' extends '); | 
|  | 94         sb.write(types.asInstanceOf(thisType, superclass)); | 
|  | 95       } | 
|  | 96       return sb.toString(); | 
|  | 97     }); | 
|  | 98   } | 
|  | 99 | 
|  | 100   env.forEachClass(env.mainLibrary, createEnv); | 
|  | 101 | 
|  | 102   return classEnv; | 
|  | 103 } | 
|  | 104 | 
|  | 105 main(List<String> args) { | 
|  | 106   asyncTest(() async { | 
|  | 107     useOptimizedMixins = true; | 
|  | 108 | 
|  | 109     Uri entryPoint = await createTemp(Uri.parse('memory:main.dart'), SOURCE, | 
|  | 110         printSteps: true); | 
|  | 111 | 
|  | 112     print( | 
|  | 113         '---- compiler from ast -----------------------------------------------'
     ); | 
|  | 114     var result = | 
|  | 115         await runCompiler(entryPoint: entryPoint, options: [Flags.analyzeOnly]); | 
|  | 116     Compiler compiler1 = result.compiler; | 
|  | 117 | 
|  | 118     Compiler compiler2 = await compileWithDill( | 
|  | 119         entryPoint, {}, [Flags.analyzeOnly], | 
|  | 120         printSteps: true); | 
|  | 121 | 
|  | 122     ElementEnvironment env1 = compiler1.frontendStrategy.elementEnvironment; | 
|  | 123     DartTypes types1 = compiler1.frontendStrategy.dartTypes; | 
|  | 124     ClosedWorld closedWorld1 = compiler1.resolutionWorldBuilder.closeWorld(); | 
|  | 125 | 
|  | 126     KernelFrontEndStrategy frontendStrategy = compiler2.frontendStrategy; | 
|  | 127     ElementEnvironment env2 = frontendStrategy.elementEnvironment; | 
|  | 128     DartTypes types2 = frontendStrategy.dartTypes; | 
|  | 129     ClosedWorld closedWorld2 = compiler2.resolutionWorldBuilder.closeWorld(); | 
|  | 130 | 
|  | 131     KernelEquivalence equivalence = | 
|  | 132         new KernelEquivalence(frontendStrategy.elementMap); | 
|  | 133 | 
|  | 134     if (args.contains('-v')) { | 
|  | 135       Map<ClassEntity, String> classEnv1 = generateClassEnv(env1, types1); | 
|  | 136       Map<ClassEntity, String> classEnv2 = generateClassEnv(env2, types2); | 
|  | 137 | 
|  | 138       print('----'); | 
|  | 139       classEnv1.forEach((ClassEntity cls, String env) { | 
|  | 140         print(env); | 
|  | 141       }); | 
|  | 142       print('----'); | 
|  | 143       classEnv2.forEach((ClassEntity cls, String env) { | 
|  | 144         print(env); | 
|  | 145       }); | 
|  | 146     } | 
|  | 147 | 
|  | 148     void checkClasses(ClassEntity cls1, ClassEntity cls2) { | 
|  | 149       if (cls1 == cls2) return; | 
|  | 150       Expect.isNotNull(cls1, 'Missing class ${cls2.name}'); | 
|  | 151       Expect.isNotNull(cls2, 'Missing class ${cls1.name}'); | 
|  | 152 | 
|  | 153       check(cls1.library, cls2.library, 'class ${cls1.name}', cls1, cls2, | 
|  | 154           equivalence.entityEquivalence); | 
|  | 155       InterfaceType thisType1 = types1.getThisType(cls1); | 
|  | 156       InterfaceType thisType2 = types2.getThisType(cls2); | 
|  | 157       check(cls1, cls2, 'thisType', thisType1, thisType2, | 
|  | 158           equivalence.typeEquivalence); | 
|  | 159       check(cls1, cls2, 'supertype', types1.getSupertype(cls1), | 
|  | 160           types2.getSupertype(cls2), equivalence.typeEquivalence); | 
|  | 161       checkClasses(env1.getSuperClass(cls1), env2.getSuperClass(cls2)); | 
|  | 162 | 
|  | 163       List<DartType> mixins1 = <DartType>[]; | 
|  | 164       env1.forEachMixin(cls1, (ClassEntity mixin) { | 
|  | 165         mixins1.add(types1.asInstanceOf(thisType1, mixin)); | 
|  | 166       }); | 
|  | 167       List<DartType> mixins2 = <DartType>[]; | 
|  | 168       env2.forEachMixin(cls2, (ClassEntity mixin) { | 
|  | 169         mixins2.add(types2.asInstanceOf(thisType2, mixin)); | 
|  | 170       }); | 
|  | 171       checkLists( | 
|  | 172           mixins1, mixins2, '${cls1.name} mixins', equivalence.typeEquivalence); | 
|  | 173 | 
|  | 174       checkLists( | 
|  | 175           types1.getInterfaces(cls1).toList(), | 
|  | 176           types2.getInterfaces(cls2).toList(), | 
|  | 177           '${cls1.name} interfaces', | 
|  | 178           equivalence.typeEquivalence); | 
|  | 179       checkLists( | 
|  | 180           types1.getSupertypes(cls1).toList(), | 
|  | 181           types2.getSupertypes(cls2).toList(), | 
|  | 182           '${cls1.name} supertypes', | 
|  | 183           equivalence.typeEquivalence); | 
|  | 184 | 
|  | 185       if (cls1 == compiler1.frontendStrategy.commonElements.objectClass) return; | 
|  | 186 | 
|  | 187       ClassHierarchyNode node1 = closedWorld1.getClassHierarchyNode(cls1); | 
|  | 188       ClassHierarchyNode node2 = closedWorld2.getClassHierarchyNode(cls2); | 
|  | 189       checkSets( | 
|  | 190           new Set.from(node1.directSubclasses), | 
|  | 191           new Set.from(node2.directSubclasses), | 
|  | 192           '${cls1.name} direct subclasses', | 
|  | 193           (a, b) => equivalence.entityEquivalence(a.cls, b.cls)); | 
|  | 194     } | 
|  | 195 | 
|  | 196     env1.forEachClass(env1.mainLibrary, (ClassEntity cls1) { | 
|  | 197       ClassEntity cls2 = env2.lookupClass(env2.mainLibrary, cls1.name); | 
|  | 198       checkClasses(cls1, cls2); | 
|  | 199     }); | 
|  | 200   }); | 
|  | 201 } | 
| OLD | NEW | 
|---|