Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 42976b2

Browse files
author
Dart CI
committed
Version 2.17.0-58.0.dev
Merge commit 'e0d0ff605976837486090055caded78f7b70d195' into 'dev'
2 parents fd27fda + e0d0ff6 commit 42976b2

11 files changed

+504
-54
lines changed

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

Lines changed: 80 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import '../fasta_codes.dart'
3737

3838
import '../kernel/body_builder.dart';
3939
import '../kernel/constructor_tearoff_lowering.dart';
40+
import '../kernel/expression_generator_helper.dart';
4041
import '../kernel/kernel_helper.dart';
4142
import '../kernel/internal_ast.dart';
4243

@@ -253,7 +254,20 @@ class SourceEnumBuilder extends SourceClassBuilder {
253254
members["values"] = valuesBuilder;
254255

255256
DeclaredSourceConstructorBuilder? synthesizedDefaultConstructorBuilder;
256-
if (constructorScope.local.isEmpty) {
257+
258+
// The default constructor is added if no generative or unnamed factory
259+
// constructors are declared.
260+
bool needsSynthesizedDefaultConstructor = true;
261+
if (constructorScope.local.isNotEmpty) {
262+
for (MemberBuilder constructorBuilder in constructorScope.local.values) {
263+
if (!constructorBuilder.isFactory || constructorBuilder.name == "") {
264+
needsSynthesizedDefaultConstructor = false;
265+
break;
266+
}
267+
}
268+
}
269+
270+
if (needsSynthesizedDefaultConstructor) {
257271
synthesizedDefaultConstructorBuilder =
258272
new DeclaredSourceConstructorBuilder(
259273
/* metadata = */ null,
@@ -540,6 +554,13 @@ class SourceEnumBuilder extends SourceClassBuilder {
540554
if (enumConstantInfos != null) {
541555
for (EnumConstantInfo? enumConstantInfo in enumConstantInfos!) {
542556
if (enumConstantInfo != null) {
557+
if (enumConstantInfo.argumentsBeginToken == null &&
558+
enumConstantInfo.constructorReferenceBuilder?.typeArguments !=
559+
null) {
560+
addProblem(messageEnumEntryWithTypeArgumentsWithoutArguments,
561+
enumConstantInfo.charOffset, noLength);
562+
}
563+
543564
String constant = enumConstantInfo.name;
544565
Builder declaration = firstMemberNamed(constant)!;
545566
SourceFieldBuilder field;
@@ -554,63 +575,69 @@ class SourceEnumBuilder extends SourceClassBuilder {
554575
MemberBuilder? constructorBuilder =
555576
constructorScopeBuilder[constructorName];
556577

557-
if (constructorBuilder == null ||
558-
constructorBuilder is! SourceConstructorBuilder) {
559-
// TODO(cstefantsova): Report an error.
560-
} else {
561-
if (enumConstantInfo.argumentsBeginToken == null &&
562-
enumConstantInfo.constructorReferenceBuilder?.typeArguments !=
563-
null) {
564-
addProblem(messageEnumEntryWithTypeArgumentsWithoutArguments,
565-
enumConstantInfo.charOffset, noLength);
566-
}
567-
568-
Arguments arguments;
569-
List<Expression> enumSyntheticArguments = <Expression>[
570-
new IntLiteral(index++),
571-
new StringLiteral(constant),
572-
];
573-
List<DartType>? typeArguments;
574-
List<TypeBuilder>? typeArgumentBuilders =
575-
enumConstantInfo.constructorReferenceBuilder?.typeArguments;
576-
if (typeArgumentBuilders != null) {
577-
typeArguments = <DartType>[];
578-
for (TypeBuilder typeBuilder in typeArgumentBuilders) {
579-
typeArguments.add(typeBuilder.build(library));
580-
}
581-
}
582-
BodyBuilder? bodyBuilder;
583-
if (enumConstantInfo.argumentsBeginToken != null ||
584-
typeArgumentBuilders == null && cls.typeParameters.isNotEmpty) {
585-
// We need to create a BodyBuilder in two cases: 1) if the
586-
// arguments token is provided, we'll use the BodyBuilder to
587-
// parse them and perform inference, 2) if the type arguments
588-
// aren't provided, but required, we'll use it to infer them.
589-
bodyBuilder = library.loader
590-
.createBodyBuilderForOutlineExpression(
591-
library, this, this, scope, fileUri);
592-
bodyBuilder.constantContext = ConstantContext.required;
578+
Arguments arguments;
579+
List<Expression> enumSyntheticArguments = <Expression>[
580+
new IntLiteral(index++),
581+
new StringLiteral(constant),
582+
];
583+
List<DartType>? typeArguments;
584+
List<TypeBuilder>? typeArgumentBuilders =
585+
enumConstantInfo.constructorReferenceBuilder?.typeArguments;
586+
if (typeArgumentBuilders != null) {
587+
typeArguments = <DartType>[];
588+
for (TypeBuilder typeBuilder in typeArgumentBuilders) {
589+
typeArguments.add(typeBuilder.build(library));
593590
}
591+
}
592+
BodyBuilder? bodyBuilder;
593+
if (enumConstantInfo.argumentsBeginToken != null ||
594+
typeArgumentBuilders == null && cls.typeParameters.isNotEmpty) {
595+
// We need to create a BodyBuilder in two cases: 1) if the
596+
// arguments token is provided, we'll use the BodyBuilder to
597+
// parse them and perform inference, 2) if the type arguments
598+
// aren't provided, but required, we'll use it to infer them.
599+
bodyBuilder = library.loader.createBodyBuilderForOutlineExpression(
600+
library, this, this, scope, fileUri);
601+
bodyBuilder.constantContext = ConstantContext.required;
602+
}
594603

595-
if (enumConstantInfo.argumentsBeginToken != null) {
596-
arguments = bodyBuilder!
597-
.parseArguments(enumConstantInfo.argumentsBeginToken!);
598-
bodyBuilder.performBacklogComputations(delayedActionPerformers);
604+
if (enumConstantInfo.argumentsBeginToken != null) {
605+
arguments = bodyBuilder!
606+
.parseArguments(enumConstantInfo.argumentsBeginToken!);
607+
bodyBuilder.performBacklogComputations(delayedActionPerformers);
599608

600-
arguments.positional.insertAll(0, enumSyntheticArguments);
601-
} else {
602-
arguments = new ArgumentsImpl(enumSyntheticArguments);
603-
}
609+
arguments.positional.insertAll(0, enumSyntheticArguments);
610+
} else {
611+
arguments = new ArgumentsImpl(enumSyntheticArguments);
612+
}
604613

605-
if (typeArguments != null && arguments is ArgumentsImpl) {
606-
ArgumentsImpl.setNonInferrableArgumentTypes(
607-
arguments, typeArguments);
608-
} else if (cls.typeParameters.isNotEmpty) {
609-
arguments.types.addAll(new List<DartType>.filled(
610-
cls.typeParameters.length, const UnknownType()));
611-
}
612-
setParents(enumSyntheticArguments, arguments);
614+
if (typeArguments != null && arguments is ArgumentsImpl) {
615+
ArgumentsImpl.setNonInferrableArgumentTypes(
616+
arguments, typeArguments);
617+
} else if (cls.typeParameters.isNotEmpty) {
618+
arguments.types.addAll(new List<DartType>.filled(
619+
cls.typeParameters.length, const UnknownType()));
620+
}
621+
setParents(enumSyntheticArguments, arguments);
613622

623+
if (constructorBuilder == null ||
624+
constructorBuilder is! SourceConstructorBuilder) {
625+
bodyBuilder ??= library.loader
626+
.createBodyBuilderForOutlineExpression(
627+
library, this, this, scope, fileUri)
628+
..constantContext = ConstantContext.required;
629+
field.buildBody(
630+
classHierarchy.coreTypes,
631+
bodyBuilder.buildUnresolvedError(
632+
new NullLiteral(),
633+
enumConstantInfo
634+
.constructorReferenceBuilder?.fullNameForErrors ??
635+
constructorName,
636+
arguments,
637+
enumConstantInfo.constructorReferenceBuilder?.charOffset ??
638+
enumConstantInfo.charOffset,
639+
kind: UnresolvedKind.Constructor));
640+
} else {
614641
Expression initializer = new ConstructorInvocation(
615642
constructorBuilder.constructor, arguments,
616643
isConst: true)
Lines changed: 18 additions & 0 deletions
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+
enum E {
6+
e1,
7+
e2;
8+
factory E.f(int i) => E.values[i];
9+
}
10+
11+
enum F {
12+
f1,
13+
f2(42),
14+
f3.foo();
15+
factory F(int i) => F.values[i];
16+
}
17+
18+
main() {}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
6+
// f1,
7+
// ^
8+
//
9+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:13:5: Error: Couldn't find constructor 'F'.
10+
// f2(42),
11+
// ^
12+
//
13+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:14:5: Error: Couldn't find constructor 'F.foo'.
14+
// f3.foo();
15+
// ^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
class E extends core::_Enum /*isEnum*/ {
21+
static const field core::List<self::E> values = #C7;
22+
static const field self::E e1 = #C3;
23+
static const field self::E e2 = #C6;
24+
const constructor •(core::int index, core::String name) → self::E
25+
: super core::_Enum::•(index, name)
26+
;
27+
method toString() → core::String
28+
return "E.${this.{core::_Enum::_name}{core::String}}";
29+
static factory f(core::int i) → self::E
30+
return #C7.{core::List::[]}(i){(core::int) → self::E};
31+
}
32+
class F extends core::_Enum /*isEnum*/ {
33+
static const field core::List<self::F> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
34+
f1,
35+
^";
36+
static const field self::F f1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
37+
f1,
38+
^";
39+
static const field self::F f2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:13:5: Error: Couldn't find constructor 'F'.
40+
f2(42),
41+
^";
42+
static const field self::F f3 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:14:5: Error: Couldn't find constructor 'F.foo'.
43+
f3.foo();
44+
^^^";
45+
method toString() → core::String
46+
return "F.${this.{core::_Enum::_name}{core::String}}";
47+
static factory •(core::int i) → self::F
48+
return invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
49+
f1,
50+
^".{core::List::[]}(i){(core::int) → self::F};
51+
}
52+
static method main() → dynamic {}
53+
54+
constants {
55+
#C1 = 0
56+
#C2 = "e1"
57+
#C3 = self::E {index:#C1, _name:#C2}
58+
#C4 = 1
59+
#C5 = "e2"
60+
#C6 = self::E {index:#C4, _name:#C5}
61+
#C7 = <self::E>[#C3, #C6]
62+
}
63+
64+
65+
Constructor coverage from constants:
66+
org-dartlang-testcase:///issue48181.dart:
67+
- E. (from org-dartlang-testcase:///issue48181.dart:5:6)
68+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
69+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
6+
// f1,
7+
// ^
8+
//
9+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:13:5: Error: Couldn't find constructor 'F'.
10+
// f2(42),
11+
// ^
12+
//
13+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:14:5: Error: Couldn't find constructor 'F.foo'.
14+
// f3.foo();
15+
// ^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
class E extends core::_Enum /*isEnum*/ {
21+
static const field core::List<self::E> values = #C7;
22+
static const field self::E e1 = #C3;
23+
static const field self::E e2 = #C6;
24+
const constructor •(core::int index, core::String name) → self::E
25+
: super core::_Enum::•(index, name)
26+
;
27+
method toString() → core::String
28+
return "E.${this.{core::_Enum::_name}{core::String}}";
29+
static factory f(core::int i) → self::E
30+
return #C7.{core::List::[]}(i){(core::int) → self::E};
31+
}
32+
class F extends core::_Enum /*isEnum*/ {
33+
static const field core::List<self::F> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
34+
f1,
35+
^";
36+
static const field self::F f1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
37+
f1,
38+
^";
39+
static const field self::F f2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:13:5: Error: Couldn't find constructor 'F'.
40+
f2(42),
41+
^";
42+
static const field self::F f3 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:14:5: Error: Couldn't find constructor 'F.foo'.
43+
f3.foo();
44+
^^^";
45+
method toString() → core::String
46+
return "F.${this.{core::_Enum::_name}{core::String}}";
47+
static factory •(core::int i) → self::F
48+
return invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
49+
f1,
50+
^".{core::List::[]}(i){(core::int) → self::F};
51+
}
52+
static method main() → dynamic {}
53+
54+
constants {
55+
#C1 = 0
56+
#C2 = "e1"
57+
#C3 = self::E {index:#C1, _name:#C2}
58+
#C4 = 1
59+
#C5 = "e2"
60+
#C6 = self::E {index:#C4, _name:#C5}
61+
#C7 = <self::E>[#C3, #C6]
62+
}
63+
64+
65+
Constructor coverage from constants:
66+
org-dartlang-testcase:///issue48181.dart:
67+
- E. (from org-dartlang-testcase:///issue48181.dart:5:6)
68+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
69+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum E { e1, e2; factory E.f(int i) => E.values[i]; }
2+
enum F { f1, f2(42), f3.foo(); factory F(int i) => F.values[i]; }
3+
main() {}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
6+
// f1,
7+
// ^
8+
//
9+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:13:5: Error: Couldn't find constructor 'F'.
10+
// f2(42),
11+
// ^
12+
//
13+
// pkg/front_end/testcases/enhanced_enums/issue48181.dart:14:5: Error: Couldn't find constructor 'F.foo'.
14+
// f3.foo();
15+
// ^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
class E extends core::_Enum /*isEnum*/ {
21+
static const field core::List<self::E> values = #C7;
22+
static const field self::E e1 = #C3;
23+
static const field self::E e2 = #C6;
24+
const constructor •(core::int index, core::String name) → self::E
25+
: super core::_Enum::•(index, name)
26+
;
27+
method toString() → core::String
28+
return "E.${this.{core::_Enum::_name}{core::String}}";
29+
static factory f(core::int i) → self::E
30+
return #C7.{core::List::[]}(i){(core::int) → self::E};
31+
}
32+
class F extends core::_Enum /*isEnum*/ {
33+
static const field core::List<self::F> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
34+
f1,
35+
^";
36+
static const field self::F f1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
37+
f1,
38+
^";
39+
static const field self::F f2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:13:5: Error: Couldn't find constructor 'F'.
40+
f2(42),
41+
^";
42+
static const field self::F f3 = invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:14:5: Error: Couldn't find constructor 'F.foo'.
43+
f3.foo();
44+
^^^";
45+
method toString() → core::String
46+
return "F.${this.{core::_Enum::_name}{core::String}}";
47+
static factory •(core::int i) → self::F
48+
return invalid-expression "pkg/front_end/testcases/enhanced_enums/issue48181.dart:12:5: Error: Couldn't find constructor 'F'.
49+
f1,
50+
^".{core::List::[]}(i){(core::int) → self::F};
51+
}
52+
static method main() → dynamic {}
53+
54+
constants {
55+
#C1 = 0
56+
#C2 = "e1"
57+
#C3 = self::E {index:#C1, _name:#C2}
58+
#C4 = 1
59+
#C5 = "e2"
60+
#C6 = self::E {index:#C4, _name:#C5}
61+
#C7 = <self::E*>[#C3, #C6]
62+
}
63+
64+
65+
Constructor coverage from constants:
66+
org-dartlang-testcase:///issue48181.dart:
67+
- E. (from org-dartlang-testcase:///issue48181.dart:5:6)
68+
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
69+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)

0 commit comments

Comments
 (0)