This patch adds a python function to syntax node gyb support called
"check_child_condition". Given a child's definition, this function
generate a C++ closure to check whether a given syntax node can satisfy
the condition of the child node. This function recursively generates code
for node choices too, therefore we don't need to hard code the
condition checking for node choices.
Some structures of syntax nodes can have children choices, e.g. a
dictionary expression can either contain a single ':' token or a list of
key-value pairs.
This patch gives the existing code generation infrastructure a way to
specify such node choices. Node choices are specified under a child
declaration with two constraints: a choice cannot be declared as
optional, and a choice cannot have further recursive choices.
Since we don't have too many node structures with choices, part of the
SyntaxFactory code for these nodes is manually typed.
This patch also teaches AccessorBlock to use node choices.
Variable declarations are declarations led by either 'var' or 'let'. It
can contain multiple pattern bindings as children.
For patterns, this patch only creates syntax nodes for simple identifier
patterns, e.g. 'a = 3'. The rest of the pattern kinds are still left
unknown (UnknownPattern).
This document breaks all existing syntactic AST nodes into five categories:
expression, declaration, statement, pattern and typerepr. Nodes in each
category can be further defined as "specialized", "in-progress" and
"not-specialized".
The parser currently can recognize specialized nodes; for "in-progress"
and "not-specialized" nodes, the parser will wrap their underlying source
to be an unknown entity, e.g. UnknownDecl or UnknownStmt.
"in-progress" nodes are considered in a higher priority to be specialized
than "not-specialized" nodes. However, eventually all nodes should be
marked as "specialized".
to check text-choices of a token child.
This allows us to reject the creation of a syntax node if one of its token
syntax children doesn't follow the required textual choices, e.g.
modifiers.
To construct struct syntax, this patch first specialized type
inheritance clause. For protocol's class requirement, we currently
treat it as an unknown type.
This patch also teaches SyntaxParsingContext to collect syntax nodes
from back in place. This is useful to squash multiple decl modifiers
for declarations like function. This is not used for struct declaration
because only accessibility modifier is allowed.
This patch also performs minor refactoring to align syntax parsing
context with the right scope. We start to support the generic clauses
because they are necessary pieces to construct struct or
function syntax node.
Because generic where clause doesn't coerce well to our existing syntax
context kinds, we add a new syntax context kind with this patch called
"Syntax". This context kind indicates that when error occurs, the
collection of syntax nodes falling into the context should be coerced
to UnknownSyntax.
* libSyntax: Parse member access expression.
This patch uses createNodeInPlace from syntax parsing context API to
merge an expression with its suffix to create recursive nodes such as
member access expression.
Meanwhile, this patch breaks down a signed integer or float literal to a
prefix operator expression. This expression consists of two parts: an
operator and the following expression. This makes literals like "+1" or
"-1" no different from other prefix unary expressions such as "!true".
Along with starting to support ternary expressions, this commit also
slightly changes SyntaxParsingContext APIs as follows:
1. Previously, makeNode() only supports node creation by using the nodes
from the underlying syntax token array; this commit allows it to use the nodes from
the pending syntax list as well.
2. This commit strictly limits that the pending syntax list should never
contain token syntax node.
3. The node kind test shouldn't include unknown kinds. They are noisy.