Package com.redhat.ceylon.compiler.java.runtime.metamodel

Source Code of com.redhat.ceylon.compiler.java.runtime.metamodel.FreeClass

package com.redhat.ceylon.compiler.java.runtime.metamodel;

import java.util.List;

import ceylon.language.Anything;
import ceylon.language.Iterator;
import ceylon.language.Sequential;
import ceylon.language.empty_;
import ceylon.language.finished_;
import ceylon.language.meta.declaration.ClassDeclaration$impl;
import ceylon.language.meta.declaration.FunctionOrValueDeclaration;
import ceylon.language.meta.declaration.ValueDeclaration;

import com.redhat.ceylon.compiler.java.Util;
import com.redhat.ceylon.compiler.java.metadata.Ceylon;
import com.redhat.ceylon.compiler.java.metadata.Defaulted;
import com.redhat.ceylon.compiler.java.metadata.Ignore;
import com.redhat.ceylon.compiler.java.metadata.Name;
import com.redhat.ceylon.compiler.java.metadata.Sequenced;
import com.redhat.ceylon.compiler.java.metadata.TypeInfo;
import com.redhat.ceylon.compiler.java.metadata.TypeParameter;
import com.redhat.ceylon.compiler.java.metadata.TypeParameters;
import com.redhat.ceylon.compiler.java.metadata.Variance;
import com.redhat.ceylon.compiler.java.runtime.model.TypeDescriptor;
import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Parameter;
import com.redhat.ceylon.compiler.typechecker.model.ParameterList;
import com.redhat.ceylon.compiler.typechecker.model.ProducedType;

