com.redhat.ceylon.compiler.java.codegen.CtorDelegation Maven / Gradle / Ivy
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