Source Code

This module defines types for a Ceylon Abstract Syntax Tree (AST), a hierarchical and immutable data structure that represents a Ceylon program.

Obtaining an AST

There are two major ways to obtain an AST:

Create it yourself

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")))

Compile it

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.

Operating on an AST

Analyze it

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.

Attaching additional information

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).

Edit it

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 ifs 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.

Consuming an AST

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.

Meaning of an AST

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.

By: Lucas Werkmeister
License: http://www.apache.org/licenses/LICENSE-2.0.html
Packages
ceylon.ast.core
Dependencies
ceylon.collection1.1.0
Aliases
AddingExpressionSource Codeshared AddingExpression=> ScalingExpression|SumOperation|DifferenceOperation

An expression on or above the precedence level of addition and subtraction.

AssigningExpressionSource 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.

ComparingExpressionSource Codeshared ComparingExpression=> ExistsNonemptyExpression|IsOperation|OfOperation|InOperation|ComparisonOperation|CompareOperation|WithinOperation

An expression on or above the precedence level of comparison, containment, assignability and inheritance tests.

ConjoiningExpressionSource Codeshared ConjoiningExpression=> NegatingExpression|AndOperation

An expression on or above the precedence level of logical conjunction.

DisjoiningExpressionSource Codeshared DisjoiningExpression=> ConjoiningExpression|OrOperation

An expression on or above the precedence level of logical disjunction.

This contains all “Layer 3” operators.

EquatingExpressionSource Codeshared EquatingExpression=> ComparingExpression|EqualityOperation

An expression on or above the precedence level of equality tests.

This contains all “Layer 2” operators.

ExistsNonemptyExpressionSource Codeshared ExistsNonemptyExpression=> SpanningExpression|ExistsOperation|NonemptyOperation

An expression on or above the precedence level of existence and nonemptiness tests.

ExponentiatingExpressionSource Codeshared ExponentiatingExpression=> PrePostfixingExpression|ExponentiationOperation

An expression on or above the precedence level of exponentiation.

IntersectingExpressionSource Codeshared IntersectingExpression=> InvertingExpression|IntersectionOperation

An expression on or above the precedence level of intersection.

InvertingExpressionSource 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 (NegatingExpression).

MemberNameSource Codeshared MemberName=> LIdentifier
MetaQualifierSource Codeshared MetaQualifier=> SimpleType|GroupedType|MemberName

A node that can appear as the qualifier of a MemberMeta.

MultiplyingExpressionSource Codeshared MultiplyingExpression=> UnioningExpression|ProductOperation|QuotientOperation|RemainderOperation

An expression on or above the precedence level of multiplication or division.

NegatingExpressionSource 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 (InvertingExpression).

PackageNameSource Codeshared PackageName=> LIdentifier
PrePostfixingExpressionSource 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.)

ScalingExpressionSource Codeshared ScalingExpression=> MultiplyingExpression|ScaleOperation

An expression on or above the precedence level of scaling.

SpanningExpressionSource 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.

ThenElseExpressionSource Codeshared ThenElseExpression=> DisjoiningExpression|ThenOperation|ElseOperation

An expression on or above the precedence level of “then” and “else” expressions.

TypeNameSource Codeshared TypeName=> UIdentifier
UnioningExpressionSource Codeshared UnioningExpression=> IntersectingExpression|UnionOperation|ComplementOperation

An expression on or above the precedence level of union or complementation.

Values
outerInstanceSource Codeshared Outer outerInstance
packageInstanceSource Codeshared Package packageInstance
superInstanceSource Codeshared Super superInstance
thisInstanceSource Codeshared This thisInstance
Functions
annotationSource Codeshared Annotation annotation(String name)

Shortcut helper function for an Annotation with the specified name and no arguments.

lidentifierNeedsPrefixSource Codeshared Boolean lidentifierNeedsPrefix(String name)
Parameters:
  • name
    • Name must not be empty

uidentifierNeedsPrefixSource Codeshared Boolean uidentifierNeedsPrefix(String name)
Parameters:
  • name
    • Name must not be empty

Interfaces
CascadingNarrowingTransformerSource Codeshared CascadingNarrowingTransformer<out Result>

A NarrowingTransformer that narrows cascadingly to the “less abstract” type of the visited subject by switching on the case types and invoking the proper transformX method.

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 ImmediateNarrowingTransformer; perhaps the strongest argument for its existence is that it was trivial to generate along with other generated code while ceylon.ast was originally written, but would be significantly more painful to create (by hand or automatically) afterwards.

EditorSource 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 NarrowingTransformer, see there.) By itself, an Editor will not actually edit the AST – it’s only scaffolding that allows you to easily edit parts of the AST without having to bother with the deep nesting of the nodes.

For example:

class PrefixEditor(String prefix) extends Editor() {
    shared actual Identifier editIdentifier(Identifier that)
            => that.copy { name = prefix + that.name; };
}

will prepend prefix to every Identifier in the AST.

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 return this instead of a deep copy (in this example, override Editor.transformBody()).

ImmediateNarrowingTransformerSource Codeshared ImmediateNarrowingTransformer<out Result>

A NarrowingTransformer that narrows immediately to the type of the visited subject by invoking its transform (Node.transform) method.

For example:

shared actual default Result transformValueExpression(ValueExpression that)
        => that.transform(this);

This interface should be functionally equivalent to CascadingNarrowingTransformer, but is likely a lot faster because it uses only a single virtual method lookup instead of a series of type checks and calls.

NarrowingTransformerSource Codeshared NarrowingTransformer<out Result>

A Transformer with the default operation to narrow the type of the visited subject; all methods for abstract node types have a default implementation while those for concrete node types remain formal.

There are two ways to perform this narrowing:

  • immediately, by invoking the transform (Node.transform) method on the subject, or
  • cascadingly, where each method switches on the enumerated subtypes of the node type and narrows only by one layer by invoking the corresponding transformX method on the transformer.

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.

TransformerSource Codeshared Transformer<out Result>

Abstract interface to perform some operations on AST nodes and possibly get some result.

For every subtype of Node, there is one transform method, each returning Result. These are all formal, as there are two sensible default behaviors:

Be careful when mixing the two behaviors, lest you end up in an infinite recursion!

VisitorSource 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 Visitor.visitIdentifier(), you will receive calls to both Node.visit() and Node.visit(), as the default operation for Visitor.visitLIdentifier() and Visitor.visitUIdentifier() is to delegate to Visitor.visitIdentifier(). Visitor.visitNode() is different: As the root of the AST class hierarchy, it has no superclass; instead, it visits all the children of the node. Thus, the default visitor will already traverse the AST fully, and if you need to perform some operation only for some node type that might appear anywhere in the AST, you can simply override that particular method and leave the rest as it is.

WideningTransformerSource Codeshared WideningTransformer<out Result>

A Transformer with the default operation to widen the type of the visited subject: WideningTransformer.transformLIdentifier() delegates to WideningTransformer.transformIdentifier(), which in turn delegates to Transformer.transformNode(), which (Node being without a superclass) is the only formal method left.

Classes
AddAssignmentOperationSource Codeshared AddAssignmentOperation

An add assignment operation (+=).

Right-associative.

Examples:

index += step
document.cursor.position += insertion.size
AliasDecSource Codeshared AliasDec

An alias reference expression, that is, the AliasDec.name of an alias, optionally qualified by a AliasDec.qualifier (separated from it by a member operator ‘.’), prefixed by the type keyword alias and surrounded by backticks.

Examples:

`alias TypeName`
`alias A.B.C
AndAssignmentOperationSource Codeshared AndAssignmentOperation

A logical conjunction assignment expression.

Right-associative.

Examples:

valid &&= parsed exists
legal &&= !globalLock
AndOperationSource Codeshared AndOperation

A logical conjunction expression.

Left-associative.

Examples:

i%2 == 0 && j%2 == 1
attr1 == that.attr1 && attr2 == that.attr2 && attr3 == that.attr3
AnnotationSource Codeshared Annotation

An annotation.

For the common case “no arguments”, the toplevel helper function annotation() may be used.

Examples:

shared
formal
by ("John Doe <john.doe@company.com>")
see (`function print`)
action { description = "Log in"; url = "/login"; }
AnnotationsSource 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 doc() annotation.

Annotations are not separated by any punctuation.

Examples:

shared formal
"The number of elements in this list" see (`value List.lastIndex`) shared actual
AnonymousArgumentSource Codeshared AnonymousArgument

An anonymous named argument, that is, an expression followed by a semicolon.

Examples:

name;
width * height;
AnyClassSource 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);
AnyCompilationUnitSource 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 CompilationUnit and this abstract class is called AnyCompilationUnit, rather than calling this CompilationUnit and using RegularCompilationUnit or CodeCompilationUnit for regular compilation units.)

Every compilation unit starts with a (possibly empty) list of AnyCompilationUnit.imports.

Examples (separated by blank lines):

module tmp "1.0.0" {}

package tmp;

void run() {
    print("Hello, World!");
}
AnyFunctionSource Codeshared abstract AnyFunction

A function declaration or definition.

If the AnyFunction.definition is missing or a specifier, then the statement must be terminated by a semicolon; if it’s a Block, the semicolon is not necessary.

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" ``!");
AnyInterfaceSource 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*};
AnyInterfaceDefinitionSource 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;
    // ...
}
AnyMemberOperatorSource Codeshared abstract AnyMemberOperator

A member operator, used in a QualifiedExpression.

AnySpecifierSource Codeshared abstract AnySpecifier

An eager or lazy expression specifier.

Examples:

= 1
=> text.uppercased
AnyValueSource Codeshared abstract AnyValue

A value declaration or definition.

If the TypedDeclaration.definition is missing or a specifier, then the statement must be terminated by a semicolon; if it’s a Block, the semicolon is not necesary.

Examples:

shared String name;
shared formal Comparison compare(Other that);
shared default Boolean empty => iterator().next() is Finished;
ArgumentListSource 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
ArgumentsSource Codeshared abstract Arguments

An argument list that can be used in an Invocation.

Not to be confused with ArgumentList. An ArgumentList is just a comma-separated list of arguments with an optional trailing sequential argument. Arguments either simply wrap an ArgumentList in parentheses (PositionalArguments), or can also add named arguments (NamedArguments).

Examples:

(x, y, *messages)
()
(for (i in 1..10) i^2)
{ factor = 2.1; *actors }
ArithmeticAssignmentOperationSource Codeshared abstract ArithmeticAssignmentOperation

An arithmetic assignment operation, a shortcut for an ArithmeticOperation combined with an AssignmentOperation.

Right-associative.

ArithmeticOperationSource Codeshared abstract ArithmeticOperation

An arithmetic operation expression.

AssertionSource Codeshared Assertion

An assertion statement, that is, an annotation list, followed by the keyword ‘assert’, a condition list, and terminated by a semicolon.

Examples:

assert (exists num = parseFloat(numText));
"Weight cannot be negative" assert (weight >= 0);
AssignOperationSource Codeshared AssignOperation

An assignment expression.

Right-associative.

Examples:

i = 1
text = "Hello, ``name else "World"``!"
AssignmentOperationSource Codeshared abstract AssignmentOperation

An assignment expression.

Right-associative.

This is the abstract superclass of all assignment operations, with operators like =, +=, &=, etc. Not to be confused with AssignOperation, the concrete class for = expressions!

AssignmentStatementSource Codeshared AssignmentStatement

An assignment expression statement, that is, an assignment terminated by a semicolon.

In principle, a statement like i = 0; could be parsed ambigously, either as an assignment statement or as a specification. When possible, the Ceylon language favors the latter interpretation, which means that an assignment statement where the target is a BaseExpression is invalid. (This is only true for simple AssignOperations; other assignment operations, e. g. i += size;, are still valid assignment expression statements.)

Examples:

text.length += added.length;
ret.endToken = tokens.token(";", semicolon);
AtomSource 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 [1, 2, 3], the child expressions are wrapped in the surrounding brackets; in 1.add, however, the child expressions are not wrapped. Therefore, a Tuple is an atom, while a QualifiedExpression isn’t.

BaseExpressionSource Codeshared BaseExpression

An unqualified identifier with an optional list of type arguments.

A base expression can refer to either:

  • a toplevel function, value, or class,
  • a function, value, or class in the current scope, or
  • a function, value, or class in the current block.

Examples:

null
max<Integer,Nothing>
BaseMetaSource 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 TypeMeta.)

Examples:

`sum<Float>`
`system`
BaseTypeSource Codeshared BaseType

A type name with optional type arguments.

BinaryOperationSource Codeshared abstract BinaryOperation

A binary operator expression.

Binary operations can be left-associative (a X b X c means (a X b) X c) or right-associative (a X b X c means a X (b X c)). To represent this in the type system, the left and right children of concrete classes usually have different types: One has the type of the current precedence level (see the PrecedenceXOperation aliases), one has the type of the precedence level below.

(Some binary operations have no precedence because they can’t be nested (for example, a == b == c is never allowed); in this case, both children have the type of the precedence level below.)

BlockSource 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 "";
    }
}
BodySource Codeshared abstract Body

A list of statements and declarations, surrounded by braces.

Examples:

{}
{ shared String name; string => name; }
BooleanConditionSource Codeshared BooleanCondition

A boolean condition, that is, an expression.

The condition is satisfied when the expression evaluates to true.

Examples:

type in { type_ws, type_comment }
literals.size == expressions.size + 1
BoundSource Codeshared abstract Bound

A lower or upper bound of a bounded comparison operation.

BreakSource Codeshared Break

A break directive.

CallableParameterSource Codeshared CallableParameter

A callable parameter.

Examples:

Comparison comparing(Element left, Element right)
void onSuccess()
CallableTypeSource Codeshared CallableType

A callable type, that is, a shortcut for SimpleType(TypeNameWithTypeArguments(UIdentifier("Callable"), [returnType, TupleType(argumentTypes)])).

Examples:

Integer(Integer,Integer)
String(Character*)
CaseClauseSource Codeshared CaseClause

A ‘case’ clause of a switch’ statement (SwitchCaseElse), that is, the keyword ‘case’, followed by a case item enclosed in parentheses and a CaseClause.block.

Examples (multi-line):

case (is String) {
    int = parseInteger(val);
}

case (null) { return; }
CaseItemSource Codeshared abstract CaseItem

A ‘case’ item from a case’ clause (CaseClause).

Examples:

is String
0, 1
CaseTypesSource Codeshared CaseTypes

A nonempty list of case types, separated by the union operator (‘|’).

Examples:

of String | Float | Integer
of Other
of empty | [Element+]
CatchClauseSource Codeshared CatchClause

A ‘catch’ clause, that is, the keyword ‘catch’, followed by a CatchClause.variable (enclosed in parentheses) and a CatchClause.block.

Examples (multi-line):

catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

catch (e) {
    console.error(e);
}
CeylonExpressionTransformerSource 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());
CharacterLiteralSource Codeshared CharacterLiteral

A character literal consists of a single character or an escape sequence.

Note: in contrast to IntegerLiteral and FloatLiteral, the value of CharacterLiteral.text isn’t verified, and there is no attribute to get the Character value of the literal; getting that value requires unicode support (to parse \{CHARACTER NAME}) that isn’t available on all platforms.

ClassAliasDefinitionSource 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);
ClassBodySource Codeshared ClassBody

A list of statements and declarations, surrounded by braces.

Logically, a class body is divided into two sections:

  • An initializer section, mixing statements and declarations, and
  • a declaration section, containing only statements.

There is, however, no syntactical separation between these, so syntactically a class body looks exactly like a Block.

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) {
        ████ ███████ ██ █;
    }
}
ClassDecSource Codeshared ClassDec

A class reference expression, that is, the ClassDec.name of a class or anonymous class, optionally qualified by a ClassDec.qualifier (separated from it by a member operator ‘.’), prefixed by the type keyword class and surrounded by backticks.

The ClassDec.name may be an LIdentifier to refer to the class declaration of an anonymous class. For example, in

value dec1 = `class null`;
value dec2 = `value null`;

dec1 refers to the anonymous class of the null object, while dec2 refers to the only instance of that class, the null object itself.

Examples:

`class String`
`class A.B.C`
ClassDefinitionSource 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++;
}
ClassInstantiationSource Codeshared ClassInstantiation

A class instantiation, used in an extends clause and in a class alias.

(This node is only used as child of ExtendedType and ClassSpecifier; for normal instantiations of a class, use a regular Invocation with a BaseExpression for the class name.)

The class name may optionally be qualified with super..

Examples:

Node()
super.Entry<Key, Item>(key, item)
ClassOrInterfaceSource 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;
}
ClassSpecifierSource Codeshared ClassSpecifier

A class specifier for a class alias, that is, a lazy specification operator ‘=>’ followed by a class instantiation.

Examples:

=> String(characters)
=> Entry<String,Item>(name, item)
ClosedBoundSource Codeshared ClosedBound

A closed lower or upper bound of a bounded comparison operation.

In a closed bound, the ClosedBound.endpoint is a part of the designated interval; therefore, the minimum / maximum value of the interval is the endpoint.

CompareOperationSource Codeshared CompareOperation

A compare expression.

No associativity.

Examples:

first <=> last
n <=> 0

This is the concrete class for expressions like first <=> last; not to be confused with ComparisonOperation, the abstract superclass of expressions like a <= b and x > 3!

ComparisonOperationSource Codeshared abstract ComparisonOperation

A comparison expression.

No associativity.

This is the abstract superclass of expressions like a <= b and x > 3; not to be confused with CompareOperation, the concrete class representing expressions like first <=> second!

CompilationUnitSource 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);
ComplementAssignmentOperationSource Codeshared ComplementAssignmentOperation

A complement assignment operation.

Right-associative.

Examples:

people ~= kids
elements ~= otherElements
ComplementOperationSource Codeshared ComplementOperation

A set complement expression.

Defined via Set.complement(). Left-associative.

Examples:

receivers~blocked
primes ~ HashSet { 2 }
ComprehensionSource Codeshared Comprehension

A comprehension, that is, a chain of comprehension clauses, beginning with an InitialComprehensionClause and terminated by an ExpressionComprehensionClause.

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
ComprehensionClauseSource Codeshared abstract ComprehensionClause

A comprehension clause, one component of a Comprehension.

Examples:

for (person in people) if (person.age > 18) person.age
if (isPrime(i)) i
ConditionSource 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
ConditionsSource Codeshared Conditions

A comma-separated list of one or more Conditions.conditions, enclosed in parentheses.

Examples:

(nonempty elems = that.elements, elems.first == expected)
(is Integer num = obj.num, is Integer num2 = obj2.num, num == num2)
ContinueSource Codeshared Continue

A continue directive.

ControlStructureSource 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 Assertion is not a control structure.)

Examples:

if (exists elem = queue.take) { process(elem); }
for (i in 1:12) { print(month(i)); }
DecSource 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 Meta, which represents a typed reference. Simply speaking, if there’s a keyword (`class String`, `value system`), then it’s a Dec, otherwise it’s a Meta.

Reference expressions are often used in annotations, e. g. see().

DecQualifierSource Codeshared DecQualifier

A qualifier for a Dec, that is, either a period-separated sequence of one or more type names, or exactly one member name.

Examples:

process
Entry
DeclarationSource 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 Declaration.name of the declared program element and its Declaration.annotations.

Examples:

shared actual String string => "``outer.string`` by ``step``";
shared class Person(shared String name) { string => name; }
DefaultedCallableParameterSource 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);
DefaultedParameterSource Codeshared abstract DefaultedParameter

A defaulted parameter.

Examples:

length = text.size
Comparison comparing(Element x, Element y) => x.hash <=> y.hash
DefaultedParameterReferenceSource 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
DefaultedTypeSource Codeshared DefaultedType

A defaulted type.

Examples:

String=
Integer->String=
DefaultedValueParameterSource Codeshared DefaultedValueParameter

A value parameter, along with a default value for the parameter.

Examples:

Integer length = text.size
Boolean discounted = false
DifferenceOperationSource Codeshared DifferenceOperation

A difference expression.

Defined via Invertible.minus(). Left-associative.

Examples:

size - 1
lastIndex - firstIndex
DirectiveSource Codeshared abstract Directive

A control directive, terminated by a semicolon.

There are four kinds of control directives:

  • the return (Return) directive, to return a value or terminate execution,
  • the throw (Throw) directive, to raise an exception,
  • the break (Break) directive, to terminate a loop, and
  • the continue (Continue) directive, to jump to the next iteration of a loop.

Examples:

return ret;
throw AssertionError("Not implemented yet!"); // TODO implement
break;
continue;
DivideAssignmentOperationSource Codeshared DivideAssignmentOperation

A divide assignment operation (/=).

Right-associative.

Examples:

width /= 2
amount /= exchangeRate
DynamicBlockSource Codeshared DynamicBlock

A dynamic block, that is, a DynamicBlock.block prefixed by the keyword ‘dynamic’.

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
}
DynamicInterfaceDefinitionSource 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());
}
DynamicModifierSource Codeshared DynamicModifier

A ‘dynamic’ modifier keyword.

DynamicValueSource Codeshared DynamicValue

A dynamic value expression, that is, the keyword ‘dynamic’ followed by any number of named arguments and a (possibly empty) argument list, enclosed in brackets.

Examples:

dynamic [ error = 404; message = "not found"; ]
dynamic [ ]
ElementOrSubrangeExpressionSource Codeshared ElementOrSubrangeExpression

An element or subrange access expression, that is, a target ElementOrSubrangeExpression.primary followed by a ElementOrSubrangeExpression.subscript surrounded with brackets.

Examples:

text[start...]
map[key]
ElseCaseClauseSource Codeshared ElseCaseClause

An ‘else’ clause of a switch’ statement (SwitchCaseElse).

(This is not quite the same thing as an ElseClause, since in an ElseCaseClauseelse if’ is not allowed.)

Examples (multi-line):

else {
    throw AssertionError("Unknown type!");
}

else {
    items.add(null);
}
ElseClauseSource Codeshared ElseClause

An else clause, that is, the keyword ‘else’, followed by a block or another if/else conditional.

Examples (multi-line):

else {
    return "<null>";
}

else if (exists div) {
    visit(div.paragraphs);
}
ElseOperationSource Codeshared ElseOperation

An “else” operation.

Left-associative.

Examples:

0 <= val <= 10 then priority(val) else invalid
parseInteger(input) else 0
EntryOperationSource Codeshared EntryOperation

An entry expression.

Defined via Entry. No associativity.

Examples:

"1"->1
name->Person(name)
EntryTypeSource Codeshared EntryType

An entry type, that is, a shortcut for TypeNameWithTypeArguments(TypeName(UIdentifier("Entry")), [left, right]).

Examples:

String->Integer
Printable&Persistent&Identifiable->Handle
EqualOperationSource Codeshared EqualOperation

An equals expression.

Defined via Object.equals(). No associativity.

Examples:

length == 1
first == last
parseInteger(input) == 0
EqualityOperationSource Codeshared abstract EqualityOperation

An expression to test for identity or (in)equality of two objects.

This is the abstract superclass of the nodes for ==, !=, ===; not to be confused with EqualOperation, the concrete class for ==!

ExistsConditionSource Codeshared ExistsCondition

An existence condition, that is, the keyword ‘exists’, followed by either an (optionally typed) specified variable or an (untyped) member name.

Examples:

exists name
exists firstItem = first?.item
ExistsOperationSource Codeshared ExistsOperation

A postfix existence test expression.

No associativity.

Examples:

element exists
parseInteger(text) exists
ExistsOrNonemptyConditionSource Codeshared abstract ExistsOrNonemptyCondition

An existence or nonemptiness condition, that is, the keyword ‘exists’ or ‘nonempty’, followed by either an (optionally typed) specified variable or an (untyped) member name.

Examples:

nonempty employees
exists String name = person.name
ExponentiationOperationSource Codeshared ExponentiationOperation

An exponentiation expression.

Defined via Exponentiable.power(). Right-associative.

Examples:

sideLength^dimension
e^x
ExpressionSource 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 ProductOperation’s child nodes are crafted such that only nodes with correct precedence and associativity can be created.

To ensure this, there is one type alias for each precedence level, specified as the union type of

  • the next higher level’s alias, and
  • all operator types on this level.

For example, there is MultiplyingExpression for multiplicative expressions and AddingExpression for summative expressions. ProductOperation.leftFactor then has type MultiplyingExpression, which does not include SumOperation. ProductOperation.rightFactor has the next higher level’s type UnioningExpression, reflecting the left-associativity of product operations: Instead of

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:

ExpressionComprehensionClauseSource Codeshared ExpressionComprehensionClause

An expression that terminates a comprehension.

Examples:

person.age
i
ExpressionIshSource Codeshared abstract ExpressionIsh

All node types in the expression sub-hierarchy: Expression and some auxiliary node types that aren’t proper Expressions.

ExpressionStatementSource 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 AssignmentStatement where the target of the AssignOperation is a BaseExpression is invalid.

Examples:

text.length += added.length;
i++;
print("Hello, World!");
ExtendedTypeSource Codeshared ExtendedType

An ‘extends’ clause for a class definition.

Examples:

extends Node()
extends super.Entry<Key, Item>(key, item)
FailClauseSource Codeshared FailClause

An ‘else’ failure clause for a for’ loop (ForFail), that is, the keyword ‘else’ followed by a FailClause.block.

Examples:

else { print("Hello, World!"); }
FinallyClauseSource Codeshared FinallyClause

A ‘finally’ clause, that is, the keyword ‘finally’ followed by a FinallyClause.block.

Examples:

finally { print("END"); }
finally { workers.collect(Worker.kill); }
FloatLiteralSource Codeshared FloatLiteral

A floating point literal is distinguished from an integer literal (IntegerLiteral) by the presence of fractional digits or a fractional magnitude.

ForClauseSource Codeshared ForClause

A ‘for’ clause, that is, the keyword ‘for’ followed by an ForClause.iterator and a ForClause.block.

(Not to be confused with a complete for’ loop (ForFail), which also includes an optional failure clause.)

Examples:

for (person in people) { print(person.name); }
for (name->person in peopleByName) { print("``name``: ``person.age``"); }
ForComprehensionClauseSource Codeshared ForComprehensionClause

A ‘for’ comprehension clause, also known as a quantifier clause.

A ‘for’ comprehension clause consists of the keyword ‘for’, an ForComprehensionClause.iterator and a following ForComprehensionClause.clause.

Examples:

for (person in people) "``person.firstName`` ``person.lastName``"
for (people in peoples) for (person in people) if (person.age >= 18) person
ForFailSource Codeshared ForFail

A ‘for’ loop with an optional failure clause, that is, a for’ clause (forClause), optionally followed by an else’ failure clause (failClause).

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!");
}
ForIteratorSource Codeshared abstract ForIterator

An iterator for a ‘for’ loop, enclosed in parentheses.

Examples:

(person in people)
(name->person in peopleByName)
FullPackageNameSource Codeshared FullPackageName

A full package name, that is, a period-separated list of lowercase identifiers.

Examples:

ceylon.language
ceylon.ast.core
FunctionArgumentSource 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);
FunctionDecSource Codeshared FunctionDec

A function reference expression, that is, the FunctionDec.name of a function or method, optionally qualified by a FunctionDec.qualifier (separated from it by a member operator ‘.’), prefixed by the member keyword function and surrounded by backticks.

Examples:

`function concatenate`
`function Iterable.chain`
FunctionDeclarationSource Codeshared FunctionDeclaration

A function declaration.

A function declaration declares the FunctionDeclaration.name, FunctionDeclaration.type, parameters,
type parameters and type constraints of the value, but doesn’t provide a FunctionDeclaration.definition for it. There are several possible reasons for this:

  • The function can be a formal() method of an abstract() class or an interface, and subtypes have to provide the definition.
  • The function can be the declaration of a class or function parameter that only listed the name.
  • The function can be forward-declared, and the definition will be provided later.

In any case, the declaration must explicitly specify a type; a function’ modifier (FunctionModifier) indicating type inference cannot be used. (The ’dynamic’ modifier counts as a “type” here, indicating not the inference, but rather the absense of typing information.)

FunctionDefinitionSource 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;
    }
}
FunctionExpressionSource 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...]];
}
FunctionModifierSource Codeshared FunctionModifier

A ‘function’ modifier keyword.

The ‘function’ modifier keyword indicates that the type of a function is inferred.

FunctionShortcutDefinitionSource 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;
GivenDecSource Codeshared GivenDec

A type parameter reference expression, that is, the name of a type parameter, prefixed by the type keyword given and surrounded by backticks.

Note that the type parameter may not be qualified (i. e., `given Entry.Key` is not allowed), because a type parameter is not considered visible outside the declaration with the type parameter. For more information, see ceylon/ceylon-spec#1002.

GroupedExpressionSource Codeshared GroupedExpression

A grouped, or parenthesized expression.

Examples:

(1 + 2) * 3
"Hello, " + (process.arguments.first else "World")
GroupedTypeSource 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>[]
IdenticalOperationSource Codeshared IdenticalOperation

An identity test operation.

Defined natively, on objects that satisfy Identifiable. No associativity.

Examples:

node === rootNode
this === zero
IdentifierSource Codeshared abstract Identifier
IdentityOperationSource Codeshared IdentityOperation

The expression +i.

This expression is defined to return i for any i of Invertible type.

(Not to be confused with IdenticalOperation, i === i.)

IfClauseSource Codeshared IfClause

An if clause, that is, the keyword ‘if’, followed by a condition list and a IfClause.block.

Examples:

if (15 <= estimatedAge <= 25) { askForID(); }
if (exists elseClause = that.elseClause) { elseClause.visit(this); }
IfComprehensionClauseSource Codeshared IfComprehensionClause

An ‘if’ comprehension clause, also knows as a filter clause.

An ‘if’ comprehension clause consists of the keyword ‘if’, a condition list and a following IfComprehensionClause.clause.

Examples:

if (person.age >= 18) person
if (exists typeArguments = that.typeArguments) for (typeArgument in typeArguments) typeArgument.type
IfElseSource Codeshared IfElse

An if/else conditional.

The conditional begins with an if clause (ifClause) and may then optionally be followed by a chain of if/else clauses, optionally terminated by an else clause.

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;
}
ImportSource Codeshared Import

An import statement, that is, the keyword ‘import’ followed by the package name and the imported Import.elements from the package.

Examples:

import ceylon.ast.core { ... }
import java.lang { JString=String, System { sysout=\iout } }
import ceylon.collection { ArrayList, MutableList }
ImportAliasSource Codeshared abstract ImportAlias

An import alias, that is, an identifier followed by an “equals” character.

(Not to be confused with an alias declaration like alias TypeName => UIdentifier;.)

Examples:

JString=
sysout=
ImportElementSource Codeshared abstract ImportElement

A single import element, that is, the name of an imported program element,
optionally preceded by an alias and/or followed by nested import elements.

Examples:

HashMap
ln=log
System { sysout=out }
ImportElementsSource 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.

(ceylon.ast ImportElements are slightly different from the specification’s ImportElements; in the specification, the surrounding braces are always part of the “parent” node (Import, ImportTypeElement), while in ceylon.ast, they are part of the ImportElements.)

Examples:

MutableList, ArrayList
JString=String, System { sysout=out }
ImportFunctionValueAliasSource Codeshared ImportFunctionValueAlias

A function or value import alias, that is, a lowercase identifier followed by an “equals” character.

Examples:

sysout=
ln=
ImportFunctionValueElementSource 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
ImportTypeAliasSource Codeshared ImportTypeAlias

A type import alias, that is, an uppercase identifier followed by an “equals” character.

Examples:

JString=
Char=
ImportTypeElementSource 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 }
ImportWildcardSource Codeshared ImportWildcard

An import wildcard, that is, three colons (‘...’).

Used to indicate that all elements from a package should be imported.

InModifierSource Codeshared InModifier

An ‘in’ modifier, indicating a contravariant type parameter or argument.

InOperationSource Codeshared InOperation

A containment test expression.

Defined via Category.contains().

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, lhs in rhs corresponds to

rhs.contains(lhs)

while e. g. lhs * rhs corresponds to

lhs.times(rhs)

(the qualifier and argument swapped places).

InitialComprehensionClauseSource Codeshared abstract InitialComprehensionClause

A comprehension clause that can start a comprehension. Examples: for (person in people) “person.firstName person.lastName

if (exists typeArguments = that.typeArguments) for (typeArgument in typeArguments) typeArgument.type
InlineDefinitionArgumentSource 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);
}
IntegerLiteralSource 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.

InterfaceAliasDefinitionSource 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);
InterfaceBodySource Codeshared InterfaceBody

A list of declarations, surrounded by braces.

Unlike class bodies, interface bodies can’t immediately contain runnable code, so the InterfaceBody.content is just declarations, no statements.

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>");
}
InterfaceDecSource Codeshared InterfaceDec

An interface reference expression, that is, the InterfaceDec.name of an interface, optionally qualified by a InterfaceDec.qualifier (separated from it by a member operator ‘.’), prefixed by the type keyword interface and surrounded by backticks.

Examples:

`interface Iterable`
`interface A.B.C`
InterfaceDefinitionSource 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);
}
IntersectAssignmentOperationSource Codeshared IntersectAssignmentOperation

An intersect assignment operation.

Right-associative.

Examples:

people &= authorizedUsers
commonElements &= elements
IntersectionOperationSource Codeshared IntersectionOperation

A set intersection expression.

Defined via Set.intersection(). Left-associative.

Examples:

persistents&printables&identifiables
x1&y1
IntersectionTypeSource Codeshared IntersectionType

An intersection type.

Examples:

Element&Identifiable
Persistent&Printable&Identifiable
InvocationSource Codeshared Invocation

An invocation, that is, an invoked expression with an argument list.

Examples:

print("Hello, World!")
process.kill()
ArrayList { initialCapacity = 100; 1, 1 }
InvocationStatementSource 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);
IsCaseSource Codeshared IsCase

A ‘case’ item to test the type of the switch expression.

Examples:

is String
is Persistent&Serializable
is Integer|Float
IsConditionSource Codeshared IsCondition

An assignability condition, that is, the keyword ‘is’, followed by an (optionally specified) typed variable and optionally prefixed by a negation operator ‘!’.

Examples:

is Integer|Float num
is Administrator user
IsOperationSource Codeshared IsOperation

A postfix assignability test expression.

No associativity.

Examples:

element is String|Integer
user is ExecutiveUser
IterableSource Codeshared Iterable

An iterable object instantiation expression.

Examples:

{}
{ second, first, *rest.rest }
IterableTypeSource Codeshared IterableType

An iterable type, like {String*} or {}.

KeySource Codeshared Key<Type>
given Type satisfies Object

A key by which a Node’s additional information can be accessed.

KeySubscriptSource Codeshared KeySubscript

A key / index subscript expression, to select an element from a Correspondence expression.

Examples:

key
offset + i
KeyValueIteratorSource Codeshared KeyValueIterator

A key→value iterator for a ‘for’ loop, enclosed in parentheses.

Examples:

(name->person in peopleByName)
(index->char in text.indexed)
LIdentifierSource Codeshared LIdentifier

An initial lowercase identifier.

LargeAsOperationSource Codeshared LargeAsOperation

A “large as” expression.

No associativity.

LargerOperationSource Codeshared LargerOperation

A “larger than” expression.

No associativity.

LazySpecificationSource 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);
LazySpecifierSource Codeshared LazySpecifier

A lazy expression specifier, that is, an expression prefixed by a computation operator ‘=>’.

Examples:

=> text.uppercased
=> nothing
LiteralSource Codeshared abstract Literal

A literal is a single token that represents a Unicode character, a character string, or a numeric value.

LocalModifierSource Codeshared abstract LocalModifier

A modifier that indicates type inference.

It can only be used on local definitions (not toplevel, not shared), hence the name.

LogicalAssignmentOperationSource Codeshared abstract LogicalAssignmentOperation

A logical assignment expression.

Right-associative.

LogicalOperationSource Codeshared abstract LogicalOperation

A logical binary operation expression.

MainTypeSource Codeshared abstract MainType

“Main” types: the types that you normally use.

This class is used as “Type, except EntryType” in EntryType and VariadicType, since both of these can’t have entry types as children. In other words, this class is only there to represent how types are parsed, not their semantics.

MatchCaseSource Codeshared MatchCase

A ‘case’ item to test if the switch expression matches one or more expressions.

Examples:

null
0 | 1
null | smaller | larger
MeasureOperationSource Codeshared MeasureOperation

A measured range expression.

Defined via measure(). No associativity.

Examples:

0:size
today:14
MeasureSubscriptSource Codeshared MeasureSubscript

A measure subscript, to select a (sub)range from a Ranged expression using the first index and MeasureSubscript.length.

Examples:

0:30
match.start:match.size
MemberDecSource Codeshared abstract MemberDec

A member reference expression.

Examples:

`value null`
`function Iterable.map`
MemberMetaSource Codeshared MemberMeta

A member metamodel expression, that is, a MemberMeta.qualifier, followed by a member name with optional type arguments, surrounded by backticks.

(A qualifier followed by a type name with optional type arguments surrounded by backticks is a TypeMeta.)

Examples:

`Person.say`
`system.milliseconds`
`Iterable<String>.collect<Integer?>`
MemberNameWithTypeArgumentsSource Codeshared MemberNameWithTypeArguments

A member name and, optionally, type arguments.

MemberOperatorSource Codeshared MemberOperator

A regular member operator, ‘.’.

MetaSource 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 Dec, which represents a detyped reference. Simply speaking, if there’s a keyword (`class String`, `value system`), then it’s a Dec, otherwise it’s a Meta.

ModifierSource Codeshared abstract Modifier

A modifier keyword.

Note: The Ceylon Language Specification also refers to certain annotations, e. g. shared(), abstract(), variable(), etc., as “modifiers” – see §7.4.1, Declaration Modifiers. In ceylon.ast, however, Modifier refers only to the reserved keywords that can be used on a function or value:

ModuleBodySource 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 Body. If a future version of Ceylon allows procedural code in a module body, then this may change.)

Examples:

{}
{ shared import ceylon.test "1.1.0"; }
{ import ceylon.collection "1.1.0"; }
ModuleCompilationUnitSource 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";
}
ModuleDecSource 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`
ModuleDescriptorSource Codeshared ModuleDescriptor

A module descriptor: a list of annotations, followed by the keyword ‘module’, and then the module ModuleDescriptor.name, ModuleDescriptor.version and ModuleDescriptor.body.

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";
}
ModuleImportSource Codeshared ModuleImport

An import of another module within a module descriptor.

Each module import consists of a list of ModuleImport.annotations, followed by the keyword ‘package’, the ModuleImport.name of the imported module, and the ModuleImport.version of the imported module, terminated by a semicolon.

Examples:

shared import ceylon.test "1.1.0";
import ceylon.collection "1.1.0";
MultiplyAssignmentOperationSource Codeshared MultiplyAssignmentOperation

A multiply assignment operation (*=).

Right-associative.

Examples:

balance *= 1 + interestRate
NameWithTypeArgumentsSource Codeshared abstract NameWithTypeArguments

A name and, optionally, type arguments.

NamedArgumentSource Codeshared abstract NamedArgument

A named argument.

Examples:

name;
size = width * height;
Color color(Integer x, Integer y) => red;
NamedArgumentsSource 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)
    }
}
NegationOperationSource Codeshared NegationOperation

An arithmetic unary negation operation, that is, -i.

This operator is defined in terms of Invertible.negated.

NodeSource Codeshared abstract Node

Abstract superclass of all AST nodes.

Note that nodes are not Identifiable: as they are immutable, the identity of a particular instance is meaningless.

Additional information

You can attach additional information to individual AST nodes using the Node.put() and Node.get() methods. Usage example:

// 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));
NonemptyConditionSource Codeshared NonemptyCondition

A nonemptiness condition, that is, the keyword ‘nonempty’, followed by either an (optionally typed) specified variable or an (untyped) member name.

Examples:

nonempty employees
nonempty persons = people.sequence()
NonemptyOperationSource Codeshared NonemptyOperation

A nonempty postfix expression.

No associativity.

NotEqualOperationSource Codeshared NotEqualOperation

A not equals expression.

Defined via Object.equals(). No associativity.

Examples:

uid != 0
process.arguments.length != 7
NotOperationSource Codeshared NotOperation

A logical not expression.

Right-associative.

Examples:

!n in primes
!predicate(element)
ObjectArgumentSource 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();
}
ObjectDefinitionSource 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");
    }
}
OfOperationSource 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?
OpenBoundSource Codeshared OpenBound

An open lower or upper bound of a bounded comparison operation.

In an open bound, the OpenBound.endpoint is not a part of the designated interval; therefore, when dealing with real numbers, the interval has no minimum / maximum value, as you can get infinitely close to the endpoint without reaching it.

