The Ceylon metamodel open type and declaration package.

As described in the ceylon.language.meta documentation, this package contains all the types that represent Ceylon declarations and open types.

Usage example

The following code will list all the classes in the ceylon.language package and print their extended type:

for(decl in `package ceylon.language`.members<ClassDeclaration>()){
    if(exists extendedType = decl.extendedType){
        print("Class ``decl.name`` extends: ``extendedType``");
    }else{
        print("Class ``decl.name`` does not extend anything");
    }
}

The following code will iterate all the class declarations in the ceylon.language package that are not abstract, anonymous or annotations, and that have no type parameters nor initialiser parameters. For each matching class, we will apply it to get a class model which we can then use to instantiate the class and display its instance:

for(decl in `package ceylon.language`.members<ClassDeclaration>()){
    if(!decl.abstract 
            && !decl.anonymous 
            && !decl.annotation
            && decl.parameterDeclarations.empty
            && decl.typeParameterDeclarations.empty){
        Class<Object,[]> classModel = decl.classApply<Object,[]>();
        Object instance = classModel();
        print("Instance of ``decl.name`` is: ``instance``");
    }
}
By: Gavin King, Stephane Epardaud, Tom Bentley
Aliases
OpenTypeArgumentshared OpenTypeArgument=> [OpenType, Variance]

A tuple representing an open type argument and its use-site variance.

Values
contravariantshared contravariant contravariant

Contravariant means that supertypes of the given type may be accepted.

covariantshared covariant covariant

Covariant means that subtypes of the given type may be returned.

invariantshared invariant invariant

Invariant means that neither subtype nor supertype can be accepted, the type has to be exactly that which is declared.

nothingTypeshared nothingType nothingType

The singleton open type for Nothing.

Interfaces
AliasDeclarationshared AliasDeclaration

Type alias declaration. While type aliases are erased (substituted for what they alias is a better term) from every declaration that uses them during compile-time, the declaration of the type alias is still visible at run-time.

AnnotatedDeclarationshared AnnotatedDeclaration

Declaration which can be annotated, such as:

You can query annotations that are placed on a given annotated declaration with:

CallableConstructorDeclarationshared CallableConstructorDeclaration

Declaration model for callable constructors, for example

