blob: ce822ac58ad34dc31d437bf5eee6d16ed7d1063f [file] [log] [blame]
// Copyright (c) 2019, 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.
// Tests extension method resolution failures.
import "package:expect/expect.dart";
main() {
A a = C();
B1 b1 = C();
B2 b2 = C();
C c = C();
Expect.equals("EA.v1", a.v1);
Expect.equals("EB1.v1", b1.v1);
Expect.equals("EB2.v1", b2.v1);
Expect.equals("EC.v1", c.v1);
Expect.equals("EA.v2", a.v2);
Expect.equals("EB1.v2", b1.v2);
Expect.equals("EB2.v2", b2.v2);
// Cannot determine which of EB1 and EB2's v2 is more specific
c.v2;
//^^
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
// [cfe] The property 'v2' is defined in multiple extensions for 'C' and neither is more specific.
Expect.equals("EA.v3", a.v3);
Expect.equals("EA.v3", b1.v3);
Expect.equals("EA.v3", b2.v3);
Expect.equals("EA.v3", c.v3);
Iterable<num> i_num = <int>[];
Iterable<int> ii = <int>[];
List<num> ln = <int>[];
List<int> li = <int>[];
// No `i_num` extension declared.
i_num.i_num;
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
// [cfe] The getter 'i_num' isn't defined for the class 'Iterable<num>'.
Expect.equals("Iterable<int>.i_num", ii.i_num);
Expect.equals("List<num>.i_num", ln.i_num);
// Both apply, neither is more specific.
li.i_num;
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
// [cfe] The property 'i_num' is defined in multiple extensions for 'List<int>' and neither is more specific.
// no most specific because both are equally specific.
c.cs;
//^^
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
// [cfe] The property 'cs' is defined in multiple extensions for 'C' and neither is more specific.
// Both EIT.e1 and ELO.e1 apply, but their instantiated on
// types are incomparable, and hence this is an error.
ln.e1();
// ^^
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
// [cfe] The method 'e1' is defined in multiple extensions for 'List<num>' and neither is more specific.
}
// Diamond class hierarchy.
class A {}
class B1 implements A {}
class B2 implements A {}
class C implements B1, B2 {}
extension EA on A {
String get v1 => "EA.v1";
String get v2 => "EA.v2";
String get v3 => "EA.v3";
}
extension EB1 on B1 {
String get v1 => "EB1.v1";
String get v2 => "EB1.v2";
}
extension EB2 on B2 {
String get v1 => "EB2.v1";
String get v2 => "EB2.v2";
}
extension EC on C {
String get v1 => "EC.v1";
}
// Iterable<num>, Iterable<int>, List<num> and List<int> also forms diamond
// hierarchy.
extension II on Iterable<int> {
String get i_num => "Iterable<int>.i_num";
}
extension LN on List<num> {
String get i_num => "List<num>.i_num";
}
// Two exactly identical `on` types.
extension C1 on C {
String get cs => "C1.cs";
}
extension C2 on C {
String get cs => "C2.cs";
}
extension EIT<T> on Iterable<T> {
String e1() => "Iterable<T>.e1";
}
extension ELO on List<Object> {
String e1() => "List<Object>.e1";
}