Skip to content

Commit

Permalink
[cfe] Report error on instantiation of enums from .dill
Browse files Browse the repository at this point in the history
Closes #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>
  • Loading branch information
johnniwinther authored and Commit Bot committed Feb 11, 2022
1 parent 7263b35 commit 2e6d7bf
Show file tree
Hide file tree
Showing 16 changed files with 403 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ abstract class TypeDeclarationBuilder implements ModifierBuilder {
@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].
Expand Down Expand Up @@ -74,6 +77,9 @@ abstract class TypeDeclarationBuilderImpl extends ModifierBuilderImpl
@override
bool get isTypeDeclaration => true;

@override
bool get isEnum => false;

@override
String get fullNameForErrors => name;

Expand Down
3 changes: 3 additions & 0 deletions pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class DillClassBuilder extends ClassBuilderImpl {
parent,
cls.fileOffset);

@override
bool get isEnum => cls.isEnum;

@override
DillClassBuilder get origin => this;

Expand Down
2 changes: 1 addition & 1 deletion pkg/front_end/lib/src/fasta/kernel/body_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5371,7 +5371,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
} else {
target = b.member;
}
if (type is SourceEnumBuilder &&
if (type.isEnum &&
!(libraryBuilder.enableEnhancedEnumsInLibrary &&
target is Procedure &&
target.kind == ProcedureKind.Factory)) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@ class SourceEnumBuilder extends SourceClassBuilder {
return enumBuilder;
}

@override
bool get isEnum => true;

@override
TypeBuilder? get mixedInTypeBuilder => null;

Expand Down
Original file line number Diff line number Diff line change
@@ -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')
Original file line number Diff line number Diff line change
@@ -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^^";
2 changes: 2 additions & 0 deletions pkg/front_end/testcases/expression/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,5 @@ void hasClosure() {
.fold<int>(0, (previousValue, element) => previousValue + element.length);
print("xCombinedLength = $xCombinedLength");
}

enum En { a, b, c }
18 changes: 18 additions & 0 deletions pkg/front_end/testcases/general/instantiate_enum/main.dart
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'main_lib.dart';

enum Enum1 { a, b, c }
typedef Alias1 = Enum1;
test() {}
main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'main_lib.dart';

enum Enum1 { a, b, c }
main() {}
test() {}
typedef Alias1 = Enum1;
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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)
Loading

0 comments on commit 2e6d7bf

Please sign in to comment.