[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:
Aske Simon Christensen
2019-09-19 12:01:21 +00:00
committed by commit-bot@chromium.org
parent 515a597710
commit 3fa2bbf202
9 changed files with 89 additions and 12 deletions
@@ -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);
+10
View File
@@ -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]) {
// ^
@@ -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]) {
// ^