All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.ceylon.compiler.java.codegen.CtorDelegation Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
package com.redhat.ceylon.compiler.java.codegen;

import java.util.Map;

import com.redhat.ceylon.langtools.tools.javac.tree.JCTree.JCStatement;
import com.redhat.ceylon.model.typechecker.model.Class;
import com.redhat.ceylon.model.typechecker.model.Constructor;
import com.redhat.ceylon.model.typechecker.model.Declaration;
import com.redhat.ceylon.model.typechecker.model.FunctionOrValue;

public class CtorDelegation {
    
    private final Constructor ctor;
    private final Declaration extending;
    private String error;
    
    /**
     * 
     * @param ctor The constructor
     * @param extending The declaration of what the constructor extends 
     * (Class, Constructor from superclass, Constructor from this class)
     */
    public CtorDelegation(Constructor ctor, Declaration extending){
        this.ctor = ctor;
        if (extending instanceof FunctionOrValue) {
            this.extending = ((FunctionOrValue)extending).getTypeDeclaration();
        } else if (extending instanceof Class
                    && ((Class)extending).hasConstructors()) {
            this.extending = Decl.getDefaultConstructor(((Class)extending));
        } else {
            this.extending = extending;
        }
        if (!(extending instanceof Class || extending instanceof Constructor)) {
            throw new RuntimeException();
        }
    }
    
    private CtorDelegation(Constructor ctor, String errorMessage) {
        this.ctor = ctor;
        this.error = errorMessage;
        this.extending = null;
    }
    
    public static CtorDelegation brokenDelegation(Constructor ctorModel) {
        String message;
        if (ctorModel.getName() == null) {
            message = "constructor delegates to default constructor which has a compiler error";
        } else {
            message = "constructor delegates to constructor with a compiler error: " + ctorModel.getName();
        }
        return new CtorDelegation(ctorModel, message);
    }
    
    public boolean isError() {
        return this.error != null;
    }
    
    public JCStatement makeThrow(AbstractTransformer gen) {
        return gen.makeThrowUnresolvedCompilationError(this.error);
    }
    
    /**
     * The constructor
     * @return
     */
    public Constructor getConstructor() {
        return ctor;
    }
    
    /**
     * The declaration of what the constructor extends 
     * (Class, Constructor from superclass, Constructor from this class)
     * @return
     */
    public Declaration getExtending() {
        return extending;
    }
    /**
     * The extended Constructor if it is a Constructor. Will be null if extending a Class initializer
     */
    public Constructor getExtendingConstructor() {
        return extending instanceof Constructor ? (Constructor)extending : null;
    }
    /**
     * Is the constructor delegating to another constructor in the same class
     * @return
     */
    public boolean isSelfDelegation() {
        return ctor != null 
                && ((extending instanceof Constructor 
                && ctor.getContainer().equals(extending.getContainer()))
                || (extending instanceof Class
                && ctor.getContainer().equals(extending)));
    }
    /**
     * true if the constructor is extending a non-abstract constructor from the same class
     * @return
     */
    public boolean isConcreteSelfDelegation() {
        return isSelfDelegation() 
                && (extending instanceof Class 
                || !((Constructor)extending).isAbstract());
    }
    /**
     * true if the constructor is extends an abstract constructor from the same class
     * @return
     */
    public boolean isAbstractSelfDelegation() {
        return isSelfDelegation()
                && extending instanceof Constructor
                && ((Constructor)extending).isAbstract();
    }
    /**
     * true if this delegation is delegating to a superclass initializer or constructor,
     * or is delegating to an abstract constructor of the same class
     * @return
     */
    public boolean isAbstractSelfOrSuperDelegation() {
        return !isSelfDelegation() || 
                extending instanceof Constructor && ((Constructor)extending).isAbstract();
    }
    /**
     * Does any other constructor in the given map delegate to the given constructor? 
     */
    public static boolean isDelegatedTo(Map allDelegations, Constructor ctor) {
        for (CtorDelegation d : allDelegations.values()) {
            if (ctor.equals(d.getExtending())) {
                return true;
            }
        }
        return false;
    }
    
    public String toString() {
        return ctor + " extends " + extending;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy