This module defines types for a Ceylon Abstract Syntax Tree (AST), a hierarchical and immutable data structure that represents a Ceylon program.
There are two major ways to obtain an AST:
You can of course construct the AST yourself.
To reduce the amount of boilerplate code necessary, we strongly recommend
using the ceylon.ast.create
module (module ceylon.ast.create
);
this will, for example, allow you to write
baseExpression("null")
instead of
BaseExpression(MemberNameWithTypeArguments(LIdentifier("null")))
The ceylon.ast.redhat
module (module ceylon.ast.redhat
) allows you to
compile any AST node from a corresponding code string (internally using the
RedHat Ceylon compiler).
If you have a node from the RedHat AST, you can also convert it using that module.
You can analyze an AST node (and its child nodes) using the Visitor
interface.
For example, you can count the amount of else if
snippets like this:
variable Integer elseIfCount = 0; that.visit { object visitor satisfies Visitor { shared actual void visitElseClause(ElseClause that) { if (that.child is IfElse) { elseIfCount++; } super.visitElseClause(that); } } };
Visitor
takes care of the AST traversal for you;
you only need to override the functions that correspond to the nodes
that concern you.
You can also attach your analysis results to the AST nodes.
To do this, you first need to create a Key
:
shared Key<Token[]> tokensKey = ScopedKey<Token[]>(`module my.parser`, "tokens");
(We recommend the use of ScopedKey
to avoid naming collisions.)
Then, you can attach information using Node.put()
node.put(tokensKey, tokens)
and later retrieve it with Node.get()
(perhaps in a different module):
assert (exists tokens = node.get(tokensKey));
The key is typed, so you don’t lose typing information (except about the presence of the attached information).
Since the AST is immutable, you can’t edit it directly.
However, you can easily obtain an edited copy using the Editor
interface.
For example, you can replace else if
s with else { if … }
s like this:
that.transform { object transformer satisfies Editor { shared actual ElseClause transformElseClause(ElseClause that) { if (is IfElse ifElse = that.child) { return that.copy { child = Block([ifElse]); }; } else { return super.transformElseClause(that); } } } };
Editor
performs a deep copy by default;
again, you only need to override the functions that correspond to the
nodes that concern you.
You can also transform your AST into something completely different
using the Transformer
interface.
A Transformer<Something>
transforms an AST into an instance of
Something
.
Here are a few examples:
CeylonExpressionTransformer
CeylonExpressionTransformer
is a Transformer<String>
and transforms
individual nodes like this:
transformSumOperation(SumOperation that) => "SumOperation { leftSummand = ``that.leftSummand.transform(this)``; rightSummand = ``that.rightSummand.transform(this)``; }";
(In reality it’s a bit more complicated because we need to deal with indentation.)
While the traversal doesn’t happen automatically, it’s mostly taken care of
by the ceylon.ast
infrastructure, at least if your resulting
representation retains the node hierarchy (here: direct use of
child.transform(this)
).
RedHatTransformer
RedHatTransformer
, in the
ceylon.ast.redhat
module (module ceylon.ast.redhat
), is a
Transformer<JNode>
(where JNode
is an import alias for RedHat AST nodes).
It can be used to transform a ceylon.ast
node to a RedHat AST node.
This node can then, for example, be fed into the RedHat Ceylon compiler
to compile it, or into the ceylon.formatter
(module ceylon.formatter
)
to generate code for it (ceylon.formatter::format
function).
Editor
Editor
is a Transformer<Node>
, that is, a transformer from
ceylon.ast
to ceylon.ast
.
(That’s why the methods it uses are called transform
and not edit
.)
Visitor
Visitor
is a Transformer<Anything>
, that is, a transformer
from ceylon.ast
to void
(nothing).
The traversal mechanism comes from WideningTransformer
, which you may
also use yourself.
An AST node represents a syntactically valid Ceylon program. It doesn’t necessarily have to be semantically valid; for example, the following expression
null.wrdlbrmpfd(nothing.attr)
will not compile, but has a perfectly valid AST representation. On the other hand, you cannot create an
LIdentifier("My Identifier")
(it will throw an AssertionError
at runtime), because My Identifier
is not a syntactically valid lowercase identifier.
Likewise, equality of nodes (Object.equals()
) only means syntactic equality:
Even though the following two types are equal
String|Integer Integer|String
their AST nodes are not.
The distinction between syntactical and semantical restrictions is sometimes
unclear or ambiguous; note especially that the RedHat compiler’s parser
(grammar) allows (for better error messages) some syntax that is refused
in ceylon.ast
(for example, empty resource lists for try
).
ceylon.ast
seeks to comply only with the Ceylon Language Specification,
not its implementation in the compiler.
Packages | |
ceylon.ast.core |
Dependencies | ||
ceylon.collection | 1.1.0 |
Aliases | |
AddingExpression | Source Codeshared AddingExpression=> ScalingExpression|SumOperation|DifferenceOperation An expression on or above the precedence level of addition and subtraction. |
AssigningExpression | Source Codeshared AssigningExpression=> ThenElseExpression|AssignmentOperation An expression on or above the precedence level of assignment. This contains all “Layer 4” operators, that is, all operators total. |
ComparingExpression | Source Codeshared ComparingExpression=> ExistsNonemptyExpression|IsOperation|OfOperation|InOperation|ComparisonOperation|CompareOperation|WithinOperation An expression on or above the precedence level of comparison, containment, assignability and inheritance tests. |
ConjoiningExpression | Source Codeshared ConjoiningExpression=> NegatingExpression|AndOperation An expression on or above the precedence level of logical conjunction. |
DisjoiningExpression | Source Codeshared DisjoiningExpression=> ConjoiningExpression|OrOperation An expression on or above the precedence level of logical disjunction. This contains all “Layer 3” operators. |
EquatingExpression | Source Codeshared EquatingExpression=> ComparingExpression|EqualityOperation An expression on or above the precedence level of equality tests. This contains all “Layer 2” operators. |
ExistsNonemptyExpression | Source Codeshared ExistsNonemptyExpression=> SpanningExpression|ExistsOperation|NonemptyOperation An expression on or above the precedence level of existence and nonemptiness tests. |
ExponentiatingExpression | Source Codeshared ExponentiatingExpression=> PrePostfixingExpression|ExponentiationOperation An expression on or above the precedence level of exponentiation. |
IntersectingExpression | Source Codeshared IntersectingExpression=> InvertingExpression|IntersectionOperation An expression on or above the precedence level of intersection. |
InvertingExpression | Source Codeshared InvertingExpression=> ExponentiatingExpression|UnaryArithmeticOperation An expression on or above the precedence level of arithmetic inversion or identity. Not to be confused with the precedence level of logical negation ( |
MemberName | Source Codeshared MemberName=> LIdentifier |
MetaQualifier | Source Codeshared MetaQualifier=> SimpleType|GroupedType|MemberName A node that can appear as the qualifier of a |
MultiplyingExpression | Source Codeshared MultiplyingExpression=> UnioningExpression|ProductOperation|QuotientOperation|RemainderOperation An expression on or above the precedence level of multiplication or division. |
NegatingExpression | Source Codeshared NegatingExpression=> EquatingExpression|NotOperation An expression on or above the precedence level of logical negation. Not to be confused with the precedence level of arithmetic inversion ( |
PackageName | Source Codeshared PackageName=> LIdentifier |
PrePostfixingExpression | Source Codeshared PrePostfixingExpression=> Primary|PrefixOperation|PostfixOperation An expression on or above the precedence level of arithmetic pre- or postfix expressions. (This is the highest precedence level for operators; only primary expressions rank higher.) |
ScalingExpression | Source Codeshared ScalingExpression=> MultiplyingExpression|ScaleOperation An expression on or above the precedence level of scaling. |
SpanningExpression | Source Codeshared SpanningExpression=> AddingExpression|SpanOperation|MeasureOperation|EntryOperation An expression on or above the precedence level of range and entry construction. This contains all “Layer 1” operators. |
ThenElseExpression | Source Codeshared ThenElseExpression=> DisjoiningExpression|ThenOperation|ElseOperation An expression on or above the precedence level of “ |
TypeName | Source Codeshared TypeName=> UIdentifier |
UnioningExpression | Source Codeshared UnioningExpression=> IntersectingExpression|UnionOperation|ComplementOperation An expression on or above the precedence level of union or complementation. |
Values | |
outerInstance | Source Codeshared Outer outerInstance |
packageInstance | Source Codeshared Package packageInstance |
superInstance | Source Codeshared Super superInstance |
thisInstance | Source Codeshared This thisInstance |
Functions | |
annotation | Source Codeshared Annotation annotation(String name) Shortcut helper function for an |
lidentifierNeedsPrefix | Source Codeshared Boolean lidentifierNeedsPrefix(String name) Parameters:
|
uidentifierNeedsPrefix | Source Codeshared Boolean uidentifierNeedsPrefix(String name) Parameters:
|
Interfaces | |
CascadingNarrowingTransformer | Source Codeshared CascadingNarrowingTransformer<out Result> A For example: // ValueExample has the case types Primary | Operation shared actual default Result transformValueExpression(ValueExpression that) { switch (that) case (is Primary) { return transformPrimary(that); } case (is Operation) { return transformOperation(that); } } I honestly don’t know when you’d want to use this instead of |
Editor | Source Codeshared Editor An AST editor. There is one method per AST node; override the methods for which you need to change the AST, and leave the others untouched. The default operation for “bottom“ node types’ methods is to copy the node, editing the children.
(The default operation for non-“bottom” node types’ methods is inherited from For example: class PrefixEditor(String prefix) extends Editor() { shared actual Identifier editIdentifier(Identifier that) => that.copy { name = prefix + that.name; }; } will prepend Note that this deep copy of the AST can be expensive; if you know that you will not touch
certain parts of the AST – for example, you only edit method names, and never instructions –
you might want to override some methods to |
ImmediateNarrowingTransformer | Source Codeshared ImmediateNarrowingTransformer<out Result> A For example: shared actual default Result transformValueExpression(ValueExpression that) => that.transform(this); This interface should be functionally equivalent to |
NarrowingTransformer | Source Codeshared NarrowingTransformer<out Result> A There are two ways to perform this narrowing:
It should be possible to use them interchangeably (swap out the satisfying type of your implementing class without any effect), and since the immediate version is faster (it’s only a virtual method lookup instead of a series of calls and type checks), you should probably use that. |
Transformer | Source Codeshared Transformer<out Result> Abstract interface to perform some operations on AST nodes and possibly get some result. For every subtype of
Be careful when mixing the two behaviors, lest you end up in an infinite recursion! |
Visitor | Source Codeshared Visitor An AST visitor. There is one method per AST node; override the methods for which you need to do something, and leave the others untouched. The default operation for most node types is to pass the visit up to the node’s supertype;
for example, if you override only |
WideningTransformer | Source Codeshared WideningTransformer<out Result> A |
Classes | |
AddAssignmentOperation | Source Codeshared AddAssignmentOperation An add assignment operation ( Right-associative. Examples: index += step document.cursor.position += insertion.size |
AliasDec | Source Codeshared AliasDec An alias reference expression, that is,
the Examples: `alias TypeName` `alias A.B.C |
AndAssignmentOperation | Source Codeshared AndAssignmentOperation A logical conjunction assignment expression. Right-associative. Examples: valid &&= parsed exists legal &&= !globalLock |
AndOperation | Source Codeshared AndOperation A logical conjunction expression. Left-associative. Examples: i%2 == 0 && j%2 == 1 attr1 == that.attr1 && attr2 == that.attr2 && attr3 == that.attr3 |
Annotation | Source Codeshared Annotation An annotation. For the common case “no arguments”, the toplevel helper function Examples: shared formal by ("John Doe <john.doe@company.com>") see (`function print`) action { description = "Log in"; url = "/login"; } |
Annotations | Source Codeshared Annotations A list of annotations. The first annotation may optionally be an anonymous annotation,
that is, a string literal interpreted as the argument of a Annotations are not separated by any punctuation. Examples: shared formal "The number of elements in this list" see (`value List.lastIndex`) shared actual |
AnonymousArgument | Source Codeshared AnonymousArgument An anonymous named argument, that is, an expression followed by a semicolon. Examples: name; width * height; |
AnyClass | Source Codeshared abstract AnyClass A class definition or alias. Examples (multi-line): shared class PrintableWrapper<T>(shared T wrapped) satisfies Printable { shared actual void print() { package.print(wrapped else "<null>"); } } shared class VariadicString(Character* characters) => String(characters); |
AnyCompilationUnit | Source Codeshared abstract AnyCompilationUnit A compilation unit. There are three kinds of compilation unit:
(Because it is the most commonly used, and also what most people associate with a “compilation unit”,
the first kind is simply called Every compilation unit starts with a (possibly empty) list of Examples (separated by blank lines): module tmp "1.0.0" {} package tmp; void run() { print("Hello, World!"); } |
AnyFunction | Source Codeshared abstract AnyFunction A function declaration or definition. If the Examples: shared formal Boolean equals(Object that); function compareByLength({Anything*} first, {Anything*} second) => first.length.compare(second.length); shared void run() { print("Hello, `` process.arguments.first else "World" ``!"); |
AnyInterface | Source Codeshared abstract AnyInterface An interface definition or alias. Examples (multi-line): shared interface Printable { shared default void print() => package.print(this); } shared interface People => {Person*}; |
AnyInterfaceDefinition | Source Codeshared abstract AnyInterfaceDefinition A regular or dynamic interface definition. Examples (multi-line): shared interface Printable { shared default void print() => package.print(this); } shared dynamic Document { shared formal String xmlVersion; shared formal StyleSheetList styleSheets; shared formal String documentURI; // ... } |
AnyMemberOperator | Source Codeshared abstract AnyMemberOperator A member operator, used in a |
AnySpecifier | Source Codeshared abstract AnySpecifier |
AnyValue | Source Codeshared abstract AnyValue A value declaration or definition. If the Examples: shared String name; shared formal Comparison compare(Other that); shared default Boolean empty => iterator().next() is Finished; |
ArgumentList | Source Codeshared ArgumentList An argument list. A list of expressions, here called listed arguments, optionally followed by a spread argument or a comprehension. Examples: width, height *args /* empty parameter list is also allowed */ this, *others |
Arguments | Source Codeshared abstract Arguments An argument list that can be used in an Not to be confused with Examples: (x, y, *messages) () (for (i in 1..10) i^2) { factor = 2.1; *actors } |
ArithmeticAssignmentOperation | Source Codeshared abstract ArithmeticAssignmentOperation An arithmetic assignment operation,
a shortcut for an Right-associative. |
ArithmeticOperation | Source Codeshared abstract ArithmeticOperation An arithmetic operation expression. |
Assertion | Source Codeshared Assertion An assertion statement, that is,
an annotation list, followed by the keyword ‘ Examples: assert (exists num = parseFloat(numText)); "Weight cannot be negative" assert (weight >= 0); |
AssignOperation | Source Codeshared AssignOperation An assignment expression. Right-associative. Examples: i = 1 text = "Hello, ``name else "World"``!" |
AssignmentOperation | Source Codeshared abstract AssignmentOperation An assignment expression. Right-associative. This is the abstract superclass of all assignment operations, with operators like |
AssignmentStatement | Source Codeshared AssignmentStatement An assignment expression statement, that is, an assignment terminated by a semicolon. In principle, a statement like Examples: text.length += added.length; ret.endToken = tokens.token(";", semicolon); |
Atom | Source Codeshared abstract Atom An “atomic” expression. While atoms can wrap and contain other expressions, they never consist of several expressions chained together without any wrapping.
For example, in |
BaseExpression | Source Codeshared BaseExpression An unqualified identifier with an optional list of type arguments. A base expression can refer to either:
Examples: null max<Integer,Nothing> |
BaseMeta | Source Codeshared BaseMeta A base metamodel expression, that is, a member name with optional type arguments, surrounded by backticks. (A type name with optional type arguments surrounded by backticks is a Examples: `sum<Float>` `system` |
BaseType | Source Codeshared BaseType A type name with optional type arguments. |
BinaryOperation | Source Codeshared abstract BinaryOperation A binary operator expression. Binary operations can be left-associative ( (Some binary operations have no precedence because they can’t be nested
(for example, |
Block | Source Codeshared Block A list of statements and declarations, surrounded by braces. A block contains imperative code, a series of statements that is executed sequentially each time the block is entered (declarations can’t be executed). It may also return a value. Examples (multi-line): { print("``indent``BEGIN ``that``"); value origIndent = indent; indent += indentLevel; that.visit(this); indent = origIndent; print("``indent``END ``that``"); } { throw AssertionError("Not yet implemented!"); } { if (exists first = s.first) { return String { first.lowercased, *s.rest }; } else { return ""; } } |
Body | Source Codeshared abstract Body A list of statements and declarations, surrounded by braces. Examples: {} { shared String name; string => name; } |
BooleanCondition | Source Codeshared BooleanCondition A boolean condition, that is, an expression. The condition is satisfied when the expression evaluates to Examples: type in { type_ws, type_comment } literals.size == expressions.size + 1 |
Bound | Source Codeshared abstract Bound A lower or upper bound of a bounded comparison operation. |
Break | Source Codeshared Break A |
CallableParameter | Source Codeshared CallableParameter A callable parameter. Examples: Comparison comparing(Element left, Element right) void onSuccess() |
CallableType | Source Codeshared CallableType A callable type, that is, a shortcut for
Examples: Integer(Integer,Integer) String(Character*) |
CaseClause | Source Codeshared CaseClause A ‘ Examples (multi-line): case (is String) { int = parseInteger(val); } case (null) { return; } |
CaseItem | Source Codeshared abstract CaseItem A ‘ Examples: is String 0, 1 |
CaseTypes | Source Codeshared CaseTypes A nonempty list of case types, separated by the union operator (‘ Examples: of String | Float | Integer of Other of empty | [Element+] |
CatchClause | Source Codeshared CatchClause A ‘ Examples (multi-line): catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (e) { console.error(e); } |
CeylonExpressionTransformer | Source Codeshared CeylonExpressionTransformer Builds a Ceylon expression string for an AST node; compiling and evaluating the resulting string will yield a copy of the transformed node. Usage: myNode.transform(CeylonExpressionTransformer()); |
CharacterLiteral | Source Codeshared CharacterLiteral A character literal consists of a single character or an escape sequence. Note: in contrast to |
ClassAliasDefinition | Source Codeshared ClassAliasDefinition A class alias definition. A class alias definition has the following components:
(While semantically, a class alias may never have case types or extend or satisfy other types, these nodes may syntactically still be present.) Examples: shared class VariadicString(Character* characters) => String(characters); shared class MemberName(String name) => LIdentifier(name); |
ClassBody | Source Codeshared ClassBody A list of statements and declarations, surrounded by braces. Logically, a class body is divided into two sections:
There is, however, no syntactical separation between these,
so syntactically a class body looks exactly like a Examples (multi-line): { shared formal Float x; shared formal Float y; shared actual default Float distance(Point other) => ((x-other.x)^2 + (y-other.y)^2)^0.5; } { if (token != secret) { throw AssertionError("You may not instantiate this class!"); } shared void hack(Anything victim) { ████ ███████ ██ █; } } |
ClassDec | Source Codeshared ClassDec A class reference expression, that is,
the The value dec1 = `class null`; value dec2 = `value null`;
Examples: `class String` `class A.B.C` |
ClassDefinition | Source Codeshared ClassDefinition A class definition. A class definition has the following components:
Examples (multi-line): shared class PrintableWrapper<T>(shared T wrapped) satisfies Printable { shared actual void print() { package.print(wrapped else "<null>"); } } shared class Counter(Integer initialCount=0) { variable Integer n = initialCount; shared Integer count => n; shared void increment() => n++; } |
ClassInstantiation | Source Codeshared ClassInstantiation A class instantiation, used in an (This node is only used as child of The class name may optionally be qualified with Examples: Node() super.Entry<Key, Item>(key, item) |
ClassOrInterface | Source Codeshared abstract ClassOrInterface A class or interface declaration. Examples (multi-line): shared class PrintableWrapper<T>(shared T wrapped) satisfies Printable { shared actual void print() { package.print(wrapped else "<null>"); } } shared interface 3DSized<Unit> given Unit satisfies Numeric<Unit> { shared formal Unit width; shared formal Unit length; shared formal Unit height; } |
ClassSpecifier | Source Codeshared ClassSpecifier A class specifier for a class alias,
that is, a lazy specification operator ‘ Examples: => String(characters) => Entry<String,Item>(name, item) |
ClosedBound | Source Codeshared ClosedBound A closed lower or upper bound of a bounded comparison operation. In a closed bound, the |
CompareOperation | Source Codeshared CompareOperation A compare expression. No associativity. Examples: first <=> last n <=> 0 This is the concrete class for expressions like |
ComparisonOperation | Source Codeshared abstract ComparisonOperation A comparison expression. No associativity. This is the abstract superclass of expressions like |
CompilationUnit | Source Codeshared CompilationUnit A regular compilation unit, containing toplevel type, value, or function definitions. This is the most commonly used type of compilation unit, and the basic “container” for your declarations. Examples: void run() { print("Hello, World!"); } // end of example, start of next example import ceylon.collection { SetMutator } MyPlugin myPlugin = MyPlugin(); // only instance register shared void registerMyPlugin(SetMutator<Plugin> registry) => registry.put(myPlugin); |
ComplementAssignmentOperation | Source Codeshared ComplementAssignmentOperation A complement assignment operation. Right-associative. Examples: people ~= kids elements ~= otherElements |
ComplementOperation | Source Codeshared ComplementOperation A set complement expression. Defined via Examples: receivers~blocked primes ~ HashSet { 2 } |
Comprehension | Source Codeshared Comprehension A comprehension, that is,
a chain of comprehension clauses,
beginning with an Examples: for (people in peoples) for (person in people) if (person.age >= age) person if (exists typeArguments = that.typeArguments) for (typeArgument in typeArguments) typeArgument.type |
ComprehensionClause | Source Codeshared abstract ComprehensionClause A comprehension clause, one component of a Examples: for (person in people) if (person.age > 18) person.age if (isPrime(i)) i |
Condition | Source Codeshared abstract Condition A condition. There are four kinds of conditions:
Examples: exists first = string.first type in { type_ws, type_comment } is Float number nonempty members |
Conditions | Source Codeshared Conditions A comma-separated list of one or more Examples: (nonempty elems = that.elements, elems.first == expected) (is Integer num = obj.num, is Integer num2 = obj2.num, num == num2) |
Continue | Source Codeshared Continue A |
ControlStructure | Source Codeshared abstract ControlStructure A control structure statement, used to control normal execution flow. (An assertion failure is not considered as “normal” control flow;
therefore, an Examples: if (exists elem = queue.take) { process(elem); } for (i in 1:12) { print(month(i)); } |
Dec | Source Codeshared abstract Dec A reference expression, that is, a detyped reference to a program element. Reference expressions may refer to:
Not to be confused with Reference expressions are often used in annotations, e. g. |
DecQualifier | Source Codeshared DecQualifier A qualifier for a Examples: process Entry |
Declaration | Source Codeshared abstract Declaration A declaration. Most declarations either define or have a type. The general order of the children of a declaration is as follows: Annotations (Modifier | Type) Identifier TypeParameters? Parameters* CaseTypes? ExtendedType? SatisfiedTypes? TypeConstraints? (Body | AnySpecifier? ";") However, the only children common to all declarations are the Examples: shared actual String string => "``outer.string`` by ``step``"; shared class Person(shared String name) { string => name; } |
DefaultedCallableParameter | Source Codeshared DefaultedCallableParameter A callable parameter, along with a default implementation for the parameter. Examples: Float weight(Item item) => item.cost void log(String message) => process.writeErrorLine(message); |
DefaultedParameter | Source Codeshared abstract DefaultedParameter A defaulted parameter. Examples: length = text.size Comparison comparing(Element x, Element y) => x.hash <=> y.hash |
DefaultedParameterReference | Source Codeshared DefaultedParameterReference The name of a parameter declared in the body of the function or class, along with a default value for the parameter. Examples: length = text.size status = ok |
DefaultedType | Source Codeshared DefaultedType A defaulted type. Examples: String= Integer->String= |
DefaultedValueParameter | Source Codeshared DefaultedValueParameter A value parameter, along with a default value for the parameter. Examples: Integer length = text.size Boolean discounted = false |
DifferenceOperation | Source Codeshared DifferenceOperation A difference expression. Defined via Examples: size - 1 lastIndex - firstIndex |
Directive | Source Codeshared abstract Directive A control directive, terminated by a semicolon. There are four kinds of control directives:
Examples: return ret; throw AssertionError("Not implemented yet!"); // TODO implement break; continue; |
DivideAssignmentOperation | Source Codeshared DivideAssignmentOperation A divide assignment operation ( Right-associative. Examples: width /= 2 amount /= exchangeRate |
DynamicBlock | Source Codeshared DynamicBlock A Examples (multi-line): dynamic { setTimeout(\iMath.random() * 1000, () => print("A message from the past")); } dynamic { console.log("Direct console access"); console.dir(this); // I wonder what this looks like } |
DynamicInterfaceDefinition | Source Codeshared DynamicInterfaceDefinition A dynamic interface definition. A dynamic interface definition has the following components:
Examples (multi-line): shared dynamic Document { shared formal String xmlVersion; shared formal StyleSheetList styleSheets; shared formal String documentURI; // ... } shared dynamic Promise { shared formal Promise \ithen(void onFulfilled(dynamic result) => noop(), void onRejected(dynamic error) => noop()); shared formal Promise catch(void onRejected(dynamic error) => noop()); } |
DynamicModifier | Source Codeshared DynamicModifier A ‘ |
DynamicValue | Source Codeshared DynamicValue A dynamic value expression, that is, the keyword ‘ Examples: dynamic [ error = 404; message = "not found"; ] dynamic [ ] |
ElementOrSubrangeExpression | Source Codeshared ElementOrSubrangeExpression An element or subrange access expression, that is,
a target Examples: text[start...] map[key] |
ElseCaseClause | Source Codeshared ElseCaseClause An ‘ (This is not quite the same thing as an Examples (multi-line): else { throw AssertionError("Unknown type!"); } else { items.add(null); } |
ElseClause | Source Codeshared ElseClause An Examples (multi-line): else { return "<null>"; } else if (exists div) { visit(div.paragraphs); } |
ElseOperation | Source Codeshared ElseOperation An “else” operation. Left-associative. Examples: 0 <= val <= 10 then priority(val) else invalid parseInteger(input) else 0 |
EntryOperation | Source Codeshared EntryOperation |
EntryType | Source Codeshared EntryType An entry type, that is, a shortcut for Examples: String->Integer Printable&Persistent&Identifiable->Handle |
EqualOperation | Source Codeshared EqualOperation An equals expression. Defined via Examples: length == 1 first == last parseInteger(input) == 0 |
EqualityOperation | Source Codeshared abstract EqualityOperation An expression to test for identity or (in)equality of two objects. This is the abstract superclass of the nodes for |
ExistsCondition | Source Codeshared ExistsCondition An existence condition, that is,
the keyword ‘ Examples: exists name exists firstItem = first?.item |
ExistsOperation | Source Codeshared ExistsOperation A postfix existence test expression. No associativity. Examples: element exists parseInteger(text) exists |
ExistsOrNonemptyCondition | Source Codeshared abstract ExistsOrNonemptyCondition An existence or nonemptiness condition, that is,
the keyword ‘ Examples: nonempty employees exists String name = person.name |
ExponentiationOperation | Source Codeshared ExponentiationOperation An exponentiation expression. Defined via Examples: sideLength^dimension e^x |
Expression | Source Codeshared abstract Expression Abstract superclass of all expression nodes. Correct operator precedence and associativity is enforced by the parameter types of the various child classes. For example, consider the following simple expression: 1 + 2 * 3 Because multiplication has higher precedence than addition, the correct syntax tree for this expression is: SumOperation { leftOperand = IntegerLiteral("1"); rightOperand = ProductOperation { leftOperand = IntegerLiteral("2"); rightOperand = IntegerLiteral("3"); }; } A very simple, strictly left-associative parser that doesn’t respect operator precedence might instead try to produce: ProductOperation { leftFactor = SumOperation { leftSummand = IntegerLiteral("1"); rightSummand = IntegerLiteral("2"); }; rightFactor = IntegerLiteral("3"); } However, this is not well-typed (the parser would likely have an assertion failure
at runtime), because the types of To ensure this, there is one type alias for each precedence level, specified as the union type of
For example, there is ProductOperation { leftFactor = IntegerLiteral("1"); rightFactor = ProductOperation { leftFactor = IntegerLiteral("2"); rightFactor = IntegerLiteral("3"); }; } you should have ProductOperation { leftFactor = ProductOperation { leftFactor = IntegerLiteral("1"); rightFactor = IntegerLiteral("2"); }; rightFactor = IntegerLiteral("3"); } These aliases are, from highest to lowest precedence:
|
ExpressionComprehensionClause | Source Codeshared ExpressionComprehensionClause An expression that terminates a comprehension. Examples: person.age i |
ExpressionIsh | Source Codeshared abstract ExpressionIsh All node types in the expression sub-hierarchy:
|
ExpressionStatement | Source Codeshared abstract ExpressionStatement An expression statement, that is, an expression terminated by a semicolon. Only certain expressions are valid statements:
Be aware that very simple assignments are specifications;
an Examples: text.length += added.length; i++; print("Hello, World!"); |
ExtendedType | Source Codeshared ExtendedType An ‘ Examples: extends Node() extends super.Entry<Key, Item>(key, item) |
FailClause | Source Codeshared FailClause An ‘ Examples: else { print("Hello, World!"); } |
FinallyClause | Source Codeshared FinallyClause A ‘ Examples: finally { print("END"); } finally { workers.collect(Worker.kill); } |
FloatLiteral | Source Codeshared FloatLiteral A floating point literal is distinguished from an
integer literal ( |
ForClause | Source Codeshared ForClause A ‘ (Not to be confused with a complete ‘ Examples: for (person in people) { print(person.name); } for (name->person in peopleByName) { print("``name``: ``person.age``"); } |
ForComprehensionClause | Source Codeshared ForComprehensionClause A ‘ A ‘ Examples: for (person in people) "``person.firstName`` ``person.lastName``" for (people in peoples) for (person in people) if (person.age >= 18) person |
ForFail | Source Codeshared ForFail A ‘ Examples (multi-line): for (i in 1:12) { print(month(i)); } for (person in people) { if (!person.greeted) { print("Hello, ``person.name``!"); break; } } else { print("Hello, World!"); } |
ForIterator | Source Codeshared abstract ForIterator An iterator for a ‘ Examples: (person in people) (name->person in peopleByName) |
FullPackageName | Source Codeshared FullPackageName A full package name, that is, a period-separated list of lowercase identifiers. Examples: ceylon.language ceylon.ast.core |
FunctionArgument | Source Codeshared FunctionArgument An inline function argument definition. Examples (multi-line): void onClick() { DialogBox { message = "Hello!"; parent = this; }.show(); } void onError(dynamic err) => console.error(err); |
FunctionDec | Source Codeshared FunctionDec A function reference expression, that is,
the Examples: `function concatenate` `function Iterable.chain` |
FunctionDeclaration | Source Codeshared FunctionDeclaration A function declaration. A function declaration declares the
In any case, the declaration must explicitly specify a type;
a ‘ |
FunctionDefinition | Source Codeshared FunctionDefinition A function definition, using a block. Exampes (multi-line): shared void run() { print("Hello, `` process.arguments.first else "World" ``!"); } shared actual Boolean equals(Object that) { if (is Color that) { return red == that.red && green == that.green && blue == that.blue; } else { return false; } } |
FunctionExpression | Source Codeshared FunctionExpression An expression that returns a callable function. Unlike value expressions, function expressions don’t return instances of classes. Examples (multi-line): (String? name) => name else "John Doe" (String string) { value mid = string.size / 2; return [string[...mid], [string[mid+1...]]; } |
FunctionModifier | Source Codeshared FunctionModifier A ‘ The ‘ |
FunctionShortcutDefinition | Source Codeshared FunctionShortcutDefinition A function shortcut definition, using a lazy specifier and terminated by a semicolon. Examples: shared void run() => print("Hello, `` process.arguments.first else "World" ``!"); shared actual Boolean equals(Object that) => that is This; |
GivenDec | Source Codeshared GivenDec A type parameter reference expression, that is,
the name of a type parameter, prefixed by the type keyword Note that the type parameter may not be qualified (i. e., |
GroupedExpression | Source Codeshared GroupedExpression A grouped, or parenthesized expression. Examples: (1 + 2) * 3 "Hello, " + (process.arguments.first else "World") |
GroupedType | Source Codeshared GroupedType A type, grouped in angle brackets to resolve lexical ambiguity: String->String[] is parsed as Entry<String,String[]> To get Entry<String,String>[] you need to write <String->String>[] |
IdenticalOperation | Source Codeshared IdenticalOperation An identity test operation. Defined natively, on objects that satisfy Examples: node === rootNode this === zero |
Identifier | Source Codeshared abstract Identifier |
IdentityOperation | Source Codeshared IdentityOperation The expression This expression is defined to return (Not to be confused with |
IfClause | Source Codeshared IfClause An Examples: if (15 <= estimatedAge <= 25) { askForID(); } if (exists elseClause = that.elseClause) { elseClause.visit(this); } |
IfComprehensionClause | Source Codeshared IfComprehensionClause An ‘ An ‘ Examples: if (person.age >= 18) person if (exists typeArguments = that.typeArguments) for (typeArgument in typeArguments) typeArgument.type |
IfElse | Source Codeshared IfElse An if/else conditional. The conditional begins with an Examples (multi-line): if (exists p = paragraphs.first) { setupAnchor(p); paragraphs.collect(output); } else if (exists div) { visit(div.paragraphs); } else { outputEmpty(); } if (text.size >= terminalWidth) { print(text); } else if (text.size >= remainingWidth) { wrap(); print(text); remainingWidth = terminalWidth - text.size; } else { print(text); remainingWidth -= text.size; } |
Import | Source Codeshared Import An import statement, that is,
the keyword ‘ Examples: import ceylon.ast.core { ... } import java.lang { JString=String, System { sysout=\iout } } import ceylon.collection { ArrayList, MutableList } |
ImportAlias | Source Codeshared abstract ImportAlias An import alias, that is, an identifier followed by an “equals” character. (Not to be confused with an alias declaration like Examples: JString= sysout= |
ImportElement | Source Codeshared abstract ImportElement A single import element, that is,
the name of an imported program element, Examples: HashMap ln=log System { sysout=out } |
ImportElements | Source Codeshared ImportElements A comma-separated list of import elements, where the last element may optionally be a wildcard instead, surrounded by braces. Import elements may not be empty. ( Examples: MutableList, ArrayList JString=String, System { sysout=out } |
ImportFunctionValueAlias | Source Codeshared ImportFunctionValueAlias A function or value import alias, that is, a lowercase identifier followed by an “equals” character. Examples: sysout= ln= |
ImportFunctionValueElement | Source Codeshared ImportFunctionValueElement A single function or value import element, that is, the name of an imported function or value, optionally preceded by a type alias. Examples: ln=log sysout=out |
ImportTypeAlias | Source Codeshared ImportTypeAlias A type import alias, that is, an uppercase identifier followed by an “equals” character. Examples: JString= Char= |
ImportTypeElement | Source Codeshared ImportTypeElement A single type import element, that is, the name of an imported type, optionally preceded by a type alias and/or followed by nested import elements to import and rename members. Examples: HashMap System { sysout=out } |
ImportWildcard | Source Codeshared ImportWildcard An import wildcard, that is, three colons (‘ Used to indicate that all elements from a package should be imported. |
InModifier | Source Codeshared InModifier An ‘ |
InOperation | Source Codeshared InOperation A containment test expression. Defined via Examples: digit in (0..9 by 2) user in authorizedUsers input in { "yes", "no" } The containment operation is special because the receiver of the method invocation by which it is defined
is the right-hand side, not the left-hand side. In other words,
rhs.contains(lhs) while e. g. lhs.times(rhs) (the qualifier and argument swapped places). |
InitialComprehensionClause | Source Codeshared abstract InitialComprehensionClause A comprehension clause that can start a comprehension. Examples: for (person in people) “ if (exists typeArguments = that.typeArguments) for (typeArgument in typeArguments) typeArgument.type |
InlineDefinitionArgument | Source Codeshared abstract InlineDefinitionArgument A named argument that defines a getter, function, or anonymous class, and assigns it to a parameter. Examples (multi-line): void onSuccess(Result result) { print(result); logger.end(currentTask, result); } object destroyable satisfies Destroyable { shared actual void destroy(Anything error) => process.exit(1); } |
IntegerLiteral | Source Codeshared IntegerLiteral An integer literal may be expressed in decimal (no prefix), hexadecimal (prefix ‘#’) or binary (prefix ‘$’) notation. Integer literals may be grouped with underscores, and may contain a magnitude. |
InterfaceAliasDefinition | Source Codeshared InterfaceAliasDefinition An interface alias definition. An interface alias definition has the following components:
(While semantically, an interface alias may never have case types or satisfy other types, these nodes may syntactically still be present.) Examples: shared interface People => {Person*}; shared interface Compare<Value> => Comparison(Value,Value); |
InterfaceBody | Source Codeshared InterfaceBody A list of declarations, surrounded by braces. Unlike class bodies, interface bodies can’t immediately contain runnable code,
so the Examples (multi-line): { shared formal Other plus(Other other); } { shared default void writeString(String string) => print(string); shared default void write(Anything that) => writeString(that?.string else "<null>"); } |
InterfaceDec | Source Codeshared InterfaceDec An interface reference expression, that is,
the Examples: `interface Iterable` `interface A.B.C` |
InterfaceDefinition | Source Codeshared InterfaceDefinition A regular interface definition. An interface definition has the following components:
Examples (multi-line): shared interface Printable { shared default void print() => package.print(this); } shared interface Numeric<Other> of Other satisfies Invertible<Other> given Other satisfies Numeric<Other> { shared formal Other times(other); shared formal Other divided(other); } |
IntersectAssignmentOperation | Source Codeshared IntersectAssignmentOperation An intersect assignment operation. Right-associative. Examples: people &= authorizedUsers commonElements &= elements |
IntersectionOperation | Source Codeshared IntersectionOperation A set intersection expression. Defined via Examples: persistents&printables&identifiables x1&y1 |
IntersectionType | Source Codeshared IntersectionType An intersection type. Examples: Element&Identifiable Persistent&Printable&Identifiable |
Invocation | Source Codeshared Invocation An invocation, that is, an invoked expression with an argument list. Examples: print("Hello, World!") process.kill() ArrayList { initialCapacity = 100; 1, 1 } |
InvocationStatement | Source Codeshared InvocationStatement An invocation statement, that is, an invocation terminated by a semicolon. (The invocation can also be an instantiation invocation.) Examples: print("Hello, World!"); that.visitChildren(this); |
IsCase | Source Codeshared IsCase A ‘ Examples: is String is Persistent&Serializable is Integer|Float |
IsCondition | Source Codeshared IsCondition An assignability condition, that is,
the keyword ‘ Examples: is Integer|Float num is Administrator user |
IsOperation | Source Codeshared IsOperation A postfix assignability test expression. No associativity. Examples: element is String|Integer user is ExecutiveUser |
Iterable | Source Codeshared Iterable An iterable object instantiation expression. Examples: {} { second, first, *rest.rest } |
IterableType | Source Codeshared IterableType An iterable type, like |
Key | Source Codeshared Key<Type> A key by which a |
KeySubscript | Source Codeshared KeySubscript A key / index subscript expression,
to select an element from a Examples: key offset + i |
KeyValueIterator | Source Codeshared KeyValueIterator A key→value iterator for a ‘ Examples: (name->person in peopleByName) (index->char in text.indexed) |
LIdentifier | Source Codeshared LIdentifier An initial lowercase identifier. |
LargeAsOperation | Source Codeshared LargeAsOperation A “large as” expression. No associativity. |
LargerOperation | Source Codeshared LargerOperation A “larger than” expression. No associativity. |
LazySpecification | Source Codeshared LazySpecification A lazy specification statement, that is, a member name, optionally followed by one or more parameter lists, and specified by a lazy specifier. Examples: string => counter.string; visitIdentifier(Identifier that) => names.put((names[that.name] else 0) + 1); |
LazySpecifier | Source Codeshared LazySpecifier A lazy expression specifier, that is, an expression prefixed by a computation operator ‘ Examples: => text.uppercased => nothing |
Literal | Source Codeshared abstract Literal A literal is a single token that represents a Unicode character, a character string, or a numeric value. |
LocalModifier | Source Codeshared abstract LocalModifier A modifier that indicates type inference. It can only be used on local definitions (not toplevel, not shared), hence the name. |
LogicalAssignmentOperation | Source Codeshared abstract LogicalAssignmentOperation A logical assignment expression. Right-associative. |
LogicalOperation | Source Codeshared abstract LogicalOperation A logical binary operation expression. |
MainType | Source Codeshared abstract MainType “Main” types: the types that you normally use. This class is used as “Type, except EntryType” in |
MatchCase | Source Codeshared MatchCase A ‘ Examples: null 0 | 1 null | smaller | larger |
MeasureOperation | Source Codeshared MeasureOperation |
MeasureSubscript | Source Codeshared MeasureSubscript A measure subscript,
to select a (sub)range from a Examples: 0:30 match.start:match.size |
MemberDec | Source Codeshared abstract MemberDec A member reference expression. Examples: `value null` `function Iterable.map` |
MemberMeta | Source Codeshared MemberMeta A member metamodel expression, that is, a (A qualifier followed by a type name with optional type arguments surrounded by backticks
is a Examples: `Person.say` `system.milliseconds` `Iterable<String>.collect<Integer?>` |
MemberNameWithTypeArguments | Source Codeshared MemberNameWithTypeArguments A member name and, optionally, type arguments. |
MemberOperator | Source Codeshared MemberOperator A regular member operator, ‘ |
Meta | Source Codeshared abstract Meta A metamodel expression, that is, a typed reference to a type, class, function or value. Examples: `List<String>` `sum<Float>` `system.milliseconds` Not to be confused with |
Modifier | Source Codeshared abstract Modifier A modifier keyword. Note: The Ceylon Language Specification also refers to certain annotations,
e. g.
|
ModuleBody | Source Codeshared ModuleBody A module descriptor body, that is, any number of module imports surrounded by braces. (Because a module body can’t contain procedural code, this is not a subclass of Examples: {} { shared import ceylon.test "1.1.0"; } { import ceylon.collection "1.1.0"; } |
ModuleCompilationUnit | Source Codeshared ModuleCompilationUnit A module descriptor compilation unit, containing a module descriptor. Examples (separated by blank lines): module tmp "1.0.0" {} "Representation of a Ceylon AST in Ceylon." by ("Lucas Werkmeister <mail@lucaswerkmeister.de>") license ("http://www.apache.org/licenses/LICENSE-2.0.html") module ceylon.ast.core "1.1.0" { import ceylon.collection "1.1.0"; } |
ModuleDec | Source Codeshared ModuleDec A module reference expression, that is, the name of a module, prefixed by the keyword “module” and surrounded by backticks. Examples: `module ceylon.language` `module ceylon.ast.core` |
ModuleDescriptor | Source Codeshared ModuleDescriptor A module descriptor:
a list of annotations, followed by the keyword ‘ Examples (multi-line): module tmp "1.0.0" {} "Tests for the [[ceylon.ast.core module|module ceylon.ast.core]]" by ("Lucas Werkmeister <mail@lucaswerkmeister.de>") license ("http://www.apache.org/licenses/LICENSE-2.0.html") module test.ceylon.ast.core "1.1.0" { shared import ceylon.test "1.1.0"; import ceylon.ast.core "1.1.0"; } |
ModuleImport | Source Codeshared ModuleImport An import of another module within a module descriptor. Each module import consists of a list of Examples: shared import ceylon.test "1.1.0"; import ceylon.collection "1.1.0"; |
MultiplyAssignmentOperation | Source Codeshared MultiplyAssignmentOperation A multiply assignment operation ( Right-associative. Examples: balance *= 1 + interestRate |
NameWithTypeArguments | Source Codeshared abstract NameWithTypeArguments A name and, optionally, type arguments. |
NamedArgument | Source Codeshared abstract NamedArgument A named argument. Examples: name; size = width * height; Color color(Integer x, Integer y) => red; |
NamedArguments | Source Codeshared NamedArguments A named argument list. Any number of named arguments, followed by a (possibly empty) ordinary list of arguments. Examples: {} { name; size = width * height; } { Head { title = pageTitle; } Body { for (paragraph in paragraphs) P(paragraph) } } |
NegationOperation | Source Codeshared NegationOperation An arithmetic unary negation operation, that is, This operator is defined in terms of |
Node | Source Codeshared abstract Node Abstract superclass of all AST nodes. Note that nodes are not Additional informationYou can attach additional information to individual AST nodes
using the // toplevel shared Key<Token[]> tokensKey = ScopedKey<Token[]>(`module my.parser`, "tokens"); // in the parser node.put(tokensKey, tokens); // somewhere else assert (exists tokens = node.get(tokensKey)); |
NonemptyCondition | Source Codeshared NonemptyCondition A nonemptiness condition, that is,
the keyword ‘ Examples: nonempty employees nonempty persons = people.sequence() |
NonemptyOperation | Source Codeshared NonemptyOperation A nonempty postfix expression. No associativity. |
NotEqualOperation | Source Codeshared NotEqualOperation A not equals expression. Defined via Examples: uid != 0 process.arguments.length != 7 |
NotOperation | Source Codeshared NotOperation A logical not expression. Right-associative. Examples: !n in primes !predicate(element) |
ObjectArgument | Source Codeshared ObjectArgument An object argument definition. Examples (multi-line): object destroyable satisfies Destroyable { shared actual void destroy(Anything error) => process.exit(1); } object items satisfies Iterable<Integer> { variable Integer accesses = 0; shared actual Iterator<Integer> iterator() => (0..(++accesses)).iterator(); } |
ObjectDefinition | Source Codeshared ObjectDefinition An object definition. Examples (multi-line): shared object red extends Color(255, 0, 0) { string => "Red"; } object stdoutWriter satisfies Writer { shared actual void close() => flush(); shared actual void flush() {} shared actual void write(String string) { process.write(string); } shared actual void writeLine(String line) { process.writeLine(line); } shared actual void writeBytes({Byte*} bytes) { throw AssertionError("Can’t write bytes"); } } |
OfOperation | Source Codeshared OfOperation A coverage expression. Narrows or widens the type of an expression to another type that covers the expression type. Defined natively. No associativity. Examples: thing of Object? component.parent of Container? |
OpenBound | Source Codeshared OpenBound An open lower or upper bound of a bounded comparison operation. In an open bound, the For example, in the interval |
Operation | Source Codeshared abstract Operation An operator expression. Operations combine Primaries, as well as other operations, depending on precedence.
Operator precedence and associativity is represented in the AST through the child types of the nodes;
an AST that would violate associativity (for example, using a sum expression as the direct child of a
product expression – without wrapping it in a (This class is called |
OptionalType | Source Codeshared OptionalType An optional type, that is, a shortcut for Examples: String? <String->Integer>? |
OrAssignmentOperation | Source Codeshared OrAssignmentOperation A logical disjunction assignment expression. Right-associative. Examples: permitted ||= backdoorTriggered canPrint ||= networkPrinterPresent |
OrOperation | Source Codeshared OrOperation A logical disjunction expression. Left-associative. Examples: digit == 0 || digit == 1 element in errors || !element exists |
OutModifier | Source Codeshared OutModifier An ’ |
Outer | Source Codeshared Outer The value of this expression is the current instance of the type which immediately contains the immediately containing type, and its type is assignable to that type. As this class is completely stateless, you can reuse |
Package | Source Codeshared Package
As this class is completely stateless, you can reuse |
PackageCompilationUnit | Source Codeshared PackageCompilationUnit A package descriptor compilation unit, containing a package descriptor. Examples: package tmp; shared package ceylon.ast.core; |
PackageDec | Source Codeshared PackageDec A package reference expression, that is, the name of a package, prefixed by the keyword “package” and surrounded by backticks. Examples: `package ceylon.language` `package ceylon.ast.core` |
PackageDescriptor | Source Codeshared PackageDescriptor A package descriptor:
a list of annotations, followed by the keyword ‘ Examples: package tmp; "Test package" see (`package my.application`) package test.my.application; |
Parameter | Source Codeshared abstract Parameter A class, method, or function parameter. Examples: String name comparing Integer length = text.size Element+ elements |
ParameterReference | Source Codeshared ParameterReference The name of a parameter declared in the body of the function or class. This is frequently used for class parameters, where having the documentation in the parameter list would clutter the parameter list. Examples: comparing name |
Parameters | Source Codeshared Parameters A parameter list. Examples: () (String text, Integer length = text.size) (Element+ elements) A note about this class’ parametersIt would seem reasonable to instead declare the parameters of this class like this: class Parameters(RequiredParameter[] required, DefaultedParameter[] defaulted, VariadicParameter|ParameterReference variadic) Note that (param) In this parameter list, is
To decide this, you need to look into the body of the function,
and check if the declaration of Instead, we have just one list of parameters; the separation into required, defaulted, and variadic ones may then be done in later stages of AST processing. |
PositionalArguments | Source Codeshared PositionalArguments A positional argument list. A list of arguments where the mapping from an argument to its parameter
is based only on the position of the argument. Syntactically, this is
just a wrapper for an Examples: (x, y, *messages) () (for (i in 1..10) i^2) |
PostfixDecrementOperation | Source Codeshared PostfixDecrementOperation A postfix decrement expression ( |
PostfixIncrementOperation | Source Codeshared PostfixIncrementOperation A postfix increment expression ( |
PostfixOperation | Source Codeshared abstract PostfixOperation A postfix arithmetic expression, that is, |
PrefixDecrementOperation | Source Codeshared PrefixDecrementOperation A prefix decrement expression ( |
PrefixIncrementOperation | Source Codeshared PrefixIncrementOperation A prefix increment expression ( |
PrefixOperation | Source Codeshared abstract PrefixOperation A prefix arithmetic expression, that is, |
PrefixPostfixStatement | Source Codeshared PrefixPostfixStatement A prefix or postfix increment or decrement expression statement. Examples: i++; --size; |
Primary | Source Codeshared abstract Primary A primary expression. Primaries can be combined using operations. |
PrimaryType | Source Codeshared abstract PrimaryType A primary type; only intersection and union types come before these. |
ProductOperation | Source Codeshared ProductOperation A product expression. Defined via |
QualifiedExpression | Source Codeshared QualifiedExpression A receiver expression,
followed by a member operator (usually ‘ Examples: ", ".join process.arguments.first people*.name sort(people, byAscending(Person.salary)).first?.salary |
QualifiedType | Source Codeshared QualifiedType A qualified type, consisting of a qualifying type and a type name with arguments, separated by a member operator. Foo.Bar // Foo is the qualifying type, Bar the type name X<A>.Y<B>.Z<C> // X<A>.Y<B> is the qualifying type – another qualified type –, Z the type name and C the type arguments |
QuotientOperation | Source Codeshared QuotientOperation A quotient or division expression. Defined via |
RangeSubscript | Source Codeshared abstract RangeSubscript A range subscript,
to select a (sub)range from a Examples: 1 .. text.size - 2 1... |
RemainderAssignmentOperation | Source Codeshared RemainderAssignmentOperation A remainder assignment operation ( Right-associative. Examples: increment %= step |
RemainderOperation | Source Codeshared RemainderOperation A remainder expression. Defined via |
RequiredParameter | Source Codeshared abstract RequiredParameter A required parameter (neither defaulted nor variadic). Examples: String name comparing |
Resource | Source Codeshared Resource A resource in a try-with-resources statement. Examples: lock writer = file.Writer() |
Resources | Source Codeshared Resources A comma-separated list of Examples: (lock) (reader = inFile.Reader(), writer = outFile.Writer()) |
Return | Source Codeshared Return A |
SafeMemberOperator | Source Codeshared SafeMemberOperator A nullsafe member operator, ‘ Technically, the nullsafe attribute operator and the nullsafe method operator are two different operators, since a nullsafe invocation is not the same as an invocation of a nullsafely accessed method attribute; however, that distinction is only semantical, not syntactical, and therefore does not belong in the AST. |
SatisfiedTypes | Source Codeshared SatisfiedTypes A nonempty list of satisfied types, separated by the intersection operator (‘ Examples: satisfies {Element+} satisfies Printable & Persistent |
ScaleOperation | Source Codeshared ScaleOperation A scale expression. Defined via Examples: 2 ** vector brakeFactor ** velocity The scale operation is special because the receiver of the method invocation by which it is defined
is the right-hand side, not the left-hand side. In other words,
rhs.scale(lhs) while e. g. lhs.times(rhs) (the qualifier and argument swapped places). |
ScopedKey | Source Codeshared ScopedKey<Type> A |
SelfReference | Source Codeshared abstract SelfReference
While these expressions are interesting from a typing perspective,
their AST nodes are actually really boring and completely stateless.
In order to save some memory, you can reuse |
SequentialType | Source Codeshared SequentialType A sequential type, that is, a shortcut for Examples: String[] <String->Integer>[] |
SetAssignmentOperation | Source Codeshared abstract SetAssignmentOperation A set assignment operation. Right-associative. |
SetOperation | Source Codeshared abstract SetOperation A set operation: intersection, union or complement. |
SimpleType | Source Codeshared abstract SimpleType A simple type: One or more TypeNamesWithArguments, separated by member operators. String Iterable<String,Nothing> Outer.Inner The type of every instance can be written as a |
SmallAsOperation | Source Codeshared SmallAsOperation A “small as” expression. No associativity. |
SmallerOperation | Source Codeshared SmallerOperation A “smaller than” expression. No associativity. |
SpanFromSubscript | Source Codeshared SpanFromSubscript A span-from subscript,
to select a (sub)range from a Examples: 1... match.start ... |
SpanOperation | Source Codeshared SpanOperation A spanned range expression. Defined via Examples: 0..9 monday..friday first.successor..last.predecessor |
SpanSubscript | Source Codeshared SpanSubscript |
SpanToSubscript | Source Codeshared SpanToSubscript A span-to subscript,
to select a (sub)range from a Examples: ... text.size - 1 ...count |
Specification | Source Codeshared abstract Specification A specification statement. Examples: offset = preamble.size + title.size; debug(Anything a) => process.writeErrorLine(a); |
SpecifiedArgument | Source Codeshared SpecifiedArgument A specified named argument, that is, a Examples: groupSeparators = false; initialCapacity = 256; |
SpecifiedVariable | Source Codeshared SpecifiedVariable A specified inline variable declaration. Examples: num = parseFloat(numString) String name = person.name |
Specifier | Source Codeshared Specifier An expression specifier, that is, an expression prefixed by a specification operator ‘ Examples: = 1 = nothing |
SpreadArgument | Source Codeshared SpreadArgument A spread argument. Used in argument lists to “spread” a sequential value over multiple arguments. (The spread “operator” Examples: *args *values.collect(Object.string) *[] |
SpreadMemberOperator | Source Codeshared SpreadMemberOperator A spread member operator, ‘ Technically, the spread attribute operator and the spread method operator are two different operators, since a spread invocation is not the same as an invocation of a spread accessed method attribute; however, that distinction is only semantical, not syntactical, and therefore does not belong in the AST. |
Statement | Source Codeshared abstract Statement A statement. Examples: value name = person.name else "<unnamed>"; print("Hello, World!"); |
StringLiteral | Source Codeshared StringLiteral A string literal consists of a series of characters and/or, if it’s not verbatim, escape sequences. Note: in contrast to |
StringTemplate | Source Codeshared StringTemplate A string template, that is, a string start, followed by any number of value expression and string mid pairs, followed by a value expression and a string end. (The distinction between string starts, mids, and ends is a purely lexical one,
and not covered in There must be at least one expression in a string template, and the number of string literals must be exactly the number of expressions plus one. Examples: "Elapsed: `` tEnd - tStart ``ms" "Hello, ``person.firstName`` ``person.lastName``. How nice to see you back in ``person.homeTown``." |
Subscript | Source Codeshared abstract Subscript A subscript used to access an element or subrange
in a In mathematical notations, these accessors are usually written as subscript, e. g. xi for the ith x element. Examples: index ... text.size - 2 |
SubtractAssignmentOperation | Source Codeshared SubtractAssignmentOperation A subtract assignment operation ( Right-associative. Examples: countdown -= \iΔt |
SumOperation | Source Codeshared SumOperation |
Super | Source Codeshared Super The value of this expression is the current instance, and its type is the intersection of the immediate superclass and all immediate superinterfaces of the current class. As this class is completely stateless, you can reuse |
SwitchCaseElse | Source Codeshared SwitchCaseElse A Examples (multi-line): switch (i.magnitude) case (0, 1) { return false; } case (2) { return true; } else { return i % 2 == 1 && expensivePrimeTest(i); } switch (that) case (is Block) { return transformBlock(that); } case (is IfElse) { return transformIfElse(that); } |
SwitchCases | Source Codeshared SwitchCases A list of ‘ Examples (multi-line): case (is Block) { return transformBlock(that); } case (is IfElse) { return transformIfElse(that); } case (0, 1) { return false; } case (2) { return true; } else { return i % 2 == 1 && expensivePrimeTest(i); } |
SwitchClause | Source Codeshared SwitchClause A ‘ Examples: switch (i.magnitude) switch (child) |
ThenOperation | Source Codeshared ThenOperation A “then” operation. Left-associative. Examples: !name.empty then name age != -1 then age |
This | Source Codeshared This The value of this expression is the current instance, and its type is the immediately containing type. As this class is completely stateless, you can reuse |
Throw | Source Codeshared Throw A |
TryCatchFinally | Source Codeshared TryCatchFinally A try-cA try/catch/finally statement, that is,
a ‘ Examples (multi-line): // removing a non-critical entity, e. g. when running low on resources try (writer = file.Writer()) { that.serialize(writer); } finally { despawn(that); } // a compilation controller try (lock) { compilationUnit.compile(this); } catch (CancellationException e) { // ignore } catch (otherException) { log(otherException); compilationUnit.compiled = false; } |
TryClause | Source Codeshared TryClause A ‘ Examples (multi-line): try { value zombie = spawn { Zombie; center = player.location; spread = 50; }; zombie.aggro = player; } try (writer = file.Writer()) { that.serialize(writer); } |
Tuple | Source Codeshared Tuple A tuple instantiation expression. Examples: [] [x, y] [father, mother, *children] |
TupleType | Source Codeshared TupleType A tuple type. Examples: [String,Integer,Integer] [Float,Integer*] [] |
Type | Source Codeshared abstract Type Representation of a type. |
TypeAliasDefinition | Source Codeshared TypeAliasDefinition A type alias definition. A type alias definition has the following components:
Examples: alias Primitive => Boolean|Integer|Float|Character|String|Null; alias AnyMutableSet<Element> given Element satisfies Object => Set<Element>&SetMutator<Element>; |
TypeArgument | Source Codeshared TypeArgument A type argument, that is, a (Use-site variance is only rarely used; most of the time, Examples: String out T |
TypeArguments | Source Codeshared TypeArguments A nonempty comma-separated list of type arguments, enclosed in angle brackets. Examples: <String,Nothing> <out Element> |
TypeConstraint | Source Codeshared TypeConstraint A constraint upon a type parameter. Examples: given Key satisfies Object given Printable of String | Integer | Float given T of T1|T2|T3 satisfies U |
TypeDec | Source Codeshared abstract TypeDec A type reference expression. |
TypeDeclaration | Source Codeshared abstract TypeDeclaration A type declaration. Examples (multi-line): shared interface Printable { shared default void print() { package.print(this); } } shared alias TypeName => UIdentifier; |
TypeIsh | Source Codeshared abstract TypeIsh All node types in the type sub-hierarchy:
(For example, while |
TypeList | Source Codeshared TypeList A list of types, with an optional trailing variadic type. Examples: String, String, String+ |
TypeMeta | Source Codeshared TypeMeta A type metamodel expression, that is, a Examples: `List<String>` `Integer|Float` |
TypeModifier | Source Codeshared abstract TypeModifier A modifier that can be used instead of a type in some places. This includes:
|
TypeNameWithTypeArguments | Source Codeshared TypeNameWithTypeArguments A type name and, optionally, type arguments. |
TypeParameter | Source Codeshared TypeParameter A type parameter of a class, method or function. The type parameter may optionally declare a type Examples: out Element out Absent=Null |
TypeParameters | Source Codeshared TypeParameters A nonempty comma-separated list of type parameters, surrounded by angle brackets. Examples: <in Key, out Item> <out Element> |
TypeSpecifier | Source Codeshared TypeSpecifier A type specifier, that is, a type prefixed by a computation operator ‘ Examples: => Map<String,Person> => Comparison(Value,Value) |
TypedDeclaration | Source Codeshared abstract TypedDeclaration A declaration with a type. The type can either be explicitly specified ( Examples: shared String name; shared actual void visit(Node that) { print(that); that.visitChildren(this); } |
TypedVariable | Source Codeshared TypedVariable A typed inline variable declaration. Examples: Integer|Float num String name |
UIdentifier | Source Codeshared UIdentifier An initial uppercase identifier. |
UnaryArithmeticOperation | Source Codeshared abstract UnaryArithmeticOperation A unary arithmetic expression, that is, |
UnaryIshOperation | Source Codeshared abstract UnaryIshOperation An expression consisting of a These can be regular unary operations – either prefix or postfix – or unary type operations, which are always postfix, and include a type. |
UnaryOperation | Source Codeshared abstract UnaryOperation A unary operator expression. |
UnaryTypeOperation | Source Codeshared abstract UnaryTypeOperation A unary type operation. A subclass of |
UnionAssignmentOperation | Source Codeshared UnionAssignmentOperation A union assignment operation. Right-associative. Examples: students |= course.students allElements |= elements |
UnionOperation | Source Codeshared UnionOperation A set union expression. Defined via Examples: ints|floats x1&y1|x2&y2 |
UnionType | Source Codeshared UnionType A union type. Examples: String|Integer|Float |
UnionableType | Source Codeshared abstract UnionableType Types that can be children of a This class is only there to represent how types are parsed, not their semantics. |
UnspecifiedVariable | Source Codeshared UnspecifiedVariable An unspecified inline variable declaration. The value of the variable is assigned by the surrounding construct, e. g. the current iteration result, or the caught exception. Examples: element AssertionError ae |
ValueArgument | Source Codeshared ValueArgument An inline getter argument definition. Examples (multi-line): String val { StringBuilder sb = StringBuilder(); for (person in people) { sb.append("``person.firstName`` ``person.lastName``"); if (exists age = person.age) { sb.append(", ``age`` year`` age != 1 then "s" else "" ``"); } sb.appendNewline(); } return sb.string; } value elements = people.collect(Person.age); |
ValueDec | Source Codeshared ValueDec A value reference expression, that is,
the Examples: `value null` `value Iterable.first` |
ValueDeclaration | Source Codeshared ValueDeclaration A value declaration. A value declaration declares the
In any case, the declaration must explicitly specify a type;
a |
ValueDefinition | Source Codeshared ValueDefinition A value definition, using a specifier. Examples: shared actual String string => "``name`` from ``countryOfOrigin`` of age ``age``"; shared actual Null definition = null; |
ValueExpression | Source Codeshared abstract ValueExpression An expression that returns an ordinary value. Value expressions return instances of classes, while function expressions return first-class functions. |
ValueGetterDefinition | Source Codeshared ValueGetterDefinition A value definition, using a getter block. Examples: shared actual String string { value s = element.string; return ", ".join(Singleton(element).cycled.take(size)); } |
ValueIterator | Source Codeshared ValueIterator A value iterator for a ‘ Examples: (person in people) (char in text) |
ValueModifier | Source Codeshared ValueModifier A ‘ The ‘ |
ValueParameter | Source Codeshared ValueParameter A value parameter. Examples: String name Integer length Boolean(Element) selecting shared Address privateAddress |
ValueSetterDefinition | Source Codeshared ValueSetterDefinition A setter definition, that is,
the keyword ‘ Examples: assign diameter => radius = diameter / 2; assign diameter { throw AssertionError("Can’t set the diameter of the unit circle"); } |
ValueSpecification | Source Codeshared ValueSpecification A value specification statement, that is, a member name followed by a Examples: size = 0; it = iterators.next(); |
Variable | Source Codeshared abstract Variable An inline variable declaration. Assertions and some control structures allow inline declarations of variables. Examples: firstEmployee = employees.first Integer|Float num |
VariadicParameter | Source Codeshared VariadicParameter A variadic parameter. Examples: Element+ elements String* messages "The indexes" Integer+ indexes |
VariadicType | Source Codeshared VariadicType A variadic type is a |
Variance | Source Codeshared abstract Variance A modifier that indicates type parameter / argument variance. Examples: in out |
VoidModifier | Source Codeshared VoidModifier A ‘ |
While | Source Codeshared While A Examples: while (i++ <= count) { lines.add(process.readLine()); } while (!((elem = it.next()) is Finished)) { expressions.add(elem); literals.add(it.next()); } |
WithinOperation | Source Codeshared WithinOperation A bounded comparison operation, also known as “within” operation. Examples: 0 <= x < 10 1 <= x <= 31 |