class WithConstructors {
    shared new () {}
    shared new clone(WithConstructors other) {}

// ...

CallableConstructorDeclaration default = `new WithConstructors`;
CallableConstructorDeclaration clone = `new WithConstructors.clone`;

The initializer of a class with a parameter list can also be represented as a CallableConstructorDeclaration.

ClassDeclarationshared ClassDeclaration

Class declaration.

Callable classes

Since Ceylon 1.2 classes are not always directly invokable (if the class has constructors, but not a default constructor). Thus members of ClassDeclaration which depend on the class parameter list typically have optional type, but are refined on ClassWithInitializerDeclaration to be non-optional. The exceptions to this are ClassDeclaration.instantiate() and ClassDeclaration.memberInstantiate(), which throw exceptions.

Usage sample for toplevel classes

Because some classes have type parameters, getting a model requires applying type arguments to the class declaration with ClassDeclaration.classApply() in order to be able to instantiate that class. For example, here is how you would obtain a class model that you can instantiate from a toplevel class declaration:

class Foo<T>(){
    string => "Hello, our T is: ``typeLiteral<T>()``";
}

void test(){
    // We need to apply the Integer closed type to the Foo declaration in order to get the Foo<Integer> closed type
    Class<Foo<Integer>,[]> classModel = `class Foo`.classApply<Foo<Integer>,[]>(`Integer`);
    // This will print: Hello, our T is: ceylon.language::Integer
    print(classModel());
}

Usage sample for member classes

For member classes it is a bit longer, because member classes need to be applied not only their type arguments but also the containing type, so you should use ClassDeclaration.memberClassApply() and start by giving the containing closed type:

class Outer(){
    shared class Inner(){
        string => "Hello";
    }
}

void test(){
    // apply the containing closed type `Outer` to the member class declaration `Outer.Inner`
    MemberClass<Outer,Outer.Inner,[]> memberClassModel = `class Outer.Inner`.memberClassApply<Outer,Outer.Inner,[]>(`Outer`);
    // We now have a MemberClass, which needs to be applied to a containing instance in order to become an
    // invokable class model:
    Class<Outer.Inner,[]> boundMemberClassModel = memberClassModel(Outer());
    // This will print: Hello
    print(boundMemberClassModel());
}
ClassOrInterfaceDeclarationshared ClassOrInterfaceDeclaration

A class or interface declaration.

Usage sample for toplevel classes

Because some classes have type parameters, getting a model requires applying type arguments to the class declaration with ClassOrInterfaceDeclaration.apply() in order to be able to instantiate that class. For example, here is how you would obtain a class or interface model that you can instantiate from a toplevel class declaration:

class Foo<T>() {
    string => "Hello, our T is: ``typeLiteral<T>()``";
}

void test(){
    // We need to apply the Integer closed type to the Foo declaration in order to get the Foo<Integer> closed type
    ClassOrInterface<Foo<Integer>> classOrInterfaceModel = `class Foo`.apply<Foo<Integer>>(`Integer`);
    assert(is Class<Foo<Integer>,[]> classOrInterfaceModel);
    // This will print: Hello, our T is: ceylon.language::Integer
    print(classOrInterfaceModel());
}

Note that there are more specialised versions of ClassOrInterfaceDeclaration.apply() in ClassDeclaration.classApply() and InterfaceDeclaration.interfaceApply().

Usage sample for member classes

For member classes or interfaces it is a bit longer, because member types need to be applied not only their type arguments but also the containing type, so you should use ClassOrInterfaceDeclaration.memberApply() and start by giving the containing closed type:

class Outer(){
    shared class Inner(){
        string => "Hello";
    }
}

void test(){
    // apply the containing closed type `Outer` to the member class declaration `Outer.Inner`
    value memberClassModel = `class Outer.Inner`.memberApply<Outer,Outer.Inner>(`Outer`);
    assert(is MemberClass<Outer,Outer.Inner,[]> memberClassModel);
    // We now have a MemberClass, which needs to be applied to a containing instance in order to become an
    // invokable class model:
    Class<Outer.Inner,[]> boundMemberClassModel = memberClassModel(Outer());
    // This will print: Hello
    print(boundMemberClassModel());
}

Note that there are more specialised versions of ClassOrInterfaceDeclaration.memberApply() in ClassDeclaration.memberClassApply() and InterfaceDeclaration.memberInterfaceApply().

ClassWithConstructorsDeclarationshared ClassWithConstructorsDeclaration

The declaration model of a class that has constructors. For example:

class Point {
    shared new(Float x, Float y) {
        // ...
    }
    shared new polar(Float r, Float theta) {
        // ...
    }
    shared new origin {
        // ...
    }
}

Such classes may not have a default (unnamed) constructor, so defaultConstructor has optional type.

ClassWithInitializerDeclarationshared ClassWithInitializerDeclaration

The declaration model of a class that has a parameter list rather than explicit constructors. For example:

class Color(Integer rgba) {
}

Such classes have a meaningful parameter list and for abstraction purposes have a single ClassWithInitializerDeclaration.defaultConstructor representing the class' parameter list and the class initializer code. This “constructor” will have the same SharedAnnotation, DeprecationAnnotation and ThrownExceptionAnnotation annotations as the class, but will have no other annotations.

ConstructorDeclarationshared ConstructorDeclaration
Declarationshared Declaration

A declaration.

There are only two types of declarations:

FunctionDeclarationshared FunctionDeclaration

Abstraction over declarations which can be invoked, namely functions, methods and constructors

FunctionOrValueDeclarationshared FunctionOrValueDeclaration

A function or value declaration.

FunctionalDeclarationshared FunctionalDeclaration

A function declaration.

Usage sample for toplevel function

Because some functions have type parameters, getting a model requires applying type arguments to the function declaration with FunctionalDeclaration.apply() in order to be able to invoke that function. For example, here is how you would obtain a function model that you can invoke from a toplevel function declaration:

String foo<T>(){
    return "Hello, our T is: ``typeLiteral<T>()``";
}

void test(){
    // We need to apply the Integer closed type to the foo declaration in order to get the foo<Integer> function model
    Function<String,[]> functionModel = `function foo`.apply<String,[]>(`Integer`);
    // This will print: Hello, our T is: ceylon.language::Integer
    print(functionModel());
}

Usage sample for methods

For methods it is a bit longer, because methods need to be applied not only their type arguments but also the containing type, so you should use FunctionalDeclaration.memberApply() and start by giving the containing closed type:

class Outer(){
    shared String hello() => "Hello";
}

void test(){
    // apply the containing closed type `Outer` to the method declaration `Outer.hello`
    Method<Outer,String,[]> methodModel = `function Outer.hello`.memberApply<Outer,String,[]>(`Outer`);
    // We now have a Method, which needs to be applied to a containing instance in order to become an
    // invokable function:
    Function<String,[]> boundMethodModel = methodModel(Outer());
    // This will print: Hello
    print(boundMethodModel());
}
GenericDeclarationshared GenericDeclaration

A declaration that can have type parameters.

GettableDeclarationshared GettableDeclaration

Abstraction over declarations from which a value can be obtained, namely

Importshared Import

Model of an import declaration within a module declaration.

InterfaceDeclarationshared InterfaceDeclaration

An interface declaration.

Usage sample for toplevel interfaces

Because some interfaces have type parameters, getting a model requires applying type arguments to the interface declaration with InterfaceDeclaration.interfaceApply() in order to be able to get a closed type. For example, here is how you would obtain an interface model from a toplevel interface declaration:

interface Foo<T> satisfies List<T> {
}

void test(){
    // We need to apply the Integer closed type to the Foo declaration in order to get the Foo<Integer> closed type
    Interface<Foo<Integer>> interfaceModel = `interface Foo`.interfaceApply<Foo<Integer>>(`Integer`);
    // This will print: ceylon.language::List<ceylon.language::Integer>
    for(satisfiedType in interfaceModel.satisfiedTypes){
        print(satisfiedType);
    }
}

Usage sample for member interfaces

For member interfaces it is a bit longer, because member interfaces need to be applied not only their type arguments but also the containing type, so you should use InterfaceDeclaration.memberInterfaceApply() and start by giving the containing closed type:

class Outer(){
    shared interface Inner<T> satisfies List<T> {
    }
}

void test(){
    // apply the containing closed type `Outer` to the member class declaration `Outer.Inner`
    MemberInterface<Outer,Outer.Inner<Integer>> memberInterfaceModel = `interface Outer.Inner`.memberInterfaceApply<Outer,Outer.Inner<Integer>>(`Outer`, `Integer`);
    // This will print: ceylon.language::List<ceylon.language::Integer>
    for(satisfiedType in memberInterfaceModel.satisfiedTypes){
        print(satisfiedType);
    }
}
Moduleshared Module

A module declaration from a module.ceylon compilation unit

NestableDeclarationshared NestableDeclaration

A declaration which can be contained in a Package or in another NestableDeclaration.

Functions, values, classes, interfaces and aliases are such declarations.

OpenClassOrInterfaceTypeshared OpenClassOrInterfaceType

An open class or interface, with open type arguments.

For example, List<T> is an open interface type, with a type argument which is the OpenTypeVariable T.

OpenClassTypeshared OpenClassType

An open class type.

OpenInterfaceTypeshared OpenInterfaceType

An open interface type.

OpenIntersectionshared OpenIntersection

An open intersection type.

OpenTypeshared OpenType

An open type.

An open type is a type which may contain unbound type variables, such as List<T>.

OpenTypeVariableshared OpenTypeVariable

An open type variable.

OpenUnionshared OpenUnion

An open union type.

Packageshared Package

Model of a package declaration from a package.ceylon compilation unit

SetterDeclarationshared SetterDeclaration

A setter declaration represents the assign block of a ValueDeclaration.

TypeParametershared TypeParameter

A type parameter declaration.

TypedDeclarationshared TypedDeclaration

Declaration which has an open type.

ValueConstructorDeclarationshared ValueConstructorDeclaration

Declaration model for value constructors, for example

class Currency {
    "The US Dollar"
    shared new usd {}
    // ...
}

ValueConstructorDeclaration dollars = `new Currency.usd`;
ValueDeclarationshared ValueDeclaration

A value declaration.

Usage sample for toplevel value

Getting a model requires applying type arguments to the value declaration with ValueDeclaration.apply() in order to be able to read that value. For example, here is how you would obtain a value model that you can read from a toplevel attribute declaration:

String foo = "Hello";

void test(){
    // We need to apply the the foo declaration in order to get the foo value model
    Value<String> valueModel = `value foo`.apply<String>();
    // This will print: Hello
    print(valueModel.get());
}

Usage sample for attributes

For attributes it is a bit longer, because attributes need to be applied the containing type, so you should use ValueDeclaration.memberApply() and start by giving the containing closed type:

class Outer(){
    shared String foo => "Hello";
}

void test(){
    // Apply the containing closed type `Outer` to the attribute declaration `Outer.foo`
    Attribute<Outer,String> valueModel = `value Outer.foo`.memberApply<Outer,String>(`Outer`);
    // We now have an Attribute, which needs to be applied to a containing instance in order to become a
    // readable value:
    Value<String> boundValueModel = valueModel(Outer());
    // This will print: Hello
    print(boundValueModel.get());
}
Varianceshared Variance

Variance information.

Classes
contravariantshared contravariant

Contravariant means that supertypes of the given type may be accepted.

covariantshared covariant

Covariant means that subtypes of the given type may be returned.

invariantshared invariant

Invariant means that neither subtype nor supertype can be accepted, the type has to be exactly that which is declared.

nothingTypeshared nothingType

The singleton open type for Nothing.