mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:37:12 +00:00
b3af778a38
- including tests for issues 46719 and 46887 Change-Id: I601fcfcb956e059f502cbece29fb2a6a00f68846 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210464 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
262 lines
7.2 KiB
Dart
262 lines
7.2 KiB
Dart
// 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 interactions between getters and setters where there is a conflict.
|
|
|
|
// Conflicting class declarations.
|
|
|
|
class C0 {
|
|
int get m1 => 0;
|
|
void set m2(int x) {}
|
|
int operator [](int index) => 0;
|
|
}
|
|
|
|
extension E0 on C0 {
|
|
void set m1(int x) {}
|
|
int get m2 => 0;
|
|
void operator []=(int index, int value) {}
|
|
}
|
|
|
|
void test0() {
|
|
C0 c0 = C0();
|
|
c0.m1;
|
|
c0.m1 = 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
|
|
// [cfe] The setter 'm1' isn't defined for the class 'C0'.
|
|
E0(c0).m1 = 0;
|
|
E0(c0).m1;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_GETTER
|
|
// [cfe] Getter not found: 'm1'.
|
|
|
|
c0.m1 += 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
|
|
// [cfe] The setter 'm1' isn't defined for the class 'C0'.
|
|
|
|
c0.m1++;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
|
|
// [cfe] The setter 'm1' isn't defined for the class 'C0'.
|
|
|
|
c0.m2 = 0;
|
|
c0.m2;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
|
|
// [cfe] The getter 'm2' isn't defined for the class 'C0'.
|
|
c0.m2 += 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
|
|
// [cfe] The getter 'm2' isn't defined for the class 'C0'.
|
|
c0.m2++;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
|
|
// [cfe] The getter 'm2' isn't defined for the class 'C0'.
|
|
|
|
E0(c0).m2;
|
|
|
|
c0[0];
|
|
c0[0] = 0;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]=' isn't defined for the class 'C0'.
|
|
E0(c0)[0];
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
|
|
// [cfe] Method not found: '[]'.
|
|
E0(c0)[0] = 0;
|
|
|
|
c0[0] += 0;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]=' isn't defined for the class 'C0'.
|
|
c0[0]++;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]=' isn't defined for the class 'C0'.
|
|
|
|
E0(c0)[0] += 0;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
|
|
// [cfe] The operator '[]' isn't defined for the class 'C0'.
|
|
E0(c0)[0]++;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
|
|
// [cfe] The operator '[]' isn't defined for the class 'C0'.
|
|
}
|
|
|
|
// Conflicting extensions.
|
|
|
|
class C1<T> {}
|
|
|
|
extension E1A<T> on C1<T> {
|
|
int get m1 => 0;
|
|
void set m2(int x) {}
|
|
int operator [](int index) => 0;
|
|
}
|
|
|
|
extension E1B on C1<Object?> {
|
|
void set m1(int x) {}
|
|
int get m2 => 0;
|
|
void operator []=(int index, int value) {}
|
|
}
|
|
|
|
void test1() {
|
|
C1<int> c1a = C1(); // E1A is more specific.
|
|
c1a.m1;
|
|
|
|
c1a.m1 = 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
|
|
// [cfe] The setter 'm1' isn't defined for the class 'C1<int>'.
|
|
|
|
c1a.m2;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
|
|
// [cfe] The getter 'm2' isn't defined for the class 'C1<int>'.
|
|
|
|
c1a.m2 = 0;
|
|
|
|
c1a[0] = 0;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
|
|
|
|
c1a[0] += 0;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
|
|
|
|
c1a[0]++;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
|
|
|
|
c1a[0];
|
|
|
|
C1<Object?> c1b = C1<Object?>(); // Neither extension is more specific.
|
|
|
|
c1b.m1;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b.m1 = 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b.m1 += 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b.m1++;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b.m2;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// [cfe] The property 'm2' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b[0];
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// ^
|
|
// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b[0] = 0;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// ^
|
|
// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b[0] += 0;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// ^
|
|
// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
c1b[0]++;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
|
|
// ^
|
|
// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object?>' and neither is more specific.
|
|
|
|
C1<Object> c1c = C1<Object>(); // E1A is more specific.
|
|
|
|
c1c.m1 = 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
|
|
// [cfe] The setter 'm1' isn't defined for the class 'C1<Object>'.
|
|
|
|
c1c.m2;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
|
|
// [cfe] The getter 'm2' isn't defined for the class 'C1<Object>'.
|
|
}
|
|
|
|
// Getter on the extension itself.
|
|
class C2 {
|
|
int get m1 => 0;
|
|
void set m2(int x) {}
|
|
int get mc => 0;
|
|
void operator []=(int index, int value) {}
|
|
}
|
|
|
|
extension E2 on C2 {
|
|
void set m1(int x) {}
|
|
int get m2 => 0;
|
|
String get me => "";
|
|
int operator [](int index) => 0;
|
|
|
|
void test2() {
|
|
// Using `this.member` means using the `on` type.
|
|
|
|
this.m1;
|
|
this.m1 = 0;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
|
|
// [cfe] The setter 'm1' isn't defined for the class 'C2'.
|
|
|
|
this.m2 = 0;
|
|
this.m2;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
|
|
// [cfe] The getter 'm2' isn't defined for the class 'C2'.
|
|
|
|
this[0] = 0;
|
|
this[0];
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]' isn't defined for the class 'C2'.
|
|
|
|
this[0] += 0;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]' isn't defined for the class 'C2'.
|
|
|
|
this[0]++;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_OPERATOR
|
|
// [cfe] The operator '[]' isn't defined for the class 'C2'.
|
|
|
|
// Check that `this.mc` refers to `C2.mc`.
|
|
this.mc.toRadixString(16);
|
|
// Check that `this.me` refers to `E2.me`.
|
|
this.me.substring(0);
|
|
}
|
|
}
|
|
|
|
main() {
|
|
test0();
|
|
test1();
|
|
C2().test2();
|
|
}
|