[cfe] Fix incorrect const contexts.
Fixes https://github.com/dart-lang/sdk/issues/36533 Change-Id: Id157edb09ee5bf16003b33b16ecf6edc900b38f1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117324 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
515a597710
commit
3fa2bbf202
@@ -165,7 +165,7 @@ class FieldBuilder extends MemberBuilder {
|
||||
.createBodyBuilderForOutlineExpression(
|
||||
library, classBuilder, this, scope, fileUri);
|
||||
bodyBuilder.constantContext =
|
||||
isConst ? ConstantContext.inferred : ConstantContext.none;
|
||||
isConst ? ConstantContext.inferred : ConstantContext.required;
|
||||
initializer = bodyBuilder.parseFieldInitializer(constInitializerToken)
|
||||
..parent = field;
|
||||
bodyBuilder.typeInferrer
|
||||
|
||||
@@ -905,7 +905,7 @@ class ConstructorBuilder extends FunctionBuilder {
|
||||
BodyBuilder bodyBuilder = library.loader
|
||||
.createBodyBuilderForOutlineExpression(
|
||||
library, classBuilder, this, classBuilder.scope, fileUri);
|
||||
bodyBuilder.constantContext = ConstantContext.inferred;
|
||||
bodyBuilder.constantContext = ConstantContext.required;
|
||||
bodyBuilder.parseInitializers(beginInitializers);
|
||||
bodyBuilder.resolveRedirectingFactoryTargets();
|
||||
}
|
||||
|
||||
@@ -6925,6 +6925,16 @@ const MessageCode messageMissingConstFinalVarOrType = const MessageCode(
|
||||
tip:
|
||||
r"""Try adding the name of the type of the variable or the keyword 'var'.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Null> codeMissingExplicitConst = messageMissingExplicitConst;
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const MessageCode messageMissingExplicitConst = const MessageCode(
|
||||
"MissingExplicitConst",
|
||||
analyzerCodes: <String>["NOT_CONSTANT_EXPRESSION"],
|
||||
message: r"""Constant expression expected.""",
|
||||
tip: r"""Try inserting 'const'.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(int count)>
|
||||
templateMissingExplicitTypeArguments =
|
||||
|
||||
@@ -2491,6 +2491,11 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
int count, Token leftBracket, Token constKeyword, Token rightBracket) {
|
||||
debugEvent("LiteralList");
|
||||
|
||||
if (constantContext == ConstantContext.required && constKeyword == null) {
|
||||
addProblem(fasta.messageMissingExplicitConst, offsetForToken(leftBracket),
|
||||
noLength);
|
||||
}
|
||||
|
||||
// TODO(danrubel): Replace this with popListForValue
|
||||
// when control flow and spread collections have been enabled by default
|
||||
List<Expression> expressions =
|
||||
@@ -2583,6 +2588,11 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
) {
|
||||
debugEvent("LiteralSetOrMap");
|
||||
|
||||
if (constantContext == ConstantContext.required && constKeyword == null) {
|
||||
addProblem(fasta.messageMissingExplicitConst, offsetForToken(leftBrace),
|
||||
noLength);
|
||||
}
|
||||
|
||||
List<dynamic> setOrMapEntries =
|
||||
new List<dynamic>.filled(count, null, growable: true);
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
@@ -3445,12 +3455,14 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
charOffset);
|
||||
}
|
||||
|
||||
bool isConst = constness == Constness.explicitConst;
|
||||
bool isConst = constness == Constness.explicitConst ||
|
||||
constantContext != ConstantContext.none;
|
||||
if (target is Constructor) {
|
||||
isConst =
|
||||
isConst || constantContext != ConstantContext.none && target.isConst;
|
||||
if ((isConst || constantContext == ConstantContext.inferred) &&
|
||||
!target.isConst) {
|
||||
if (constantContext == ConstantContext.required &&
|
||||
constness == Constness.implicit) {
|
||||
addProblem(fasta.messageMissingExplicitConst, charOffset, charLength);
|
||||
}
|
||||
if (isConst && !target.isConst) {
|
||||
return wrapInvalidConstructorInvocation(
|
||||
desugarSyntheticExpression(buildProblem(
|
||||
fasta.messageNonConstConstructor, charOffset, charLength)),
|
||||
@@ -3467,10 +3479,11 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
} else {
|
||||
Procedure procedure = target;
|
||||
if (procedure.isFactory) {
|
||||
isConst = isConst ||
|
||||
constantContext != ConstantContext.none && procedure.isConst;
|
||||
if ((isConst || constantContext == ConstantContext.inferred) &&
|
||||
!procedure.isConst) {
|
||||
if (constantContext == ConstantContext.required &&
|
||||
constness == Constness.implicit) {
|
||||
addProblem(fasta.messageMissingExplicitConst, charOffset, charLength);
|
||||
}
|
||||
if (isConst && !procedure.isConst) {
|
||||
return wrapInvalidConstructorInvocation(
|
||||
desugarSyntheticExpression(buildProblem(
|
||||
fasta.messageNonConstFactory, charOffset, charLength)),
|
||||
@@ -3486,8 +3499,9 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
node, typeEnvironment, uri);
|
||||
return node;
|
||||
} else {
|
||||
assert(constness == Constness.implicit);
|
||||
StaticInvocation node =
|
||||
new StaticInvocation(target, arguments, isConst: isConst)
|
||||
new StaticInvocation(target, arguments, isConst: false)
|
||||
..fileOffset = charOffset;
|
||||
libraryBuilder.checkBoundsInStaticInvocation(
|
||||
node, typeEnvironment, uri);
|
||||
@@ -4906,6 +4920,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
forest.createIntLiteral(location?.line ?? 0, null)
|
||||
..fileOffset = charOffset,
|
||||
]),
|
||||
constness: Constness.explicitNew,
|
||||
charOffset: charOffset))
|
||||
..fileOffset = charOffset;
|
||||
}
|
||||
@@ -4922,6 +4937,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
forest.createArguments(charOffset, <Expression>[
|
||||
forest.createStringLiteral(className, null)..fileOffset = charOffset
|
||||
]),
|
||||
constness: Constness.explicitNew,
|
||||
charOffset: charOffset);
|
||||
if (invocation is shadow.SyntheticExpressionJudgment) {
|
||||
invocation = desugarSyntheticExpression(invocation);
|
||||
@@ -5025,6 +5041,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
forest.createStringLiteral(name, null)
|
||||
..fileOffset = assignmentOffset
|
||||
]),
|
||||
constness: Constness.explicitNew,
|
||||
charOffset: assignmentOffset);
|
||||
if (invocation is shadow.SyntheticExpressionJudgment) {
|
||||
invocation = desugarSyntheticExpression(invocation);
|
||||
|
||||
@@ -195,6 +195,16 @@ NotAConstantExpression:
|
||||
template: "Not a constant expression."
|
||||
analyzerCode: NOT_CONSTANT_EXPRESSION
|
||||
|
||||
MissingExplicitConst:
|
||||
template: "Constant expression expected."
|
||||
tip: "Try inserting 'const'."
|
||||
analyzerCode: NOT_CONSTANT_EXPRESSION
|
||||
script: >
|
||||
class A {
|
||||
final x;
|
||||
const A(): x = [];
|
||||
}
|
||||
|
||||
NonAsciiIdentifier:
|
||||
template: "The non-ASCII character '#character' (#unicode) can't be used in identifiers, only in strings and comments."
|
||||
tip: "Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)."
|
||||
|
||||
@@ -15,6 +15,21 @@ library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:15:9: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// foo({a: Constant(), b: Constant(), c: []}) {}
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:15:24: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// foo({a: Constant(), b: Constant(), c: []}) {}
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// foo({a: Constant(), b: Constant(), c: []}) {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const NotConstant();
|
||||
|
||||
@@ -15,6 +15,21 @@ library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:15:9: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// foo({a: Constant(), b: Constant(), c: []}) {}
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:15:24: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// foo({a: Constant(), b: Constant(), c: []}) {}
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// foo({a: Constant(), b: Constant(), c: []}) {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const NotConstant();
|
||||
|
||||
@@ -20,6 +20,11 @@ library;
|
||||
// main(arguments = [x]) {
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// main(arguments = [x]) {
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
|
||||
// main(arguments = [x]) {
|
||||
// ^
|
||||
|
||||
+5
@@ -20,6 +20,11 @@ library;
|
||||
// main(arguments = [x]) {
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Constant expression expected.
|
||||
// Try inserting 'const'.
|
||||
// main(arguments = [x]) {
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
|
||||
// main(arguments = [x]) {
|
||||
// ^
|
||||
|
||||
Reference in New Issue
Block a user