-
Notifications
You must be signed in to change notification settings - Fork 229
Description
The Dart static access shorthand proposal specifies a new grammar construct allowing a selector chain to begin with a . followed by an identifier or new (the . may be preceded by const). For example (from the spec draft):
Endian littleEndian = .little; // short for `Endian.little`The currently specified semantics is that the context for the entire selector chain is used to resolve the identifier. This enables more complex examples like this (also from the spec draft):
int posNum = .parse(userInput).abs(); // short for `int.parse(userInput).abs()`This implies some action at a distance, which will in turn require some extra bookkeeping in the implementations. To see why, consider that a selector chain can involve an arbitrary large number of method invocations, function invocations, null checks, index operations, and property accesses. For example, this would be permitted:
A x = .b()()![1].c; // short for `A.b()()![1].c`The parse tree for this declaration would look something like this (making some guesses and simplifying assumptions about the AST representation):
VariableDeclaration
/ | | \
A x = PropertyGet
/ \
Index .c
/ \
NullCheck [1]
/ \
Function !
Invocation
/ \
Method ()
Invocation
\
.b()
The existing downwards inference mechanism passes the context A down from the VariableDeclaration to the PropertyGet, but no further. To implement the feature as currently described, we would need some sort of mechanism for plumbing the context down to the MethodInvocation at the bottom of the tree.
The question at issue here is: what would be the cost of such a mechanism (both in terms of performance and implementation complexity)? Would there be enough user benefit to justify it?
Follow up question: what if we decided to expand the mechanism to cover other kinds of syntax that can appear to the right of an expression (binary operators, conditional expressions, or cascades)? For example:
int i = .parse(userInput).abs() / 2 + 1;
Endian opposite = .host == .little ? .big : .little;
List<int> x = .of(iterator1)..addAll(iterator2);