@Ceylon(major = 7)
@com.redhat.ceylon.compiler.java.metadata.Class
public class FreeClass
    extends FreeClassOrInterface
    implements ceylon.language.meta.declaration.ClassDeclaration {

    @Ignore
    public static final TypeDescriptor $TypeDescriptor$ = TypeDescriptor.klass(FreeClass.class);
    private Sequential<? extends ceylon.language.meta.declaration.FunctionOrValueDeclaration> parameters;
   
    public FreeClass(com.redhat.ceylon.compiler.typechecker.model.Class declaration) {
        super(declaration);
    }
   
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    protected void init() {
        super.init();
        // anonymous classes don't have parameter lists
        if(!declaration.isAnonymous()){
            com.redhat.ceylon.compiler.typechecker.model.Class classDeclaration = (com.redhat.ceylon.compiler.typechecker.model.Class)declaration;
            if(classDeclaration.isAbstraction()){
                List<Declaration> overloads = classDeclaration.getOverloads();
                if(overloads.size() == 1){
                    classDeclaration = (com.redhat.ceylon.compiler.typechecker.model.Class) overloads.get(0);
                }else{
                    throw Metamodel.newModelError("Class has more than one overloaded constructor");
                }
            }
            ParameterList parameterList = classDeclaration.getParameterList();
            List<Parameter> modelParameters = parameterList.getParameters();
            ceylon.language.meta.declaration.FunctionOrValueDeclaration[] parameters = new ceylon.language.meta.declaration.FunctionOrValueDeclaration[modelParameters.size()];
            int i=0;
            for(Parameter modelParameter : modelParameters){
                parameters[i] = (ceylon.language.meta.declaration.FunctionOrValueDeclaration) Metamodel.getOrCreateMetamodel(modelParameter.getModel());
                i++;
            }
            this.parameters = Util.sequentialWrapper(ceylon.language.meta.declaration.FunctionOrValueDeclaration.$TypeDescriptor$, parameters);
        }else{
            this.parameters = (Sequential<? extends FunctionOrValueDeclaration>) (Sequential)empty_.get_();
        }
    }
   
    @Override
    @Ignore
    public ClassDeclaration$impl $ceylon$language$meta$declaration$ClassDeclaration$impl() {
        return null;
    }

    @Override
    public boolean getAnonymous(){
        return declaration.isAnonymous();
    }

    @TypeInfo("ceylon.language.meta.declaration::ValueDeclaration|ceylon.language::Null")
    @Override
    public ceylon.language.meta.declaration.ValueDeclaration getObjectValue(){
        if(getAnonymous()){
            Object container = getContainer();
            if(container instanceof ceylon.language.meta.declaration.ClassOrInterfaceDeclaration){
                return ((ceylon.language.meta.declaration.ClassOrInterfaceDeclaration) container).getDeclaredMemberDeclaration(ValueDeclaration.$TypeDescriptor$, getName());
            }else if(container instanceof ceylon.language.meta.declaration.Package){
                return ((ceylon.language.meta.declaration.Package) container).getMember(ValueDeclaration.$TypeDescriptor$, getName());
            }
            // don't know how to find the object value decl
        }
        return null;
    }

   
    @Override
    public boolean getAnnotation(){
        return declaration.isAnnotation();
    }

    @Override
    public boolean getAbstract() {
        return ((com.redhat.ceylon.compiler.typechecker.model.Class)declaration).isAbstract();
    }

    @Override
    public boolean getFinal() {
        return ((com.redhat.ceylon.compiler.typechecker.model.Class)declaration).isFinal();
    }

    @Override
    @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.declaration::FunctionOrValueDeclaration>")
    public Sequential<? extends ceylon.language.meta.declaration.FunctionOrValueDeclaration> getParameterDeclarations(){
        checkInit();
        return parameters;
    }

    @Override
    @TypeInfo("ceylon.language.meta.declaration::FunctionOrValueDeclaration|ceylon.language::Null")
    public ceylon.language.meta.declaration.FunctionOrValueDeclaration getParameterDeclaration(@Name("name") String name){
        checkInit();
        Iterator<?> iterator = parameters.iterator();
        Object o;
        while((o = iterator.next()) != finished_.get_()){
            ceylon.language.meta.declaration.FunctionOrValueDeclaration pd = (ceylon.language.meta.declaration.FunctionOrValueDeclaration) o;
            if(pd.getName().equals(name))
                return pd;
        }
        return null;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public <Type, Arguments extends Sequential<? extends Object>> ceylon.language.meta.model.Class<Type, Arguments> classApply(TypeDescriptor $reifiedType,
            TypeDescriptor $reifiedArguments){
        return classApply($reifiedType, $reifiedArguments, (Sequential)empty_.get_());
    }

    @SuppressWarnings("unchecked")
    @Override
    @TypeInfo("ceylon.language.meta.model::Class<Type,Arguments>")
    @TypeParameters({
        @TypeParameter("Type"),
        @TypeParameter(value = "Arguments", satisfies = "ceylon.language::Sequential<ceylon.language::Anything>")
    })
    public <Type, Arguments extends Sequential<? extends Object>> ceylon.language.meta.model.Class<Type, Arguments> classApply(@Ignore TypeDescriptor $reifiedType,
            @Ignore TypeDescriptor $reifiedArguments,
            @Name("typeArguments") @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.model::Type<ceylon.language::Anything>>") @Sequenced Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        if(!getToplevel())
            throw new ceylon.language.meta.model.TypeApplicationException("Cannot apply a member declaration with no container type: use memberApply");
        List<com.redhat.ceylon.compiler.typechecker.model.ProducedType> producedTypes = Metamodel.getProducedTypes(typeArguments);
        Metamodel.checkTypeArguments(null, declaration, producedTypes);
        com.redhat.ceylon.compiler.typechecker.model.ProducedReference appliedType = declaration.getProducedReference(null, producedTypes);
        AppliedClass<Type, Arguments> ret = (AppliedClass<Type, Arguments>) Metamodel.getAppliedMetamodel(appliedType.getType());;
        Metamodel.checkReifiedTypeArgument("classApply", "Class<$1,$2>", Variance.OUT, appliedType.getType(), $reifiedType,
                Variance.IN, Metamodel.getProducedType(ret.$reifiedArguments), $reifiedArguments);
        return ret;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Ignore
    @Override
    public <Container, Type, Arguments extends Sequential<? extends Object>>
        ceylon.language.meta.model.MemberClass<Container, Type, Arguments> memberClassApply(TypeDescriptor $reifiedContainer,
                                                                                       TypeDescriptor $reifiedType,
                                                                                       TypeDescriptor $reifiedArguments,
                                                                                       ceylon.language.meta.model.Type<? extends Container> containerType){
       
        return this.<Container, Type, Arguments>memberClassApply($reifiedContainer,
                                                 $reifiedType,
                                                 $reifiedArguments,
                                                 containerType,
                                                 (Sequential)empty_.get_());
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @TypeInfo("ceylon.language.meta.model::MemberClass<Container,Type,Arguments>")
    @TypeParameters({
        @TypeParameter("Container"),
        @TypeParameter("Type"),
        @TypeParameter(value = "Arguments", satisfies = "ceylon.language::Sequential<ceylon.language::Anything>")
    })
    @Override
    public <Container, Type, Arguments extends Sequential<? extends Object>>
    ceylon.language.meta.model.MemberClass<Container, Type, Arguments> memberClassApply(
                @Ignore TypeDescriptor $reifiedContainer,
                @Ignore TypeDescriptor $reifiedType,
                @Ignore TypeDescriptor $reifiedArguments,
                @Name("containerType") ceylon.language.meta.model.Type<? extends Container> containerType,
                @Name("typeArguments") @Sequenced Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        if(getToplevel())
            throw new ceylon.language.meta.model.TypeApplicationException("Cannot apply a toplevel declaration to a container type: use apply");

        ceylon.language.meta.model.MemberClass<Container, Type, Arguments> member
            = (ceylon.language.meta.model.MemberClass)
                getAppliedClassOrInterface(null, null, typeArguments, containerType);
       
        // This is all very ugly but we're trying to make it cheaper and friendlier than just checking the full type and showing
        // implementation types to the user, such as AppliedMemberClass
        TypeDescriptor actualReifiedContainer = ((AppliedMemberClass)member).$reifiedContainer;
        TypeDescriptor actualReifiedArguments = ((AppliedMemberClass)member).$reifiedArguments;
        ProducedType actualType = Metamodel.getModel((ceylon.language.meta.model.Type<?>) member);
        Metamodel.checkReifiedTypeArgument("memberApply", "Member<$1,Class<$2,$3>>&Class<$2,$3>",
                Variance.IN, Metamodel.getProducedType(actualReifiedContainer), $reifiedContainer,
                Variance.OUT, actualType, $reifiedType,
                Variance.IN, Metamodel.getProducedType(actualReifiedArguments), $reifiedArguments);
        return member;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> instantiate$typeArguments(){
        return (ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public java.lang.Object instantiate(){
        return instantiate((ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_());
    }

    @Ignore
    @Override
    public java.lang.Object instantiate(
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        return instantiate(typeArguments, empty_.get_());
    }

    @TypeInfo("ceylon.language::Anything")
    @Override
    public java.lang.Object instantiate(
            @Name("typeArguments") @Defaulted
            @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.model::Type<ceylon.language::Anything>>")
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments,
            @Name("arguments") @Sequenced @TypeInfo("ceylon.language::Sequential<ceylon.language::Anything>")
            ceylon.language.Sequential<?> arguments){
        return classApply(Anything.$TypeDescriptor$, TypeDescriptor.NothingType, typeArguments).apply(arguments);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>
        memberInstantiate$typeArguments(java.lang.Object container){
        return (ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public java.lang.Object memberInstantiate(java.lang.Object container){
        return memberInstantiate(container, (ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_());
    }

    @Ignore
    @Override
    public java.lang.Object memberInstantiate(
            java.lang.Object container,
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        return memberInstantiate(container, typeArguments, empty_.get_());
    }

    @SuppressWarnings("unchecked")
    @TypeInfo("ceylon.language::Anything")
    @Override
    public java.lang.Object memberInstantiate(
            @Name("container") @TypeInfo("ceylon.language::Anything")
            java.lang.Object container,
            @Name("typeArguments") @Defaulted
            @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.model::Type<ceylon.language::Anything>>")
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments,
            @Name("arguments") @Sequenced @TypeInfo("ceylon.language::Sequential<ceylon.language::Anything>")
            ceylon.language.Sequential<?> arguments){
        ceylon.language.meta.model.Type<?> containerType = Metamodel.getAppliedMetamodel(Metamodel.getTypeDescriptor(container));
        return memberClassApply(TypeDescriptor.NothingType, Anything.$TypeDescriptor$, TypeDescriptor.NothingType,
                containerType, typeArguments).bind(container).apply(arguments);
    }

    @Override
    public int hashCode() {
        return Metamodel.hashCode(this, "class");
    }
   
    @Override
    public boolean equals(Object obj) {
        if(obj == null)
            return false;
        if(obj == this)
            return true;
        if(obj instanceof FreeClass == false)
            return false;
        return Metamodel.equalsForSameType(this, (FreeClass)obj);
    }

    @Override
    public String toString() {
        return "class "+super.toString();
    }
   
    @Override
    @Ignore
    public TypeDescriptor $getType$() {
        return $TypeDescriptor$;
    }
}
TOP

Related Classes of com.redhat.ceylon.compiler.java.runtime.metamodel.FreeClass

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.