| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:expect/expect.dart'; |
| import 'package:async_helper/async_helper.dart'; |
| import 'package:compiler/src/commandline_options.dart'; |
| import 'package:compiler/src/compiler.dart'; |
| import 'package:compiler/src/common_elements.dart'; |
| import 'package:compiler/src/elements/entities.dart'; |
| import 'package:compiler/src/universe/world_builder.dart'; |
| import 'package:compiler/src/world.dart'; |
| import '../memory_compiler.dart'; |
| |
| main() { |
| useStrongModeWorldStrategy = true; |
| asyncTest(() async { |
| print('--test from non-strong mode---------------------------------------'); |
| await runTest(strongMode: false); |
| print('--test from strong mode-------------------------------------------'); |
| await runTest(strongMode: true); |
| }); |
| } |
| |
| runTest({bool strongMode}) async { |
| CompilationResult result = await runCompiler(memorySourceFiles: { |
| 'main.dart': ''' |
| class A { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class B { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class C extends A { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class D implements B { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class E implements A { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class F extends B { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class G { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class H extends Object with G implements A {} |
| |
| class I { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class J extends I implements A {} |
| |
| class K { |
| method1() {} |
| method2() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class L = Object with K; |
| class L2 = Object with L; |
| class M extends L {} |
| class M2 extends L2 {} |
| |
| class N { |
| method1() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| abstract class O extends N {} |
| |
| class P implements O { |
| method1() {} |
| get getter => 42; |
| set setter(_) {} |
| } |
| |
| class Q { |
| method3() {} |
| } |
| |
| class R extends Q {} |
| |
| main() { |
| A a = new A(); |
| B b = new B(); |
| a.method1(); |
| a.getter; |
| b.method2(); |
| b.setter = 42; |
| new C(); |
| new D(); |
| new H(); |
| new J(); |
| new M().method1(); |
| new M2().getter; |
| new N(); |
| O o = new P(); |
| o.method1(); |
| o.getter; |
| o.setter = 42; |
| R r; |
| r.method3(); |
| r = new R(); // Create R after call. |
| } |
| ''' |
| }, options: strongMode ? [Flags.strongMode] : [Flags.noPreviewDart2]); |
| Expect.isTrue(result.isSuccess); |
| Compiler compiler = result.compiler; |
| |
| Map<String, List<String>> expectedLiveMembersMap = <String, List<String>>{ |
| 'A': strongMode |
| ? ['method1', 'getter'] |
| : ['method1', 'method2', 'getter', 'setter'], |
| 'B': strongMode |
| ? ['method2', 'setter'] |
| : ['method1', 'method2', 'getter', 'setter'], |
| 'C': strongMode |
| ? ['method1', 'getter'] |
| : ['method1', 'method2', 'getter', 'setter'], |
| 'D': strongMode |
| ? ['method2', 'setter'] |
| : ['method1', 'method2', 'getter', 'setter'], |
| 'G': strongMode |
| ? ['method1', 'getter'] |
| : ['method1', 'method2', 'getter', 'setter'], |
| 'I': strongMode |
| ? ['method1', 'getter'] |
| : ['method1', 'method2', 'getter', 'setter'], |
| 'K': strongMode |
| ? ['method1', 'getter'] |
| : ['method1', 'method2', 'getter', 'setter'], |
| 'N': strongMode ? [] : ['method1', 'getter', 'setter'], |
| 'P': ['method1', 'getter', 'setter'], |
| 'Q': ['method3'], |
| }; |
| |
| KClosedWorld closedWorld = |
| compiler.resolutionWorldBuilder.closedWorldForTesting; |
| ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; |
| |
| elementEnvironment.forEachClass(elementEnvironment.mainLibrary, |
| (ClassEntity cls) { |
| List<String> expectedLiveMembers = |
| expectedLiveMembersMap[cls.name] ?? const <String>[]; |
| List<String> actualLiveMembers = <String>[]; |
| closedWorld.processedMembers.forEach((MemberEntity member) { |
| if (member.enclosingClass != cls) return; |
| if (member.isConstructor) return; |
| actualLiveMembers.add(member.name); |
| }); |
| Expect.setEquals( |
| expectedLiveMembers, |
| actualLiveMembers, |
| "Unexpected live members for $cls " |
| "in ${strongMode ? 'Dart 2' : 'Dart 1'}. \n" |
| "Expected members for ${cls.name}: $expectedLiveMembers\n" |
| "Actual members for ${cls.name} : $actualLiveMembers"); |
| }); |
| } |