[cfe] Report all compile-time errors found during constant evaluation

Closes #46925

Change-Id: I81e97cae05c39c24b24dae82a222f857d4730ac7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210465
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2021-08-24 11:42:53 +00:00 committed by commit-bot@chromium.org
parent b54269e255
commit ae4543fcb9
82 changed files with 1319 additions and 365 deletions

View file

@ -1317,6 +1317,26 @@ Message _withArgumentsConstEvalDeferredLibrary(String nameOKEmpty) {
arguments: {'nameOKEmpty': nameOKEmpty});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String string)> templateConstEvalError =
const Template<Message Function(String string)>(
messageTemplate: r"""Error evaluating constant expression: #string""",
withArguments: _withArgumentsConstEvalError);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String string)> codeConstEvalError =
const Code<Message Function(String string)>(
"ConstEvalError",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsConstEvalError(String string) {
if (string.isEmpty) throw 'No string provided';
return new Message(codeConstEvalError,
message: """Error evaluating constant expression: ${string}""",
arguments: {'string': string});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeConstEvalExtension = messageConstEvalExtension;

View file

@ -100,12 +100,7 @@ class ErrorReporter implements ir.ErrorReporter {
ErrorReporter(this._reportError);
@override
void reportInvalidExpression(ir.InvalidExpression node) {
// Ignore.
}
@override
void report(ir.LocatedMessage message, List<ir.LocatedMessage> context) {
void report(ir.LocatedMessage message, [List<ir.LocatedMessage> context]) {
if (requiresConstant) {
_reportError(message, context);
}

View file

@ -6404,8 +6404,12 @@ class BodyBuilder extends ScopeListener<JumpTarget>
allowPotentiallyConstantType: allowPotentiallyConstantType);
if (message == null) return unresolved;
return new UnresolvedType(
new NamedTypeBuilder(typeParameter.name!, builder.nullabilityBuilder,
/* arguments = */ null, unresolved.fileUri, unresolved.charOffset)
new NamedTypeBuilder(
typeParameter.name!,
builder.nullabilityBuilder,
/* arguments = */ null,
unresolved.fileUri,
unresolved.charOffset)
..bind(new InvalidTypeDeclarationBuilder(
typeParameter.name!, message)),
unresolved.charOffset,

View file

@ -44,7 +44,7 @@ abstract class _ListOrSetConstantBuilder<L extends Expression> {
parts.add(spread);
} else if (spread == evaluator.nullConstant) {
// Null spread
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
spreadExpression, messageConstEvalNullValue);
} else {
// Fully evaluated spread
@ -67,7 +67,7 @@ abstract class _ListOrSetConstantBuilder<L extends Expression> {
});
} else {
// Not list or set in spread
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
spreadExpression, messageConstEvalNotListOrSetInSpread);
}
for (Constant entry in entries) {
@ -159,14 +159,14 @@ class SetConstantBuilder extends _ListOrSetConstantBuilder<SetLiteral> {
@override
AbortConstant? addConstant(Constant constant, TreeNode context) {
if (!evaluator.hasPrimitiveEqual(constant)) {
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
context,
templateConstEvalElementImplementsEqual.withArguments(
constant, evaluator.isNonNullableByDefault));
}
bool unseen = seen.add(constant);
if (!unseen) {
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
context,
templateConstEvalDuplicateElement.withArguments(
constant, evaluator.isNonNullableByDefault));
@ -176,7 +176,7 @@ class SetConstantBuilder extends _ListOrSetConstantBuilder<SetLiteral> {
evaluator._weakener.visitConstant(constant) ?? constant;
bool weakUnseen = weakSeen.add(weakConstant);
if (unseen != weakUnseen) {
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
context, messageNonAgnosticConstant);
}
}
@ -267,7 +267,7 @@ class MapConstantBuilder {
parts.add(spread);
} else if (spread == evaluator.nullConstant) {
// Null spread
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
spreadExpression, messageConstEvalNullValue);
} else {
// Fully evaluated spread
@ -286,7 +286,7 @@ class MapConstantBuilder {
if (error != null) return error;
} else {
// Not map in spread
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
spreadExpression, messageConstEvalNotMapInSpread);
}
}
@ -305,14 +305,14 @@ class MapConstantBuilder {
parts.add(lastPart = <ConstantMapEntry>[]);
}
if (!evaluator.hasPrimitiveEqual(key)) {
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
keyContext,
templateConstEvalKeyImplementsEqual.withArguments(
key, evaluator.isNonNullableByDefault));
}
bool unseenKey = seenKeys.add(key);
if (!unseenKey) {
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
keyContext,
templateConstEvalDuplicateKey.withArguments(
key, evaluator.isNonNullableByDefault));
@ -321,7 +321,7 @@ class MapConstantBuilder {
Constant weakKey = evaluator._weakener.visitConstant(key) ?? key;
bool weakUnseenKey = weakSeenKeys.add(weakKey);
if (unseenKey != weakUnseenKey) {
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
keyContext, messageNonAgnosticConstant);
}
}

View file

