There are some expressions where an isConst field implies that sub
expressions can omit the const keyword. This is manually handled in
the appropriate visit methods for the expressions where a const context
is sensible. In InvokeExpression a type field expressed the same
intent.
Using declareConst and assign did not carry the const context, so an
expression would have an omittable const keyword.
Add an isConst getter on Expression. Default to false since the
expressions which already can imply const already have definitions
with correct usage, except for InvokeExpression which had a
different API. This is only necessary to allow forwarding in assign
without overriding in each subclass which can imply a const context.
In assignments, forward isConst to the BinaryExpression. A const
left hand side implies const for the right hand side.
Deprecate the type field for InvokeExpression in favor of a new
override for isConst. There is no need for a null unknown-const
state. Expressions are by default assumed to not imply a const context
and only relevant expression types are checked for isConst by the
relevant visitors. Update the invoke expression visitor to use
isConst over checking the type. No methods may be invoked in a const
expression and the private constructor is used for invoking methods,
so assume false.
Always use a BinaryExpression for declareConst, and mark it as
const. This allows the assignment to carry the context through to the
other expressions.
Add tests that assigning to a declareConst uses an implicit const
on the right hand side, while assigning to a non-const var uses an
explicit const.
There are some expressions where an
isConst
field implies that sub expressions can omit theconst
keyword. This is manually handled in the appropriate visit methods for the expressions where a const context is sensible. InInvokeExpression
atype
field expressed the same intent.Using
declareConst
andassign
did not carry the const context, so an expression would have an omittableconst
keyword.isConst
getter onExpression
. Default to false since the expressions which already can imply const already have definitions with correct usage, except forInvokeExpression
which had a different API. This is only necessary to allow forwarding inassign
without overriding in each subclass which can imply a const context.isConst
to theBinaryExpression
. A const left hand side implies const for the right hand side.type
field forInvokeExpression
in favor of a new override forisConst
. There is no need for a null unknown-const state. Expressions are by default assumed to not imply a const context and only relevant expression types are checked forisConst
by the relevant visitors. Update the invoke expression visitor to useisConst
over checking the type. No methods may be invoked in a const expression and the private constructor is used for invoking methods, so assumefalse
.BinaryExpression
fordeclareConst
, and mark it as const. This allows the assignment to carry the context through to the other expressions.declareConst
uses an implicitconst
on the right hand side, while assigning to a non-const var uses an explicitconst
.