For example, in the interval 0 < x < 1, the values 0.9, 0.99, 0.999, etc. for x are all within the interval.

OperationSource 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 GroupedExpression) isn’t well-typed.

(This class is called Operation rather than OperatorExpression to avoid overly long names of the subtypes; for the same reason, subtypes are only suffixed -Operation rather than -BinaryOperation or -UnaryOperation.)

OptionalTypeSource Codeshared OptionalType

An optional type, that is, a shortcut for UnionType(definiteType, nullType).

Examples:

String?
<String->Integer>?
OrAssignmentOperationSource Codeshared OrAssignmentOperation

A logical disjunction assignment expression.

Right-associative.

Examples:

permitted ||= backdoorTriggered
canPrint ||= networkPrinterPresent
OrOperationSource Codeshared OrOperation

A logical disjunction expression.

Left-associative.

Examples:

digit == 0 || digit == 1
element in errors || !element exists
OutModifierSource Codeshared OutModifier

An ’out’ modifier, indicating a covariant type parameter or argument.

OuterSource 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 outerInstance instead of creating new instances of this class in order to save memory.

PackageSource Codeshared Package

package isn’t actually an expression; it can be used to qualify and disambiguate a value or callable reference.

As this class is completely stateless, you can reuse packageInstance instead of creating new instances of this class in order to save memory.

PackageCompilationUnitSource Codeshared PackageCompilationUnit

A package descriptor compilation unit, containing a package descriptor.

Examples:

package tmp;
shared package ceylon.ast.core;
PackageDecSource 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`
PackageDescriptorSource Codeshared PackageDescriptor

A package descriptor: a list of annotations, followed by the keyword ‘package’, the package name, and terminated by a semicolon.

Examples:

package tmp;
"Test package" see (`package my.application`) package test.my.application;
ParameterSource Codeshared abstract Parameter

A class, method, or function parameter.

Examples:

String name
comparing
Integer length = text.size
Element+ elements
ParameterReferenceSource 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
ParametersSource Codeshared Parameters

A parameter list.

Examples:

()
(String text, Integer length = text.size)
(Element+ elements)

A note about this class’ parameters

It would seem reasonable to instead declare the parameters of this class like this:

class Parameters(RequiredParameter[] required,
    DefaultedParameter[] defaulted,
    VariadicParameter|ParameterReference variadic)

Note that variadic must have the type VariadicParameter|ParameterReference, not just VariadicParameter, because a variadic parameter can also be just a reference, and declared in the body of the function or class. And this is where the problem comes in:

(param)

In this parameter list, is param a required or a defaulted parameter? In other words, is this

  • a Parameters { required = [param]; }, or
  • a Parameters { variadic = param; }?

To decide this, you need to look into the body of the function, and check if the declaration of param has a regular or a variadic type. This is a semantical distinction, not a syntactical one, and in general we can’t expect tools that operate on an AST to be able to make this distinction.

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.

PositionalArgumentsSource 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 ArgumentList, enclosed in parentheses.

Examples:

(x, y, *messages)
()
(for (i in 1..10) i^2)
PostfixDecrementOperationSource Codeshared PostfixDecrementOperation

A postfix decrement expression (i--).

PostfixIncrementOperationSource Codeshared PostfixIncrementOperation

A postfix increment expression (i++).

PostfixOperationSource Codeshared abstract PostfixOperation

A postfix arithmetic expression, that is, i++ or i-- for any Primary i.

PrefixDecrementOperationSource Codeshared PrefixDecrementOperation

A prefix decrement expression (--i).

PrefixIncrementOperationSource Codeshared PrefixIncrementOperation

A prefix increment expression (++i).

PrefixOperationSource Codeshared abstract PrefixOperation

A prefix arithmetic expression, that is, ++i or --i for any Primary i.

PrefixPostfixStatementSource Codeshared PrefixPostfixStatement

A prefix or postfix increment or decrement expression statement.

Examples:

i++;
--size;
PrimarySource Codeshared abstract Primary

A primary expression.

Primaries can be combined using operations.

PrimaryTypeSource Codeshared abstract PrimaryType

A primary type; only intersection and union types come before these.

ProductOperationSource Codeshared ProductOperation

A product expression.

Defined via Numeric.times(). Left-associative.

QualifiedExpressionSource Codeshared QualifiedExpression

A receiver expression, followed by a member operator (usually ‘.’) and an (unqualified) identifier with optional type arguments.

Examples:

", ".join
process.arguments.first
people*.name
sort(people, byAscending(Person.salary)).first?.salary
QualifiedTypeSource 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
QuotientOperationSource Codeshared QuotientOperation

A quotient or division expression.

Defined via Numeric.divided(). Left-associative.

RangeSubscriptSource Codeshared abstract RangeSubscript

A range subscript, to select a (sub)range from a Ranged expression.

Examples:

1 .. text.size - 2
1...
RemainderAssignmentOperationSource Codeshared RemainderAssignmentOperation

A remainder assignment operation (%=).

Right-associative.

Examples:

increment %= step
RemainderOperationSource Codeshared RemainderOperation

A remainder expression.

Defined via Integral.remainder(). Left-associative.

RequiredParameterSource Codeshared abstract RequiredParameter

A required parameter (neither defaulted nor variadic).

Examples:

String name
comparing
ResourceSource Codeshared Resource

A resource in a try-with-resources statement.

Examples:

lock
writer = file.Writer()
ResourcesSource Codeshared Resources

A comma-separated list of Resources.resources, surrounded by parentheses.

Examples:

(lock)
(reader = inFile.Reader(), writer = outFile.Writer())
ReturnSource Codeshared Return

A return directive, with an optional returned expression.

SafeMemberOperatorSource 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.

SatisfiedTypesSource Codeshared SatisfiedTypes

A nonempty list of satisfied types, separated by the intersection operator (‘&’).

Examples:

satisfies {Element+}
satisfies Printable & Persistent
ScaleOperationSource Codeshared ScaleOperation

A scale expression.

Defined via Scalable.scale(). Right-associative.

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, lhs ** rhs corresponds to

rhs.scale(lhs)

while e. g. lhs * rhs corresponds to

lhs.times(rhs)

(the qualifier and argument swapped places).

ScopedKeySource Codeshared ScopedKey<Type>
given Type satisfies Object

A Key with an explicitly provided scope, to avoid name collisions.

SelfReferenceSource Codeshared abstract SelfReference

this, super, outer and package are self reference expressions. The type of these expressions depends on the context in which they appear.

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 thisInstance, superInstance, outerInstance and packageInstance instead of creating new instances every time.

SequentialTypeSource Codeshared SequentialType

A sequential type, that is, a shortcut for TypeNameWithTypeArguments(UIdentifier("Sequential"), [elementType]).

Examples:

String[]
<String->Integer>[]
SetAssignmentOperationSource Codeshared abstract SetAssignmentOperation

A set assignment operation.

Right-associative.

SetOperationSource Codeshared abstract SetOperation

A set operation: intersection, union or complement.

SimpleTypeSource 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 SimpleType.

SmallAsOperationSource Codeshared SmallAsOperation

A “small as” expression.

No associativity.

SmallerOperationSource Codeshared SmallerOperation

A “smaller than” expression.

No associativity.

SpanFromSubscriptSource Codeshared SpanFromSubscript

A span-from subscript, to select a (sub)range from a Ranged expression using the first index.

Examples:

1...
match.start ...
SpanOperationSource Codeshared SpanOperation

A spanned range expression.

Defined via span(). No associativity.

Examples:

0..9 monday..friday first.successor..last.predecessor

SpanSubscriptSource Codeshared SpanSubscript

A span subscript, to select a (sub)range from a Ranged expression using the first and last index.

Examples:

1 .. text.size - 2
text.size - 1 .. 0
SpanToSubscriptSource Codeshared SpanToSubscript

A span-to subscript, to select a (sub)range from a Ranged expression using the last index.

Examples:

... text.size - 1
...count
SpecificationSource Codeshared abstract Specification

A specification statement.

Examples:

offset = preamble.size + title.size;
debug(Anything a) => process.writeErrorLine(a);
SpecifiedArgumentSource Codeshared SpecifiedArgument

A specified named argument, that is, a Specification.

Examples:

groupSeparators = false;
initialCapacity = 256;
SpecifiedVariableSource Codeshared SpecifiedVariable

A specified inline variable declaration.

Examples:

num = parseFloat(numString)
String name = person.name
SpecifierSource Codeshared Specifier

An expression specifier, that is, an expression prefixed by a specification operator ‘=’.

Examples:

= 1
= nothing
SpreadArgumentSource Codeshared SpreadArgument

A spread argument.

Used in argument lists to “spread” a sequential value over multiple arguments.

(The spread “operator” * looks like a prefix unary operator, but because it produces multiple values, not just one, a spread argument is not an expression.)

Examples:

*args
*values.collect(Object.string)
*[]
SpreadMemberOperatorSource 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.

StatementSource Codeshared abstract Statement

A statement.

Examples:

value name = person.name else "<unnamed>";
print("Hello, World!");
StringLiteralSource Codeshared StringLiteral

A string literal consists of a series of characters and/or, if it’s not verbatim, escape sequences.

Note: in contrast to IntegerLiteral and FloatLiteral, the value of StringLiteral.text isn’t verified, and there is no attribute to get the String value of the literal; getting that value requires unicode support (to parse '{CHARACTER NAME}') that isn’t available on all platforms.

StringTemplateSource 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 ceylon.ast.)

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``."
SubscriptSource Codeshared abstract Subscript

A subscript used to access an element or subrange in a ElementOrSubrangeExpression (where it is surrounded by brackets).

In mathematical notations, these accessors are usually written as subscript, e. g. xi for the ith x element.

Examples:

index
... text.size - 2
SubtractAssignmentOperationSource Codeshared SubtractAssignmentOperation

A subtract assignment operation (-=).

Right-associative.

Examples:

countdown -= \iΔt
SumOperationSource Codeshared SumOperation

A sum expression.

Defined via Summable.plus(). Left-associative.

Examples:

i + 1
firstIndex + size
SuperSource 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 superInstance instead of creating new instances of this class in order to save memory.

SwitchCaseElseSource Codeshared SwitchCaseElse

A switch/case/else statement, that is, a switch clause (clause), followed by SwitchCaseElse.cases.

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); }
SwitchCasesSource Codeshared SwitchCases

A list of ‘case’ clauses (with an optional trailing ‘else’ clause) for a switch statement (SwitchCaseElse).

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);
}
SwitchClauseSource Codeshared SwitchClause

A ‘switch’ clause of a switch statement (SwitchCaseElse), that is, the keyword ‘switch’, followed by an SwitchClause.expression enclosed in parentheses.

Examples:

switch (i.magnitude)
switch (child)
ThenOperationSource Codeshared ThenOperation

A “then” operation.

Left-associative.

Examples:

!name.empty then name
age != -1 then age
ThisSource 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 thisInstance instead of creating new instances of this class in order to save memory.

ThrowSource Codeshared Throw

A throw directive, with an optional thrown exception.

TryCatchFinallySource Codeshared TryCatchFinally

A try-cA try/catch/finally statement, that is, a try’ clause (tryClause), followed by any amount of catch’ clauses (catchClauses), and optionally terminated by a finally’ clause (finallyClause).

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;
}
TryClauseSource Codeshared TryClause

A ‘try’ clause, that is, the keyword ‘try’, followed optionally by TryClause.resources and then by a TryClause.block (required).

Examples (multi-line):

try {
    value zombie = spawn { Zombie; center = player.location; spread = 50; };
    zombie.aggro = player;
}

try (writer = file.Writer()) {
    that.serialize(writer);
}
TupleSource Codeshared Tuple

A tuple instantiation expression.

Examples:

[]     
[x, y]
[father, mother, *children]
TupleTypeSource Codeshared TupleType

A tuple type.

Examples:

[String,Integer,Integer]
[Float,Integer*]
[]
TypeSource Codeshared abstract Type

Representation of a type.

TypeAliasDefinitionSource 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>;
TypeArgumentSource Codeshared TypeArgument

A type argument, that is, a TypeArgument.type with optional TypeArgument.variance (use-site variance).

(Use-site variance is only rarely used; most of the time, TypeArgument.variance should be null.)

Examples:

String
out T
TypeArgumentsSource Codeshared TypeArguments

A nonempty comma-separated list of type arguments, enclosed in angle brackets.

Examples:

<String,Nothing>
<out Element>
TypeConstraintSource 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
TypeDecSource Codeshared abstract TypeDec

A type reference expression.

TypeDeclarationSource Codeshared abstract TypeDeclaration

A type declaration.

Examples (multi-line):

shared interface Printable {
    shared default void print() {
        package.print(this);
    }
}

shared alias TypeName => UIdentifier;
TypeIshSource Codeshared abstract TypeIsh

All node types in the type sub-hierarchy: Type and some auxiliary node types that aren’t proper Types.

(For example, while String* is part of the valid type {String*}, it’s not a valid type by itself.)

TypeListSource Codeshared TypeList

A list of types, with an optional trailing variadic type.

Examples:

String, String, String+
TypeMetaSource Codeshared TypeMeta

A type metamodel expression, that is, a Type surrounded by backticks.

Examples:

`List<String>`
`Integer|Float`
TypeModifierSource Codeshared abstract TypeModifier

A modifier that can be used instead of a type in some places.

This includes:

  • the local modifiers ‘value’ and ‘function’, indicating type inference;
  • the ‘void’ modifier, indicating that a function doesn’t return a value; and
  • the ‘dynamic’ modifier, indicating absense of any typing information.
TypeNameWithTypeArgumentsSource Codeshared TypeNameWithTypeArguments

A type name and, optionally, type arguments.

TypeParameterSource Codeshared TypeParameter

A type parameter of a class, method or function.

The type parameter may optionally declare a type TypeParameter.variance (without one, it is invariant) and/or a default type argument (used when the use-site declares some but not all type arguments).

Examples:

out Element
out Absent=Null
TypeParametersSource Codeshared TypeParameters

A nonempty comma-separated list of type parameters, surrounded by angle brackets.

Examples:

<in Key, out Item>
<out Element>
TypeSpecifierSource Codeshared TypeSpecifier

A type specifier, that is, a type prefixed by a computation operator ‘=>’.

Examples:

=> Map<String,Person>
=> Comparison(Value,Value)
TypedDeclarationSource Codeshared abstract TypedDeclaration

A declaration with a type.

The type can either be explicitly specified (TypedDeclaration.type is a Type) or inferred (TypedDeclaration.type is a Modifier that indicates type inference).

Examples:

shared String name;
shared actual void visit(Node that) { print(that); that.visitChildren(this); }
TypedVariableSource Codeshared TypedVariable

A typed inline variable declaration.

Examples:

Integer|Float num
String name
UIdentifierSource Codeshared UIdentifier

An initial uppercase identifier.

UnaryArithmeticOperationSource Codeshared abstract UnaryArithmeticOperation

A unary arithmetic expression, that is, +i or -i.

UnaryIshOperationSource Codeshared abstract UnaryIshOperation

An expression consisting of a ValueExpression, an operator, and possibly a Type.

These can be regular unary operations – either prefix or postfix – or unary type operations, which are always postfix, and include a type.

UnaryOperationSource Codeshared abstract UnaryOperation

A unary operator expression.

UnaryTypeOperationSource Codeshared abstract UnaryTypeOperation

A unary type operation.

A subclass of UnaryIshOperation, not BinaryOperation, because the second child is a UnaryTypeOperation.type rather than a ValueExpression.

UnionAssignmentOperationSource Codeshared UnionAssignmentOperation

A union assignment operation.

Right-associative.

Examples:

students |= course.students
allElements |= elements
UnionOperationSource Codeshared UnionOperation

A set union expression.

Defined via Set.union(). Left-associative.

Examples:

ints|floats
x1&y1|x2&y2
UnionTypeSource Codeshared UnionType

A union type.

Examples:

String|Integer|Float
UnionableTypeSource Codeshared abstract UnionableType

Types that can be children of a UnionType.

This class is only there to represent how types are parsed, not their semantics.

UnspecifiedVariableSource 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
ValueArgumentSource 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);
ValueDecSource Codeshared ValueDec

A value reference expression, that is, the ValueDec.name of a value, optionally qualified by a ValueDec.qualifier (separated from it by a member operator ‘.’), prefixed by the member keyword value and surrounded by backticks.

Examples:

`value null`
`value Iterable.first`
ValueDeclarationSource Codeshared ValueDeclaration

A value declaration.

A value declaration declares the ValueDeclaration.name and ValueDeclaration.type of the value, but doesn’t provide a ValueDeclaration.definition for it. There are several possible reasons for this:

  • The value can be a formal() attribute and be a member of an abstract() class
    or an interface, and subtypes have to provide the definition.
  • The value can be the declaration of a class or function parameter that only listed the name (and potentially a default value).
  • The value can be forward-declared, and the definition will be provided later.

In any case, the declaration must explicitly specify a type; a Modifier indicating type inference cannot be used. (The ’dynamic’ modifier counts as a “type” here, indicating not the inference, but rather the absense of typing information.)

ValueDefinitionSource Codeshared ValueDefinition

A value definition, using a specifier.

Examples:

shared actual String string => "``name`` from ``countryOfOrigin`` of age ``age``";
shared actual Null definition = null;
ValueExpressionSource Codeshared abstract ValueExpression

An expression that returns an ordinary value.

Value expressions return instances of classes, while function expressions return first-class functions.

ValueGetterDefinitionSource 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)); }
ValueIteratorSource Codeshared ValueIterator

A value iterator for a ‘for’ loop, enclosed in parentheses.

Examples:

(person in people)
(char in text)
ValueModifierSource Codeshared ValueModifier

A ‘value’ modifier keyword.

The ‘value’ modifier keyword indicates that the type of a value is inferred.

ValueParameterSource Codeshared ValueParameter

A value parameter.

Examples:

String name
Integer length
Boolean(Element) selecting
shared Address privateAddress
ValueSetterDefinitionSource Codeshared ValueSetterDefinition

A setter definition, that is, the keyword ‘assign’, followed by the ValueSetterDefinition.name of the value and the ValueSetterDefinition.definition (either a block or a lazy specifier terminated by a semicolon), preceded by ValueSetterDefinition.annotations.

Examples:

assign diameter => radius = diameter / 2;
assign diameter {
    throw AssertionError("Can’t set the diameter of the unit circle");
}
ValueSpecificationSource Codeshared ValueSpecification

A value specification statement, that is, a member name followed by a Specifier.

Examples:

size = 0;
it = iterators.next();
VariableSource Codeshared abstract Variable

An inline variable declaration.

Assertions and some control structures allow inline declarations of variables.

Examples:

firstEmployee = employees.first
Integer|Float num
VariadicParameterSource Codeshared VariadicParameter

A variadic parameter.

Examples:

Element+ elements
String* messages
"The indexes" Integer+ indexes
VariadicTypeSource Codeshared VariadicType

A variadic type is a MainType followed by a “*” (possibly-empty) or a “+” (nonempty).

VarianceSource Codeshared abstract Variance

A modifier that indicates type parameter / argument variance.

Examples:

in
out
VoidModifierSource Codeshared VoidModifier

A ‘void’ modifier keyword.

WhileSource Codeshared While

A while loop, that is, the keyword ‘while’, followed by While.conditions and a While.block.

Examples:

while (i++ <= count) { lines.add(process.readLine()); }
while (!((elem = it.next()) is Finished)) { expressions.add(elem); literals.add(it.next()); }
WithinOperationSource Codeshared WithinOperation

A bounded comparison operation, also known as “within” operation.

Examples:

0 <= x < 10
1 <= x <= 31