Skip to content

Commit

Permalink
#2976. Add more tests for shorthand equality (#3022)
Browse files Browse the repository at this point in the history
Add more tests for shorthand equality
  • Loading branch information
sgrekhov authored Dec 20, 2024
1 parent 6d2a3c5 commit e07a25b
Show file tree
Hide file tree
Showing 10 changed files with 367 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
class C<augmented> {}

augment class C<augmented> {}
// ^^^^^^^^^
// ^^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

Expand Down
79 changes: 79 additions & 0 deletions LanguageFeatures/Static-access-shorthand/equality_A01_t09.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2024, 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.

/// @assertion If an expression has the form `e1 == e2` or `e1 != e2`, or a
/// pattern has the form `== e2` or `!= e2`, where the static type of `e1`, or
/// the matched value type of the pattern, is S1, and e2 is precisely a
/// `<staticMemberShorthand>` expression, then assign the type S1 as the
/// shorthand context of the `<staticMemberShorthandHead>` of e2 before
/// inferring its static type the same way as above.
///
/// @description Checks that if a pattern has the form `== e2` or `!= e2` and
/// `e2` is a shorthand expression, then it has context type from the matched
/// value type of the pattern. Test the case when `e2` has additional selector
/// `length`.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

class C {
static const hello = "hello";

@override
bool operator ==(Object other) {
if (other is String) {
return other == "hello" || other == "world";
} else if (other is int) {
return other == 5;
}
return false;
}
}

mixin M on C {
static const world = "world";
}
class MC = C with M;

enum E {
e0;
static const hello = "hello";
}

extension type ET(int id) {
static const world = "world";
}

main() {
bool success = false;
void checkSuccess() {
Expect.isTrue(success);
success = false;
}

C c = C();
if (c case == .hello.length) {
success = true;
}
checkSuccess();

M m = MC();
if (m case == .world.length) {
success = true;
}
checkSuccess();

if (E.e0 case != .hello.length) {
success = true;
}
checkSuccess();

ET et = ET(0);
if (et case != .world.length) {
success = true;
}
checkSuccess();
}
38 changes: 20 additions & 18 deletions LanguageFeatures/Static-access-shorthand/equality_A02_t01.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// 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.

/// @assertion For ==, we special-case when the right operand is (precisely!) a
/// static member shorthand.
/// @assertion For `==`, we special-case when the right operand is (precisely!)
/// a static member shorthand.
/// ...
/// This special-casing is only against an immediate static member shorthand. It
/// does not change the context type of the second operand, so it would not work
Expand All @@ -14,17 +14,17 @@
/// nor the parameter type of the first operand's `operator==`.)
///
/// @description Checks that it is a compile-time error if the right operand of
/// `==` operator is not a precisely static member shorthand but a ternary
/// operator. Test a class.
/// `==` or `!=` operators is not a precisely static member shorthand. Test a
/// class.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

class C<T> {
T value;
C(this.value);
C.id(this.value);
factory C.f(T t) = C;
final T value;
const C(this.value);
const C.id(this.value);
const factory C.f(T t) = C;

static C<int> get intOne => C(1);
static C<int> intTwo() => C(2);
Expand All @@ -39,35 +39,37 @@ class C<T> {
}
}

C<int> foo(C<int> c) => c;

main() {
bool condition = 2 > 1;
if (C(0) == condition ? .new(0) : C.id(1)) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (C(0) == condition ? C.new(0) : .id(1)) {}
// ^
if ([C(0)] == [.id(1)]) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (C(0) != condition ? .f(0) : C.intOne) {}
// ^
if ({C(0)} != {.f(0)}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (C(0) != condition ? C.f(0) : .intOne) {}
// ^
if ({"key": C(0)} != {"key": .intOne}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (C(0) == condition ? .intTwo() : C.values[0]) {}
// ^
if (C(0) == (.intTwo())) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (C(0) == condition ? C.intTwo() : .values[0]) {}
// ^
if (C(0) == foo(.values[0])) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
32 changes: 22 additions & 10 deletions LanguageFeatures/Static-access-shorthand/equality_A02_t02.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// 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.

/// @assertion For ==, we special-case when the right operand is (precisely!) a
/// static member shorthand.
/// @assertion For `==`, we special-case when the right operand is (precisely!)
/// a static member shorthand.
/// ...
/// This special-casing is only against an immediate static member shorthand. It
/// does not change the context type of the second operand, so it would not work
Expand All @@ -14,8 +14,8 @@
/// nor the parameter type of the first operand's `operator==`.)
///
/// @description Checks that it is a compile-time error if the right operand of
/// `==` operator is not a precisely static member shorthand but a ternary
/// operator. Test a mixin.
/// `==` or `!=` operators is not a precisely static member shorthand. Test a
/// mixin.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands
Expand All @@ -41,6 +41,8 @@ mixin M<T> on C<T> {

class MC<T> = C<T> with M<T>;

M<int> foo(M<int> m) => m;

main() {
bool condition = 2 > 1;
M<int> m = MC<int>(0);
Expand All @@ -50,18 +52,28 @@ main() {
// [analyzer] unspecified
// [cfe] unspecified

if (m == condition ? M.intOne : .intTwo()) {}
// ^
if ([m] == [.intOne]) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (m != condition ? .intTwo() : M.values[0]) {}
// ^
if ({m} != {.intTwo()}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (m != condition ? .values[0] : M.intTwo()) {}
// ^
if ({"key": m} != {"key": .values[0]}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (m != (.intTwo())) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (m != foo(.values[0])) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
32 changes: 22 additions & 10 deletions LanguageFeatures/Static-access-shorthand/equality_A02_t03.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// 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.

/// @assertion For ==, we special-case when the right operand is (precisely!) a
/// static member shorthand.
/// @assertion For `==`, we special-case when the right operand is (precisely!)
/// a static member shorthand.
/// ...
/// This special-casing is only against an immediate static member shorthand. It
/// does not change the context type of the second operand, so it would not work
Expand All @@ -14,8 +14,8 @@
/// nor the parameter type of the first operand's `operator==`.)
///
/// @description Checks that it is a compile-time error if the right operand of
/// `==` operator is not a precisely static member shorthand but a ternary
/// operator. Test an enum.
/// `==` or `!=` operators is not a precisely static member shorthand. Test an
/// enum.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands
Expand All @@ -29,6 +29,8 @@ enum E<T> {
static E staticMethod(int index) => E.values[index];
}

E<int> foo(E<int> e) => e;

main() {
bool condition = 2 > 1;

Expand All @@ -37,18 +39,28 @@ main() {
// [analyzer] unspecified
// [cfe] unspecified

if (E.e0 == condition ? E.e0 : .staticGetter) {}
// ^
if ([E.e0] == [.staticGetter]) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (E.e0 != condition ? .staticMethod(0) : E.values[1]) {}
// ^
if ({E.e0} != {.staticMethod(0)}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (E.e0 != condition ? .values[0] : E.e1) {}
// ^
if ({"key": E.e0} != {"key": .values[0]}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (E.e0 == (.e0)) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (E.e0 == foo(.e0)) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
29 changes: 15 additions & 14 deletions LanguageFeatures/Static-access-shorthand/equality_A02_t04.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// 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.

/// @assertion For ==, we special-case when the right operand is (precisely!) a
/// static member shorthand.
/// @assertion For `==`, we special-case when the right operand is (precisely!)
/// a static member shorthand.
/// ...
/// This special-casing is only against an immediate static member shorthand. It
/// does not change the context type of the second operand, so it would not work
Expand All @@ -14,8 +14,8 @@
/// nor the parameter type of the first operand's `operator==`.)
///
/// @description Checks that it is a compile-time error if the right operand of
/// `==` operator is not a precisely static member shorthand but a ternary
/// operator. Test an enum.
/// `==` or `!=` operators is not a precisely static member shorthand. Test an
/// extension type.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands
Expand All @@ -29,6 +29,7 @@ extension type ET<T>(T value) {
static List<ET<String>> instances = [ET("one")];
}

ET<String> foo(ET<String> et) => et;

main() {
bool condition = 2 > 1;
Expand All @@ -39,28 +40,28 @@ main() {
// [analyzer] unspecified
// [cfe] unspecified

if (one == condition ? ET(1) : .id(2)) {}
// ^
if ([one] == [.id(2)]) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (one != condition ? .f(0) : ET.f(1)) {}
// ^
if ({one} != {.f(0)}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (one != condition ? ET(0) : .staticGetter) {}
// ^
if ({"key": one} != {"key": .staticGetter}) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (one != condition ? .staticMethod<int>(1) : ET.staticGetter) {}
// ^
if (one != (.staticMethod<int>(1))) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

if (one != condition ? ET.staticMethod<int>(1) : .instances[0]) {}
// ^
if (one != foo(.instances[0])) {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
Loading

0 comments on commit e07a25b

Please sign in to comment.