Skip to content

Commit

Permalink
dart-lang#2976. Add constant expressions tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrekhov committed Dec 24, 2024
1 parent e07a25b commit a1bc2c9
Show file tree
Hide file tree
Showing 10 changed files with 587 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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 Given an expression that is a prefix of
/// `<staticMemberShorthandHead> <selector>*`, whose assigned shorthand context
/// denotes a declaration D, and where the identifier or `new` of the
/// `<staticMemberShorthandHead>` denotes a static declaration or constructor
/// declaration S when looked up on D.
/// - An expression of the form `const .id(arguments)` or
/// `const .new(arguments)` is a constant expression. It's a compile-time
/// error if S does not declare a constant constructor, and if any expression
/// in `arguments`, which are all in a constant context, is not a constant
/// expression.
///
/// @description Checks that expressions of the form `const .id(arguments)` and
/// `const .new(arguments)` are constant expressions.
/// @author [email protected]
// SharedOptions=--enable-experiment=enum-shorthands

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

class C {
final String value;
const C(this.value);
const C.id(this.value);
const factory C.f(String value) = C;
}

extension type const ET(String value) {
const ET.id(this.value);
const factory ET.f(String value) = ET;
}

main() {
const C c1 = const .new("one");
Expect.equals("one", c1.value);

const C c2 = const .id("two");
Expect.equals("two", c2.value);

const C c3 = const .f("three");
Expect.equals("three", c3.value);

const ET et1 = const .new("new");
Expect.equals("new", et1.value);

const ET et2 = const .id("id");
Expect.equals("id", et2.value);

const ET et3 = const .f("f");
Expect.equals("f", et3.value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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 Given an expression that is a prefix of
/// `<staticMemberShorthandHead> <selector>*`, whose assigned shorthand context
/// denotes a declaration D, and where the identifier or `new` of the
/// `<staticMemberShorthandHead>` denotes a static declaration or constructor
/// declaration S when looked up on D.
/// - An expression of the form `const .id(arguments)` or
/// `const .new(arguments)` is a constant expression. It's a compile-time
/// error if S does not declare a constant constructor, and if any expression
/// in `arguments`, which are all in a constant context, is not a constant
/// expression.
///
/// @description Checks that it's a compile-time error to use expressions of the
/// form `const .id(arguments)` or `const .new(arguments)` if constructors in an
/// appropriate declaration are not constant constructors.
/// @author [email protected]
// SharedOptions=--enable-experiment=enum-shorthands

class C {
final String value;
C(this.value);
C.id(this.value);
factory C.f(String value) = C;
}

extension type ET(String value) {
ET.id(this.value);
factory ET.f(String value) = ET;
}

main() {
const C c1 = const .new("one");
// ^
// [analyzer] unspecified
// [cfe] unspecified

const C c2 = const .id("two");
// ^
// [analyzer] unspecified
// [cfe] unspecified

const C c3 = const .f("three");
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et1 = const .new("new");
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et2 = const .id("id");
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et3 = const .f("f");
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// 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 Given an expression that is a prefix of
/// `<staticMemberShorthandHead> <selector>*`, whose assigned shorthand context
/// denotes a declaration D, and where the identifier or `new` of the
/// `<staticMemberShorthandHead>` denotes a static declaration or constructor
/// declaration S when looked up on D.
/// - An expression of the form `const .id(arguments)` or
/// `const .new(arguments)` is a constant expression. It's a compile-time
/// error if S does not declare a constant constructor, and if any expression
/// in `arguments`, which are all in a constant context, is not a constant
/// expression.
///
/// @description Checks that it's a compile-time error to use expressions of the
/// form `const .id(arguments)` or `const .new(arguments)` if any expression in
/// `arguments` is not a constant expression.
/// @author [email protected]
// SharedOptions=--enable-experiment=enum-shorthands

class C {
final String value;
const C(this.value, [String s = ""]);
const C.id(this.value, {String s = ""});
const factory C.f(String value) = C;
}

extension type const ET(String value) {
const ET.id(this.value, [String s = ""]);
const factory ET.f(String value, {String s = ""}) = ET;
}

main() {
String s = "Not a constant";
const C c1 = const .new(s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const C c2 = const .new("one", s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const C c3 = const .id(s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const C c4 = const .id("two", s: s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const C c5 = const .f(s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const C c6 = const .f("three", s: s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et1 = const .new(s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et2 = const .new("new", s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et3 = const .id(s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et4 = const .id("id", s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et5 = const .f(s);
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et6 = const .f("f", s: s);
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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 Given an expression that is a prefix of
/// `<staticMemberShorthandHead> <selector>*`, whose assigned shorthand context
/// denotes a declaration D, and where the identifier or `new` of the
/// `<staticMemberShorthandHead>` denotes a static declaration or constructor
/// declaration S when looked up on D.
/// ...
/// - An expression of the form `.<identifier>` is a constant expression if S
/// declares a constant getter.
///
/// @description Checks that expressions of the form `<identifier>` is a
/// constant expression if the appropriate declaration declares a constant
/// getter with the name `<identifier>`.
/// @author [email protected]
// SharedOptions=--enable-experiment=enum-shorthands

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

class C {
final String value;
static const C instance = C("C instance");

const C(this.value);
}

mixin M {
final String value;
static const M instance = MO("M instance");
}

class MO = Object with M;

extension type const ET(String value) {
static const instance = ET("ET instance");
}

main() {
const C c = .instance;
Expect.equals("C instance", c.value);

const ET et = .instance;
Expect.equals("ET instance", et.value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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 Given an expression that is a prefix of
/// `<staticMemberShorthandHead> <selector>*`, whose assigned shorthand context
/// denotes a declaration D, and where the identifier or `new` of the
/// `<staticMemberShorthandHead>` denotes a static declaration or constructor
/// declaration S when looked up on D.
/// ...
/// - An expression of the form `.<identifier>` is a constant expression if S
/// declares a constant getter.
///
/// @description Checks that it is a compile-time error to use an expressions of
/// the form `.<identifier>` in a constant context if `<identifier>` is an
/// explicit getter declaration.
/// @author [email protected]
// SharedOptions=--enable-experiment=enum-shorthands

class C {
final String value;
static C get instance => const C("C instance");

const C(this.value);
}

extension type const ET(String value) {
static ET get instance => const ET("ET instance");
}

main() {
const C c = .instance;
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et = .instance;
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 Given an expression that is a prefix of
/// `<staticMemberShorthandHead> <selector>*`, whose assigned shorthand context
/// denotes a declaration D, and where the identifier or `new` of the
/// `<staticMemberShorthandHead>` denotes a static declaration or constructor
/// declaration S when looked up on D.
/// ...
/// - (An expression of the form `.new` followed by a `<typeArguments>` is still
/// a compile-time error.)
///
/// @description Checks that an expression of the form `.new` followed by a
/// `<typeArguments>` is still a compile-time error.
/// @author [email protected]
// SharedOptions=--enable-experiment=enum-shorthands

class C<T> {
const C();
}

extension type const ET<T>(T _) {}

main() {
const C<int> c = const .new<int>();
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified

const ET<int> et = const .new<int>(0);
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Loading

0 comments on commit a1bc2c9

Please sign in to comment.