[tests] Language tests for 'base' class modifier.

Change-Id: I2b5cf3d2d367d0cfd2d2da60268b36f16225ab1d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276762
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
This commit is contained in:
Kallen Tu 2023-01-09 22:29:14 +00:00 committed by Commit Queue
parent f502427120
commit 1e39261b4a
35 changed files with 730 additions and 0 deletions

View file

@ -0,0 +1,23 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Error when attempting to construct an abstract base class.
abstract base class NotConstructable {}
mixin M {}
abstract base class AlsoNotConstructable = Object with M;
main() {
var error = NotConstructable();
// ^
// [analyzer] unspecified
// [cfe] unspecified
var error2 = AlsoNotConstructable();
// ^
// [analyzer] unspecified
// [cfe] unspecified
}

View file

@ -0,0 +1,37 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow subtypes of a base class or mixin to be base as well.
import 'package:expect/expect.dart';
base class BaseClass {
int foo = 0;
}
base class A extends BaseClass {}
base class B implements BaseClass {
@override
int foo = 1;
}
base mixin BaseMixin {
int foo = 0;
}
base class AMixin with BaseMixin {}
base class BMixin = Object with BaseMixin;
// Used for trivial runtime tests of the base subtypes.
class AConcrete extends A {}
class BConcrete extends B {}
class AMixinConcrete extends AMixin {}
class BMixinConcrete extends BMixin {}
main() {
Expect.equals(0, AConcrete().foo);
Expect.equals(1, BConcrete().foo);
Expect.equals(0, AMixinConcrete().foo);
Expect.equals(0, BMixinConcrete().foo);
}

View file

