Skip to content

Commit 2e6d7bf

Browse files
johnniwintherCommit Bot
authored and
Commit Bot
committed
[cfe] Report error on instantiation of enums from .dill
Closes #48350 Change-Id: I0cedf8a5a12e1a8dee546eec73e012519a054e13 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232384 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 7263b35 commit 2e6d7bf

16 files changed

+403
-1
lines changed

pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ abstract class TypeDeclarationBuilder implements ModifierBuilder {
2828
@override
2929
TypeDeclarationBuilder get origin;
3030

31+
/// Return `true` if this type declaration is an enum.
32+
bool get isEnum;
33+
3134
/// Creates the [DartType] corresponding to this declaration applied with
3235
/// [arguments] in [library] with the syntactical nullability defined by
3336
/// [nullabilityBuilder].
@@ -74,6 +77,9 @@ abstract class TypeDeclarationBuilderImpl extends ModifierBuilderImpl
7477
@override
7578
bool get isTypeDeclaration => true;
7679

80+
@override
81+
bool get isEnum => false;
82+
7783
@override
7884
String get fullNameForErrors => name;
7985

pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class DillClassBuilder extends ClassBuilderImpl {
4646
parent,
4747
cls.fileOffset);
4848

49+
@override
50+
bool get isEnum => cls.isEnum;
51+
4952
@override
5053
DillClassBuilder get origin => this;
5154

pkg/front_end/lib/src/fasta/kernel/body_builder.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -5371,7 +5371,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
53715371
} else {
53725372
target = b.member;
53735373
}
5374-
if (type is SourceEnumBuilder &&
5374+
if (type.isEnum &&
53755375
!(libraryBuilder.enableEnhancedEnumsInLibrary &&
53765376
target is Procedure &&
53775377
target.kind == ProcedureKind.Factory)) {

pkg/front_end/lib/src/fasta/source/source_enum_builder.dart

+3
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,9 @@ class SourceEnumBuilder extends SourceClassBuilder {
455455
return enumBuilder;
456456
}
457457

458+
@override
459+
bool get isEnum => true;
460+
458461
@override
459462
TypeBuilder? get mixedInTypeBuilder => null;
460463

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
# for details. All rights reserved. Use of this source code is governed by a
3+
# BSD-style license that can be found in the LICENSE file.
4+
5+
entry_point: "main.dart"
6+
definitions: []
7+
position: "main.dart"
8+
expression: |
9+
En(123, 'foo')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Errors: {
2+
org-dartlang-debug:synthetic_debug_expression:1:1: Error: Enums can't be instantiated.
3+
En(123, 'foo')
4+
^^
5+
}
6+
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
7+
return invalid-expression "org-dartlang-debug:synthetic_debug_expression:1:1: Error: Enums can't be instantiated.\nEn(123, 'foo')\n^^";

pkg/front_end/testcases/expression/main.dart

+2
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,5 @@ void hasClosure() {
127127
.fold<int>(0, (previousValue, element) => previousValue + element.length);
128128
print("xCombinedLength = $xCombinedLength");
129129
}
130+
131+
enum En { a, b, c }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'main_lib.dart';
6+
7+
enum Enum1 { a, b, c }
8+
9+
typedef Alias1 = Enum1;
10+
11+
test() {
12+
Enum1(123, 'foo');
13+
Enum2(123, 'foo');
14+
Alias1(123, 'foo');
15+
Alias2(123, 'foo');
16+
}
17+
18+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import 'main_lib.dart';
2+
3+
enum Enum1 { a, b, c }
4+
typedef Alias1 = Enum1;
5+
test() {}
6+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import 'main_lib.dart';
2+
3+
enum Enum1 { a, b, c }
4+
main() {}
5+
test() {}
6+
typedef Alias1 = Enum1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
6+
// Enum1(123, 'foo');
7+
// ^^^^^
8+
//
9+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
10+
// Enum2(123, 'foo');
11+
// ^^^^^
12+
//
13+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
14+
// Alias1(123, 'foo');
15+
// ^^^^^^
16+
//
17+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
18+
// Alias2(123, 'foo');
19+
// ^^^^^^
20+
//
21+
import self as self;
22+
import "dart:core" as core;
23+
24+
import "org-dartlang-testcase:///main_lib.dart";
25+
26+
typedef Alias1 = self::Enum1;
27+
class Enum1 extends core::_Enum /*isEnum*/ {
28+
static const field core::List<self::Enum1> values = #C10;
29+
static const field self::Enum1 a = #C3;
30+
static const field self::Enum1 b = #C6;
31+
static const field self::Enum1 c = #C9;
32+
const constructor •(core::int index, core::String name) → self::Enum1
33+
: super core::_Enum::•(index, name)
34+
;
35+
method toString() → core::String
36+
return "Enum1.${this.{core::_Enum::_name}{core::String}}";
37+
}
38+
static method test() → dynamic {
39+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
40+
Enum1(123, 'foo');
41+
^^^^^";
42+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
43+
Enum2(123, 'foo');
44+
^^^^^";
45+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
46+
Alias1(123, 'foo');
47+
^^^^^^";
48+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
49+
Alias2(123, 'foo');
50+
^^^^^^";
51+
}
52+
static method main() → dynamic {}
53+
54+
library /*isNonNullableByDefault*/;
55+
import self as self2;
56+
import "dart:core" as core;
57+
58+
typedef Alias2 = self2::Enum2;
59+
class Enum2 extends core::_Enum /*isEnum*/ {
60+
static const field core::List<self2::Enum2> values = #C14;
61+
static const field self2::Enum2 a = #C11;
62+
static const field self2::Enum2 b = #C12;
63+
static const field self2::Enum2 c = #C13;
64+
const constructor •(core::int index, core::String name) → self2::Enum2
65+
: super core::_Enum::•(index, name)
66+
;
67+
method toString() → core::String
68+
return "Enum2.${this.{core::_Enum::_name}{core::String}}";
69+
}
70+
71+
constants {
72+
#C1 = 0
73+
#C2 = "a"
74+
#C3 = self::Enum1 {index:#C1, _name:#C2}
75+
#C4 = 1
76+
#C5 = "b"
77+
#C6 = self::Enum1 {index:#C4, _name:#C5}
78+
#C7 = 2
79+
#C8 = "c"
80+
#C9 = self::Enum1 {index:#C7, _name:#C8}
81+
#C10 = <self::Enum1*>[#C3, #C6, #C9]
82+
#C11 = self2::Enum2 {index:#C1, _name:#C2}
83+
#C12 = self2::Enum2 {index:#C4, _name:#C5}
84+
#C13 = self2::Enum2 {index:#C7, _name:#C8}
85+
#C14 = <self2::Enum2*>[#C11, #C12, #C13]
86+
}
87+
88+
89+
Constructor coverage from constants:
90+
org-dartlang-testcase:///main_lib.dart:
91+
- Enum2. (from org-dartlang-testcase:///main_lib.dart:5:6)
92+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
93+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
94+
95+
org-dartlang-testcase:///main.dart:
96+
- Enum1. (from org-dartlang-testcase:///main.dart:7:6)
97+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
98+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
6+
// Enum1(123, 'foo');
7+
// ^^^^^
8+
//
9+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
10+
// Enum2(123, 'foo');
11+
// ^^^^^
12+
//
13+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
14+
// Alias1(123, 'foo');
15+
// ^^^^^^
16+
//
17+
// pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
18+
// Alias2(123, 'foo');
19+
// ^^^^^^
20+
//
21+
import self as self;
22+
import "dart:core" as core;
23+
24+
import "org-dartlang-testcase:///main_lib.dart";
25+
26+
typedef Alias1 = self::Enum1;
27+
class Enum1 extends core::_Enum /*isEnum*/ {
28+
static const field core::List<self::Enum1> values = #C10;
29+
static const field self::Enum1 a = #C3;
30+
static const field self::Enum1 b = #C6;
31+
static const field self::Enum1 c = #C9;
32+
const constructor •(core::int index, core::String name) → self::Enum1
33+
: super core::_Enum::•(index, name)
34+
;
35+
method toString() → core::String
36+
return "Enum1.${this.{core::_Enum::_name}{core::String}}";
37+
}
38+
static method test() → dynamic {
39+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:12:3: Error: Enums can't be instantiated.
40+
Enum1(123, 'foo');
41+
^^^^^";
42+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:13:3: Error: Enums can't be instantiated.
43+
Enum2(123, 'foo');
44+
^^^^^";
45+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:14:3: Error: Enums can't be instantiated.
46+
Alias1(123, 'foo');
47+
^^^^^^";
48+
invalid-expression "pkg/front_end/testcases/general/instantiate_enum/main.dart:15:3: Error: Enums can't be instantiated.
49+
Alias2(123, 'foo');
50+
^^^^^^";
51+
}
52+
static method main() → dynamic {}
53+
54+
constants {
55+
#C1 = 0
56+
#C2 = "a"
57+
#C3 = self::Enum1 {index:#C1, _name:#C2}
58+
#C4 = 1
59+
#C5 = "b"
60+
#C6 = self::Enum1 {index:#C4, _name:#C5}
61+
#C7 = 2
62+
#C8 = "c"
63+
#C9 = self::Enum1 {index:#C7, _name:#C8}
64+
#C10 = <self::Enum1*>[#C3, #C6, #C9]
65+
}
66+
67+
68+
Constructor coverage from constants:
69+
org-dartlang-testcase:///main.dart:
70+
- Enum1. (from org-dartlang-testcase:///main.dart:7:6)
71+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
72+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
import "org-dartlang-testcase:///main_lib.dart";
6+
7+
typedef Alias1 = self::Enum1;
8+
class Enum1 extends core::_Enum /*isEnum*/ {
9+
static const field core::List<self::Enum1> values = const <self::Enum1>[self::Enum1::a, self::Enum1::b, self::Enum1::c];
10+
static const field self::Enum1 a = const self::Enum1::•(0, "a");
11+
static const field self::Enum1 b = const self::Enum1::•(1, "b");
12+
static const field self::Enum1 c = const self::Enum1::•(2, "c");
13+
const constructor •(core::int index, core::String name) → self::Enum1
14+
: super core::_Enum::•(index, name)
15+
;
16+
method toString() → core::String
17+
return "Enum1.${this.{core::_Enum::_name}{core::String}}";
18+
}
19+
static method test() → dynamic
20+
;
21+
static method main() → dynamic
22+
;
23+
24+
library /*isNonNullableByDefault*/;
25+
import self as self2;
26+
import "dart:core" as core;
27+
28+
typedef Alias2 = self2::Enum2;
29+
class Enum2 extends core::_Enum /*isEnum*/ {
30+
static const field core::List<self2::Enum2> values = #C10;
31+
static const field self2::Enum2 a = #C3;
32+
static const field self2::Enum2 b = #C6;
33+
static const field self2::Enum2 c = #C9;
34+
const constructor •(core::int index, core::String name) → self2::Enum2
35+
: super core::_Enum::•(index, name)
36+
;
37+
method toString() → core::String
38+
return "Enum2.${this.{core::_Enum::_name}{core::String}}";
39+
}
40+
41+
constants {
42+
#C1 = 0
43+
#C2 = "a"
44+
#C3 = self2::Enum2 {index:#C1, _name:#C2}
45+
#C4 = 1
46+
#C5 = "b"
47+
#C6 = self2::Enum2 {index:#C4, _name:#C5}
48+
#C7 = 2
49+
#C8 = "c"
50+
#C9 = self2::Enum2 {index:#C7, _name:#C8}
51+
#C10 = <self2::Enum2*>[#C3, #C6, #C9]
52+
}
53+
54+
Extra constant evaluation status:
55+
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"}])
56+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:14 -> InstanceConstant(const Enum1{_Enum.index: 0, _Enum._name: "a"})
57+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:17 -> InstanceConstant(const Enum1{_Enum.index: 1, _Enum._name: "b"})
58+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:20 -> InstanceConstant(const Enum1{_Enum.index: 2, _Enum._name: "c"})
59+
Extra constant evaluation: evaluated: 14, effectively constant: 4
60+
61+
62+
Constructor coverage from constants:
63+
org-dartlang-testcase:///main_lib.dart:
64+
- Enum2. (from org-dartlang-testcase:///main_lib.dart:5:6)
65+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
66+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)

0 commit comments

Comments
 (0)