Chromium Code Reviews| Index: tests/compiler/dart2js/needs_no_such_method_test.dart |
| diff --git a/tests/compiler/dart2js/needs_no_such_method_test.dart b/tests/compiler/dart2js/needs_no_such_method_test.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..19997bcc6abeb3db0c387343d12e6c34371638cc |
| --- /dev/null |
| +++ b/tests/compiler/dart2js/needs_no_such_method_test.dart |
| @@ -0,0 +1,293 @@ |
| +// Copyright (c) 2016, 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 'dart:async'; |
| +import 'package:async_helper/async_helper.dart'; |
| +import 'package:expect/expect.dart'; |
| +import 'package:compiler/src/common.dart'; |
| +import 'package:compiler/src/elements/elements.dart' |
| + show Element, ClassElement, PublicName; |
| +import 'package:compiler/src/universe/call_structure.dart'; |
| +import 'package:compiler/src/universe/selector.dart'; |
| +import 'package:compiler/src/world.dart' show ClosedWorld, ClassMask; |
| +import 'type_test_helper.dart'; |
| + |
| +void main() { |
| + asyncTest(() async { |
| + await testClassSets(); |
| + }); |
| +} |
| + |
| +const String CLASSES = r""" |
| +class Superclass { |
| + foo() {} |
| +} |
| +class Subclass extends Superclass { |
| + bar() {} |
| +} |
| +class Subtype implements Superclass { |
| + bar() {} |
| +} |
| +"""; |
| + |
| +testClassSets() async { |
| + Selector foo, bar, baz; |
| + ClosedWorld closedWorld; |
| + ClassElement Superclass, Subclass, Subtype; |
|
Siggi Cherem (dart-lang)
2016/10/14 16:49:57
nit: I'm torn on this, I think I'm leaning towards
Johnni Winther
2016/10/17 07:57:40
Done.
|
| + |
| + Future run(List<String> instantiated) async { |
| + StringBuffer main = new StringBuffer(); |
| + main.write('main() {'); |
| + for (String cls in instantiated) { |
| + main.write('new $cls();'); |
| + } |
| + main.write('}'); |
| + |
| + var env = await TypeEnvironment.create(CLASSES, |
| + mainSource: main.toString(), useMockCompiler: false); |
| + foo = new Selector.call(const PublicName('foo'), CallStructure.NO_ARGS); |
| + bar = new Selector.call(const PublicName('bar'), CallStructure.NO_ARGS); |
| + baz = new Selector.call(const PublicName('baz'), CallStructure.NO_ARGS); |
| + |
| + closedWorld = env.compiler.closedWorld; |
| + Superclass = env.getElement('Superclass'); |
| + Subclass = env.getElement('Subclass'); |
| + Subtype = env.getElement('Subtype'); |
| + } |
| + |
| + void check(ClassElement cls, ClassMask mask, Selector selector, |
| + bool expectedResult) { |
| + bool result = closedWorld.needsNoSuchMethod(cls, selector, mask); |
| + Expect.equals(expectedResult, result, |
| + 'Unexpected result for $selector in $cls ($mask)'); |
| + } |
| + |
| + await run([]); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Superclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Superclass)); |
| + Expect.isFalse(closedWorld.isImplemented(Superclass)); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isImplemented(Subclass)); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isImplemented(Subtype)); |
| + |
| + check(Superclass, ClassMask.EXACT, foo, false); |
| + check(Superclass, ClassMask.EXACT, bar, false); |
| + check(Superclass, ClassMask.EXACT, baz, false); |
| + check(Superclass, ClassMask.SUBCLASS, foo, false); |
| + check(Superclass, ClassMask.SUBCLASS, bar, false); |
| + check(Superclass, ClassMask.SUBCLASS, baz, false); |
| + check(Superclass, ClassMask.SUBTYPE, foo, false); |
| + check(Superclass, ClassMask.SUBTYPE, bar, false); |
| + check(Superclass, ClassMask.SUBTYPE, baz, false); |
| + |
| + check(Subclass, ClassMask.EXACT, foo, false); |
| + check(Subclass, ClassMask.EXACT, bar, false); |
| + check(Subclass, ClassMask.EXACT, baz, false); |
| + check(Subclass, ClassMask.SUBCLASS, foo, false); |
| + check(Subclass, ClassMask.SUBCLASS, bar, false); |
| + check(Subclass, ClassMask.SUBCLASS, baz, false); |
| + check(Subclass, ClassMask.SUBTYPE, foo, false); |
| + check(Subclass, ClassMask.SUBTYPE, bar, false); |
| + check(Subclass, ClassMask.SUBTYPE, baz, false); |
| + |
| + check(Subtype, ClassMask.EXACT, foo, false); |
| + check(Subtype, ClassMask.EXACT, bar, false); |
| + check(Subtype, ClassMask.EXACT, baz, false); |
| + check(Subtype, ClassMask.SUBCLASS, foo, false); |
| + check(Subtype, ClassMask.SUBCLASS, bar, false); |
| + check(Subtype, ClassMask.SUBCLASS, baz, false); |
| + check(Subtype, ClassMask.SUBTYPE, foo, false); |
| + check(Subtype, ClassMask.SUBTYPE, bar, false); |
| + check(Subtype, ClassMask.SUBTYPE, baz, false); |
| + |
| + await run(['Superclass']); |
| + |
| + Expect.isTrue(closedWorld.isDirectlyInstantiated(Superclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Superclass)); |
| + Expect.isTrue(closedWorld.isImplemented(Superclass)); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isImplemented(Subclass)); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isImplemented(Subtype)); |
| + |
| + check(Superclass, ClassMask.EXACT, foo, false); |
| + check(Superclass, ClassMask.EXACT, bar, true); |
| + check(Superclass, ClassMask.EXACT, baz, true); |
| + check(Superclass, ClassMask.SUBCLASS, foo, false); |
| + check(Superclass, ClassMask.SUBCLASS, bar, true); |
| + check(Superclass, ClassMask.SUBCLASS, baz, true); |
| + check(Superclass, ClassMask.SUBTYPE, foo, false); |
| + check(Superclass, ClassMask.SUBTYPE, bar, true); |
| + check(Superclass, ClassMask.SUBTYPE, baz, true); |
| + |
| + check(Subclass, ClassMask.EXACT, foo, false); |
| + check(Subclass, ClassMask.EXACT, bar, false); |
| + check(Subclass, ClassMask.EXACT, baz, false); |
| + check(Subclass, ClassMask.SUBCLASS, foo, false); |
| + check(Subclass, ClassMask.SUBCLASS, bar, false); |
| + check(Subclass, ClassMask.SUBCLASS, baz, false); |
| + check(Subclass, ClassMask.SUBTYPE, foo, false); |
| + check(Subclass, ClassMask.SUBTYPE, bar, false); |
| + check(Subclass, ClassMask.SUBTYPE, baz, false); |
| + |
| + check(Subtype, ClassMask.EXACT, foo, false); |
| + check(Subtype, ClassMask.EXACT, bar, false); |
| + check(Subtype, ClassMask.EXACT, baz, false); |
| + check(Subtype, ClassMask.SUBCLASS, foo, false); |
| + check(Subtype, ClassMask.SUBCLASS, bar, false); |
| + check(Subtype, ClassMask.SUBCLASS, baz, false); |
| + check(Subtype, ClassMask.SUBTYPE, foo, false); |
| + check(Subtype, ClassMask.SUBTYPE, bar, false); |
| + check(Subtype, ClassMask.SUBTYPE, baz, false); |
| + |
| + await run(['Subclass']); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Superclass)); |
| + Expect.isTrue(closedWorld.isIndirectlyInstantiated(Superclass)); |
| + Expect.isTrue(closedWorld.isImplemented(Superclass)); |
| + |
| + Expect.isTrue(closedWorld.isDirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subclass)); |
| + Expect.isTrue(closedWorld.isImplemented(Subclass)); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isImplemented(Subtype)); |
| + |
| + check(Superclass, ClassMask.EXACT, foo, false); |
| + // Should be false since the class is not directly instantiated: |
| + check(Superclass, ClassMask.EXACT, bar, true); |
| + // Should be false since the class is not directly instantiated: |
| + check(Superclass, ClassMask.EXACT, baz, true); |
| + check(Superclass, ClassMask.SUBCLASS, foo, false); |
| + // Should be false since all live subclasses have a concrete implementation: |
| + check(Superclass, ClassMask.SUBCLASS, bar, true); |
| + check(Superclass, ClassMask.SUBCLASS, baz, true); |
| + check(Superclass, ClassMask.SUBTYPE, foo, false); |
| + // Should be false since all live subtypes have a concrete implementation: |
| + check(Superclass, ClassMask.SUBTYPE, bar, true); |
| + check(Superclass, ClassMask.SUBTYPE, baz, true); |
| + |
| + check(Subclass, ClassMask.EXACT, foo, false); |
| + check(Subclass, ClassMask.EXACT, bar, false); |
| + check(Subclass, ClassMask.EXACT, baz, true); |
| + check(Subclass, ClassMask.SUBCLASS, foo, false); |
| + check(Subclass, ClassMask.SUBCLASS, bar, false); |
| + check(Subclass, ClassMask.SUBCLASS, baz, true); |
| + check(Subclass, ClassMask.SUBTYPE, foo, false); |
| + check(Subclass, ClassMask.SUBTYPE, bar, false); |
| + check(Subclass, ClassMask.SUBTYPE, baz, true); |
| + |
| + check(Subtype, ClassMask.EXACT, foo, false); |
| + check(Subtype, ClassMask.EXACT, bar, false); |
| + check(Subtype, ClassMask.EXACT, baz, false); |
| + check(Subtype, ClassMask.SUBCLASS, foo, false); |
| + check(Subtype, ClassMask.SUBCLASS, bar, false); |
| + check(Subtype, ClassMask.SUBCLASS, baz, false); |
| + check(Subtype, ClassMask.SUBTYPE, foo, false); |
| + check(Subtype, ClassMask.SUBTYPE, bar, false); |
| + check(Subtype, ClassMask.SUBTYPE, baz, false); |
| + |
| + await run(['Subtype']); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Superclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Superclass)); |
| + Expect.isTrue(closedWorld.isImplemented(Superclass)); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isImplemented(Subclass)); |
| + |
| + Expect.isTrue(closedWorld.isDirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subtype)); |
| + Expect.isTrue(closedWorld.isImplemented(Subtype)); |
| + |
| + check(Superclass, ClassMask.EXACT, foo, false); |
| + check(Superclass, ClassMask.EXACT, bar, false); |
| + check(Superclass, ClassMask.EXACT, baz, false); |
| + check(Superclass, ClassMask.SUBCLASS, foo, false); |
| + check(Superclass, ClassMask.SUBCLASS, bar, false); |
| + check(Superclass, ClassMask.SUBCLASS, baz, false); |
| + check(Superclass, ClassMask.SUBTYPE, foo, true); |
| + check(Superclass, ClassMask.SUBTYPE, bar, false); |
| + check(Superclass, ClassMask.SUBTYPE, baz, true); |
| + |
| + check(Subclass, ClassMask.EXACT, foo, false); |
| + check(Subclass, ClassMask.EXACT, bar, false); |
| + check(Subclass, ClassMask.EXACT, baz, false); |
| + check(Subclass, ClassMask.SUBCLASS, foo, false); |
| + check(Subclass, ClassMask.SUBCLASS, bar, false); |
| + check(Subclass, ClassMask.SUBCLASS, baz, false); |
| + check(Subclass, ClassMask.SUBTYPE, foo, false); |
| + check(Subclass, ClassMask.SUBTYPE, bar, false); |
| + check(Subclass, ClassMask.SUBTYPE, baz, false); |
| + |
| + check(Subtype, ClassMask.EXACT, foo, true); |
| + check(Subtype, ClassMask.EXACT, bar, false); |
| + check(Subtype, ClassMask.EXACT, baz, true); |
| + check(Subtype, ClassMask.SUBCLASS, foo, true); |
| + check(Subtype, ClassMask.SUBCLASS, bar, false); |
| + check(Subtype, ClassMask.SUBCLASS, baz, true); |
| + check(Subtype, ClassMask.SUBTYPE, foo, true); |
| + check(Subtype, ClassMask.SUBTYPE, bar, false); |
| + check(Subtype, ClassMask.SUBTYPE, baz, true); |
| + |
| + await run(['Subclass', 'Subtype']); |
| + |
| + Expect.isFalse(closedWorld.isDirectlyInstantiated(Superclass)); |
| + Expect.isTrue(closedWorld.isIndirectlyInstantiated(Superclass)); |
| + Expect.isTrue(closedWorld.isImplemented(Superclass)); |
| + |
| + Expect.isTrue(closedWorld.isDirectlyInstantiated(Subclass)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subclass)); |
| + Expect.isTrue(closedWorld.isImplemented(Subclass)); |
| + |
| + Expect.isTrue(closedWorld.isDirectlyInstantiated(Subtype)); |
| + Expect.isFalse(closedWorld.isIndirectlyInstantiated(Subtype)); |
| + Expect.isTrue(closedWorld.isImplemented(Subtype)); |
| + |
| + check(Superclass, ClassMask.EXACT, foo, false); |
| + // Should be false since the class is not directly instantiated: |
| + check(Superclass, ClassMask.EXACT, bar, true); |
| + // Should be false since the class is not directly instantiated: |
| + check(Superclass, ClassMask.EXACT, baz, true); |
| + check(Superclass, ClassMask.SUBCLASS, foo, false); |
| + // Should be false since all live subclasses have a concrete implementation: |
| + check(Superclass, ClassMask.SUBCLASS, bar, true); |
| + check(Superclass, ClassMask.SUBCLASS, baz, true); |
| + check(Superclass, ClassMask.SUBTYPE, foo, true); |
| + // Should be false since all live subtypes have a concrete implementation: |
| + check(Superclass, ClassMask.SUBTYPE, bar, true); |
| + check(Superclass, ClassMask.SUBTYPE, baz, true); |
| + |
| + check(Subclass, ClassMask.EXACT, foo, false); |
| + check(Subclass, ClassMask.EXACT, bar, false); |
| + check(Subclass, ClassMask.EXACT, baz, true); |
| + check(Subclass, ClassMask.SUBCLASS, foo, false); |
| + check(Subclass, ClassMask.SUBCLASS, bar, false); |
| + check(Subclass, ClassMask.SUBCLASS, baz, true); |
| + check(Subclass, ClassMask.SUBTYPE, foo, false); |
| + check(Subclass, ClassMask.SUBTYPE, bar, false); |
| + check(Subclass, ClassMask.SUBTYPE, baz, true); |
| + |
| + check(Subtype, ClassMask.EXACT, foo, true); |
| + check(Subtype, ClassMask.EXACT, bar, false); |
| + check(Subtype, ClassMask.EXACT, baz, true); |
| + check(Subtype, ClassMask.SUBCLASS, foo, true); |
| + check(Subtype, ClassMask.SUBCLASS, bar, false); |
| + check(Subtype, ClassMask.SUBCLASS, baz, true); |
| + check(Subtype, ClassMask.SUBTYPE, foo, true); |
| + check(Subtype, ClassMask.SUBTYPE, bar, false); |
| + check(Subtype, ClassMask.SUBTYPE, baz, true); |
| +} |