inConstantContext property
An expression e is said to occur in a constant context,
- if e is an element of a constant list literal, or a key or value of an entry of a constant map literal.
- if e is an actual argument of a constant object expression or of a metadata annotation.
- if e is the initializing expression of a constant variable declaration.
- if e is a switch case expression.
- if e is an immediate subexpression of an expression e1 which occurs
in a constant context, unless e1 is a
throw
expression or a function literal.
This roughly means that everything which is inside a syntactically
constant expression is in a constant context. A throw
expression is
currently not allowed in a constant expression, but extensions affecting
that status may be considered. A similar situation arises for function
literals.
Note that the default value of an optional formal parameter is not a constant context. This choice reserves some freedom to modify the semantics of default values.
Implementation
@override
bool get inConstantContext {
AstNode child = this;
while (child is Expression ||
child is ArgumentList ||
child is MapLiteralEntry ||
child is SpreadElement ||
child is IfElement ||
child is ForElement) {
var parent = child.parent;
if (parent is ConstantContextForExpressionImpl) {
return true;
} else if (parent is ConstantPatternImpl) {
return true;
} else if (parent is EnumConstantArguments) {
return true;
} else if (parent is TypedLiteralImpl && parent.constKeyword != null) {
// Inside an explicitly `const` list or map literal.
return true;
} else if (parent is InstanceCreationExpression &&
parent.keyword?.keyword == Keyword.CONST) {
// Inside an explicitly `const` instance creation expression.
return true;
} else if (parent is Annotation) {
// Inside an annotation.
return true;
} else if (parent is RecordLiteral && parent.constKeyword != null) {
return true;
} else if (parent is VariableDeclaration) {
var grandParent = parent.parent;
// Inside the initializer for a `const` variable declaration.
return grandParent is VariableDeclarationList &&
grandParent.keyword?.keyword == Keyword.CONST;
} else if (parent is SwitchCase) {
// Inside a switch case.
return true;
} else if (parent == null) {
break;
}
child = parent;
}
return false;
}