Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2976. Add constant expressions tests #3024

Merged
merged 3 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading