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
Values
contravariantSource Code
shared contravariant contravariant

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

covariantSource Code
shared covariant covariant

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

invariantSource Code
shared invariant invariant

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

nothingTypeSource Code
shared nothingType nothingType

The singleton open type for Nothing.

Interfaces
AliasDeclarationSource Code

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.

AnnotatedDeclarationSource Code

Declaration which can be annotated, such as:

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

ClassDeclarationSource Code

Class declaration.

Usage sample for toplevel classes

Because some classes have type parameters, getting a model requires applying type arguments to the class declaration with 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 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());
}
ClassOrInterfaceDeclarationSource Code

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 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 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 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 memberApply in ClassDeclaration.memberClassApply and InterfaceDeclaration.memberInterfaceApply.

DeclarationSource Code

A declaration.

There are only two types of declarations:

FunctionDeclarationSource Code

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 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 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());
}
FunctionOrValueDeclarationSource Code

A function or value declaration.

FunctionalDeclarationSource Code

Declaration which can be invoked, and may have parameters. Classes and functions are functional declarations.

Note that multiple-parameter lists are not reified at runtime, so if you have a function declaration like this:

Integer add(Integer a)(Integer b) => a + b;

It will only have a single parameter list at runtime (the first), and its return type will be Callable<Integer,[Integer]>.

GenericDeclarationSource Code

A declaration that can have type parameters.

ImportSource Code
shared Import

Model of an import declaration within a module declaration.

InterfaceDeclarationSource Code

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 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 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);
    }
}
ModuleSource Code
shared Module

A module declaration from a module.ceylon compilation unit

NestableDeclarationSource Code

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

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

OpenClassOrInterfaceTypeSource Code

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.

OpenClassTypeSource Code

An open class type.

OpenInterfaceTypeSource Code

An open interface type.

OpenIntersectionSource Code

An open intersection type.

OpenTypeSource Code
shared OpenType

An open type.

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

OpenTypeVariableSource Code

An open type variable.

OpenUnionSource Code
shared OpenUnion

An open union type.

PackageSource Code
shared Package

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

SetterDeclarationSource Code

A setter declaration for a variable ValueDeclaration.

TypeParameterSource Code

A type parameter declaration.

TypedDeclarationSource Code

Declaration which has an open type.

ValueDeclarationSource Code

A value declaration.

Usage sample for toplevel value

Getting a model requires applying type arguments to the value declaration with 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 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());
}
VarianceSource Code
shared Variance

Variance information.

Classes
contravariantSource Code

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

covariantSource Code
shared covariant

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

invariantSource Code
shared invariant

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

nothingTypeSource Code

The singleton open type for Nothing.