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

Fix #2546. Add constant context tests #2547

Merged
merged 3 commits into from
Feb 19, 2024
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,29 @@
// 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 Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// • e is an element of a list or set literal whose first token is const, or e
/// is a key or a value of an entry of a map literal whose first token is
/// const.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an element of a list literal whose first token is `const`. In this case
/// the `const` modifier for `e` can be omitted
/// @author sgrekhov22@gmail.com

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

class C {
final val;
const C(this.val);
}

main() {
var c1 = const [C(1)];
var c2 = const {C(2)};

Expect.identical(const C(1), c1[0]);
Expect.identical(const C(2), c2.first);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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 Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// • e is an element of a list or set literal whose first token is const, or e
/// is a key or a value of an entry of a map literal whose first token is
/// const.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an element of a list literal whose first token is `const`. In this case
/// the `const` modifier for `e` can be omitted
/// @author sgrekhov22@gmail.com

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

class C {
final val;
const C(this.val);
}

main() {
var c = const {C(1): C(2)};

Expect.identical(const C(2), c[const C(1)]);
Expect.identical(const C(1), c.keys.first);
}
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 Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// • e is an element of a list or set literal whose first token is const, or e
/// is a key or a value of an entry of a map literal whose first token is
/// const.
///
/// @description Checks that it is a compile-time error if `e` is an element of
/// a list or set literal whose first token is `const`, or `e` is a key or a
/// value of an entry of a map literal whose first token is `const` but `e` is
/// not a constant expression.
/// @author sgrekhov22@gmail.com

class C {
final val;
C(this.val);
}

main() {
const c1 = const [C(1)];
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

const c2 = const {C(2)};
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

const c3 = const {C(3): 0};
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

const c4 = const {0: C(4)};
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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 Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e occurs as @e in a construct derived from ⟨metadata⟩.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// occurs as `@e` in a construct derived from ⟨metadata⟩
/// @author sgrekhov22@gmail.com

import 'dart:mirrors';
eernstg marked this conversation as resolved.
Show resolved Hide resolved
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'dart:mirrors' will not work in the VM AOT mode, this test needs to be skipped for AOT builds.

Also 'dart:mirrors' is an unsupported feature, not sure why we need to add new tests to test it's funcitonality

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

class C {
final val;
const C(this.val);
}

@C(1)
class A {}

main() {
Expect.identical(const C(1), reflectClass(A).metadata[0].reflectee);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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 Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e is an actual argument in an expression derived from
/// ⟨constObjectExpression⟩.
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an actual argument in an expression derived from ⟨constObjectExpression⟩
/// @author sgrekhov22@gmail.com

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

class C {
final val;
const C(this.val);
}

main() {
const c = const C([]);
Expect.identical(c, const C([]));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// 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 Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e is the initializing expression of a constant variable declaration
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is the initializing expression of a constant variable declaration
/// @author sgrekhov22@gmail.com

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

class C {
final val;
const C(this.val);
}

main() {
const c = C(1);
Expect.identical(c, const C(1));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 Let e be an expression; e occurs in a constant context iff one of
/// the following applies:
/// ...
/// • e is an immediate subexpression of an expression e0 which occurs in a
/// constant context, where e0 is not a function literal
///
/// @description Checks that an expression `e` is a constant expression if `e`
/// is an immediate subexpression of an expression `e0` which occurs in a
/// constant context, where `e0` is not a function literal
/// @author sgrekhov22@gmail.com

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

class C {
final val;
const C(this.val);
}

Object foo(Object o) => o;

main() {
var c1 = const C(C(1));
const c2 = 2 > 1 ? C(0) : C(1);
var c3 = identical(C(3), C(3));
const c4 = identical(C(3), C(3));

Expect.identical(const C(1), c1.val);
Expect.identical(const C(0), c2);
Expect.isFalse(c3);
Expect.isTrue(c4);
}
Original file line number Diff line number Diff line change
@@ -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.

/// @assertion A constant context is introduced in situations where an
/// expression is required to be constant. This is used to allow the const
/// modifier to be omitted in cases where it does not contribute any new
/// information.
///
/// @description Checks that an initializer list is not a constant context
/// @author sgrekhov22@gmail.com

class A {
const A();
}

class C {
final val;
const C.c1() : this.val = [];
// ^^
// [analyzer] unspecified
// [cfe] unspecified

const C.c2() : this.val = A();
// ^^^
// [analyzer] unspecified
// [cfe] unspecified
}

main() {
print(C);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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 A constant context is introduced in situations where an
/// expression is required to be constant. This is used to allow the const
/// modifier to be omitted in cases where it does not contribute any new
/// information.
///
/// @description Checks that `when` part of a guard pattern is not a constant
/// context
/// @author sgrekhov22@gmail.com

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

class C {
final val;
const C(this.val);
}

const c1 = C(1);

bool test(bool b) => switch(b) {
true when identical(c1, C(1)) => true,
_ => false
};

main() {
bool wasTrue = false;

if (2 > 1 case true when identical(c1, C(1))) {
wasTrue = true;
}
Expect.isFalse(wasTrue);

switch (true) {
case true when identical(c1, C(1)):
wasTrue = true;
default:
}
Expect.isFalse(wasTrue);
Expect.isFalse(test(true));
}