Skip to content

Commit

Permalink
#2142. Change dynamic semantics member invocation tests to be extensi…
Browse files Browse the repository at this point in the history
…on type tests (#2154)

Change dynamic semantics member invocation tests to be extension type tests
  • Loading branch information
sgrekhov authored Jul 28, 2023
1 parent 3f9d5d1 commit 0aa3e01
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 285 deletions.
8 changes: 7 additions & 1 deletion LanguageFeatures/Extension-types/syntax_A04_t06.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
/// <extensionTypeMemberDeclaration> ::= <classMemberDefinition>
///
/// @description Checks that it is a compile-time error if `type` in
/// `representationDeclaration` is `var` or `final`
/// `representationDeclaration` is `var` or `final` or `final type`
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class
Expand All @@ -37,7 +37,13 @@ extension type ET2.n1(final id) {}
// [analyzer] unspecified
// [cfe] unspecified

extension type ET3.new(final int id) {}
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified

main() {
print(ET1);
print(ET2);
print(ET3);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,27 @@
// 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 Consider an invocation of the inline member m on the receiver e
/// according to the inline type V and with actual type arguments T1, ..., Ts.
/// If the invocation includes an actual argument part (possibly including some
/// actual type arguments) then call it args. Assume that V declares the type
/// variables X1, ..., Xs.
///
/// Let Dm be the declaration named m thath V has.
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with
/// actual type arguments T1, ..., Ts. If the invocation includes an actual
/// argument part (possibly including some actual type arguments) then call it
/// args. If the invocation omits args, but includes a list of actual type
/// arguments then call them typeArgs. Assume that V declares the type variables
/// X1, ..., Xs
/// ...
/// Let Dm be the unique declaration named m that V has.
///
/// Evaluation of this invocation proceeds by evaluating e to an object o.
///
/// Then, if args is omitted and Dm is a getter, execute the body of said
/// getter in an environment where this and the name of the representation are
/// bound to o, and the type variables of V are bound to the actual values of
/// T1, .. Ts. If the body completes returning an object o2 then the invocation
/// evaluates to o2. If the body throws an object and a stack trace then the
/// invocation completes throwing the same object and stack trace.
/// Then, if args is omitted and Dm is a getter, execute the body of said getter
/// in an environment where this is bound to o and the representation name
/// denotes a getter that returns o, and the type variables of V are bound to
/// the actual values of T1, .. Ts. If the body completes returning an object o2
/// then the invocation evaluates to o2. If the body throws an object and a
/// stack trace then the invocation completes throwing the same object and stack
/// trace.
///
/// @description Check invocation of an inline class getter. Test that if the
/// @description Check invocation of an extension type getter. Test that if the
/// body completes returning an object `o2` then the invocation evaluates to
/// `o2`.
/// @author sgrekhov22@gmail.com
Expand All @@ -29,39 +32,30 @@
import "../../Utils/expect.dart";
import "../../Utils/static_type_helper.dart";

inline class IC<T> {
final T id;
IC(this.id);
}

inline class IC2<T extends num> {
final T id;
IC2(this.id);
extension type ET1<T>(T id) {}

extension type ET2<T extends num>(T id) {
List<T> get emptyList => <T>[];
}

inline class IC3 implements IC2<int> {
final int id;
IC3(this.id);
}
extension type ET3(int id) implements ET2<int> {}

main() {
IC<Object?> ic1_1 = IC(42);
Expect.equals(42, ic1_1.id);
ET1<Object?> et1_1 = ET1(42);
Expect.equals(42, et1_1.id);

IC<Object?> ic1_2 = IC("42");
Expect.equals("42", ic1_2.id);
ET1<String> et1_2 = ET1("42");
Expect.equals("42", et1_2.id);

IC2<int> ic2_1 = IC2(42);
ic2_1.emptyList.expectStaticType<Exactly<List<int>>>();
Expect.throws(() {ic2_1.emptyList.add(3.14 as dynamic);});
ET2<int> et2_1 = ET2(42);
et2_1.emptyList.expectStaticType<Exactly<List<int>>>();
Expect.throws(() {et2_1.emptyList.add(3.14 as dynamic);});

IC2<num> ic2_2 = IC2(3.14);
ic2_2.emptyList.expectStaticType<Exactly<List<num>>>();
ic2_2.emptyList.add(42);
ic2_2.emptyList.add(3.14);
ET2<num> et2_2 = ET2(3.14);
et2_2.emptyList.expectStaticType<Exactly<List<num>>>();
et2_2.emptyList.add(42);
et2_2.emptyList.add(3.14);

IC3 ic3 = IC3(3);
ic3.emptyList.expectStaticType<Exactly<List<int>>>();
ET3 et3 = ET3(3);
et3.emptyList.expectStaticType<Exactly<List<int>>>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,27 @@
// 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 Consider an invocation of the inline member m on the receiver e
/// according to the inline type V and with actual type arguments T1, ..., Ts.
/// If the invocation includes an actual argument part (possibly including some
/// actual type arguments) then call it args. Assume that V declares the type
/// variables X1, ..., Xs.
///
/// Let Dm be the declaration named m thath V has.
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with
/// actual type arguments T1, ..., Ts. If the invocation includes an actual
/// argument part (possibly including some actual type arguments) then call it
/// args. If the invocation omits args, but includes a list of actual type
/// arguments then call them typeArgs. Assume that V declares the type variables
/// X1, ..., Xs
/// ...
/// Let Dm be the unique declaration named m that V has.
///
/// Evaluation of this invocation proceeds by evaluating e to an object o.
///
/// Then, if args is omitted and Dm is a getter, execute the body of said
/// getter in an environment where this and the name of the representation are
/// bound to o, and the type variables of V are bound to the actual values of
/// T1, .. Ts. If the body completes returning an object o2 then the invocation
/// evaluates to o2. If the body throws an object and a stack trace then the
/// invocation completes throwing the same object and stack trace.
/// Then, if args is omitted and Dm is a getter, execute the body of said getter
/// in an environment where this is bound to o and the representation name
/// denotes a getter that returns o, and the type variables of V are bound to
/// the actual values of T1, .. Ts. If the body completes returning an object o2
/// then the invocation evaluates to o2. If the body throws an object and a
/// stack trace then the invocation completes throwing the same object and stack
/// trace.
///
/// @description Check invocation of an inline class getter in the case when
/// @description Check invocation of an extension type getter in the case when
/// type arguments are omitted. Test that if the body throws an object and a
/// stack trace then the invocation completes throwing the same object and stack
/// trace
Expand All @@ -31,10 +34,7 @@ import "../../Utils/expect.dart";

StackTrace st = StackTrace.fromString("42");

inline class IC<T extends num> {
final T id;
IC(this.id);

extension type ET1<T extends num>(T id) {
T get testMe {
if (2 > 1) {
Error.throwWithStackTrace("T is $T", st);
Expand All @@ -43,31 +43,28 @@ inline class IC<T extends num> {
}
}

inline class IC2<T extends num> implements IC<T> {
final T id;
IC2(this.id);
}
extension type ET2<T extends num> implements ET2<T>(T id) {}

main() {
IC<num> ic_1 = IC(42);
ET1<num> et1_1 = ET1(42);
try {
ic_1.testMe;
et1_1.testMe;
} catch (e, _st) {
Expect.equals("T is num", e);
Expect.equals(st, _st);
}

IC<int> ic_2 = IC(42);
ET1<int> et1_2 = ET1(42);
try {
ic_2.testMe;
et1_2.testMe;
} catch (e, _st) {
Expect.equals("T is int", e);
Expect.equals(st, _st);
}

IC2<int> ic2 = IC2(42);
ET2<int> et2 = ET2(42);
try {
ic2.testMe;
et2.testMe;
} catch (e, _st) {
Expect.equals("T is int", e);
Expect.equals(st, _st);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,38 @@
// 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 Consider an invocation of the inline member m on the receiver e
/// according to the inline type V and with actual type arguments T1, ..., Ts.
/// If the invocation includes an actual argument part (possibly including some
/// actual type arguments) then call it args. Assume that V declares the type
/// variables X1, ..., Xs.
///
/// Let Dm be the declaration named m thath V has.
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with
/// actual type arguments T1, ..., Ts. If the invocation includes an actual
/// argument part (possibly including some actual type arguments) then call it
/// args. If the invocation omits args, but includes a list of actual type
/// arguments then call them typeArgs. Assume that V declares the type variables
/// X1, ..., Xs
/// ...
/// Let Dm be the unique declaration named m that V has.
///
/// Evaluation of this invocation proceeds by evaluating e to an object o.
/// ...
/// Otherwise, if args is omitted and Dm is a method, the invocation evaluates
/// to a closurization of Dm where this and the name of the representation are
/// bound to o, and the type variables of V are bound to the actual values of
/// T1, .. Ts. The operator == of the closurization returns true if and only if
/// the operand is the same object.
/// bound as with the getter invocation, and the type variables of V are bound
/// to the actual values of T1, .. Ts. The operator == of the closurization
/// returns true if and only if the operand is the same object.
///
/// @description Check that in case of invocation of an inline class method with
/// the omitted type argument the actual type variables of V are bound to the
/// actual values of T1, .. Ts.
/// @description Check that in case of invocation of an extension type method
/// with the omitted type argument the actual type variables of V are bound to
/// the actual values of T1, .. Ts.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/expect.dart";

inline class IC<T> {
final T id;
IC(this.id);

extension type ET<T>(T id) {
Map<K, Type> asMap<K, V extends T>(K key1, K key2) => {key1: V, key2: T};
}

main() {
IC<num> ic1_1 = IC(42);
Expect.mapEquals({"key1": num, "key2": num}, ic1_1.asMap("key1", "key2"));
ET<num> et = ET(42);
Expect.mapEquals({"key1": num, "key2": num}, et.asMap("key1", "key2"));
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@
// 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 Consider an invocation of the inline member m on the receiver e
/// according to the inline type V and with actual type arguments T1, ..., Ts.
/// If the invocation includes an actual argument part (possibly including some
/// actual type arguments) then call it args. Assume that V declares the type
/// variables X1, ..., Xs.
///
/// Let Dm be the declaration named m thath V has.
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with
/// actual type arguments T1, ..., Ts. If the invocation includes an actual
/// argument part (possibly including some actual type arguments) then call it
/// args. If the invocation omits args, but includes a list of actual type
/// arguments then call them typeArgs. Assume that V declares the type variables
/// X1, ..., Xs
/// ...
/// Let Dm be the unique declaration named m that V has.
///
/// Evaluation of this invocation proceeds by evaluating e to an object o.
/// ...
/// Otherwise, if args is omitted and Dm is a method, the invocation evaluates
/// to a closurization of Dm where this and the name of the representation are
/// bound to o, and the type variables of V are bound to the actual values of
/// T1, .. Ts. The operator == of the closurization returns true if and only if
/// the operand is the same object.
/// bound as with the getter invocation, and the type variables of V are bound
/// to the actual values of T1, .. Ts. The operator == of the closurization
/// returns true if and only if the operand is the same object.
///
/// @description Check that `this` is bound to `o`
/// @author sgrekhov22@gmail.com
Expand All @@ -25,28 +27,21 @@

import "../../Utils/expect.dart";

inline class IC<T> {
final T id;
IC(this.id);

extension type ET<T>(T id) {
Object test1() => this;
void test2() {
Expect.identical(this, id);
}
}

inline class IC2<T> implements IC<T> {
final T id;
IC2(this.id);
}

extension type ET2<T> implements ET<T>(T id) {}

main() {
IC ic = IC(42);
Expect.identical(ic, ic.test1());
ic.test2();
ET et = ET(42);
Expect.identical(et, et.test1());
et.test2();

IC2 ic2 = IC2(42);
Expect.identical(ic2, ic2.test1());
ic2.test2();
ET2 et2 = ET2(42);
Expect.identical(et2, et2.test1());
et2.test2();
}
Loading

0 comments on commit 0aa3e01

Please sign in to comment.