| Index: docs/language/informal/optional-const.md
|
| diff --git a/docs/language/informal/optional-const.md b/docs/language/informal/optional-const.md
|
| index debf705e3d140384485b6c167afac61e19610e5c..45fd20103d49b1b2bb04899be221a7087627c8bd 100644
|
| --- a/docs/language/informal/optional-const.md
|
| +++ b/docs/language/informal/optional-const.md
|
| @@ -2,9 +2,9 @@
|
|
|
| Author: eernst@.
|
|
|
| -Version: 0.1 (2017-08-10)
|
| +Version: 0.2 (2017-08-30)
|
|
|
| -Status: Under discussion
|
| +Status: Under implementation.
|
|
|
| **This document** is an informal specification of the *optional const* feature.
|
| **The feature** adds support for omitting the reserved word `const` in list and
|
| @@ -26,8 +26,8 @@ literal provides no extra information: It is a compile-time error if that
|
| object expression is modified to use `new` rather than `const`. In that
|
| situation it carries no extra information whether `new` or `const` is used, and
|
| it is even possible to omit the reserved word entirely. It is also required for
|
| -certain other expressions to be constant, e.g., default values on formal
|
| -parameters and initializing expressions for constant variables.
|
| +certain other expressions to be constant, e.g., initializing expressions for
|
| +constant variables.
|
|
|
| In all these cases the presence of `const` is required, and hence such a
|
| `const` may be inferred by compilers and similar tools if it is omitted.
|
| @@ -35,9 +35,9 @@ In all these cases the presence of `const` is required, and hence such a
|
| Developers reading the source code are likely to find it easy to understand
|
| that a required `const` was omitted and is implied, because the reason for
|
| the requirement is visible in the enclosing syntax: The expression where
|
| -`const` is inferred is a subexpression of an expression with `const`, it is
|
| -used to initialize a constant variable, or it is a default value for a formal
|
| -parameter.
|
| +`const` is inferred is a subexpression of an expression with `const` or it
|
| +is used in another situation where a constant value is required, e.g., to
|
| +initialize a constant variable.
|
|
|
| In summary, tools do not need the required occurrences of `const`, and they
|
| are also unimportant for developers. Conversely, omitting required occurrences
|
| @@ -80,42 +80,21 @@ postfixExpression ::=
|
| primary selector*
|
| constructorInvocation ::= // NEW
|
| typeName typeArguments '.' identifier arguments
|
| -assignableExpression ::=
|
| - SUPER unconditionalAssignableSelector |
|
| - typeName typeArguments '.' identifier arguments
|
| - (arguments* assignableSelector)+ | // NEW
|
| - identifier |
|
| - primary (arguments* assignableSelector)+
|
| ```
|
|
|
| -*A complete grammar which includes these changes is available
|
| -[here](https://gist.github.com/eernstg/024a997f4f8c7ef885d459c3703a35f6).*
|
| -
|
| -*Note that the alternative which is added in the rule for `assignableExpression`
|
| -is required in order to allow expressions which are obtained by constructing a
|
| -constant object expression in Dart without optional const and removing the
|
| -`const`. That particular case will not match any of the cases where the `const`
|
| -is required (because `assignableExpression` is only used in contexts which
|
| -cannot be constant expressions). However, this approach yields syntactic support
|
| -for omitting `const` in every `constantObjectExpression`, and it also allows for
|
| -omitting `new` from every `newExpression`, which is useful for the
|
| -associated
|
| -[optional new feature](https://gist.github.com/eernstg/7e819b44acd8dd9d71f0cc510b618a3d).*
|
| -
|
| *The grammar only needs to be adjusted for one case, namely invocations of named
|
| constructors for generic classes. In this case we can derive expressions like
|
| `const Foo<int>.bar()`, and the corresponding `Foo<int>.bar()` is not derivable
|
| in the same situations where the variant with `const` can be derived. In other
|
| words, we must add support for constructs like `Foo<int>.bar()` as part of a
|
| -`postfixExpression` and as part of an `assignableExpression`. For all other
|
| -situations, the variant with `const` becomes a construct which is already
|
| -syntactically correct Dart when the `const` is removed. For instance `const
|
| -C(42)` becomes `C(42)` which could already be a function invocation and is hence
|
| -already allowed syntactically.*
|
| +`postfixExpression`. For all other situations, the variant with `const` becomes
|
| +a construct which is already syntactically correct Dart when the `const` is
|
| +removed. For instance `const C(42)` becomes `C(42)` which is already allowed
|
| +syntactically (syntactically, it could be a function invocation).*
|
|
|
| ## Static analysis
|
|
|
| -We specify a type directed source code transformation which eliminates the
|
| +We specify a type directed source code transformation which eliminates the
|
| feature. The static analysis proceeds to work on the transformed program.
|
|
|
| *This means that the feature is "sugar", but because of the need to refer
|
| @@ -123,44 +102,63 @@ to types it could be described as static semantic sugar rather than
|
| syntactic sugar. We do not specify the dynamic semantics for this feature,
|
| because the feature is eliminated in this transformation step.*
|
|
|
| +We need to treat expressions differently in different locations, hence the
|
| +following definition: An expression _e_ is said to *occur in a constant
|
| +context*,
|
| +
|
| +- if _e_ is an immediate subexpression of a constant list literal or a
|
| + constant map literal.
|
| +- if _e_ is an immediate subexpression of a constant object expression.
|
| +- if _e_ is the initializing expression of a constant variable declaration.
|
| +- if _e_ is an immediate subexpression of an expression which occurs in a
|
| + constant context.
|
| +
|
| +*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.*
|
| +
|
| An expression on one of the following forms must be modified to be or
|
| contain a `constantObjectExpression` as described:
|
|
|
| -With a `postfixExpression` _e_,
|
| +With a `postfixExpression` _e_ occurring in a constant context,
|
|
|
| -- if _e_ is on the form `constructorInvocation`, i.e.,
|
| - `typeName typeArguments '.' identifier arguments` then replace _e_ by
|
| - `'const' typeName typeArguments '.' identifier arguments`.
|
| +- if _e_ is on the form `constructorInvocation` then replace _e_ by
|
| + `const` _e_.
|
| - if _e_ is on the form
|
| `typeIdentifier arguments` where `typeIdentifier` denotes a class then
|
| - replace _e_ by
|
| - `'const' typeIdentifier arguments`.
|
| + replace _e_ by `const` _e_.
|
| - if _e_ is on the form
|
| `identifier1 '.' identifier2 arguments` where `identifier1` denotes
|
| - a class and `identifier2` is the name of a named constructor in that class,
|
| - or `identifier1` denotes a prefix for a library _L_ and `identifier2` denotes
|
| - a class exported by _L_, replace _e_ by
|
| - `'const' identifier1 '.' identifier2 arguments`.
|
| + a class and `identifier2` is the name of a named constructor in that
|
| + class, or `identifier1` denotes a prefix for a library _L_ and
|
| + `identifier2` denotes a class exported by _L_, replace _e_ by
|
| + `const` _e_.
|
| - if _e_ is on the form
|
| - `identifier1 '.' typeIdentifier '.' identifier2 arguments` where
|
| - `identifier1` denotes a library prefix for a library _L_, `typeIdentifier`
|
| - denotes a class _C_ exported by _L_, and `identifier2` is the name of a named
|
| - constructor in _C_, replace _e_ by
|
| - `'const' identifier1 '.' typeIdentifier '.' identifier2 arguments`.
|
| + `identifier1 '.' typeIdentifier '.' identifier2 arguments` where
|
| + `identifier1` denotes a library prefix for a library _L_,
|
| + `typeIdentifier` denotes a class _C_ exported by _L_, and `identifier2`
|
| + is the name of a named constructor in _C_, replace _e_ by
|
| + `const` _e_.
|
| +
|
| +For a list literal _e_ occurring in a constant context, replace _e_ by
|
| +`const` _e_. For a map literal _e_ occurring in a constant context,
|
| +replace _e_ by `const` _e_.
|
|
|
| *In short, in these specific situations: "just add `const`". It is easy to
|
| verify that each of the replacements can be derived from
|
| `constObjectExpression`, which can be derived from `postfixExpression` via
|
| -`primary selector*`; hence the transformation preserves syntactic correctness.*
|
| +`primary selector*`. Hence, the transformation preserves syntactic
|
| +correctness.*
|
|
|
| The remaining static analysis proceeds to work on the transformed program.
|
|
|
| *It is possible that this transformation will create
|
| `constObjectExpressions` which violate the constraints on constant object
|
| -expressions. It is recommended that the error messages emitted by tools in
|
| -response to such violations include information about the transformative
|
| -step that added this `const` to the given construct and informs developers
|
| -that they may add `new` explicitly if that matches the intention.*
|
| +expressions, e.g., when `const [[new A()]]` is transformed to
|
| +`const [const [new A()]]` where the inner list is an error that was created
|
| +by the transformation (so the error was moved from the outer to the inner
|
| +list). It is recommended that the error messages emitted by tools in response
|
| +to such violations include information about the transformation.*
|
|
|
| ## Dynamic Semantics
|
|
|
| @@ -170,7 +168,12 @@ eliminated by code transformation.
|
|
|
| ## Revisions
|
|
|
| -- 0.1 (2017-08-10) Stand-alone proposal for optional const created, using
|
| - version 0.8 of the combined proposal
|
| +- 0.2 (2017-08-30) Updated the document to specify the previously missing
|
| + transformations for composite literals (lists and maps), and to specify a
|
| + no-magic approach (where no `const` is introduced except when forced by
|
| + the syntactic context).
|
| +
|
| +- 0.1 (2017-08-10) Stand-alone informal specification for optional const
|
| + created, using version 0.8 of the combined proposal
|
| [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
|
| as the starting point.
|
|
|