[tests] Enum shorthands - Tests for constructors and static members.

A few starting tests for constructor and static member shorthands.

Test compile-time errors for `.new<types>` and `.new<types>()`.

Test that type alias get expanded before the shorthand inference is applied.

Bug: https://github.com/dart-lang/sdk/issues/57038
Change-Id: If32c9c027021ab31e7a9a5a07167058fac62f521
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398588
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
This commit is contained in:
Kallen Tu
2024-12-09 18:13:31 +00:00
committed by Commit Queue
parent 77caf366bb
commit 2ed121f795
6 changed files with 299 additions and 0 deletions
@@ -0,0 +1,45 @@
// 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.
// Errors involving enum shorthands of constructors.
// SharedOptions=--enable-experiment=enum-shorthands
import '../enum_shorthand_helper.dart';
void main() {
// Using a constructor shorthand without any context.
var ctorNew = .new();
// ^
// [analyzer] unspecified
// [cfe] unspecified
const ctorConstNew = .new();
// ^
// [analyzer] unspecified
// [cfe] unspecified
var ctorNamed = .regular();
// ^
// [analyzer] unspecified
// [cfe] unspecified
const ctorConstNamed = .regular();
// ^
// [analyzer] unspecified
// [cfe] unspecified
// `.new<type-args>()` and `.new<type-args>` are a compile-time error.
UnnamedConstructorTypeParameters typeParameters = .new<int>();
// ^
// [analyzer] unspecified
// [cfe] unspecified
UnnamedConstructorTypeParameters Function() tearOff = .new<int>;
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
@@ -0,0 +1,77 @@
// 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.
// Testing shorthands for constructor calls.
// SharedOptions=--enable-experiment=enum-shorthands
import '../enum_shorthand_helper.dart';
class ConstructorClassContext {
final ConstructorClass? x;
ConstructorClassContext(this.x);
ConstructorClassContext.named({this.x});
ConstructorClassContext.optional([this.x]);
}
class ConstructorExtContext {
final ConstructorExt? x;
ConstructorExtContext(this.x);
ConstructorExtContext.named({this.x});
ConstructorExtContext.optional([this.x]);
}
void main() {
int x = 1;
ConstructorClass ctor = .new(x);
ConstructorClass ctor1 = .regular(x);
ConstructorClass ctor2 = .named(x: x);
ConstructorClass ctor3 = .optional(x);
ConstructorClass ctor4 = .constRegular(x);
ConstructorClass ctor5 = .constNamed(x: x);
ConstructorClass ctor6 = .constOptional(x);
ConstructorExt ctorExt = .new(x);
ConstructorExt ctorExt1 = .regular(x);
ConstructorExt ctorExt2 = .named(x: x);
ConstructorExt ctorExt3 = .optional(x);
ConstructorExt ctorExt4 = .constRegular(x);
ConstructorExt ctorExt5 = .constNamed(x: x);
ConstructorExt ctorExt6 = .constOptional(x);
ConstructorClass? ctorNullable = .new(x);
ConstructorClass? ctorNullable1 = .regular(x);
ConstructorClass? ctorNullable2 = .named(x: x);
ConstructorClass? ctorNullable3 = .optional(x);
ConstructorClass? ctorNullable4 = .constRegular(x);
ConstructorClass? ctorNullable5 = .constNamed(x: x);
ConstructorClass? ctorNullable6 = .constOptional(x);
ConstructorExt? ctorExtNullable = .new(x);
ConstructorExt? ctorExtNullable1 = .regular(x);
ConstructorExt? ctorExtNullable2= .named(x: x);
ConstructorExt? ctorExtNullable3 = .optional(x);
ConstructorExt? ctorExtNullable4 = .constRegular(x);
ConstructorExt? ctorExtNullable5 = .constNamed(x: x);
ConstructorExt? ctorExtNullable6 = .constOptional(x);
UnnamedConstructor Function() ctorTearoff = .new;
// Parameter context type.
ConstructorClassContext(.new(1));
ConstructorClassContext.named(x: .optional(1));
ConstructorClassContext.optional(.optional(1));
ConstructorExtContext(.new(1));
ConstructorExtContext.named(x: .optional(1));
ConstructorExtContext.optional(.optional(1));
// Collection
<ConstructorClass>[.new(x), .regular(x), .constRegular(x)];
<ConstructorClass?>[.new(x), .regular(x), .constRegular(x)];
<ConstructorExt>[.new(x), .regular(x), .constRegular(x)];
<ConstructorExt?>[.new(x), .regular(x), .constRegular(x)];
}
@@ -37,3 +37,44 @@ class _IntegerWithMixin extends Integer with IntegerMixin {
const _IntegerWithMixin(int integer) : this._(integer);
const _IntegerWithMixin._(super.integer) : super._();
}
// Selector chain test declarations.
class ConstructorClass {
final int? x;
ConstructorClass(this.x);
ConstructorClass.regular(this.x);
ConstructorClass.named({this.x});
ConstructorClass.optional([this.x]);
const ConstructorClass.constRegular(this.x);
const ConstructorClass.constNamed({this.x});
const ConstructorClass.constOptional([this.x]);
}
class UnnamedConstructor {}
class UnnamedConstructorTypeParameters<T> {}
extension type ConstructorExt(int? x) {
ConstructorExt.regular(this.x);
ConstructorExt.named({this.x});
ConstructorExt.optional([this.x]);
const ConstructorExt.constRegular(this.x);
const ConstructorExt.constNamed({this.x});
const ConstructorExt.constOptional([this.x]);
}
class StaticMember<T> {
static StaticMember<int> member() => StaticMember(1);
static StaticMember<U> memberType<U, V>(U u) => StaticMember(u);
final T t;
StaticMember(this.t);
}
extension type StaticMemberExt<T>(T x) {
static StaticMemberExt<int> member() => StaticMemberExt(1);
static StaticMemberExt<U> memberType<U, V>(U u) => StaticMemberExt(u);
}
@@ -0,0 +1,51 @@
// 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.
// Basic usages of enum shorthands with static members in classes and extension
// types.
// SharedOptions=--enable-experiment=enum-shorthands
import '../enum_shorthand_helper.dart';
class StaticMemberContext {
final StaticMember? clas;
StaticMemberContext(this.clas);
StaticMemberContext.named({this.clas});
StaticMemberContext.optional([this.clas]);
}
class StaticMemberExtContext {
final StaticMemberExt? ext;
StaticMemberExtContext(this.ext);
StaticMemberExtContext.named({this.ext});
StaticMemberExtContext.optional([this.ext]);
}
void main() {
StaticMember<int> s = .member();
StaticMemberContext(.member());
StaticMemberContext.named(clas: .member());
StaticMemberContext.optional(.member());
StaticMember<String> sTypeParameters = .memberType("s");
StaticMemberContext(.memberType("s"));
StaticMemberContext.named(clas: .memberType("s"));
StaticMemberContext.optional(.memberType("s"));
StaticMemberExt<int> sExt = .member();
StaticMemberExtContext(.member());
StaticMemberExtContext.named(ext: .member());
StaticMemberExtContext.optional(.member());
StaticMemberExt<String> sTypeParametersExt = .memberType("s");
StaticMemberExtContext(.memberType("s"));
StaticMemberExtContext.named(ext: .memberType("s"));
StaticMemberExtContext.optional(.memberType("s"));
<StaticMember>[.member(), .memberType('s')];
<StaticMember?>[.member(), .memberType('s')];
<StaticMemberExt>[.member(), .memberType('s')];
<StaticMemberExt?>[.member(), .memberType('s')];
}
@@ -0,0 +1,32 @@
// 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.
// Errors when the type parameters of the shorthand methods don't match the
// context type.
// SharedOptions=--enable-experiment=enum-shorthands
import '../enum_shorthand_helper.dart';
void main() {
StaticMember<bool> s = .member();
// ^
// [analyzer] unspecified
// [cfe] unspecified
StaticMember<int> sTypeParameters = .memberType("s");
// ^
// [analyzer] unspecified
// [cfe] unspecified
StaticMemberExt<bool> sExt = .member();
// ^
// [analyzer] unspecified
// [cfe] unspecified
StaticMemberExt<int> sTypeParametersExt = .memberType("s");
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
@@ -0,0 +1,53 @@
// 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.
// Type aliases with enum shorthands.
// SharedOptions=--enable-experiment=enum-shorthands
typedef ClassAlias = A<int>;
typedef ExtensionAlias = AExt<int>;
class A<T> {
static ClassAlias get alias => A(1);
static const ClassAlias constAlias = const A._(1);
static ClassAlias method() => A(1);
final T t;
A(this.t);
const A._(this.t);
ClassAlias get aliasGetter => A(1);
}
extension type AExt<T>(T t) {
static ExtensionAlias get alias => AExt(1);
static const ExtensionAlias constAlias = const AExt._(1);
static ExtensionAlias method() => AExt(1);
const AExt._(this.t);
ExtensionAlias get aliasGetter => AExt(1);
}
void main() {
// Class
ClassAlias classAlias = .alias;
ClassAlias classAlias2 = .new('s').aliasGetter;
ClassAlias classAliasMethod = .method();
const ClassAlias constClassAlias = .constAlias;
// Extension type
ExtensionAlias extensionAlias = .alias;
ExtensionAlias extensionAliasCtor = .new('s').aliasGetter;
ExtensionAlias extensionAliasMethod = .method();
const ExtensionAlias constExtensionAlias = .constAlias;
}