use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class AbstractTransformer method nonWideningTypeDecl.
TypedReference nonWideningTypeDecl(TypedReference typedReference, Type currentType) {
TypedReference refinedTypedReference = getRefinedDeclaration(typedReference, currentType);
if (refinedTypedReference != null) {
/*
* We are widening if the type:
* - is not object
* - is erased to object
* - refines a declaration that is not erased to object
*/
Type declType = typedReference.getType();
Type refinedDeclType = refinedTypedReference.getType();
if (declType == null || refinedDeclType == null)
return typedReference;
boolean isWidening = isWidening(declType, refinedDeclType);
if (!isWidening) {
// make sure we get the instantiated refined decl
if (refinedDeclType.getDeclaration() instanceof TypeParameter && !(declType.getDeclaration() instanceof TypeParameter))
refinedDeclType = nonWideningType(typedReference, refinedTypedReference);
if (!typedReference.getTypeArguments().containsKey(simplifyType(refinedDeclType).getDeclaration())) {
isWidening = isWideningTypeArguments(declType, refinedDeclType, true);
}
}
if (isWidening)
return refinedTypedReference;
}
return typedReference;
}
use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class AbstractTransformer method getTypedSignature.
private java.util.List<Type> getTypedSignature(Type currentType, TypedDeclaration found) {
// check that its signature is compatible
java.util.List<ParameterList> parameterLists = ((Function) found).getParameterLists();
if (parameterLists == null || parameterLists.isEmpty())
return null;
// only consider first param list
java.util.List<Parameter> parameters = parameterLists.get(0).getParameters();
if (parameters == null)
return null;
TypedReference typedMember = currentType.getTypedMember(found, Collections.<Type>emptyList());
if (typedMember == null)
return null;
java.util.List<Type> typedSignature = new ArrayList<Type>(parameters.size());
for (Parameter p : parameters) {
Type parameterType = typedMember.getTypedParameter(p).getFullType();
typedSignature.add(parameterType);
}
return typedSignature;
}
use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class AbstractTransformer method nonWideningType.
Type nonWideningType(TypedReference declaration, TypedReference refinedDeclaration) {
final Reference pr;
if (declaration.equals(refinedDeclaration)) {
pr = declaration;
} else {
Type refinedType = refinedDeclaration.getType();
// since it may have changed name
if (refinedType.getDeclaration() instanceof TypeParameter && refinedType.getDeclaration().getContainer() instanceof Function) {
// find its index in the refined declaration
TypeParameter refinedTypeParameter = (TypeParameter) refinedType.getDeclaration();
Function refinedMethod = (Function) refinedTypeParameter.getContainer();
int i = 0;
for (TypeParameter tp : refinedMethod.getTypeParameters()) {
if (tp.getName().equals(refinedTypeParameter.getName()))
break;
i++;
}
if (i >= refinedMethod.getTypeParameters().size()) {
throw new BugException("can't find type parameter " + refinedTypeParameter.getName() + " in its container " + refinedMethod.getName());
}
// the refining method type parameter should be at the same index
if (declaration.getDeclaration() instanceof Function == false)
throw new BugException("refining declaration is not a method: " + declaration);
Function refiningMethod = (Function) declaration.getDeclaration();
if (i >= refiningMethod.getTypeParameters().size()) {
throw new BugException("refining method does not have enough type parameters to refine " + refinedMethod.getName());
}
pr = refiningMethod.getTypeParameters().get(i).getType();
} else {
pr = refinedType;
}
}
if (pr.getDeclaration() instanceof Functional && Decl.isMpl((Functional) pr.getDeclaration())) {
// the innermost Callable.
return getReturnTypeOfCallable(pr.getFullType());
}
return pr.getType();
}
use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class AbstractTransformer method isWideningTypeDecl.
public boolean isWideningTypeDecl(TypedReference typedReference, Type currentType) {
TypedReference refinedTypedReference = getRefinedDeclaration(typedReference, currentType);
if (refinedTypedReference == null)
return false;
/*
* We are widening if the type:
* - is not object
* - is erased to object
* - refines a declaration that is not erased to object
*/
Type declType = typedReference.getType();
Type refinedDeclType = refinedTypedReference.getType();
if (declType == null || refinedDeclType == null)
return false;
if (isWidening(declType, refinedDeclType))
return true;
// make sure we get the instantiated refined decl
if (refinedDeclType.getDeclaration() instanceof TypeParameter && !(declType.getDeclaration() instanceof TypeParameter))
refinedDeclType = nonWideningType(typedReference, refinedTypedReference);
if (isWideningTypeArguments(declType, refinedDeclType, true))
return true;
if (CodegenUtil.hasTypeErased(refinedTypedReference.getDeclaration()) && !willEraseToObject(declType))
return true;
return false;
}
use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class ClassTransformer method refineMethod.
private Function refineMethod(Scope container, TypedReference pr, ClassOrInterface classModel, Function formalMethod, Unit unit) {
Function refined = new Function();
refined.setActual(true);
refined.setShared(formalMethod.isShared());
refined.setContainer(container);
// in case there are subclasses
refined.setDefault(true);
refined.setDeferred(false);
refined.setDeprecated(formalMethod.isDeprecated());
refined.setName(formalMethod.getName());
refined.setRefinedDeclaration(formalMethod.getRefinedDeclaration());
refined.setScope(container);
refined.setType(pr.getType());
refined.setUnit(unit);
refined.setUnboxed(formalMethod.getUnboxed());
refined.setUntrustedType(formalMethod.getUntrustedType());
refined.setTypeErased(formalMethod.getTypeErased());
ArrayList<TypeParameter> refinedTp = new ArrayList<TypeParameter>();
;
for (TypeParameter formalTp : formalMethod.getTypeParameters()) {
refinedTp.add(formalTp);
}
refined.setTypeParameters(refinedTp);
for (ParameterList formalPl : formalMethod.getParameterLists()) {
ParameterList refinedPl = new ParameterList();
for (Parameter formalP : formalPl.getParameters()) {
Parameter refinedP = new Parameter();
refinedP.setAtLeastOne(formalP.isAtLeastOne());
refinedP.setDeclaration(refined);
refinedP.setDefaulted(formalP.isDefaulted());
refinedP.setDeclaredAnything(formalP.isDeclaredAnything());
refinedP.setHidden(formalP.isHidden());
refinedP.setSequenced(formalP.isSequenced());
refinedP.setName(formalP.getName());
final TypedReference typedParameter = pr.getTypedParameter(formalP);
FunctionOrValue paramModel;
if (formalP.getModel() instanceof Value) {
Value paramValueModel = refineValue((Value) formalP.getModel(), typedParameter, refined, classModel.getUnit());
paramValueModel.setInitializerParameter(refinedP);
paramModel = paramValueModel;
} else {
Function paramFunctionModel = refineMethod(refined, typedParameter, classModel, (Function) formalP.getModel(), unit);
paramFunctionModel.setInitializerParameter(refinedP);
paramModel = paramFunctionModel;
}
refinedP.setModel(paramModel);
refinedPl.getParameters().add(refinedP);
}
refined.addParameterList(refinedPl);
}
return refined;
}
Aggregations