@ -0,0 +1,15 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base classes to be extended by multiple classes in the same library.
base class BaseClass {
int foo = 0;
}
abstract class A extends BaseClass {}
class B extends BaseClass {}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Error when extending a base class where the subclass is not also a base class
// or final.
import 'base_class_extend_lib.dart';
abstract class AOutside extends BaseClass {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
class BOutside extends BaseClass {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

View file

@ -0,0 +1,21 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base classes to be extended by multiple classes outside its library.
import 'package:expect/expect.dart';
import 'base_class_extend_lib.dart';
abstract base class AOutside extends BaseClass {}
base class AOutsideImpl extends AOutside {}
base class BOutside extends BaseClass {}
main() {
Expect.equals(0, AOutsideImpl().foo);
Expect.equals(0, BOutside().foo);
}

View file

@ -0,0 +1,18 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base classes to be extended by multiple classes inside its
// library.
import 'package:expect/expect.dart';
import 'base_class_extend_lib.dart';
class AImpl extends A {}
main() {
Expect.equals(0, AImpl().foo);
Expect.equals(0, B().foo);
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Error when attempting to implement base class outside of library.
import 'base_class_implement_lib.dart';
abstract class AOutside implements BaseClass {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
class BOutside implements BaseClass {
// ^
// [analyzer] unspecified
// [cfe] unspecified
@override
int foo = 1;
}

View file

@ -0,0 +1,18 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base classes to be implemented by multiple classes in the same library.
base class BaseClass {
int foo = 0;
}
abstract class A implements BaseClass {}
class B implements BaseClass {
@override
int foo = 1;
}

View file

@ -0,0 +1,21 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base classes to be implemented by multiple classes inside its
// library.
import 'package:expect/expect.dart';
import 'base_class_implement_lib.dart';
class AImpl implements A {
@override
int foo = 1;
}
main() {
Expect.equals(1, AImpl().foo);
Expect.equals(1, B().foo);
}

View file

@ -0,0 +1,17 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
base class BaseClass {}
abstract class A extends BaseClass {}
class B extends BaseClass {}
base mixin BaseMixin {}
class C extends BaseClass with BaseMixin {}
class D with BaseMixin {}

View file

@ -0,0 +1,36 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow a base type to appear in the "on" clause of a mixin declaration in
// another library.
import 'package:expect/expect.dart';
import 'base_class_mixin_on_lib.dart';
mixin MA on BaseClass {}
mixin MB on BaseClass {}
class ConcreteA extends A with MA, MB {
int foo = 0;
}
mixin MC on BaseClass, BaseMixin {}
class ConcreteC extends C with MC {
int foo = 0;
}
mixin MCSingular on BaseMixin {}
class ConcreteD extends D with MCSingular {
int foo = 0;
}
main() {
Expect.equals(0, ConcreteA().foo);
Expect.equals(0, ConcreteC().foo);
Expect.equals(0, ConcreteD().foo);
}

View file

@ -0,0 +1,14 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
part of 'base_class_part_test.dart';
class A extends BaseClass {}
class B implements BaseClass {
@override
int foo = 1;
}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow extending and implementing base classes in a part file of
// the same library
import 'package:expect/expect.dart';
part 'base_class_part_lib.dart';
base class BaseClass {
int foo = 0;
}
main() {
Expect.equals(0, A().foo);
Expect.equals(1, B().foo);
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2022, 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.
// Make sure errors are emitted when trying to use base classes without
// the `class-modifiers` experiment enabled.
base class BaseClass {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
mixin M {}
base class BaseClassTypeAlias = Object with M;
// ^
// [analyzer] unspecified
// [cfe] unspecified
base mixin BaseMixin {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

View file

@ -0,0 +1,45 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Syntax errors such as using `base` keyword in a place other than a class or
// mixin.
abstract class BaseMembers {
base int foo;
// ^
// [analyzer] unspecified
// [cfe] unspecified
int bar(base int x);
// ^
// [analyzer] unspecified
// [cfe] unspecified
base void bar2();
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
base base class BaseDuplicateClass {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
base abstract class BaseAbstractClass {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
class BaseVariable {
int foo() {
base var x = 2;
// ^
// [analyzer] unspecified
// [cfe] unspecified
return x;
}
}

View file

@ -0,0 +1,17 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Tests that we can still use `base` as an identifier for mixin names.
import 'package:expect/expect.dart';
mixin class base {
int x = 0;
}
main() {
Expect.equals(0, base().x);
}

View file

@ -0,0 +1,19 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Tests that we can still use `base` as an identifier for mixin names.
import 'package:expect/expect.dart';
mixin base {
int x = 0;
}
class Class with base {}
main() {
Expect.equals(0, Class().x);
}

View file

@ -0,0 +1,58 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Tests we can still use `base` as an identifier.
import 'package:expect/expect.dart';
class base {
int x = 0;
}
class BaseField {
int base = 0;
}
class BaseMethod {
int base() => 1;
int foo(int base) => base;
int? foo1([int? base]) => base;
int? foo2({int? base}) => base;
}
class BaseVariable {
int foo() {
var base = 2;
return base;
}
}
class BaseAsType {
int foo(base x) => x.x;
base foo1 = base();
}
main() {
var baseClass = base();
var baseField = BaseField();
var baseMethod = BaseMethod();
var baseVariable = BaseVariable();
var baseAsType = BaseAsType();
Expect.equals(0, baseClass.x);
Expect.equals(0, baseField.base);
Expect.equals(1, baseMethod.base());
Expect.equals(1, baseMethod.foo(1));
Expect.equals(1, baseMethod.foo1(1));
Expect.equals(1, baseMethod.foo2(base: 1));
Expect.equals(2, baseVariable.foo());
Expect.equals(0, baseAsType.foo(base()));
Expect.equals(0, baseAsType.foo1.x);
}

View file

@ -0,0 +1,17 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Error when attempting to implement typedef base class outside of its library.
import 'base_class_typedef_lib.dart';
class BTypeDef implements BaseClassTypeDef {
// ^
// [analyzer] unspecified
// [cfe] unspecified
@override
int foo = 1;
}

View file

@ -0,0 +1,18 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
base class BaseClass {
int foo = 0;
}
typedef BaseClassTypeDef = BaseClass;
class A extends BaseClassTypeDef {}
class B implements BaseClassTypeDef {
@override
int foo = 1;
}

View file

@ -0,0 +1,17 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
import 'base_class_typedef_outside_of_library_lib2.dart';
base class BaseClass {
int foo = 0;
}
class A extends ATypeDef {}
class B implements ATypeDef {
int foo = 1;
}

View file

@ -0,0 +1,9 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
import "base_class_typedef_outside_of_library_lib.dart";
typedef ATypeDef = BaseClass;

View file

@ -0,0 +1,15 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow typedef in different library, used by class in library.
import 'package:expect/expect.dart';
import 'base_class_typedef_outside_of_library_lib.dart';
main() {
Expect.equals(0, A().foo);
Expect.equals(1, B().foo);
}

View file

@ -0,0 +1,16 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow typedef base classes to be extended and implemented by
// multiple classes in the same library.
import 'package:expect/expect.dart';
import 'base_class_typedef_lib.dart';
main() {
Expect.equals(0, A().foo);
Expect.equals(1, B().foo);
}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Error when trying to implement a typedef base class outside of
// the base class' library when the typedef is also outside the base class
// library.
import 'base_class_typedef_used_outside_lib.dart';
typedef ATypeDef = BaseClass;
class B implements ATypeDef {
// ^
// [analyzer] unspecified
// [cfe] unspecified
int foo = 1;
}

View file

@ -0,0 +1,9 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
base class BaseClass {
int foo = 0;
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Error when attempting to implement base mixin outside of library.
import 'base_mixin_implement_lib.dart';
abstract class AOutside implements BaseMixin {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
class BOutside implements BaseMixin {
// ^
// [analyzer] unspecified
// [cfe] unspecified
@override
int foo = 1;
}

View file

@ -0,0 +1,18 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base mixins to be implemented by multiple classes in the same library.
base mixin BaseMixin {
int foo = 0;
}
abstract class A implements BaseMixin {}
class B implements BaseMixin {
@override
int foo = 1;
}

View file

@ -0,0 +1,16 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
base mixin BaseMixin {
int foo = 0;
}
typedef BaseMixinTypeDef = BaseMixin;
class A with BaseMixinTypeDef {
@override
int foo = 1;
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow typedef base mixins to be mixed in by multiple classes outside the
// library.
import 'package:expect/expect.dart';
import 'base_mixin_typedef_with_lib.dart';
abstract base class AOutside with BaseMixinTypeDef {}
class AOutsideImpl extends AOutside {}
base class BOutside with BaseMixinTypeDef {}
main() {
Expect.equals(0, AOutsideImpl().foo);
Expect.equals(0, BOutside().foo);
}

View file

@ -0,0 +1,15 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow typedef base mixins to be mixed in by multiple classes in the same
// library.
import 'package:expect/expect.dart';
import 'base_mixin_typedef_with_lib.dart';
main() {
Expect.equals(1, A().foo);
}

View file

@ -0,0 +1,15 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base mixins to be mixed by multiple classes in the same library.
base mixin BaseMixin {
int foo = 0;
}
abstract class A with BaseMixin {}
class B with BaseMixin {}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Error when mixing in a base mixin where the class mixing it in is not base or
// final.
import 'base_mixin_with_lib.dart';
abstract class AOutside with BaseMixin {}
// ^
// [analyzer] unspecified
// [cfe] unspecified
class BOutside with BaseMixin {}
// ^
// [analyzer] unspecified
// [cfe] unspecified

View file

@ -0,0 +1,21 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base mixins to be mixed by multiple classes outside its library.
import 'package:expect/expect.dart';
import 'base_mixin_with_lib.dart';
abstract base class AOutside with BaseMixin {}
class AOutsideImpl extends AOutside {}
base class BOutside with BaseMixin {}
main() {
Expect.equals(0, AOutsideImpl().foo);
Expect.equals(0, BOutside().foo);
}

View file

@ -0,0 +1,17 @@
// Copyright (c) 2022, 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.
// SharedOptions=--enable-experiment=class-modifiers
// Allow base mixins to be mixed by multiple classes in the same library.
import 'package:expect/expect.dart';
import 'base_mixin_with_lib.dart';
class AImpl extends A {}
main() {
Expect.equals(0, AImpl().foo);
Expect.equals(0, B().foo);
}