diff --git a/Language/Classes/Constructors/Factories/function_type_t06.dart b/Language/Classes/Constructors/Factories/function_type_t06.dart new file mode 100644 index 0000000000..592769cd7a --- /dev/null +++ b/Language/Classes/Constructors/Factories/function_type_t06.dart @@ -0,0 +1,48 @@ +// Copyright (c) 2023, 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 Assume that C is the name +/// and formal type parameters of the enclosing class, const? is const or empty, +/// N is C or C.id0 for some identifier id0, and id is an identifier, then +/// consider a declaration of a redirecting factory constructor k of one of the +/// forms +/// const? factory +/// N(T1 x1 . . . , Tn xn, [Tn+1 xn+1=d1, . . . , Tn+k xn+k=dk]) = R; +/// const? factory +/// N(T1 x1 . . . , Tn xn, {Tn+1 xn+1=d1, . . . , Tn+k xn+k=dk}) = R; +/// where R is of one of the forms T or T.id. +/// ... +/// The redirectee constructor for this declaration is the constructor k′ +/// denoted by R. +/// ... +/// It is a compile error if the function type of k' is not a subtype of the +/// type of k. +/// +/// @description Checks that it is a compile-time error is if a factory +/// constructor redirects to a null +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=inline-class + +class F { + factory F(x) = null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +enum E { + e1, e2; + const E(); + + factory E.f() = null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + print(F); + print(E); +} diff --git a/Language/Classes/Constructors/Factories/parameter_type_t01.dart b/Language/Classes/Constructors/Factories/parameter_type_t01.dart new file mode 100644 index 0000000000..e5268f6277 --- /dev/null +++ b/Language/Classes/Constructors/Factories/parameter_type_t01.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2023, 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 For the dynamic semantics, assume that k is a redirecting factory +/// constructor and k′ is the redirectee of k +/// +/// It is a dynamic type error if an actual argument passed in an invocation of +/// k is not a subtype of the actual type of the corresponding formal parameter +/// in the declaration of k. +/// +/// @description Checks that it is a dynamic type error if an actual argument +/// type of a redirecting factory constructor call is not a subtype of the +/// actual type of its corresponding formal parameter. +/// @author sgrekhov22@gmail.com + +import "../../../../Utils/expect.dart"; + +class F { + factory F(num x) = C; + factory F.foo(num x, [num y]) = C.foo; + factory F.bar(num x, {num z}) = C.bar; +} + +class C implements F { + num x, y = 1, z = 2; + + C(this.x); + C.foo(this.x, [this.y = 1]); + C.bar(this.x, {this.z = 2}); +} + +enum E { + e1, e2; + const E(); + + factory E.g1(num x) => E.e1; + factory E.g2(num x, [num y = 1]) => E.e1; + factory E.g3(num x, {num z = 2}) => E.e1; + factory E.f1(num x) = E.g1; + factory E.f2(num x, [num y]) = E.g2; + factory E.f3(num x, {num z}) = E.g3; +} + +main() { + Expect.throws(() {F(Object() as dynamic);}); + Expect.throws(() {F.foo(42, Object() as dynamic);}); + Expect.throws(() {F.bar(3.14, z: Object() as dynamic);}); + Expect.throws(() {E.f1(Object() as dynamic);}); + Expect.throws(() {E.f2(42, Object() as dynamic);}); + Expect.throws(() {E.f3(3.14, z: Object() as dynamic);}); +} diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_call_t01.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_call_t01.dart index 9e0279155d..811a22e964 100644 --- a/Language/Classes/Constructors/Factories/redirecting_constructor_call_t01.dart +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_call_t01.dart @@ -2,11 +2,16 @@ // 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 Calling a redirecting factory constructor k causes the -/// constructor k' denoted by type (respectively, type.identifier) to be called -/// with the actual arguments passed to k, and returns the result of k' as the -/// result of k. The resulting constructor call is governed by the same rules -/// as an instance creation expression using new. +/// @assertion For the dynamic semantics, assume that k is a redirecting factory +/// constructor and k′ is the redirectee of k +/// ... +/// When the redirectee k′ is a generative constructor, let o be a +/// fresh instance of the class that contains k′. Execution of k then amounts to +/// execution of k′ to initialize o, governed by the same rules as an instance +/// creation expression. If k′ completed normally then the execution of k +/// completes normally returning o, otherwise k completes by throwing the +/// exception and stack trace thrown by k′. +/// /// @description Checks that a call to redirecting factory constructor indeed /// results in a call to referenced constructor with the same actual arguments. /// @author ilya diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_call_t02.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_call_t02.dart index 8f4372a4c8..f487bc880e 100644 --- a/Language/Classes/Constructors/Factories/redirecting_constructor_call_t02.dart +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_call_t02.dart @@ -2,16 +2,20 @@ // 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 Calling a redirecting factory constructor k causes the -/// constructor k' denoted by type (respectively, type.identifier) to be called -/// with the actual arguments passed to k, and returns the result of k' as the -/// result of k. The resulting constructor call is governed by the same rules -/// as an instance creation expression using new. +/// @assertion For the dynamic semantics, assume that k is a redirecting factory +/// constructor and k′ is the redirectee of k +/// ... +/// When the redirectee k′ is a generative constructor, let o be a +/// fresh instance of the class that contains k′. Execution of k then amounts to +/// execution of k′ to initialize o, governed by the same rules as an instance +/// creation expression. If k′ completed normally then the execution of k +/// completes normally returning o, otherwise k completes by throwing the +/// exception and stack trace thrown by k′. +/// /// @description Checks that compile error occurs when referenced type is not /// defined or refers to non class or non constructor. /// @author ilya - function() {} var variable; @@ -39,4 +43,5 @@ class D { } main() { + print(F); } diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_call_t03.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_call_t03.dart index 49ea1e6665..2edca4c888 100644 --- a/Language/Classes/Constructors/Factories/redirecting_constructor_call_t03.dart +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_call_t03.dart @@ -2,11 +2,16 @@ // 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 Calling a redirecting factory constructor k causes the -/// constructor k' denoted by type (respectively, type.identifier) to be called -/// with the actual arguments passed to k, and returns the result of k' as the -/// result of k. The resulting constructor call is governed by the same rules -/// as an instance creation expression using new. +/// @assertion For the dynamic semantics, assume that k is a redirecting factory +/// constructor and k′ is the redirectee of k +/// ... +/// When the redirectee k′ is a generative constructor, let o be a +/// fresh instance of the class that contains k′. Execution of k then amounts to +/// execution of k′ to initialize o, governed by the same rules as an instance +/// creation expression. If k′ completed normally then the execution of k +/// completes normally returning o, otherwise k completes by throwing the +/// exception and stack trace thrown by k′. +/// /// @description Checks that a call to redirecting factory constructor indeed /// results in a call to referenced constructor with the same actual arguments. /// Test type aliases diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_t01.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_t01.dart index f497656b3c..5588c7e816 100644 --- a/Language/Classes/Constructors/Factories/redirecting_constructor_t01.dart +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_t01.dart @@ -5,10 +5,13 @@ /// @assertion A redirecting factory constructor specifies a call to a /// constructor of another class that is to be used whenever the redirecting /// constructor is called. -/// redirectingFactoryConstructorSignature: -/// const? factory identifier (‘.’ identifier)? formalParameterList -/// ‘=’ typeName (‘.’ identifier)? -/// ; +/// ⟨redirectingFactoryConstructorSignature⟩ ::= +/// const? factory ⟨constructorName⟩ ⟨formalParameterList⟩ ‘=’ +/// ⟨constructorDesignation⟩ +/// ⟨constructorDesignation⟩ ::= ⟨typeIdentifier⟩ +/// | ⟨qualifiedName⟩ +/// | ⟨typeName⟩ ⟨typeArguments⟩ (‘.’ ⟨identifier⟩)? +/// /// @description Checks that correct declarations of redirecting factory /// constructors do not cause errors. /// @author kaigorodov diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_t02.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_t02.dart index 725b814d3b..b5300e6014 100644 --- a/Language/Classes/Constructors/Factories/redirecting_constructor_t02.dart +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_t02.dart @@ -5,15 +5,17 @@ /// @assertion A redirecting factory constructor specifies a call to a /// constructor of another class that is to be used whenever the redirecting /// constructor is called. -/// redirectingFactoryConstructorSignature: -/// const? factory identifier (‘.’ identifier)? formalParameterList -/// ‘=’ typeName (‘.’ identifier)? -/// ; +/// ⟨redirectingFactoryConstructorSignature⟩ ::= +/// const? factory ⟨constructorName⟩ ⟨formalParameterList⟩ ‘=’ +/// ⟨constructorDesignation⟩ +/// ⟨constructorDesignation⟩ ::= ⟨typeIdentifier⟩ +/// | ⟨qualifiedName⟩ +/// | ⟨typeName⟩ ⟨typeArguments⟩ (‘.’ ⟨identifier⟩)? +/// /// @description Checks that formal parameters list of redirecting factory /// constructor can not be omitted /// @author ilya - class A { A() {} factory A.foo = C; @@ -25,6 +27,18 @@ class A { class C extends A { } +enum E { + e1, e2; + const E(); + + factory E.f1() => E.e1; + factory E.f2 = E.f1; +// ^ +// [analyzer] unspecified +// [cfe] unspecified +} + main() { - new A.foo(); + print(A); + print(E); } diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_t03.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_t03.dart index 53cf13d93b..b26b6e7326 100644 --- a/Language/Classes/Constructors/Factories/redirecting_constructor_t03.dart +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_t03.dart @@ -5,15 +5,17 @@ /// @assertion A redirecting factory constructor specifies a call to a /// constructor of another class that is to be used whenever the redirecting /// constructor is called. -/// redirectingFactoryConstructorSignature: -/// const? factory identifier (‘.’ identifier)? formalParameterList -/// ‘=’ typeName (‘.’ identifier)? -/// ; +/// ⟨redirectingFactoryConstructorSignature⟩ ::= +/// const? factory ⟨constructorName⟩ ⟨formalParameterList⟩ ‘=’ +/// ⟨constructorDesignation⟩ +/// ⟨constructorDesignation⟩ ::= ⟨typeIdentifier⟩ +/// | ⟨qualifiedName⟩ +/// | ⟨typeName⟩ ⟨typeArguments⟩ (‘.’ ⟨identifier⟩)? +/// /// @description Checks that parameters list can not occur after another class /// constructor name /// @author ilya - class A { A() {} factory A.foo() = C(); @@ -27,6 +29,18 @@ class C extends A { // [analyzer] unspecified } +enum E { + e1, e2; + const E(); + + factory E.f1() => E.e1; + factory E.f2() = E.f1(); +// ^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + main() { - new A.foo(); + print(A); + print(E); } diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_t04.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_t04.dart index edbfb9a525..2a568c2ed5 100644 --- a/Language/Classes/Constructors/Factories/redirecting_constructor_t04.dart +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_t04.dart @@ -5,10 +5,13 @@ /// @assertion A redirecting factory constructor specifies a call to a /// constructor of another class that is to be used whenever the redirecting /// constructor is called. -/// redirectingFactoryConstructorSignature: -/// const? factory identifier (‘.’ identifier)? formalParameterList -/// ‘=’ typeName (‘.’ identifier)? -/// ; +/// ⟨redirectingFactoryConstructorSignature⟩ ::= +/// const? factory ⟨constructorName⟩ ⟨formalParameterList⟩ ‘=’ +/// ⟨constructorDesignation⟩ +/// ⟨constructorDesignation⟩ ::= ⟨typeIdentifier⟩ +/// | ⟨qualifiedName⟩ +/// | ⟨typeName⟩ ⟨typeArguments⟩ (‘.’ ⟨identifier⟩)? +/// /// @description Checks that correct declarations of redirecting factory /// constructors do not cause errors. Test type aliases /// @author sgrekhov@unipro.ru @@ -35,7 +38,17 @@ class D extends CAlias { } typedef DAlias = D; +enum E { + e1, e2; + const E(); + + factory E.f1() => E.e1; + factory E.f2() = EAlias.f1; +} +typedef EAlias = E; + main() { A a = new A.foo(); Expect.equals(2, a.m()); + Expect.identical(E.e1, E.f2()); } diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_t05.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_t05.dart new file mode 100644 index 0000000000..7e49d614d8 --- /dev/null +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_t05.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2023, 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 A redirecting factory constructor specifies a call to a +/// constructor of another class that is to be used whenever the redirecting +/// constructor is called. +/// ⟨redirectingFactoryConstructorSignature⟩ ::= +/// const? factory ⟨constructorName⟩ ⟨formalParameterList⟩ ‘=’ +/// ⟨constructorDesignation⟩ +/// ⟨constructorDesignation⟩ ::= ⟨typeIdentifier⟩ +/// | ⟨qualifiedName⟩ +/// | ⟨typeName⟩ ⟨typeArguments⟩ (‘.’ ⟨identifier⟩)? +/// +/// @description Checks that it is a compile-time error if any parameter of the +/// factory constructor has modifier `covariant` +/// @author sgrekhov22@gmail.com +/// @issue 54030 + +class F { + factory F(covariant num x) = C; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + factory F.f1(num x, [covariant num y]) = C.f1; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + factory F.f2(num x, {covariant num z}) = C.f2; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + factory F.f3(num x, {required covariant num z}) = C.f3; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +class C implements F { + num x, y = 1, z = 2; + + C(this.x); + C.f1(this.x, [this.y = 1]); + C.f2(this.x, {this.z = 2}); + C.f3(this.x, {required this.z}); +} + +enum E { + e1, e2; + const E(); + + factory E.g1(num x) => E.e1; + factory E.g2(num x, [num y = 1]) => E.e1; + factory E.g3(num x, {num z = 2}) => E.e1; + factory E.g4(num x, {num z = 2}) => E.e1; + factory E.f1(covariant num x) = E.g1; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + factory E.f2(num x, [covariant num y]) = E.g2; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + factory E.f3(num x, {covariant num z}) = E.g3; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + factory E.f4(num x, {required covariant num z}) = E.g3; +// ^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + print(C); + print(E); +} diff --git a/Language/Classes/Constructors/Factories/redirecting_constructor_t06.dart b/Language/Classes/Constructors/Factories/redirecting_constructor_t06.dart new file mode 100644 index 0000000000..931df302c9 --- /dev/null +++ b/Language/Classes/Constructors/Factories/redirecting_constructor_t06.dart @@ -0,0 +1,57 @@ +// Copyright (c) 2023, 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 A redirecting factory constructor specifies a call to a +/// constructor of another class that is to be used whenever the redirecting +/// constructor is called. +/// ⟨redirectingFactoryConstructorSignature⟩ ::= +/// const? factory ⟨constructorName⟩ ⟨formalParameterList⟩ ‘=’ +/// ⟨constructorDesignation⟩ +/// ⟨constructorDesignation⟩ ::= ⟨typeIdentifier⟩ +/// | ⟨qualifiedName⟩ +/// | ⟨typeName⟩ ⟨typeArguments⟩ (‘.’ ⟨identifier⟩)? +/// +/// @description Checks that it is a compile-time error if a redirecting factory +/// is external +/// @author sgrekhov22@gmail.com + +class F { + external factory F(num x) = C; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + external factory F.f1(num x) = C.f1; +// ^ +// [analyzer] unspecified +// [cfe] unspecified +} + +class C implements F { + num x; + + external C(this.x); + C.f1(this.x); +} + +enum E { + e1, e2; + const E(); + + factory E.g1(num x) => E.e1; + external factory E.f0(num x); + external factory E.f1(num x) = E.g1; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + external factory E.f2(num x) = E.f0; +// ^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + print(C); + print(E); +} diff --git a/Language/Classes/Constructors/Factories/return_type_A03_t01.dart b/Language/Classes/Constructors/Factories/return_type_A03_t01.dart new file mode 100644 index 0000000000..0903fef1b8 --- /dev/null +++ b/Language/Classes/Constructors/Factories/return_type_A03_t01.dart @@ -0,0 +1,54 @@ +// Copyright (c) 2023, 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 It is a dynamic type error if a factory returns a non-null object +/// whose type is not a subtype of its actual return type. +/// +/// @description Checks that it is a dynamic type error if a factory returns a +/// non-null object whose type is not a subtype of its actual return type. +/// @author sgrekhov22@gmail.com + +import "../../../../Utils/expect.dart"; + +class A {} + +class C extends A { + factory C() => "42" as dynamic; + + factory C.f1() => A() as dynamic; + + factory C.f2() => A() as C; +} + +enum E implements A { + e1, e2; + const E(); + + factory E.f1() => "42" as dynamic; + + factory E.f2() => A() as dynamic; + + factory E.f3() => A() as E; +} + +main() { + Expect.throws(() { + C(); + }); + Expect.throws(() { + C.f1(); + }); + Expect.throws(() { + C.f2(); + }); + Expect.throws(() { + E.f1(); + }); + Expect.throws(() { + E.f2(); + }); + Expect.throws(() { + E.f3(); + }); +} diff --git a/Language/Classes/Constructors/Factories/return_type_A03_t02.dart b/Language/Classes/Constructors/Factories/return_type_A03_t02.dart new file mode 100644 index 0000000000..f53637ba62 --- /dev/null +++ b/Language/Classes/Constructors/Factories/return_type_A03_t02.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2023, 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 It is a dynamic type error if a factory returns a non-null object +/// whose type is not a subtype of its actual return type. +/// +/// @description Checks that it is a dynamic type error if a factory returns a +/// null object. +/// @author sgrekhov22@gmail.com + +import "../../../../Utils/expect.dart"; + +class C { + factory C() => null as dynamic; +} + +enum E { + e1, e2; + const E(); + + factory E.f() => null as dynamic; +} + +main() { + Expect.throws(() { + C(); + }); + Expect.throws(() { + E.f(); + }); +} diff --git a/Language/Classes/Constructors/Factories/return_type_A03_t03.dart b/Language/Classes/Constructors/Factories/return_type_A03_t03.dart new file mode 100644 index 0000000000..89dd376796 --- /dev/null +++ b/Language/Classes/Constructors/Factories/return_type_A03_t03.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2023, 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 It is a dynamic type error if a factory returns a non-null object +/// whose type is not a subtype of its actual return type. +/// +/// @description Checks that it is a dynamic type error if a factory returns a +/// null object. +/// @author sgrekhov22@gmail.com + +class C { + factory C() => null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +enum E { + e1, e2; + const E(); + + factory E.f() => null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + print(C); + print(F); +}