[cfe] Report error on instantiation of enums from .dill
Closes https://github.com/dart-lang/sdk/issues/48350
Change-Id: I0cedf8a5a12e1a8dee546eec73e012519a054e13
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232384
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
index 65085dc..1e51ffb 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
@@ -28,6 +28,9 @@
@override
TypeDeclarationBuilder get origin;
+ /// Return `true` if this type declaration is an enum.
+ bool get isEnum;
+
/// Creates the [DartType] corresponding to this declaration applied with
/// [arguments] in [library] with the syntactical nullability defined by
/// [nullabilityBuilder].
@@ -75,6 +78,9 @@
bool get isTypeDeclaration => true;
@override
+ bool get isEnum => false;
+
+ @override
String get fullNameForErrors => name;
@override
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 18b8478..d8e6d6a 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -47,6 +47,9 @@
cls.fileOffset);
@override
+ bool get isEnum => cls.isEnum;
+
+ @override
DillClassBuilder get origin => this;
@override
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 422afdf..b2ab970 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -5371,7 +5371,7 @@
} else {
target = b.member;
}
- if (type is SourceEnumBuilder &&
+ if (type.isEnum &&
!(libraryBuilder.enableEnhancedEnumsInLibrary &&
target is Procedure &&
target.kind == ProcedureKind.Factory)) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index 7fd4e11..d23c72b 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -456,6 +456,9 @@
}
@override
+ bool get isEnum => true;
+
+ @override
TypeBuilder? get mixedInTypeBuilder => null;
@override
diff --git a/pkg/front_end/testcases/expression/instantiate_enum.expression.yaml b/pkg/front_end/testcases/expression/instantiate_enum.expression.yaml
new file mode 100644
index 0000000..b6739e7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/instantiate_enum.expression.yaml
@@ -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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ En(123, 'foo')
diff --git a/pkg/front_end/testcases/expression/instantiate_enum.expression.yaml.expect b/pkg/front_end/testcases/expression/instantiate_enum.expression.yaml.expect
new file mode 100644
index 0000000..447cbd7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/instantiate_enum.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+ org-dartlang-debug:synthetic_debug_expression:1:1: Error: Enums can't be instantiated.
+ En(123, 'foo')
+ ^^
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return invalid-expression "org-dartlang-debug:synthetic_debug_expression:1:1: Error: Enums can't be instantiated.\nEn(123, 'foo')\n^^";
diff --git a/pkg/front_end/testcases/expression/main.dart b/pkg/front_end/testcases/expression/main.dart
index 59f53f0..35045e1 100644
--- a/pkg/front_end/testcases/expression/main.dart
+++ b/pkg/front_end/testcases/expression/main.dart
@@ -127,3 +127,5 @@
.fold<int>(0, (previousValue, element) => previousValue + element.length);
print("xCombinedLength = $xCombinedLength");
}
+
+enum En { a, b, c }
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main.dart b/pkg/front_end/testcases/general/instantiate_enum/main.dart
new file mode 100644
index 0000000..85515b3
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main.dart
@@ -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.
+
+import 'main_lib.dart';
+
+enum Enum1 { a, b, c }
+
+typedef Alias1 = Enum1;
+
+test() {
+ Enum1(123, 'foo');
+ Enum2(123, 'foo');
+ Alias1(123, 'foo');
+ Alias2(123, 'foo');
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/instantiate_enum/main.dart.textual_outline.expect
new file mode 100644
index 0000000..9e362fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import 'main_lib.dart';
+
+enum Enum1 { a, b, c }
+typedef Alias1 = Enum1;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/instantiate_enum/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..596d8b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import 'main_lib.dart';
+
+enum Enum1 { a, b, c }
+main() {}
+test() {}
+typedef Alias1 = Enum1;
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.expect b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.expect
new file mode 100644
index 0000000..2976547
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.expect
@@ -0,0 +1,98 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
+// Enum1(123, 'foo');
+// ^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
+// Enum2(123, 'foo');
+// ^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
+// Alias1(123, 'foo');
+// ^^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
+// Alias2(123, 'foo');
+// ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+typedef Alias1 = self::Enum1;
+class Enum1 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::Enum1> values = #C10;
+ static const field self::Enum1 a = #C3;
+ static const field self::Enum1 b = #C6;
+ static const field self::Enum1 c = #C9;
+ const constructor •(core::int index, core::String name) → self::Enum1
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "Enum1.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
+ Enum1(123, 'foo');
+ ^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
+ Enum2(123, 'foo');
+ ^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
+ Alias1(123, 'foo');
+ ^^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
+ Alias2(123, 'foo');
+ ^^^^^^";
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+typedef Alias2 = self2::Enum2;
+class Enum2 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self2::Enum2> values = #C14;
+ static const field self2::Enum2 a = #C11;
+ static const field self2::Enum2 b = #C12;
+ static const field self2::Enum2 c = #C13;
+ const constructor •(core::int index, core::String name) → self2::Enum2
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "Enum2.${this.{core::_Enum::_name}{core::String}}";
+}
+
+constants {
+ #C1 = 0
+ #C2 = "a"
+ #C3 = self::Enum1 {index:#C1, _name:#C2}
+ #C4 = 1
+ #C5 = "b"
+ #C6 = self::Enum1 {index:#C4, _name:#C5}
+ #C7 = 2
+ #C8 = "c"
+ #C9 = self::Enum1 {index:#C7, _name:#C8}
+ #C10 = <self::Enum1*>[#C3, #C6, #C9]
+ #C11 = self2::Enum2 {index:#C1, _name:#C2}
+ #C12 = self2::Enum2 {index:#C4, _name:#C5}
+ #C13 = self2::Enum2 {index:#C7, _name:#C8}
+ #C14 = <self2::Enum2*>[#C11, #C12, #C13]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Enum2. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+
+org-dartlang-testcase:///main.dart:
+- Enum1. (from org-dartlang-testcase:///main.dart:7:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.modular.expect b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.modular.expect
new file mode 100644
index 0000000..8b09079
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.modular.expect
@@ -0,0 +1,72 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
+// Enum1(123, 'foo');
+// ^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
+// Enum2(123, 'foo');
+// ^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
+// Alias1(123, 'foo');
+// ^^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
+// Alias2(123, 'foo');
+// ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+typedef Alias1 = self::Enum1;
+class Enum1 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::Enum1> values = #C10;
+ static const field self::Enum1 a = #C3;
+ static const field self::Enum1 b = #C6;
+ static const field self::Enum1 c = #C9;
+ const constructor •(core::int index, core::String name) → self::Enum1
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "Enum1.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
+ Enum1(123, 'foo');
+ ^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
+ Enum2(123, 'foo');
+ ^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
+ Alias1(123, 'foo');
+ ^^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
+ Alias2(123, 'foo');
+ ^^^^^^";
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "a"
+ #C3 = self::Enum1 {index:#C1, _name:#C2}
+ #C4 = 1
+ #C5 = "b"
+ #C6 = self::Enum1 {index:#C4, _name:#C5}
+ #C7 = 2
+ #C8 = "c"
+ #C9 = self::Enum1 {index:#C7, _name:#C8}
+ #C10 = <self::Enum1*>[#C3, #C6, #C9]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main.dart:
+- Enum1. (from org-dartlang-testcase:///main.dart:7:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.outline.expect
new file mode 100644
index 0000000..cc966f8
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.outline.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+typedef Alias1 = self::Enum1;
+class Enum1 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::Enum1> values = const <self::Enum1>[self::Enum1::a, self::Enum1::b, self::Enum1::c];
+ static const field self::Enum1 a = const self::Enum1::•(0, "a");
+ static const field self::Enum1 b = const self::Enum1::•(1, "b");
+ static const field self::Enum1 c = const self::Enum1::•(2, "c");
+ const constructor •(core::int index, core::String name) → self::Enum1
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "Enum1.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+typedef Alias2 = self2::Enum2;
+class Enum2 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self2::Enum2> values = #C10;
+ static const field self2::Enum2 a = #C3;
+ static const field self2::Enum2 b = #C6;
+ static const field self2::Enum2 c = #C9;
+ const constructor •(core::int index, core::String name) → self2::Enum2
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "Enum2.${this.{core::_Enum::_name}{core::String}}";
+}
+
+constants {
+ #C1 = 0
+ #C2 = "a"
+ #C3 = self2::Enum2 {index:#C1, _name:#C2}
+ #C4 = 1
+ #C5 = "b"
+ #C6 = self2::Enum2 {index:#C4, _name:#C5}
+ #C7 = 2
+ #C8 = "c"
+ #C9 = self2::Enum2 {index:#C7, _name:#C8}
+ #C10 = <self2::Enum2*>[#C3, #C6, #C9]
+}
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///main.dart:7:6 -> ListConstant(const <Enum1*>[const Enum1{_Enum.index: 0, _Enum._name: "a"}, const Enum1{_Enum.index: 1, _Enum._name: "b"}, const Enum1{_Enum.index: 2, _Enum._name: "c"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:14 -> InstanceConstant(const Enum1{_Enum.index: 0, _Enum._name: "a"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:17 -> InstanceConstant(const Enum1{_Enum.index: 1, _Enum._name: "b"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:20 -> InstanceConstant(const Enum1{_Enum.index: 2, _Enum._name: "c"})
+Extra constant evaluation: evaluated: 14, effectively constant: 4
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Enum2. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..2976547
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main.dart.weak.transformed.expect
@@ -0,0 +1,98 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
+// Enum1(123, 'foo');
+// ^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
+// Enum2(123, 'foo');
+// ^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
+// Alias1(123, 'foo');
+// ^^^^^^
+//
+// pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
+// Alias2(123, 'foo');
+// ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+typedef Alias1 = self::Enum1;
+class Enum1 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::Enum1> values = #C10;
+ static const field self::Enum1 a = #C3;
+ static const field self::Enum1 b = #C6;
+ static const field self::Enum1 c = #C9;
+ const constructor •(core::int index, core::String name) → self::Enum1
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "Enum1.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
+ Enum1(123, 'foo');
+ ^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
+ Enum2(123, 'foo');
+ ^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
+ Alias1(123, 'foo');
+ ^^^^^^";
+ invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
+ Alias2(123, 'foo');
+ ^^^^^^";
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+typedef Alias2 = self2::Enum2;
+class Enum2 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self2::Enum2> values = #C14;
+ static const field self2::Enum2 a = #C11;
+ static const field self2::Enum2 b = #C12;
+ static const field self2::Enum2 c = #C13;
+ const constructor •(core::int index, core::String name) → self2::Enum2
+ : super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "Enum2.${this.{core::_Enum::_name}{core::String}}";
+}
+
+constants {
+ #C1 = 0
+ #C2 = "a"
+ #C3 = self::Enum1 {index:#C1, _name:#C2}
+ #C4 = 1
+ #C5 = "b"
+ #C6 = self::Enum1 {index:#C4, _name:#C5}
+ #C7 = 2
+ #C8 = "c"
+ #C9 = self::Enum1 {index:#C7, _name:#C8}
+ #C10 = <self::Enum1*>[#C3, #C6, #C9]
+ #C11 = self2::Enum2 {index:#C1, _name:#C2}
+ #C12 = self2::Enum2 {index:#C4, _name:#C5}
+ #C13 = self2::Enum2 {index:#C7, _name:#C8}
+ #C14 = <self2::Enum2*>[#C11, #C12, #C13]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Enum2. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+
+org-dartlang-testcase:///main.dart:
+- Enum1. (from org-dartlang-testcase:///main.dart:7:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/instantiate_enum/main_lib.dart b/pkg/front_end/testcases/general/instantiate_enum/main_lib.dart
new file mode 100644
index 0000000..f59f17d
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/main_lib.dart
@@ -0,0 +1,7 @@
+// 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.
+
+enum Enum2 { a, b, c }
+
+typedef Alias2 = Enum2;
diff --git a/pkg/front_end/testcases/general/instantiate_enum/test.options b/pkg/front_end/testcases/general/instantiate_enum/test.options
new file mode 100644
index 0000000..bfe6dc8
--- /dev/null
+++ b/pkg/front_end/testcases/general/instantiate_enum/test.options
@@ -0,0 +1 @@
+main_lib.dart
\ No newline at end of file