@ -20,7 +20,6 @@ library fasta.constant_evaluator;
import 'dart:io' as io;
import 'package:front_end/src/fasta/kernel/constructor_tearoff_lowering.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/clone.dart';
@ -34,48 +33,10 @@ import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
import 'package:kernel/target/targets.dart';
import '../fasta_codes.dart'
show
LocatedMessage,
Message,
messageConstEvalCircularity,
messageConstEvalContext,
messageConstEvalExtension,
messageConstEvalExternalConstructor,
messageConstEvalExternalFactory,
messageConstEvalFailedAssertion,
messageConstEvalNotListOrSetInSpread,
messageConstEvalNotMapInSpread,
messageConstEvalNonNull,
messageConstEvalNullValue,
messageConstEvalStartingPoint,
messageConstEvalUnevaluated,
messageNonAgnosticConstant,
messageNotAConstantExpression,
noLength,
templateConstEvalCaseImplementsEqual,
templateConstEvalDeferredLibrary,
templateConstEvalDuplicateElement,
templateConstEvalDuplicateKey,
templateConstEvalElementImplementsEqual,
templateConstEvalFailedAssertionWithMessage,
templateConstEvalFreeTypeParameter,
templateConstEvalGetterNotFound,
templateConstEvalInvalidType,
templateConstEvalInvalidBinaryOperandType,
templateConstEvalInvalidEqualsOperandType,
templateConstEvalInvalidMethodInvocation,
templateConstEvalInvalidPropertyGet,
templateConstEvalInvalidStaticInvocation,
templateConstEvalInvalidStringInterpolationOperand,
templateConstEvalInvalidSymbolName,
templateConstEvalKeyImplementsEqual,
templateConstEvalNonConstantVariableGet,
templateConstEvalUnhandledCoreException,
templateConstEvalUnhandledException,
templateConstEvalZeroDivisor;
import '../fasta_codes.dart';
import 'constant_int_folder.dart';
import 'constructor_tearoff_lowering.dart';
part 'constant_collection_builders.dart';
@ -1070,13 +1031,14 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
if (result is _AbortDueToErrorConstant) {
final LocatedMessage locatedMessageActualError =
createLocatedMessage(result.node, result.message);
if (result.isEvaluationError) {
final List<LocatedMessage> contextMessages = <LocatedMessage>[
locatedMessageActualError
];
if (result.context != null) contextMessages.addAll(result.context!);
if (contextNode != null && contextNode != result.node) {
contextMessages
.add(createLocatedMessage(contextNode, messageConstEvalContext));
contextMessages.add(
createLocatedMessage(contextNode, messageConstEvalContext));
}
{
@ -1084,15 +1046,13 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
createLocatedMessage(node, messageConstEvalStartingPoint);
errorReporter.report(locatedMessage, contextMessages);
}
} else {
errorReporter.report(locatedMessageActualError);
}
return new UnevaluatedConstant(
new InvalidExpression(result.message.message));
}
if (result is _AbortDueToInvalidExpressionConstant) {
InvalidExpression invalid = new InvalidExpression(result.message)
..fileOffset = node.fileOffset;
errorReporter.reportInvalidExpression(invalid);
return new UnevaluatedConstant(invalid);
} else if (result is _AbortDueToThrowConstant) {
if (result is _AbortDueToThrowConstant) {
final Object value = result.throwValue;
Message? message;
if (value is Constant) {
@ -1116,11 +1076,18 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
return new UnevaluatedConstant(new InvalidExpression(message.message));
}
if (result is _AbortDueToInvalidExpressionConstant) {
return new UnevaluatedConstant(
// Create a new [InvalidExpression] without the expression, which
// might now have lost the needed context. For instance references
// to variables no longer in scope.
new InvalidExpression(result.node.message));
}
throw "Unexpected error constant";
}
if (result is UnevaluatedConstant) {
if (errorOnUnevaluatedConstant) {
return createErrorConstant(node, messageConstEvalUnevaluated);
return createEvaluationErrorConstant(node, messageConstEvalUnevaluated);
}
return canonicalize(new UnevaluatedConstant(
removeRedundantFileUriExpressions(result.expression)));
@ -1146,8 +1113,11 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
// No return statement in function body with void return type.
return new NullConstant();
}
return createInvalidExpressionConstant(statement,
'No valid constant returned from the execution of $statement.');
return createEvaluationErrorConstant(
statement,
templateConstEvalError.withArguments(
'No valid constant returned from the execution of the '
'statement.'));
}
/// Returns [null] on success and an error-"constant" on failure, as such the
@ -1162,27 +1132,33 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
} else if (status is ReturnStatus) {
if (status.value == null) return null;
// Should not be reachable.
return createInvalidExpressionConstant(
constructor, "Constructors can't have a return value.");
return createEvaluationErrorConstant(
constructor,
templateConstEvalError
.withArguments("Constructors can't have a return value."));
} else if (status is! ProceedStatus) {
return createInvalidExpressionConstant(
constructor, "Invalid execution status of constructor body.");
return createEvaluationErrorConstant(
constructor,
templateConstEvalError
.withArguments("Invalid execution status of constructor body."));
}
return null;
}
/// Create an error-constant indicating that an error has been detected during
/// constant evaluation.
AbortConstant createErrorConstant(TreeNode node, Message message,
AbortConstant createEvaluationErrorConstant(TreeNode node, Message message,
{List<LocatedMessage>? context}) {
return new _AbortDueToErrorConstant(node, message, context: context);
return new _AbortDueToErrorConstant(node, message,
context: context, isEvaluationError: true);
}
/// Create an error-constant indicating a construct that should not occur
/// inside a potentially constant expression.
/// It is assumed that an error has already been reported.
AbortConstant createInvalidExpressionConstant(TreeNode node, String message) {
return new _AbortDueToInvalidExpressionConstant(node, message);
/// Create an error-constant indicating that an non-constant expression has
/// been found.
AbortConstant createExpressionErrorConstant(TreeNode node, Message message,
{List<LocatedMessage>? context}) {
return new _AbortDueToErrorConstant(node, message,
context: context, isEvaluationError: false);
}
/// Produce an unevaluated constant node for an expression.
@ -1298,7 +1274,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
if (cachedResult == null) {
// [null] is a sentinel value only used when still evaluating the same
// node.
return createErrorConstant(node, messageConstEvalCircularity);
return createEvaluationErrorConstant(
node, messageConstEvalCircularity);
}
result = cachedResult;
} else {
@ -1322,7 +1299,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
if (nodeCache[node] == null &&
!(enableConstFunctions && isRecursiveFunctionCall)) {
// recursive call
return createErrorConstant(node, messageConstEvalCircularity);
return createEvaluationErrorConstant(
node, messageConstEvalCircularity);
}
// else we've seen the node before and come to a result -> we won't
// go into an infinite loop here either.
@ -1349,12 +1327,12 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return _evaluateSubexpression(node);
}
// TODO(johnniwinther): Remove this and handle each expression directly.
@override
Constant defaultExpression(Expression node) {
// Only a subset of the expression language is valid for constant
// evaluation.
return createInvalidExpressionConstant(
node, 'Constant evaluation has no support for ${node.runtimeType}!');
return createExpressionErrorConstant(node, messageNotAConstantExpression);
}
@override
@ -1427,7 +1405,10 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
@override
Constant visitListLiteral(ListLiteral node) {
if (!node.isConst && !enableConstFunctions) {
return createInvalidExpressionConstant(node, "Non-constant list literal");
return createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments('Non-constant list literal'));
}
final ListConstantBuilder builder = new ListConstantBuilder(
node, convertType(node.typeArgument), this,
@ -1461,7 +1442,10 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
@override
Constant visitSetLiteral(SetLiteral node) {
if (!node.isConst) {
return createInvalidExpressionConstant(node, "Non-constant set literal");
return createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments('Non-constant set literal'));
}
final SetConstantBuilder builder =
new SetConstantBuilder(node, convertType(node.typeArgument), this);
@ -1494,7 +1478,10 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
@override
Constant visitMapLiteral(MapLiteral node) {
if (!node.isConst) {
return createInvalidExpressionConstant(node, "Non-constant map literal");
return createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments('Non-constant map literal'));
}
final MapConstantBuilder builder = new MapConstantBuilder(
node, convertType(node.keyType), convertType(node.valueType), this);
@ -1529,25 +1516,27 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
if (enableConstFunctions) {
return new FunctionValue(node.function, env);
}
return createInvalidExpressionConstant(node, "Function literal");
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments('Function expression'));
}
@override
Constant visitConstructorInvocation(ConstructorInvocation node) {
if (!node.isConst && !enableConstFunctions) {
return createInvalidExpressionConstant(
node, 'Non-constant constructor invocation "$node".');
return createExpressionErrorConstant(
node, templateNotConstantExpression.withArguments('New expression'));
}
final Constructor constructor = node.target;
AbortConstant? error = checkConstructorConst(node, constructor);
AbortConstant? error =
checkConstructorConst(node, constructor, messageNonConstConstructor);
if (error != null) return error;
final Class klass = constructor.enclosingClass;
if (klass.isAbstract) {
// Probably unreachable.
return createInvalidExpressionConstant(
node, 'Constructor "$node" belongs to abstract class "${klass}".');
return createExpressionErrorConstant(
node, templateAbstractClassInstantiation.withArguments(klass.name));
}
final List<Constant>? positionals =
@ -1592,7 +1581,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
(isNonNullableByDefault || isValidSymbolName(nameValue.value))) {
return canonicalize(new SymbolConstant(nameValue.value, null));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node.arguments.positional.first,
templateConstEvalInvalidSymbolName.withArguments(
nameValue, isNonNullableByDefault));
@ -1640,21 +1629,20 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
/// Returns [null] on success and an error-"constant" on failure, as such the
/// return value should be checked.
AbortConstant? checkConstructorConst(TreeNode node, Constructor constructor) {
AbortConstant? checkConstructorConst(
TreeNode node, Constructor constructor, Message messageIfNonConst) {
if (!constructor.isConst) {
return createInvalidExpressionConstant(
node, 'Non-const constructor invocation.');
return createExpressionErrorConstant(node, messageIfNonConst);
}
if (constructor.function.body != null &&
constructor.function.body is! EmptyStatement &&
!enableConstFunctions) {
// Probably unreachable.
return createInvalidExpressionConstant(
node,
'Constructor "$node" has non-trivial body '
'"${constructor.function.body.runtimeType}".');
return createExpressionErrorConstant(
node, messageConstConstructorWithBody);
} else if (constructor.isExternal) {
return createErrorConstant(node, messageConstEvalExternalConstructor);
return createEvaluationErrorConstant(
node, messageConstEvalExternalConstructor);
}
return null;
}
@ -1884,7 +1872,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
if (constant is AbortConstant) return constant;
env.addVariableValue(variable, constant);
} else if (init is SuperInitializer) {
AbortConstant? error = checkConstructorConst(init, constructor);
AbortConstant? error = checkConstructorConst(
init, init.target, messageConstConstructorWithNonConstSuper);
if (error != null) return error;
List<DartType>? types = _evaluateSuperTypeArguments(
init, constructor.enclosingClass.supertype!);
@ -1923,7 +1912,9 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
} else if (init is RedirectingInitializer) {
// Since a redirecting constructor targets a constructor of the same
// class, we pass the same [typeArguments].
AbortConstant? error = checkConstructorConst(init, constructor);
AbortConstant? error = checkConstructorConst(
init, init.target, messageConstConstructorRedirectionToNonConst);
if (error != null) return error;
List<Constant>? positionalArguments =
_evaluatePositionalArguments(init.arguments);
@ -1960,10 +1951,12 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
// super that takes no arguments. It thus cannot be const.
// Explicit constructors with incorrect super calls will get a
// ShadowInvalidInitializer which is actually a LocalInitializer.
return createInvalidExpressionConstant(
constructor,
assert(
false,
'No support for handling initializer of type '
'"${init.runtimeType}".');
return createEvaluationErrorConstant(
init, messageNotAConstantExpression);
}
}
@ -2003,7 +1996,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
} else if (condition is BoolConstant) {
if (!condition.value) {
if (statement.message == null) {
return createErrorConstant(
return createEvaluationErrorConstant(
statement.condition, messageConstEvalFailedAssertion);
}
final Constant message = _evaluateSubexpression(statement.message!);
@ -2014,12 +2007,12 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
conditionStartOffset: statement.conditionStartOffset,
conditionEndOffset: statement.conditionEndOffset));
} else if (message is StringConstant) {
return createErrorConstant(
return createEvaluationErrorConstant(
statement.condition,
templateConstEvalFailedAssertionWithMessage
.withArguments(message.value));
} else {
return createErrorConstant(
return createEvaluationErrorConstant(
statement.message!,
templateConstEvalInvalidType.withArguments(
message,
@ -2029,7 +2022,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
}
} else {
return createErrorConstant(
return createEvaluationErrorConstant(
statement.condition,
templateConstEvalInvalidType.withArguments(
condition,
@ -2043,21 +2036,22 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
@override
Constant visitInvalidExpression(InvalidExpression node) {
return createInvalidExpressionConstant(node, node.message ?? '');
return new _AbortDueToInvalidExpressionConstant(node);
}
@override
Constant visitDynamicInvocation(DynamicInvocation node) {
// We have no support for generic method invocation at the moment.
if (node.arguments.types.isNotEmpty) {
return createInvalidExpressionConstant(node, "generic method invocation");
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments("Dynamic invocation"));
}
// We have no support for method invocation with named arguments at the
// moment.
if (node.arguments.named.isNotEmpty) {
return createInvalidExpressionConstant(
node, "method invocation with named arguments");
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments("Dynamic invocation"));
}
final Constant receiver = _evaluateSubexpression(node.receiver);
@ -2094,14 +2088,15 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
Constant visitInstanceInvocation(InstanceInvocation node) {
// We have no support for generic method invocation at the moment.
if (node.arguments.types.isNotEmpty) {
return createInvalidExpressionConstant(node, "generic method invocation");
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments("Instance invocation"));
}
// We have no support for method invocation with named arguments at the
// moment.
if (node.arguments.named.isNotEmpty) {
return createInvalidExpressionConstant(
node, "method invocation with named arguments");
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments("Instance invocation"));
}
final Constant receiver = _evaluateSubexpression(node.receiver);
@ -2140,7 +2135,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
@override
Constant visitFunctionInvocation(FunctionInvocation node) {
if (!enableConstFunctions) {
return createInvalidExpressionConstant(node, "function invocation");
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments('Function invocation'));
}
final Constant receiver = _evaluateSubexpression(node.receiver);
@ -2152,7 +2148,10 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
@override
Constant visitLocalFunctionInvocation(LocalFunctionInvocation node) {
if (!enableConstFunctions) {
return createInvalidExpressionConstant(node, "local function invocation");
return createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments('Local function invocation'));
}
final Constant receiver = env.lookupVariable(node.variable)!;
@ -2204,8 +2203,10 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
receiver.function, types, arguments, named,
functionEnvironment: receiver.environment);
} else {
return createInvalidExpressionConstant(
node, "function invocation with invalid receiver");
return createEvaluationErrorConstant(
node,
templateConstEvalError
.withArguments('Function invocation with invalid receiver.'));
}
}
@ -2252,7 +2253,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
// to take the special cases into account.
return doubleSpecialCases(left, right) ?? makeBoolConstant(left == right);
} else {
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidEqualsOperandType.withArguments(
left, left.getType(_staticTypeContext!), isNonNullableByDefault));
@ -2288,7 +2289,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return canonicalize(
new StringConstant(receiver.value + other.value));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
'+',
@ -2306,7 +2307,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
return canonicalize(new StringConstant(receiver.value[index]));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
'[]',
@ -2328,7 +2329,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
} else if (other is DoubleConstant) {
if ((op == '|' || op == '&' || op == '^') ||
(op == '<<' || op == '>>' || op == '>>>')) {
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
@ -2341,7 +2342,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return canonicalize(evaluateBinaryNumericOperation(
op, receiverValue, other.value, node));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
@ -2353,7 +2354,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
} else if (receiver is DoubleConstant) {
if ((op == '|' || op == '&' || op == '^') ||
(op == '<<' || op == '>>' || op == '>>>')) {
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
@ -2375,7 +2376,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return canonicalize(
evaluateBinaryNumericOperation(op, receiver.value, value, node));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
@ -2402,7 +2403,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
}
} else if (receiver is NullConstant) {
return createErrorConstant(node, messageConstEvalNullValue);
return createEvaluationErrorConstant(node, messageConstEvalNullValue);
} else if (receiver is ListConstant && enableConstFunctions) {
if (positionalArguments.length == 1) {
final Constant other = positionalArguments[0];
@ -2416,7 +2417,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
return receiver.entries[index];
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
'[]',
@ -2512,7 +2513,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidMethodInvocation.withArguments(
op, receiver, isNonNullableByDefault));
@ -2543,7 +2544,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return right;
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
logicalExpressionOperatorToString(node.operatorEnum),
@ -2552,7 +2553,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
right.getType(_staticTypeContext!),
isNonNullableByDefault));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidMethodInvocation.withArguments(
logicalExpressionOperatorToString(node.operatorEnum),
@ -2568,7 +2569,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return right;
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidBinaryOperandType.withArguments(
logicalExpressionOperatorToString(node.operatorEnum),
@ -2577,7 +2578,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
right.getType(_staticTypeContext!),
isNonNullableByDefault));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidMethodInvocation.withArguments(
logicalExpressionOperatorToString(node.operatorEnum),
@ -2585,7 +2586,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
isNonNullableByDefault));
default:
// Probably unreachable.
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidMethodInvocation.withArguments(
logicalExpressionOperatorToString(node.operatorEnum),
@ -2614,7 +2615,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
new ConditionalExpression(extract(condition), extract(then),
extract(otherwise), node.staticType));
} else {
return createErrorConstant(
return createEvaluationErrorConstant(
node.condition,
templateConstEvalInvalidType.withArguments(
condition,
@ -2631,7 +2632,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
// const.
// Access "this" during instance creation.
if (instanceBuilder == null) {
return createErrorConstant(node, messageNotAConstantExpression);
return createEvaluationErrorConstant(
node, messageNotAConstantExpression);
}
for (final MapEntry<Field, Constant> entry
@ -2645,8 +2647,11 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
// Meant as a "stable backstop for situations where Fasta fails to
// rewrite various erroneous constructs into invalid expressions".
// Probably unreachable.
return createInvalidExpressionConstant(node,
'Could not evaluate field get ${node.name} on incomplete instance');
return createEvaluationErrorConstant(
node,
templateConstEvalError.withArguments(
'Could not evaluate field get ${node.name} on incomplete '
'instance'));
}
final Constant receiver = _evaluateSubexpression(node.receiver);
@ -2660,7 +2665,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
resultType: node.resultType,
interfaceTarget: node.interfaceTarget));
} else if (receiver is NullConstant) {
return createErrorConstant(node, messageConstEvalNullValue);
return createEvaluationErrorConstant(node, messageConstEvalNullValue);
} else if (receiver is ListConstant && enableConstFunctions) {
switch (node.name.text) {
case 'first':
@ -2702,7 +2707,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
}
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidPropertyGet.withArguments(
node.name.text, receiver, isNonNullableByDefault));
@ -2718,9 +2723,9 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return unevaluated(
node, new DynamicGet(node.kind, extract(receiver), node.name));
} else if (receiver is NullConstant) {
return createErrorConstant(node, messageConstEvalNullValue);
return createEvaluationErrorConstant(node, messageConstEvalNullValue);
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidPropertyGet.withArguments(
node.name.text, receiver, isNonNullableByDefault));
@ -2730,7 +2735,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
Constant visitInstanceTearOff(InstanceTearOff node) {
final Constant receiver = _evaluateSubexpression(node.receiver);
if (receiver is AbortConstant) return receiver;
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidPropertyGet.withArguments(
node.name.text, receiver, isNonNullableByDefault));
@ -2740,7 +2745,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
Constant visitFunctionTearOff(FunctionTearOff node) {
final Constant receiver = _evaluateSubexpression(node.receiver);
if (receiver is AbortConstant) return receiver;
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidPropertyGet.withArguments(
Name.callName.text, receiver, isNonNullableByDefault));
@ -2765,14 +2770,14 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
final VariableDeclaration variable = node.variable;
if (enableConstFunctions) {
return env.lookupVariable(variable) ??
createErrorConstant(
createEvaluationErrorConstant(
node,
templateConstEvalGetterNotFound
.withArguments(variable.name ?? ''));
} else {
if (variable.parent is Let || _isFormalParameter(variable)) {
return env.lookupVariable(node.variable) ??
createErrorConstant(
createEvaluationErrorConstant(
node,
templateConstEvalNonConstantVariableGet
.withArguments(variable.name ?? ''));
@ -2781,8 +2786,10 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return _evaluateSubexpression(variable.initializer!);
}
}
return createInvalidExpressionConstant(
node, 'Variable get of a non-const variable.');
return createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments('Read of a non-const variable'));
}
@override
@ -2791,9 +2798,14 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
final VariableDeclaration variable = node.variable;
Constant value = _evaluateSubexpression(node.value);
if (value is AbortConstant) return value;
return env.updateVariableValue(variable, value) ??
createInvalidExpressionConstant(
node, 'Variable set of an unknown value.');
Constant? result = env.updateVariableValue(variable, value);
if (result != null) {
return result;
}
return createEvaluationErrorConstant(
node,
templateConstEvalError
.withArguments('Variable set of an unknown value.'));
}
return defaultExpression(node);
}
@ -2826,21 +2838,18 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
if (target.isConst) {
return _evaluateExpressionInContext(target, target.initializer!);
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidStaticInvocation
.withArguments(target.name.text));
} else if (target is Procedure) {
if (target.kind == ProcedureKind.Method) {
} else if (target is Procedure && target.kind == ProcedureKind.Method) {
// TODO(johnniwinther): Remove this. This should never occur.
return canonicalize(new StaticTearOffConstant(target));
}
return createErrorConstant(
} else {
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidStaticInvocation
.withArguments(target.name.text));
} else {
return createInvalidExpressionConstant(
node, 'No support for ${target.runtimeType} in a static-get.');
}
});
}
@ -2875,7 +2884,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
// error reporting till later.
concatenated.add(constant);
} else {
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidStringInterpolationOperand.withArguments(
constant, isNonNullableByDefault));
@ -3030,7 +3039,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return _handleHasEnvironment(name);
}
} else if (name is NullConstant) {
return createErrorConstant(node, messageConstEvalNullValue);
return createEvaluationErrorConstant(
node, messageConstEvalNullValue);
}
} else {
// Leave environment constant unevaluated.
@ -3041,7 +3051,29 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
isConst: true));
}
} else if (target.isExternal) {
return createErrorConstant(node, messageConstEvalExternalFactory);
return createEvaluationErrorConstant(
node, messageConstEvalExternalFactory);
} else if (enableConstFunctions) {
return _handleFunctionInvocation(
node.target.function, typeArguments, positionals, named);
} else {
return createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments('Non-redirecting const factory invocation'));
}
} else {
if (enableConstFunctions) {
return _handleFunctionInvocation(
node.target.function, typeArguments, positionals, named);
} else if (!node.isConst) {
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments('New expression'));
} else {
return createEvaluationErrorConstant(
node,
templateNotConstantExpression
.withArguments('Non-const factory invocation'));
}
}
} else if (target.name.text == 'identical') {
@ -3062,7 +3094,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
Constant weakResult = makeBoolConstant(
identical(weakLeft ?? left, weakRight ?? right));
if (!identical(result, weakResult)) {
return createErrorConstant(node, messageNonAgnosticConstant);
return createEvaluationErrorConstant(
node, messageNonAgnosticConstant);
}
}
}
@ -3077,26 +3110,14 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return evaluateIdentical();
}
} else if (target.isExtensionMember) {
return createErrorConstant(node, messageConstEvalExtension);
return createEvaluationErrorConstant(node, messageConstEvalExtension);
} else if (enableConstFunctions && target.kind == ProcedureKind.Method) {
return _handleFunctionInvocation(
node.target.function, typeArguments, positionals, named);
}
String name = target.name.text;
if (target.isFactory) {
if (name.isEmpty) {
name = target.enclosingClass!.name;
} else {
name = '${target.enclosingClass!.name}.${name}';
}
if (enableConstFunctions) {
return _handleFunctionInvocation(
node.target.function, typeArguments, positionals, named);
}
}
return createInvalidExpressionConstant(node, "Invocation of $name");
return createExpressionErrorConstant(
node, templateNotConstantExpression.withArguments('Static invocation'));
}
Constant _handleFunctionInvocation(
@ -3132,7 +3153,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
function.returnType.nullability == Nullability.nonNullable) {
// Ensure that the evaluated constant returned is not null if the
// function has a non-nullable return type.
return createErrorConstant(
return createEvaluationErrorConstant(
function,
templateConstEvalInvalidType.withArguments(
result,
@ -3234,7 +3255,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
Constant weakConstant = _weakener.visitConstant(constant) ?? constant;
bool weakResult = performIs(weakConstant, strongMode: false);
if (strongResult != weakResult) {
return createErrorConstant(node, messageNonAgnosticConstant);
return createEvaluationErrorConstant(
node, messageNonAgnosticConstant);
}
return makeBoolConstant(strongResult);
case EvaluationMode.weak:
@ -3252,7 +3274,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
if (shouldBeUnevaluated) {
return unevaluated(node, new Not(extract(constant)));
}
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidType.withArguments(
constant,
@ -3266,7 +3288,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
final Constant constant = _evaluateSubexpression(node.operand);
if (constant is AbortConstant) return constant;
if (constant is NullConstant) {
return createErrorConstant(node, messageConstEvalNonNull);
return createEvaluationErrorConstant(node, messageConstEvalNonNull);
}
if (shouldBeUnevaluated) {
return unevaluated(node, new NullCheck(extract(constant)));
@ -3349,18 +3371,21 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
new InstantiationConstant(constant, convertTypes(typeArguments)));
} else {
// Probably unreachable.
return createInvalidExpressionConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalError.withArguments(
'The number of type arguments supplied in the partial '
'instantiation does not match the number of type arguments '
'of the $constant.');
'of the $constant.'));
}
}
// The inner expression in an instantiation can never be null, since
// instantiations are only inferred on direct references to declarations.
// Probably unreachable.
return createInvalidExpressionConstant(
node, 'Only tear-off constants can be partially instantiated.');
return createEvaluationErrorConstant(
node,
templateConstEvalError.withArguments(
'Only tear-off constants can be partially instantiated.'));
}
@override
@ -3389,14 +3414,16 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
new TypedefTearOffConstant(typeParameters, constant, typeArguments));
} else {
// Probably unreachable.
return createInvalidExpressionConstant(
node, "Unexpected typedef tearoff target: ${constant}.");
return createEvaluationErrorConstant(
node,
templateConstEvalError.withArguments(
"Unsupported typedef tearoff target: ${constant}."));
}
}
@override
Constant visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
return createErrorConstant(node,
return createEvaluationErrorConstant(node,
templateConstEvalDeferredLibrary.withArguments(node.import.name!));
}
@ -3489,7 +3516,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
bool weakResult = isSubtype(
weakConstant, type, SubtypeCheckMode.ignoringNullabilities);
if (strongResult != weakResult) {
return createErrorConstant(node, messageNonAgnosticConstant);
return createEvaluationErrorConstant(
node, messageNonAgnosticConstant);
}
result = strongResult;
break;
@ -3499,7 +3527,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
break;
}
if (!result) {
return createErrorConstant(
return createEvaluationErrorConstant(
node,
templateConstEvalInvalidType.withArguments(constant, type,
constant.getType(_staticTypeContext!), isNonNullableByDefault));
@ -3552,7 +3580,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
final DartType result = env.substituteType(type);
if (!isInstantiated(result)) {
_gotError = createErrorConstant(
_gotError = createEvaluationErrorConstant(
node,
templateConstEvalFreeTypeParameter.withArguments(
type, isNonNullableByDefault));
@ -3663,7 +3691,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
return new DoubleConstant(a / b);
case '~/':
if (b == 0) {
return createErrorConstant(
return createEvaluationErrorConstant(
node, templateConstEvalZeroDivisor.withArguments(op, '$a'));
}
return intFolder.truncatingDivide(node, a, b);
@ -3683,8 +3711,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
}
// Probably unreachable.
return createInvalidExpressionConstant(
node, "Unexpected binary numeric operation '$op'.");
return createExpressionErrorConstant(node,
templateNotConstantExpression.withArguments("Binary '$op' operation"));
}
// TODO(johnniwinther): Remove the need for this by adding a current library
@ -4262,8 +4290,10 @@ class _AbortDueToErrorConstant extends AbortConstant {
final TreeNode node;
final Message message;
final List<LocatedMessage>? context;
final bool isEvaluationError;
_AbortDueToErrorConstant(this.node, this.message, {this.context});
_AbortDueToErrorConstant(this.node, this.message,
{this.context, required this.isEvaluationError});
@override
R accept<R>(ConstantVisitor<R> v) {
@ -4327,10 +4357,9 @@ class _AbortDueToErrorConstant extends AbortConstant {
}
class _AbortDueToInvalidExpressionConstant extends AbortConstant {
final TreeNode node;
final String message;
final InvalidExpression node;
_AbortDueToInvalidExpressionConstant(this.node, this.message);
_AbortDueToInvalidExpressionConstant(this.node);
@override
R accept<R>(ConstantVisitor<R> v) {
@ -4463,16 +4492,14 @@ class _AbortDueToThrowConstant extends AbortConstant {
abstract class ErrorReporter {
const ErrorReporter();
void report(LocatedMessage message, List<LocatedMessage>? context);
void reportInvalidExpression(InvalidExpression node);
void report(LocatedMessage message, [List<LocatedMessage>? context]);
}
class SimpleErrorReporter implements ErrorReporter {
const SimpleErrorReporter();
@override
void report(LocatedMessage message, List<LocatedMessage>? context) {
void report(LocatedMessage message, [List<LocatedMessage>? context]) {
_report(message);
if (context != null) {
for (LocatedMessage contextMessage in context) {
@ -4481,11 +4508,6 @@ class SimpleErrorReporter implements ErrorReporter {
}
}
@override
void reportInvalidExpression(InvalidExpression node) {
// Ignored
}
void _report(LocatedMessage message) {
reportMessage(message.uri, message.charOffset, message.message);
}

View file

@ -7,11 +7,7 @@ import 'package:kernel/target/targets.dart';
import 'constant_evaluator.dart';
import '../fasta_codes.dart'
show
templateConstEvalNegativeShift,
templateConstEvalTruncateError,
templateConstEvalZeroDivisor;
import '../fasta_codes.dart';
abstract class ConstantIntFolder {
final ConstantEvaluator evaluator;
@ -52,11 +48,11 @@ abstract class ConstantIntFolder {
AbortConstant? _checkOperands(
Expression node, String op, num left, num right) {
if ((op == '<<' || op == '>>' || op == '>>>') && right < 0) {
return evaluator.createErrorConstant(node,
return evaluator.createEvaluationErrorConstant(node,
templateConstEvalNegativeShift.withArguments(op, '$left', '$right'));
}
if ((op == '%' || op == '~/') && right == 0) {
return evaluator.createErrorConstant(
return evaluator.createEvaluationErrorConstant(
node, templateConstEvalZeroDivisor.withArguments(op, '$left'));
}
return null;
@ -91,8 +87,10 @@ class VmConstantIntFolder extends ConstantIntFolder {
return new IntConstant(~operand.value);
default:
// Probably unreachable.
return evaluator.createInvalidExpressionConstant(
node, "Invalid unary operator $op");
return evaluator.createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments("Unary '$op' operation"));
}
}
@ -140,8 +138,10 @@ class VmConstantIntFolder extends ConstantIntFolder {
return evaluator.makeBoolConstant(a > b);
default:
// Probably unreachable.
return evaluator.createInvalidExpressionConstant(
node, "Invalid binary operator $op");
return evaluator.createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments("Binary '$op' operation"));
}
}
@ -150,7 +150,7 @@ class VmConstantIntFolder extends ConstantIntFolder {
try {
return new IntConstant(left ~/ right);
} catch (e) {
return evaluator.createErrorConstant(node,
return evaluator.createEvaluationErrorConstant(node,
templateConstEvalTruncateError.withArguments('$left', '$right'));
}
}
@ -204,8 +204,10 @@ class JsConstantIntFolder extends ConstantIntFolder {
return new DoubleConstant(_truncate32(~intValue).toDouble());
default:
// Probably unreachable.
return evaluator.createInvalidExpressionConstant(
node, "Invalid unary operator $op");
return evaluator.createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments("Unary '$op' operation"));
}
}
@ -259,8 +261,10 @@ class JsConstantIntFolder extends ConstantIntFolder {
return evaluator.makeBoolConstant(a > b);
default:
// Probably unreachable.
return evaluator.createInvalidExpressionConstant(
node, "Invalid binary operator $op");
return evaluator.createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments("Binary '$op' operation"));
}
}
@ -268,7 +272,7 @@ class JsConstantIntFolder extends ConstantIntFolder {
Constant truncatingDivide(Expression node, num left, num right) {
double division = (left / right);
if (division.isNaN || division.isInfinite) {
return evaluator.createErrorConstant(node,
return evaluator.createEvaluationErrorConstant(node,
templateConstEvalTruncateError.withArguments('$left', '${right}'));
}
double result = division.truncateToDouble();

View file

@ -2898,8 +2898,12 @@ class DeferredAccessGenerator extends Generator {
_uri, charOffset, lengthOfSpan(prefixGenerator.token, token));
}
// TODO(johnniwinther): Could we use a FixedTypeBuilder(InvalidType()) here?
NamedTypeBuilder result = new NamedTypeBuilder(name, nullabilityBuilder,
/* arguments = */ null, /* fileUri = */ null, /* charOffset = */ null);
NamedTypeBuilder result = new NamedTypeBuilder(
name,
nullabilityBuilder,
/* arguments = */ null,
/* fileUri = */ null,
/* charOffset = */ null);
_helper.libraryBuilder.addProblem(
message.messageObject, message.charOffset, message.length, message.uri);
result.bind(result.buildInvalidTypeDeclarationBuilder(message));

View file

@ -4,8 +4,6 @@
library fasta.kernel_constants;
import 'package:kernel/ast.dart' show InvalidExpression;
import '../builder/library_builder.dart';
import '../fasta_codes.dart' show LocatedMessage;
@ -20,7 +18,7 @@ class KernelConstantErrorReporter extends ErrorReporter {
KernelConstantErrorReporter(this.loader);
@override
void report(LocatedMessage message, List<LocatedMessage>? context) {
void report(LocatedMessage message, [List<LocatedMessage>? context]) {
// Try to find library.
LibraryBuilder? builder = loader.builders[message.uri];
if (builder == null) {
@ -43,20 +41,4 @@ class KernelConstantErrorReporter extends ErrorReporter {
context: context);
}
}
@override
void reportInvalidExpression(InvalidExpression node) {
// TODO(johnniwinther): Improve the precision of this assertion. Do we
// for instance allow warnings only to have been reported in previous
// compilations.
assert(
// Either we have already reported an error
loader.hasSeenError ||
// or we have reported an error in a previous compilation.
loader.builders.values.any((builder) =>
builder.library.problemsAsJson?.isNotEmpty ?? false),
"No error reported before seeing: "
"${node.message}");
// Assumed to be already reported.
}
}

View file

@ -600,7 +600,10 @@ abstract class DataExtractor<T> extends Visitor<void>
@override
visitInvalidExpression(InvalidExpression node) {
computeForNode(node, computeDefaultNodeId(node));
// Invalid expressions produced in the constant evaluator don't have a
// file offset.
computeForNode(
node, computeDefaultNodeId(node, skipNodeWithNoOffset: true));
return super.visitInvalidExpression(node);
}
}

View file

@ -102,6 +102,8 @@ ConstEvalDeferredLibrary/example: Fail
ConstEvalDuplicateElement/example: Fail
ConstEvalDuplicateKey/example: Fail
ConstEvalElementImplementsEqual/example: Fail
ConstEvalError/analyzerCode: Fail
ConstEvalError/example: Fail
ConstEvalExtension/example: Fail
ConstEvalExternalConstructor/analyzerCode: Fail
ConstEvalExternalConstructor/example: Fail

View file

@ -228,6 +228,9 @@ ConstEvalExternalFactory:
ConstEvalUnevaluated:
template: "Couldn't evaluate constant expression."
ConstEvalError:
template: "Error evaluating constant expression: #string"
ConstEvalUnhandledCoreException:
template: "Unhandled core exception: #stringOKEmpty"

View file

@ -125,12 +125,7 @@ void benchmark(Component component, List<Library> libraries) {
class SilentErrorReporter implements constants.ErrorReporter {
@override
void report(LocatedMessage message, List<LocatedMessage> context) {
// ignore
}
@override
void reportInvalidExpression(InvalidExpression node) {
void report(LocatedMessage message, [List<LocatedMessage> context]) {
// ignore
}
}

View file

@ -1030,12 +1030,7 @@ class StressConstantEvaluatorVisitor extends RecursiveResultVisitor<Node>
}
@override
void report(LocatedMessage message, List<LocatedMessage> context) {
// ignored.
}
@override
void reportInvalidExpression(InvalidExpression node) {
void report(LocatedMessage message, [List<LocatedMessage> context]) {
// ignored.
}
}

View file

@ -209,6 +209,7 @@ confirm
consecutive
considering
consist
constr
constrains
consts
contract

View file

@ -0,0 +1,8 @@
// 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.
const dynamic a = null;
const dynamic b = a();
main() {}

View file

@ -0,0 +1,23 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error:
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation.
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing:
// const dynamic b = a();
// ^
//
import self as self;
static const field dynamic a = #C1;
static const field dynamic b = invalid-expression "Null value during constant evaluation.";
static method main() → dynamic {}
constants {
#C1 = null
}

View file

@ -0,0 +1,23 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error:
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation.
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing:
// const dynamic b = a();
// ^
//
import self as self;
static const field dynamic a = #C1;
static const field dynamic b = invalid-expression "Null value during constant evaluation.";
static method main() → dynamic {}
constants {
#C1 = null
}

View file

@ -0,0 +1,3 @@
const dynamic a = null;
const dynamic b = a();
main() {}

View file

@ -0,0 +1,3 @@
const dynamic a = null;
const dynamic b = a();
main() {}

View file

@ -0,0 +1,23 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error:
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation.
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing:
// const dynamic b = a();
// ^
//
import self as self;
static const field dynamic a = #C1;
static const field dynamic b = invalid-expression "Null value during constant evaluation.";
static method main() → dynamic {}
constants {
#C1 = null
}

View file

@ -0,0 +1,12 @@
library /*isNonNullableByDefault*/;
import self as self;
static const field dynamic a = null;
static const field dynamic b = self::a{dynamic}.call();
static method main() → dynamic
;
Extra constant evaluation status:
Evaluated: StaticGet @ org-dartlang-testcase:///non_function_invocation.dart:6:19 -> NullConstant(null)
Extra constant evaluation: evaluated: 2, effectively constant: 1

View file

@ -0,0 +1,23 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error:
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation.
// const dynamic b = a();
// ^
// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing:
// const dynamic b = a();
// ^
//
import self as self;
static const field dynamic a = #C1;
static const field dynamic b = invalid-expression "Null value during constant evaluation.";
static method main() → dynamic {}
constants {
#C1 = null
}

View file

@ -0,0 +1,26 @@
// 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.
class MyClass<T> {
final a;
const MyClass(int i, int j) : a = (i + j);
const MyClass.constr() : a = 0;
}
test() {
const v1 = MyClass<String>.new;
const v2 = MyClass<int>.constr;
const v3 = MyClass<int>.new;
const v4 = MyClass<String>.constr;
const c1 = v1(3, 14);
const c2 = v1(3, 14);
const c3 = v2();
const c4 = v2();
const c5 = v3(3, 14);
const c6 = v4();
}
main() {}

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression.
// const c1 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression.
// const c2 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression.
// const c3 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression.
// const c4 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression.
// const c5 = v3(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression.
// const c6 = v4();
// ^
//
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic {
const self::MyClass<core::String> c1 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c2 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c3 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c4 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c5 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c6 = invalid-expression "Function invocation is not a constant expression.";
}
static method main() → dynamic {}

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression.
// const c1 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression.
// const c2 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression.
// const c3 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression.
// const c4 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression.
// const c5 = v3(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression.
// const c6 = v4();
// ^
//
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic {
const self::MyClass<core::String> c1 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c2 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c3 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c4 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c5 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c6 = invalid-expression "Function invocation is not a constant expression.";
}
static method main() → dynamic {}

View file

@ -0,0 +1,8 @@
class MyClass<T> {
final a;
const MyClass(int i, int j) : a = (i + j);
const MyClass.constr() : a = 0;
}
test() {}
main() {}

View file

@ -0,0 +1,8 @@
class MyClass<T> {
const MyClass(int i, int j) : a = (i + j);
const MyClass.constr() : a = 0;
final a;
}
main() {}
test() {}

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression.
// const c1 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression.
// const c2 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression.
// const c3 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression.
// const c4 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression.
// const c5 = v3(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression.
// const c6 = v4();
// ^
//
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic {
const self::MyClass<core::String> c1 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c2 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c3 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c4 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c5 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c6 = invalid-expression "Function invocation is not a constant expression.";
}
static method main() → dynamic {}

View file

@ -0,0 +1,17 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic
;
static method main() → dynamic
;

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression.
// const c1 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression.
// const c2 = v1(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression.
// const c3 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression.
// const c4 = v2();
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression.
// const c5 = v3(3, 14);
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression.
// const c6 = v4();
// ^
//
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic {
const self::MyClass<core::String> c1 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c2 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c3 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c4 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::int> c5 = invalid-expression "Function invocation is not a constant expression.";
const self::MyClass<core::String> c6 = invalid-expression "Function invocation is not a constant expression.";
}
static method main() → dynamic {}

View file

@ -1,7 +1,7 @@
// Copyright (c) 2019, 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.
// @dart=2.9
class A {
const A() : this.bad();

View file

@ -1,4 +1,3 @@
// @dart = 2.9
class A {
const A() : this.bad();
A.bad() {}

View file

@ -1,4 +1,3 @@
// @dart = 2.9
class A {
A.bad() {}
const A() : this.bad();

View file

@ -1,4 +1,4 @@
library;
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
@ -14,30 +14,20 @@ import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A*
const constructor •() → self::A
: this self::A::bad()
;
constructor bad() → self::A*
constructor bad() → self::A
: super core::Object::•() {}
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
abstract member-signature method toString() → core::String*; -> core::Object::toString
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B*
const constructor •() → self::B
: super self::A::bad()
;
}
static method test() → dynamic {
core::print(invalid-expression "Non-const constructor invocation.");
core::print(invalid-expression "Non-const constructor invocation.");
core::print(invalid-expression "A constant constructor can't call a non-constant constructor.");
core::print(invalid-expression "A constant constructor can't call a non-constant super constructor.");
}
static method main() → dynamic {
core::print(new self::A::•());
@ -49,5 +39,4 @@ static method main() → dynamic {
Constructor coverage from constants:
org-dartlang-testcase:///const_redirect_to_nonconst.dart:
- A. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:6:9)
- A.bad (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:8:3)
- B. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:12:9)

View file

@ -1,4 +1,4 @@
library;
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
@ -10,24 +10,14 @@ import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A*
const constructor •() → self::A
: this self::A::bad()
;
constructor bad() → self::A*
constructor bad() → self::A
;
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
abstract member-signature method toString() → core::String*; -> core::Object::toString
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B*
const constructor •() → self::B
: super self::A::bad()
;
}

View file

@ -1,4 +1,4 @@
library;
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
@ -14,30 +14,20 @@ import self as self;
import "dart:core" as core;
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A*
const constructor •() → self::A
: this self::A::bad()
;
constructor bad() → self::A*
constructor bad() → self::A
: super core::Object::•() {}
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
abstract member-signature method toString() → core::String*; -> core::Object::toString
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B*
const constructor •() → self::B
: super self::A::bad()
;
}
static method test() → dynamic {
core::print(invalid-expression "Non-const constructor invocation.");
core::print(invalid-expression "Non-const constructor invocation.");
core::print(invalid-expression "A constant constructor can't call a non-constant constructor.");
core::print(invalid-expression "A constant constructor can't call a non-constant super constructor.");
}
static method main() → dynamic {
core::print(new self::A::•());
@ -49,5 +39,4 @@ static method main() → dynamic {
Constructor coverage from constants:
org-dartlang-testcase:///const_redirect_to_nonconst.dart:
- A. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:6:9)
- A.bad (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:8:3)
- B. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:12:9)

View file

@ -0,0 +1,9 @@
// 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.
method() {}
const tearOff = method;
const invocation = tearOff();
main() {}

View file

@ -0,0 +1,4 @@
method() {}
const tearOff = method;
const invocation = tearOff();
main() {}

View file

@ -0,0 +1,4 @@
const invocation = tearOff();
const tearOff = method;
main() {}
method() {}

View file

@ -0,0 +1,20 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression.
// const invocation = tearOff();
// ^^^^^^^
//
import self as self;
static const field () → dynamic tearOff = #C1;
static const field invalid-type invocation = invalid-expression "pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression.
const invocation = tearOff();
^^^^^^^";
static method method() → dynamic {}
static method main() → dynamic {}
constants {
#C1 = static-tearoff self::method
}

View file

@ -0,0 +1,23 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression.
// const invocation = tearOff();
// ^^^^^^^
//
import self as self;
static const field () → dynamic tearOff = self::method;
static const field invalid-type invocation = invalid-expression "pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression.
const invocation = tearOff();
^^^^^^^";
static method method() → dynamic
;
static method main() → dynamic
;
Extra constant evaluation status:
Evaluated: StaticTearOff @ org-dartlang-testcase:///function_invocation.dart:6:17 -> StaticTearOffConstant(method)
Extra constant evaluation: evaluated: 1, effectively constant: 1

View file

@ -0,0 +1,20 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression.
// const invocation = tearOff();
// ^^^^^^^
//
import self as self;
static const field () → dynamic tearOff = #C1;
static const field invalid-type invocation = invalid-expression "pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression.
const invocation = tearOff();
^^^^^^^";
static method method() → dynamic {}
static method main() → dynamic {}
constants {
#C1 = static-tearoff self::method
}

View file

@ -0,0 +1,26 @@
// 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.
class MyClass<T> {
final a;
const MyClass(int i, int j) : a = (i + j);
const MyClass.constr() : a = 0;
}
test() {
const v1 = MyClass<String>.new;
const v2 = MyClass<int>.constr;
const v3 = MyClass<int>.new;
const v4 = MyClass<String>.constr;
const c1 = v1(3, 14);
const c2 = v1(3, 14);
const c3 = v2();
const c4 = v2();
const c5 = v3(3, 14);
const c6 = v4();
}
main() {}

View file

@ -0,0 +1,8 @@
class MyClass<T> {
final a;
const MyClass(int i, int j) : a = (i + j);
const MyClass.constr() : a = 0;
}
test() {}
main() {}

View file

@ -0,0 +1,8 @@
class MyClass<T> {
const MyClass(int i, int j) : a = (i + j);
const MyClass.constr() : a = 0;
final a;
}
main() {}
test() {}

View file

@ -0,0 +1,95 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/issue46925.dart:13:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v1 = MyClass<String>.new;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v1 = MyClass<String>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
// const v1 = MyClass<String>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:14:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v2 = MyClass<int>.constr;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
// const v2 = MyClass<int>.constr;
// ^^^^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:15:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v3 = MyClass<int>.new;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v3 = MyClass<int>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'.
// const v3 = MyClass<int>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:16:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v4 = MyClass<String>.constr;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'.
// const v4 = MyClass<String>.constr;
// ^^^^^^
//
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic {
const invalid-type v1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
const v1 = MyClass<String>.new;
^^^";
const invalid-type v2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
const v2 = MyClass<int>.constr;
^^^^^^";
const invalid-type v3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'.
const v3 = MyClass<int>.new;
^^^";
const invalid-type v4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'.
const v4 = MyClass<String>.constr;
^^^^^^";
const dynamic c1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
const v1 = MyClass<String>.new;
^^^";
const dynamic c2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
const v1 = MyClass<String>.new;
^^^";
const dynamic c3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
const v2 = MyClass<int>.constr;
^^^^^^";
const dynamic c4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
const v2 = MyClass<int>.constr;
^^^^^^";
const dynamic c5 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'.
const v3 = MyClass<int>.new;
^^^";
const dynamic c6 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'.
const v4 = MyClass<String>.constr;
^^^^^^";
}
static method main() → dynamic {}

View file

@ -0,0 +1,17 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic
;
static method main() → dynamic
;

View file

@ -0,0 +1,95 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/issue46925.dart:13:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v1 = MyClass<String>.new;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v1 = MyClass<String>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
// const v1 = MyClass<String>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:14:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v2 = MyClass<int>.constr;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
// const v2 = MyClass<int>.constr;
// ^^^^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:15:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v3 = MyClass<int>.new;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v3 = MyClass<int>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'.
// const v3 = MyClass<int>.new;
// ^^^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:16:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
// const v4 = MyClass<String>.constr;
// ^
//
// pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'.
// const v4 = MyClass<String>.constr;
// ^^^^^^
//
import self as self;
import "dart:core" as core;
class MyClass<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
final field dynamic a;
const constructor •(core::int i, core::int j) → self::MyClass<self::MyClass::T%>
: self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•()
;
const constructor constr() → self::MyClass<self::MyClass::T%>
: self::MyClass::a = 0, super core::Object::•()
;
}
static method test() → dynamic {
const invalid-type v1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
const v1 = MyClass<String>.new;
^^^";
const invalid-type v2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
const v2 = MyClass<int>.constr;
^^^^^^";
const invalid-type v3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'.
const v3 = MyClass<int>.new;
^^^";
const invalid-type v4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'.
const v4 = MyClass<String>.constr;
^^^^^^";
const dynamic c1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
const v1 = MyClass<String>.new;
^^^";
const dynamic c2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'.
const v1 = MyClass<String>.new;
^^^";
const dynamic c3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
const v2 = MyClass<int>.constr;
^^^^^^";
const dynamic c4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'.
const v2 = MyClass<int>.constr;
^^^^^^";
const dynamic c5 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'.
const v3 = MyClass<int>.new;
^^^";
const dynamic c6 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'.
const v4 = MyClass<String>.constr;
^^^^^^";
}
static method main() → dynamic {}

View file

@ -1,7 +1,9 @@
// Copyright (c) 2020, 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.
// @dart=2.9
class Foo {
const Foo({bool x: true});
const x = Foo();

View file

@ -2,27 +2,27 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:3: Error: Only static fields can be declared as const.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:3: Error: Only static fields can be declared as const.
// Try using 'final' instead of 'const', or adding the keyword 'static'.
// const x = Foo();
// ^^^^^
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant expression expected.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant expression expected.
// Try inserting 'const'.
// const x = Foo();
// ^^^
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:6:9: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/general/constants/issue_43431.dart:8:9: Error: Constructor is marked 'const' so all fields must be final.
// const Foo({bool x: true});
// ^
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:9: Context: Field isn't final, but constructor is 'const'.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:9: Context: Field isn't final, but constructor is 'const'.
// const x = Foo();
// ^
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant evaluation error:
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant evaluation error:
// const x = Foo();
// ^
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Context: Constant expression depends on itself.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Context: Constant expression depends on itself.
// const x = Foo();
// ^
//
@ -54,4 +54,4 @@ constants {
Constructor coverage from constants:
org-dartlang-testcase:///issue_43431.dart:
- Foo. (from org-dartlang-testcase:///issue_43431.dart:6:9)
- Foo. (from org-dartlang-testcase:///issue_43431.dart:8:9)

View file

@ -2,7 +2,7 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:3: Error: Only static fields can be declared as const.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:3: Error: Only static fields can be declared as const.
// Try using 'final' instead of 'const', or adding the keyword 'static'.
// const x = Foo();
// ^^^^^

View file

@ -2,27 +2,27 @@ library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:3: Error: Only static fields can be declared as const.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:3: Error: Only static fields can be declared as const.
// Try using 'final' instead of 'const', or adding the keyword 'static'.
// const x = Foo();
// ^^^^^
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant expression expected.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant expression expected.
// Try inserting 'const'.
// const x = Foo();
// ^^^
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:6:9: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/general/constants/issue_43431.dart:8:9: Error: Constructor is marked 'const' so all fields must be final.
// const Foo({bool x: true});
// ^
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:9: Context: Field isn't final, but constructor is 'const'.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:9: Context: Field isn't final, but constructor is 'const'.
// const x = Foo();
// ^
//
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant evaluation error:
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant evaluation error:
// const x = Foo();
// ^
// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Context: Constant expression depends on itself.
// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Context: Constant expression depends on itself.
// const x = Foo();
// ^
//
@ -54,4 +54,4 @@ constants {
Constructor coverage from constants:
org-dartlang-testcase:///issue_43431.dart:
- Foo. (from org-dartlang-testcase:///issue_43431.dart:6:9)
- Foo. (from org-dartlang-testcase:///issue_43431.dart:8:9)

View file

@ -0,0 +1,16 @@
// 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.
class Class {
Class();
const Class.named() {
1;
}
}
const a = const Class();
const b = const Class.named();
main() {}

View file

@ -0,0 +1,7 @@
class Class {
Class();
const Class.named() {}
}
const a = const Class();
const b = const Class.named();
main() {}

View file

@ -0,0 +1,40 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:8:3: Error: A const constructor can't have a body.
// Try removing either the 'const' keyword or the body.
// const Class.named() {
// ^^^^^
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const a = const Class();
// ^^^^^
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const b = const Class.named();
// ^^^^^
//
import self as self;
import "dart:core" as core;
class Class extends core::Object {
constructor •() → self::Class
: super core::Object::•()
;
constructor named() → self::Class
: super core::Object::•() {
1;
}
}
static const field invalid-type a = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
const a = const Class();
^^^^^";
static const field invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
const b = const Class.named();
^^^^^";
static method main() → dynamic {}

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:8:3: Error: A const constructor can't have a body.
// Try removing either the 'const' keyword or the body.
// const Class.named() {
// ^^^^^
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const a = const Class();
// ^^^^^
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const b = const Class.named();
// ^^^^^
//
import self as self;
import "dart:core" as core;
class Class extends core::Object {
constructor •() → self::Class
;
constructor named() → self::Class
;
}
static const field invalid-type a = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
const a = const Class();
^^^^^";
static const field invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
const b = const Class.named();
^^^^^";
static method main() → dynamic
;

View file

@ -0,0 +1,40 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:8:3: Error: A const constructor can't have a body.
// Try removing either the 'const' keyword or the body.
// const Class.named() {
// ^^^^^
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const a = const Class();
// ^^^^^
//
// pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const b = const Class.named();
// ^^^^^
//
import self as self;
import "dart:core" as core;
class Class extends core::Object {
constructor •() → self::Class
: super core::Object::•()
;
constructor named() → self::Class
: super core::Object::•() {
1;
}
}
static const field invalid-type a = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
const a = const Class();
^^^^^";
static const field invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
const b = const Class.named();
^^^^^";
static method main() → dynamic {}

View file

@ -0,0 +1,10 @@
// 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.
method() {
var a = 0;
const b = a;
}
main() {}

View file

@ -0,0 +1,2 @@
method() {}
main() {}

View file

@ -0,0 +1,18 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression.
// const b = a;
// ^
//
import self as self;
import "dart:core" as core;
static method method() → dynamic {
core::int a = 0;
const invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression.
const b = a;
^";
}
static method main() → dynamic {}

View file

@ -0,0 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
static method method() → dynamic
;
static method main() → dynamic
;

View file

@ -0,0 +1,18 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression.
// const b = a;
// ^
//
import self as self;
import "dart:core" as core;
static method method() → dynamic {
core::int a = 0;
const invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression.
const b = a;
^";
}
static method main() → dynamic {}

View file

@ -100,6 +100,14 @@ library;
// class ExtendsFoo1 extends Foo {
// ^
//
// pkg/front_end/testcases/general/constants/various.dart:99:4: Error: Not a constant expression.
// @AbstractClass()
// ^
//
// pkg/front_end/testcases/general/constants/various.dart:102:4: Error: Not a constant expression.
// @AbstractClassWithConstructor()
// ^
//
// pkg/front_end/testcases/general/constants/various.dart:10:34: Error: Constant evaluation error:
// const bool notBarFromEnvOrNull = !barFromEnvOrNull;
// ^
@ -341,9 +349,9 @@ abstract class AbstractClassWithConstructor extends core::Object /*hasConstConst
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
class NotAbstractClass extends core::Object {
@invalid-expression "Constant evaluation has no support for Throw!"
@invalid-expression "Not a constant expression."
field core::Object* foo = null;
@invalid-expression "Constant evaluation has no support for Throw!"
@invalid-expression "Not a constant expression."
field core::Object* bar = null;
synthetic constructor •() → self::NotAbstractClass*
: super core::Object::•()
@ -518,8 +526,8 @@ static const field dynamic binaryOnStringWithStringOK = #C11;
static const field dynamic binaryOnStringWithInt = invalid-expression "Binary operator '+' on '\"hello\"' requires operand of type 'String', but was of type 'int'.";
static const field dynamic binaryOnStringWithStringBad = invalid-expression "The method '-' can't be invoked on '\"hello\"' in a constant expression.";
static field core::int* x = 1;
static const field core::int* x1 = invalid-expression "Constant evaluation has no support for StaticSet!";
static const field core::int* x2 = invalid-expression "Constant evaluation has no support for StaticSet!";
static const field core::int* x1 = invalid-expression "Not a constant expression.";
static const field core::int* x2 = invalid-expression "Not a constant expression.";
static const field core::int* x3 = invalid-expression "The invocation of 'x' is not allowed in a constant expression.";
static const field core::int* x4 = invalid-expression "The invocation of 'x' is not allowed in a constant expression.";
static const field core::int* y = #C12;

View file

@ -100,6 +100,14 @@ library;
// class ExtendsFoo1 extends Foo {
// ^
//
// pkg/front_end/testcases/general/constants/various.dart:99:4: Error: Not a constant expression.
// @AbstractClass()
// ^
//
// pkg/front_end/testcases/general/constants/various.dart:102:4: Error: Not a constant expression.
// @AbstractClassWithConstructor()
// ^
//
// pkg/front_end/testcases/general/constants/various.dart:10:34: Error: Constant evaluation error:
// const bool notBarFromEnvOrNull = !barFromEnvOrNull;
// ^
@ -341,9 +349,9 @@ abstract class AbstractClassWithConstructor extends core::Object /*hasConstConst
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
class NotAbstractClass extends core::Object {
@invalid-expression "Constant evaluation has no support for Throw!"
@invalid-expression "Not a constant expression."
field core::Object* foo = null;
@invalid-expression "Constant evaluation has no support for Throw!"
@invalid-expression "Not a constant expression."
field core::Object* bar = null;
synthetic constructor •() → self::NotAbstractClass*
: super core::Object::•()
@ -518,8 +526,8 @@ static const field dynamic binaryOnStringWithStringOK = #C11;
static const field dynamic binaryOnStringWithInt = invalid-expression "Binary operator '+' on '\"hello\"' requires operand of type 'String', but was of type 'int'.";
static const field dynamic binaryOnStringWithStringBad = invalid-expression "The method '-' can't be invoked on '\"hello\"' in a constant expression.";
static field core::int* x = 1;
static const field core::int* x1 = invalid-expression "Constant evaluation has no support for StaticSet!";
static const field core::int* x2 = invalid-expression "Constant evaluation has no support for StaticSet!";
static const field core::int* x1 = invalid-expression "Not a constant expression.";
static const field core::int* x2 = invalid-expression "Not a constant expression.";
static const field core::int* x3 = invalid-expression "The invocation of 'x' is not allowed in a constant expression.";
static const field core::int* x4 = invalid-expression "The invocation of 'x' is not allowed in a constant expression.";
static const field core::int* y = #C12;

View file

@ -22,6 +22,10 @@ library;
// const NotConstant();
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Non-constant list literal is not a constant expression.
// foo({a: Constant(), b: Constant(), c: []}) {}
// ^
//
import self as self;
import "dart:core" as core;
@ -55,7 +59,7 @@ class NotConstant extends core::Object {
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal"}) → dynamic {}
static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal is not a constant expression."}) → dynamic {}
static method test() → dynamic {
invalid-expression "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'.

View file

@ -22,6 +22,10 @@ library;
// const NotConstant();
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Non-constant list literal is not a constant expression.
// foo({a: Constant(), b: Constant(), c: []}) {}
// ^
//
import self as self;
import "dart:core" as core;
@ -55,7 +59,7 @@ class NotConstant extends core::Object {
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal"}) → dynamic {}
static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal is not a constant expression."}) → dynamic {}
static method test() → dynamic {
invalid-expression "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'.

View file

@ -16,6 +16,10 @@ library;
// main(arguments = [x]) {
// ^
//
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Non-constant list literal is not a constant expression.
// main(arguments = [x]) {
// ^
//
import self as self;
static method main(dynamic arguments = invalid-expression "Non-constant list literal") → dynamic {}
static method main(dynamic arguments = invalid-expression "Non-constant list literal is not a constant expression.") → dynamic {}

View file

@ -16,6 +16,10 @@ library;
// main(arguments = [x]) {
// ^
//
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Non-constant list literal is not a constant expression.
// main(arguments = [x]) {
// ^
//
import self as self;
static method main(dynamic arguments = invalid-expression "Non-constant list literal") → dynamic {}
static method main(dynamic arguments = invalid-expression "Non-constant list literal is not a constant expression.") → dynamic {}

View file

@ -41,6 +41,7 @@ general/bug31124: FormatterCrash
general/clone_function_type: FormatterCrash
general/constants/js_semantics/number_folds: FormatterCrash
general/constants/js_semantics/number_folds_opt_out: FormatterCrash
general/constants/non_const_constructor: FormatterCrash
general/constants/number_folds: FormatterCrash
general/constants/number_folds_opt_out: FormatterCrash
general/constants/various: FormatterCrash

View file

@ -3251,7 +3251,7 @@ class AssertInitializer extends Initializer {
@override
void toTextInternal(AstPrinter printer) {
// TODO(johnniwinther): Implement this.
statement.toTextInternal(printer);
}
}

View file

@ -16,13 +16,11 @@ void main() {
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] Constant evaluation error:
// ^
// [cfe] Not a constant expression.
const c4 = finalField;
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] Constant evaluation error:
// ^
// [cfe] Not a constant expression.
const c5 = constField;
const c6 = method();
@ -33,6 +31,8 @@ void main() {
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
const c8 = const Class();
}

View file

@ -51,8 +51,8 @@ class C3 {
// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
// ^
// [cfe] 'field' is a final instance variable that was initialized at the declaration.
// ^
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
// [cfe] Not a constant expression.
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
// [cfe] New expression is not a constant expression.

View file

@ -15,4 +15,6 @@ class ConstFactoryWithBody {
main() {
const ConstFactoryWithBody.one();
// ^
// [cfe] Non-redirecting const factory invocation is not a constant expression.
}

View file

@ -14,6 +14,7 @@ invalid(
// ^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_DEFAULT_VALUE
// [cfe] Constant expression expected.
// [cfe] Non-constant map literal is not a constant expression.
main() {
invalid();

View file

@ -45,6 +45,8 @@ main() {
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
var f4 = B4;
var f5 = B5;
@ -60,7 +62,6 @@ const int F3;
// ^^
// [analyzer] COMPILE_TIME_ERROR.CONST_NOT_INITIALIZED
// [cfe] Field 'F3' should be initialized because its type 'int' doesn't allow null.
// ^
// [cfe] The const variable 'F3' must be initialized.
// ^
// [cfe] The value 'null' can't be assigned to a variable of type 'int' because 'int' is not nullable.
@ -83,10 +84,14 @@ const P2 = new Point(0, 0);
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
const P3 = new Point(0, 0) + 1;
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
// Check that we cannot have cyclic references in compile time
// expressions.
@ -115,8 +120,8 @@ class C1 {
// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
// ^
// [cfe] 'x' is a final instance variable that was initialized at the declaration.
// ^
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
// [cfe] Not a constant expression.
;
final x = null;
}
@ -138,4 +143,6 @@ const B4 = identical(1, new Point(1, 2));
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
const B5 = identical(1, const Point(1, 2));

View file

@ -7,6 +7,8 @@
import "package:expect/expect.dart";
const printConst = MessageType.parse("print");
// ^
// [cfe] Non-redirecting const factory invocation is not a constant expression.
class MessageType {
static const print = MessageType._('print');

View file

@ -18,13 +18,11 @@ void main() {
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] Constant evaluation error:
// ^
// [cfe] Not a constant expression.
const c4 = finalField;
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] Constant evaluation error:
// ^
// [cfe] Not a constant expression.
const c5 = constField;
const c6 = method();
@ -35,6 +33,8 @@ void main() {
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
const c8 = const Class();
}

View file

@ -53,8 +53,8 @@ class C3 {
// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
// ^
// [cfe] 'field' is a final instance variable that was initialized at the declaration.
// ^
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
// [cfe] Not a constant expression.
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
// [cfe] New expression is not a constant expression.

View file

@ -15,4 +15,6 @@ class ConstFactoryWithBody {
main() {
const ConstFactoryWithBody.one();
// ^
// [cfe] Non-redirecting const factory invocation is not a constant expression.
}

View file

@ -16,6 +16,7 @@ invalid(
// ^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_DEFAULT_VALUE
// [cfe] Constant expression expected.
// [cfe] Non-constant map literal is not a constant expression.
main() {
invalid();

View file

@ -47,6 +47,8 @@ main() {
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
var f4 = B4;
var f5 = B5;
@ -81,10 +83,14 @@ const P2 = new Point(0, 0);
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
const P3 = new Point(0, 0) + 1;
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
// Check that we cannot have cyclic references in compile time
// expressions.
@ -113,8 +119,8 @@ class C1 {
// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
// ^
// [cfe] 'x' is a final instance variable that was initialized at the declaration.
// ^
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
// [cfe] Not a constant expression.
;
final x = null;
}
@ -136,4 +142,6 @@ const B4 = identical(1, new Point(1, 2));
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] New expression is not a constant expression.
// ^
// [cfe] New expression is not a constant expression.
const B5 = identical(1, const Point(1, 2));