[cfe] Add more compiler-time errors for incorrect enum constructors

Additionaly this CL moves the arguments checks for redirecting and
super initializer invocations from the early stage of their creation
to a later stage of their addition to the list of constructor
initializers, after the possible modifications to the arguments of the
invocation are performed.

Change-Id: I87a3710c885926a74c844288bdf266e7127a9c40
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/229967
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
Chloe Stefantsova 2022-01-28 15:07:02 +00:00 committed by Commit Bot
parent 0d4595d5dc
commit 999f267d0e
28 changed files with 630 additions and 106 deletions

View file

@ -2769,6 +2769,15 @@ Message _withArgumentsEnumConstantSameNameAsEnclosing(String name) {
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeEnumConstructorSuperInitializer =
messageEnumConstructorSuperInitializer;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageEnumConstructorSuperInitializer = const MessageCode(
"EnumConstructorSuperInitializer",
problemMessage: r"""Enum constructors can't contain super-initializers.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeEnumDeclarationEmpty = messageEnumDeclarationEmpty;
@ -2816,6 +2825,15 @@ const MessageCode messageEnumInstantiation = const MessageCode(
analyzerCodes: <String>["INSTANTIATE_ENUM"],
problemMessage: r"""Enums can't be instantiated.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeEnumNonConstConstructor = messageEnumNonConstConstructor;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageEnumNonConstConstructor = const MessageCode(
"EnumNonConstConstructor",
problemMessage:
r"""Generative enum constructors must be marked as 'const'.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)>
templateEnumSupertypeOfNonAbstractClass =

View file

@ -1712,11 +1712,11 @@ class BodyBuilder extends ScopeListener<JumpTarget>
}
List<Initializer>? initializers = _initializers;
if (initializers != null) {
if (libraryBuilder.enableSuperParametersInLibrary) {
if (initializers.isNotEmpty && initializers.last is SuperInitializer) {
SuperInitializer superInitializer =
initializers.last as SuperInitializer;
if (initializers != null && initializers.isNotEmpty) {
if (initializers.last is SuperInitializer) {
SuperInitializer superInitializer =
initializers.last as SuperInitializer;
if (libraryBuilder.enableSuperParametersInLibrary) {
Arguments arguments = superInitializer.arguments;
if (positionalSuperParametersAsArguments != null) {
@ -1742,23 +1742,24 @@ class BodyBuilder extends ScopeListener<JumpTarget>
arguments.named.addAll(namedSuperParametersAsArguments);
setParents(namedSuperParametersAsArguments, arguments);
}
LocatedMessage? message = checkArgumentsForFunction(
superInitializer.target.function,
arguments,
arguments.fileOffset, <TypeParameter>[]);
if (message != null) {
initializers[initializers.length - 1] = buildInvalidInitializer(
buildUnresolvedError(
forest.createNullLiteral(superInitializer.fileOffset),
constructorNameForDiagnostics(
superInitializer.target.name.text),
arguments,
superInitializer.fileOffset,
isSuper: true,
message: message,
kind: UnresolvedKind.Constructor));
}
} else if (libraryBuilder.enableEnhancedEnumsInLibrary) {
initializers[initializers.length - 1] = buildInvalidInitializer(
buildProblem(fasta.messageEnumConstructorSuperInitializer,
superInitializer.fileOffset, noLength))
..parent = constructor;
}
} else if (initializers.last is RedirectingInitializer) {
RedirectingInitializer redirectingInitializer =
initializers.last as RedirectingInitializer;
if (libraryBuilder.enableEnhancedEnumsInLibrary) {
redirectingInitializer.arguments.positional.insertAll(0, [
new VariableGetImpl(constructor.function.positionalParameters[0],
forNullGuardedAccess: false)
..parent = redirectingInitializer.arguments,
new VariableGetImpl(constructor.function.positionalParameters[1],
forNullGuardedAccess: false)
..parent = redirectingInitializer.arguments
]);
}
}
@ -1775,41 +1776,11 @@ class BodyBuilder extends ScopeListener<JumpTarget>
}
}
}
if (asyncModifier != AsyncMarker.Sync) {
constructor.initializers.add(buildInvalidInitializer(buildProblem(
fasta.messageConstructorNotSync, body!.fileOffset, noLength)));
}
if (libraryBuilder.enableEnhancedEnumsInLibrary &&
sourceClassBuilder is SourceEnumBuilder &&
constructor.initializers.isNotEmpty &&
constructor.initializers.last is RedirectingInitializer) {
RedirectingInitializer redirectingInitializer =
constructor.initializers.last as RedirectingInitializer;
redirectingInitializer.arguments.positional.insertAll(0, [
new VariableGet(constructor.function.positionalParameters[0])
..parent = redirectingInitializer.arguments,
new VariableGet(constructor.function.positionalParameters[1])
..parent = redirectingInitializer.arguments
]);
LocatedMessage? message = checkArgumentsForFunction(
redirectingInitializer.target.function,
redirectingInitializer.arguments,
builder.charOffset, const <TypeParameter>[]);
if (message != null) {
Initializer invalidInitializer = buildInvalidInitializer(
buildUnresolvedError(
forest.createNullLiteral(redirectingInitializer.fileOffset),
constructorNameForDiagnostics(builder.name, isSuper: false),
redirectingInitializer.arguments,
redirectingInitializer.fileOffset,
isSuper: false,
message: message,
kind: UnresolvedKind.Constructor));
constructor.initializers.removeLast();
constructor.initializers.add(invalidInitializer..parent = constructor);
}
}
if (needsImplicitSuperInitializer) {
/// >If no superinitializer is provided, an implicit superinitializer
/// >of the form super() is added at the end of ks initializer list,

View file

@ -4570,32 +4570,14 @@ class ThisAccessGenerator extends Generator {
int offset, Name name, Arguments arguments) {
Constructor? constructor =
_helper.lookupConstructor(name, isSuper: isSuper);
LocatedMessage? message;
if (constructor != null) {
// The check of the arguments is done later for super initializers if the
// 'super-parameters' language feature is enabled. In that case the
// additional parameters can be added at a later stage.
bool isPotentialSuperParametersReceiver =
isSuper && _helper.libraryBuilder.enableSuperParametersInLibrary;
// Additional arguments are added to the redirecting initializer of an
// enum constructor, so the check is performed later.
bool isEnumConstructorRedirectingInitializer =
constructor.enclosingClass.isEnum;
if (!isPotentialSuperParametersReceiver &&
!isEnumConstructorRedirectingInitializer) {
message = _helper.checkArgumentsForFunction(
constructor.function, arguments, offset, <TypeParameter>[]);
}
} else {
if (constructor == null) {
String fullName =
_helper.constructorNameForDiagnostics(name.text, isSuper: isSuper);
message = (isSuper
LocatedMessage message = (isSuper
? templateSuperclassHasNoConstructor
: templateConstructorNotFound)
.withArguments(fullName)
.withLocation(_uri, fileOffset, lengthForToken(token));
}
if (message != null) {
return _helper.buildInvalidInitializer(
_helper.buildUnresolvedError(
_forest.createNullLiteral(offset),
@ -4609,10 +4591,10 @@ class ThisAccessGenerator extends Generator {
offset);
} else if (isSuper) {
return _helper.buildSuperInitializer(
false, constructor!, arguments, offset);
false, constructor, arguments, offset);
} else {
return _helper.buildRedirectingInitializer(
constructor!, arguments, offset);
constructor, arguments, offset);
}
}

View file

@ -21,16 +21,17 @@ import '../builder/type_declaration_builder.dart';
import '../builder/type_variable_builder.dart';
import '../constant_context.dart' show ConstantContext;
import '../dill/dill_member_builder.dart';
import '../identifiers.dart';
import '../kernel/body_builder.dart' show BodyBuilder;
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/expression_generator_helper.dart'
show ExpressionGeneratorHelper;
import '../kernel/expression_generator_helper.dart';
import '../kernel/hierarchy/class_member.dart' show ClassMember;
import '../kernel/kernel_helper.dart' show SynthesizedFunctionNode;
import '../kernel/utils.dart'
show isRedirectingGenerativeConstructorImplementation;
import '../messages.dart'
show
LocatedMessage,
Message,
messageMoreThanOneSuperInitializer,
messageRedirectingConstructorWithAnotherInitializer,
@ -83,6 +84,12 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
@override
List<FormalParameterBuilder>? formals;
@override
String get fullNameForErrors {
return "${flattenName(classBuilder.name, charOffset, fileUri)}"
"${name.isEmpty ? '' : '.$name'}";
}
DeclaredSourceConstructorBuilder(
List<MetadataBuilder>? metadata,
int modifiers,
@ -523,8 +530,27 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
helper);
} else {
inferenceResult?.applyResult(initializers, _constructor);
initializers.add(initializer..parent = _constructor);
superInitializer = initializer;
LocatedMessage? message = helper.checkArgumentsForFunction(
initializer.target.function,
initializer.arguments,
initializer.arguments.fileOffset, <TypeParameter>[]);
if (message != null) {
initializers.add(helper.buildInvalidInitializer(
helper.buildUnresolvedError(
helper.forest.createNullLiteral(initializer.fileOffset),
helper.constructorNameForDiagnostics(
initializer.target.name.text),
initializer.arguments,
initializer.fileOffset,
isSuper: true,
message: message,
kind: UnresolvedKind.Constructor))
..parent = _constructor);
} else {
initializers.add(initializer..parent = _constructor);
}
}
} else if (initializer is RedirectingInitializer) {
if (superInitializer != null) {
@ -559,8 +585,28 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
redirectingInitializer = initializer;
} else {
inferenceResult?.applyResult(initializers, _constructor);
initializers.add(initializer..parent = _constructor);
redirectingInitializer = initializer;
LocatedMessage? message = helper.checkArgumentsForFunction(
initializer.target.function,
initializer.arguments,
initializer.arguments.fileOffset, const <TypeParameter>[]);
if (message != null) {
initializers.add(helper.buildInvalidInitializer(
helper.buildUnresolvedError(
helper.forest.createNullLiteral(initializer.fileOffset),
helper.constructorNameForDiagnostics(
initializer.target.name.text,
isSuper: false),
initializer.arguments,
initializer.fileOffset,
isSuper: false,
message: message,
kind: UnresolvedKind.Constructor))
..parent = _constructor);
} else {
initializers.add(initializer..parent = _constructor);
}
}
} else if (redirectingInitializer != null) {
int length = noLength;

View file

@ -28,6 +28,7 @@ import '../fasta_codes.dart'
show
LocatedMessage,
messageEnumEntryWithTypeArgumentsWithoutArguments,
messageEnumNonConstConstructor,
messageNoUnnamedConstructorInObject,
noLength,
templateDuplicatedDeclaration,
@ -36,6 +37,7 @@ import '../fasta_codes.dart'
templateEnumConstantSameNameAsEnclosing;
import '../kernel/body_builder.dart';
import '../kernel/constness.dart';
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/expression_generator_helper.dart';
import '../kernel/kernel_helper.dart';
@ -435,8 +437,18 @@ class SourceEnumBuilder extends SourceClassBuilder {
}
members.forEach(setParent);
constructors.forEach(setParent);
constructorScope.local.forEach(setParent);
selfType.bind(enumBuilder);
if (constructorScope.local.isNotEmpty) {
for (MemberBuilder constructorBuilder in constructorScope.local.values) {
if (!constructorBuilder.isFactory && !constructorBuilder.isConst) {
parent.addProblem(messageEnumNonConstConstructor,
constructorBuilder.charOffset, noLength, fileUri);
}
}
}
return enumBuilder;
}
@ -590,12 +602,13 @@ class SourceEnumBuilder extends SourceClassBuilder {
}
}
BodyBuilder? bodyBuilder;
if (enumConstantInfo.argumentsBeginToken != null ||
typeArgumentBuilders == null && cls.typeParameters.isNotEmpty) {
// We need to create a BodyBuilder in two cases: 1) if the
// arguments token is provided, we'll use the BodyBuilder to
if (libraryBuilder.enableEnhancedEnumsInLibrary) {
// We need to create a BodyBuilder to solve the following: 1) if
// the arguments token is provided, we'll use the BodyBuilder to
// parse them and perform inference, 2) if the type arguments
// aren't provided, but required, we'll use it to infer them.
// aren't provided, but required, we'll use it to infer them, and
// 3) in case of erroneous code the constructor invocation should
// be built via a body builder to detect potential errors.
bodyBuilder = library.loader.createBodyBuilderForOutlineExpression(
library, this, this, scope, fileUri);
bodyBuilder.constantContext = ConstantContext.required;
@ -622,13 +635,9 @@ class SourceEnumBuilder extends SourceClassBuilder {
if (constructorBuilder == null ||
constructorBuilder is! SourceConstructorBuilder) {
bodyBuilder ??= library.loader
.createBodyBuilderForOutlineExpression(
library, this, this, scope, fileUri)
..constantContext = ConstantContext.required;
field.buildBody(
classHierarchy.coreTypes,
bodyBuilder.buildUnresolvedError(
bodyBuilder!.buildUnresolvedError(
new NullLiteral(),
enumConstantInfo
.constructorReferenceBuilder?.fullNameForErrors ??
@ -638,16 +647,23 @@ class SourceEnumBuilder extends SourceClassBuilder {
enumConstantInfo.charOffset,
kind: UnresolvedKind.Constructor));
} else {
Expression initializer = new ConstructorInvocation(
constructorBuilder.constructor, arguments,
isConst: true)
..fileOffset = field.charOffset;
Expression initializer;
if (bodyBuilder != null) {
initializer = bodyBuilder.buildStaticInvocation(
constructorBuilder.constructor, arguments,
constness: Constness.explicitConst,
charOffset: field.charOffset);
ExpressionInferenceResult inferenceResult =
bodyBuilder.typeInferrer.inferFieldInitializer(
bodyBuilder, const UnknownType(), initializer);
initializer = inferenceResult.expression;
if (initializer is ConstructorInvocation) {}
field.fieldType = inferenceResult.inferredType;
} else {
initializer = new ConstructorInvocation(
constructorBuilder.constructor, arguments,
isConst: true)
..fileOffset = field.charOffset;
}
field.buildBody(classHierarchy.coreTypes, initializer);
}

View file

@ -213,6 +213,8 @@ DuplicatedNamedArgument/example: Fail
DuplicatedParameterName/example: Fail
Encoding/analyzerCode: Fail
EnumConstantSameNameAsEnclosing/example: Fail
EnumConstructorSuperInitializer/analyzerCode: Fail
EnumConstructorSuperInitializer/example: Fail
EnumDeclaresConstFactory/analyzerCode: Fail
EnumDeclaresConstFactory/example: Fail
EnumDeclaresFactory/analyzerCode: Fail
@ -220,6 +222,8 @@ EnumDeclaresFactory/example: Fail
EnumEntryWithTypeArgumentsWithoutArguments/analyzerCode: Fail
EnumEntryWithTypeArgumentsWithoutArguments/example: Fail
EnumInstantiation/example: Fail
EnumNonConstConstructor/analyzerCode: Fail
EnumNonConstConstructor/example: Fail
EnumSupertypeOfNonAbstractClass/analyzerCode: Fail
EnumSupertypeOfNonAbstractClass/example: Fail
EqualityCannotBeEqualityOperand/part_wrapped_script1: Fail

View file

@ -5461,3 +5461,9 @@ EnumSupertypeOfNonAbstractClass:
EnumEntryWithTypeArgumentsWithoutArguments:
problemMessage: "Missing arguments in enum constructor invocation."
EnumNonConstConstructor:
problemMessage: "Generative enum constructors must be marked as 'const'."
EnumConstructorSuperInitializer:
problemMessage: "Enum constructors can't contain super-initializers."

View file

@ -14,7 +14,7 @@ class E<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> ex
static const field self::E<core::int, core::String> one = #C3;
static const field self::E<core::double, core::num> two = #C6;
static const field self::E<core::int, core::int> three = #C9;
static const field self::E<dynamic, dynamic> four = #C12;
static const field self::E<core::num, core::bool> four = #C12;
const constructor •(core::int index, core::String name) → self::E<self::E::X%, self::E::Y%>
: super core::_Enum::•(index, name)
;

View file

@ -14,7 +14,7 @@ class E<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> ex
static const field self::E<core::int, core::String> one = #C3;
static const field self::E<core::double, core::num> two = #C6;
static const field self::E<core::int, core::int> three = #C9;
static const field self::E<dynamic, dynamic> four = #C12;
static const field self::E<core::num, core::bool> four = #C12;
const constructor •(core::int index, core::String name) → self::E<self::E::X%, self::E::Y%>
: super core::_Enum::•(index, name)
;

View file

@ -14,7 +14,7 @@ class E<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> ex
static const field self::E<core::int, core::String> one = #C3;
static const field self::E<core::double, core::num> two = #C6;
static const field self::E<core::int, core::int> three = #C9;
static const field self::E<dynamic, dynamic> four = #C12;
static const field self::E<core::num, core::bool> four = #C12;
const constructor •(core::int index, core::String name) → self::E<self::E::X%, self::E::Y%>
: super core::_Enum::•(index, name)
;

View file

@ -14,7 +14,7 @@ class E<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> ex
static const field self::E<core::int, core::String> one = #C3;
static const field self::E<core::double, core::num> two = #C6;
static const field self::E<core::int, core::int> three = #C9;
static const field self::E<dynamic, dynamic> four = #C12;
static const field self::E<core::num, core::bool> four = #C12;
const constructor •(core::int index, core::String name) → self::E<self::E::X%, self::E::Y%>
: super core::_Enum::•(index, name)
;

View file

@ -14,7 +14,7 @@ class E<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> ex
static const field self::E<core::int, core::String> one = const self::E::•<core::int, core::String>(0, "one");
static const field self::E<core::double, core::num> two = const self::E::•<core::double, core::num>(1, "two");
static const field self::E<core::int, core::int> three = const self::E::named<core::int, core::int>(2, "three", 42);
static const field self::E<dynamic, dynamic> four = const self::E::•<core::num, core::bool>(3, "four");
static const field self::E<core::num, core::bool> four = const self::E::•<core::num, core::bool>(3, "four");
const constructor •(core::int index, core::String name) → self::E<self::E::X%, self::E::Y%>
: super core::_Enum::•(index, name)
;

View file

@ -14,7 +14,7 @@ class E<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> ex
static const field self::E<core::int, core::String> one = #C3;
static const field self::E<core::double, core::num> two = #C6;
static const field self::E<core::int, core::int> three = #C9;
static const field self::E<dynamic, dynamic> four = #C12;
static const field self::E<core::num, core::bool> four = #C12;
const constructor •(core::int index, core::String name) → self::E<self::E::X%, self::E::Y%>
: super core::_Enum::•(index, name)
;

View file

@ -0,0 +1,20 @@
// Copyright (c) 2021, 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 E1 {
element;
E1(); // Error.
E1.named(); // Error.
}
enum E2 {
one.named1(),
two.named2();
const E2.named1() : super(); // Error.
const E2.named2() : super(42, "42"); // Error.
}
main() {}

View file

@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:8:3: Error: Generative enum constructors must be marked as 'const'.
// E1(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:9:3: Error: Generative enum constructors must be marked as 'const'.
// E1.named(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// element;
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
// const E2.named1() : super(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
// const E2.named2() : super(42, "42"); // Error.
// ^
//
import self as self;
import "dart:core" as core;
class E1 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E1> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
static const field invalid-type element = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
constructor •(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
constructor named(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
method toString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E2> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 one = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 two = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^";
const constructor named1(core::int index, core::String name) → self::E2
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^"
;
const constructor named2(core::int index, core::String name) → self::E2
: final dynamic #t2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^"
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
static method main() → dynamic {}
Constructor coverage from constants:
org-dartlang-testcase:///malformed_constructors.dart:
- E2.named1 (from org-dartlang-testcase:///malformed_constructors.dart:16:9)
- E2.named2 (from org-dartlang-testcase:///malformed_constructors.dart:17:9)

View file

@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:8:3: Error: Generative enum constructors must be marked as 'const'.
// E1(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:9:3: Error: Generative enum constructors must be marked as 'const'.
// E1.named(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// element;
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
// const E2.named1() : super(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
// const E2.named2() : super(42, "42"); // Error.
// ^
//
import self as self;
import "dart:core" as core;
class E1 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E1> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
static const field invalid-type element = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
constructor •(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
constructor named(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
method toString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E2> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 one = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 two = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^";
const constructor named1(core::int index, core::String name) → self::E2
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^"
;
const constructor named2(core::int index, core::String name) → self::E2
: final dynamic #t2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^"
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
static method main() → dynamic {}
Constructor coverage from constants:
org-dartlang-testcase:///malformed_constructors.dart:
- E2.named1 (from org-dartlang-testcase:///malformed_constructors.dart:16:9)
- E2.named2 (from org-dartlang-testcase:///malformed_constructors.dart:17:9)

View file

@ -0,0 +1,3 @@
enum E1 { element; E1(); E1.named(); }
enum E2 { one.named1(), two.named2(); const E2.named1() : super(); const E2.named2() : super(42, "42"); }
main() {}

View file

@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:8:3: Error: Generative enum constructors must be marked as 'const'.
// E1(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:9:3: Error: Generative enum constructors must be marked as 'const'.
// E1.named(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// element;
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
// const E2.named1() : super(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
// const E2.named2() : super(42, "42"); // Error.
// ^
//
import self as self;
import "dart:core" as core;
class E1 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E1> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
static const field invalid-type element = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
constructor •(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
constructor named(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
method toString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E2> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 one = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 two = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^";
const constructor named1(core::int index, core::String name) → self::E2
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^"
;
const constructor named2(core::int index, core::String name) → self::E2
: final dynamic #t2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^"
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
static method main() → dynamic {}
Constructor coverage from constants:
org-dartlang-testcase:///malformed_constructors.dart:
- E2.named1 (from org-dartlang-testcase:///malformed_constructors.dart:16:9)
- E2.named2 (from org-dartlang-testcase:///malformed_constructors.dart:17:9)

View file

@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:8:3: Error: Generative enum constructors must be marked as 'const'.
// E1(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:9:3: Error: Generative enum constructors must be marked as 'const'.
// E1.named(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// element;
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
// const E2.named1() : super(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
// const E2.named2() : super(42, "42"); // Error.
// ^
//
import self as self;
import "dart:core" as core;
class E1 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E1> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
static const field invalid-type element = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
constructor •(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
constructor named(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
method toString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E2> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 one = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 two = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^";
const constructor named1(core::int index, core::String name) → self::E2
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^"
;
const constructor named2(core::int index, core::String name) → self::E2
: final dynamic #t2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^"
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
static method main() → dynamic {}
Constructor coverage from constants:
org-dartlang-testcase:///malformed_constructors.dart:
- E2.named1 (from org-dartlang-testcase:///malformed_constructors.dart:16:9)
- E2.named2 (from org-dartlang-testcase:///malformed_constructors.dart:17:9)

View file

@ -0,0 +1,60 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:8:3: Error: Generative enum constructors must be marked as 'const'.
// E1(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:9:3: Error: Generative enum constructors must be marked as 'const'.
// E1.named(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// element;
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
// const E2.named1() : super(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
// const E2.named2() : super(42, "42"); // Error.
// ^
//
import self as self;
import "dart:core" as core;
class E1 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E1> values = const <self::E1>[self::E1::element];
static const field invalid-type element = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
constructor •(core::int index, core::String name) → self::E1
;
constructor named(core::int index, core::String name) → self::E1
;
method toString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E2> values = const <self::E2>[self::E2::one, self::E2::two];
static const field self::E2 one = const self::E2::named1(0, "one");
static const field self::E2 two = const self::E2::named2(1, "two");
const constructor named1(core::int index, core::String name) → self::E2
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^"
;
const constructor named2(core::int index, core::String name) → self::E2
: final dynamic #t2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^"
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
static method main() → dynamic
;

View file

@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:8:3: Error: Generative enum constructors must be marked as 'const'.
// E1(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:9:3: Error: Generative enum constructors must be marked as 'const'.
// E1.named(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// element;
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
// const E2.named1() : super(); // Error.
// ^
//
// pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
// const E2.named2() : super(42, "42"); // Error.
// ^
//
import self as self;
import "dart:core" as core;
class E1 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E1> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
static const field invalid-type element = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:6:3: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
element;
^";
constructor •(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
constructor named(core::int index, core::String name) → self::E1
: super core::_Enum::•(index, name)
;
method toString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
static const field core::List<self::E2> values = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 one = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^";
static const field self::E2 two = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^";
const constructor named1(core::int index, core::String name) → self::E2
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:16:23: Error: Enum constructors can't contain super-initializers.
const E2.named1() : super(); // Error.
^"
;
const constructor named2(core::int index, core::String name) → self::E2
: final dynamic #t2 = invalid-expression "pkg/front_end/testcases/enhanced_enums/malformed_constructors.dart:17:23: Error: Enum constructors can't contain super-initializers.
const E2.named2() : super(42, \"42\"); // Error.
^"
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
static method main() → dynamic {}
Constructor coverage from constants:
org-dartlang-testcase:///malformed_constructors.dart:
- E2.named1 (from org-dartlang-testcase:///malformed_constructors.dart:16:9)
- E2.named2 (from org-dartlang-testcase:///malformed_constructors.dart:17:9)

View file

@ -2,6 +2,10 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:15: Error: A constant constructor can't call a non-constant super constructor.
// const B() : super();
// ^
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Error: Too few positional arguments: 1 required, 0 given.
// const B() : super();
// ^

View file

@ -2,6 +2,10 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:15: Error: A constant constructor can't call a non-constant super constructor.
// const B() : super();
// ^
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Error: Too few positional arguments: 1 required, 0 given.
// const B() : super();
// ^

View file

@ -2,6 +2,10 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:15: Error: A constant constructor can't call a non-constant super constructor.
// const B() : super();
// ^
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Error: Too few positional arguments: 1 required, 0 given.
// const B() : super();
// ^

View file

@ -2,6 +2,10 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:15: Error: A constant constructor can't call a non-constant super constructor.
// const B() : super();
// ^
//
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Error: Too few positional arguments: 1 required, 0 given.
// const B() : super();
// ^

View file

@ -34,6 +34,7 @@ enhanced_enums/inference_in_constructor_parameters: FormatterCrash
enhanced_enums/instantiated_generic_enum_types: FormatterCrash
enhanced_enums/issue48084: FormatterCrash
enhanced_enums/issue48181: FormatterCrash
enhanced_enums/malformed_constructors: FormatterCrash
enhanced_enums/members: FormatterCrash
enhanced_enums/named_arguments: FormatterCrash
enhanced_enums/qualified_names_with_no_type_arguments: FormatterCrash

View file

@ -31,11 +31,9 @@ class A {
A.illegalSuper() : this(3), super(3);
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUPER_IN_REDIRECTING_CONSTRUCTOR
// [cfe] A redirecting constructor can't have other initializers.
// [cfe] A redirecting constructor can't have a 'super' initializer.
// ^
// [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
// ^^^
// [cfe] Too many positional arguments: 0 allowed, but 1 found.
}
main() {

View file

@ -33,11 +33,9 @@ class A {
A.illegalSuper() : this(3), super(3);
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUPER_IN_REDIRECTING_CONSTRUCTOR
// [cfe] A redirecting constructor can't have other initializers.
// [cfe] A redirecting constructor can't have a 'super' initializer.
// ^
// [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
// ^^^
// [cfe] Too many positional arguments: 0 allowed, but 1 found.
}
main() {