use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class AbstractTransformer method makeTypeParameter.
JCTypeParameter makeTypeParameter(TypeParameter declarationModel, java.util.List<Type> satisfiedTypesForBounds) {
TypeParameter typeParameterForBounds = declarationModel;
if (satisfiedTypesForBounds == null) {
satisfiedTypesForBounds = declarationModel.getSatisfiedTypes();
}
// special case for method refinenement where Java doesn't let us refine the parameter bounds
if (declarationModel.getContainer() instanceof Function) {
Function method = (Function) declarationModel.getContainer();
Function refinedMethod = (Function) method.getRefinedDeclaration();
if (!Decl.equal(method, refinedMethod)) {
// find the param index
int index = method.getTypeParameters().indexOf(declarationModel);
if (index == -1) {
log.error("Failed to find type parameter index: " + declarationModel.getName());
} else if (refinedMethod.getTypeParameters().size() > index) {
// ignore smaller index than size since the typechecker would have found the error
TypeParameter refinedTP = refinedMethod.getTypeParameters().get(index);
if (!haveSameBounds(declarationModel, refinedTP)) {
// find the right instantiation of that type parameter
TypeDeclaration methodContainer = (TypeDeclaration) method.getContainer();
TypeDeclaration refinedMethodContainer = (TypeDeclaration) refinedMethod.getContainer();
// find the supertype that gave us that method and its type arguments
Type supertype = methodContainer.getType().getSupertype(refinedMethodContainer);
satisfiedTypesForBounds = new ArrayList<Type>(refinedTP.getSatisfiedTypes().size());
for (Type satisfiedType : refinedTP.getSatisfiedTypes()) {
// substitute the refined type parameter bounds with the right type arguments
satisfiedTypesForBounds.add(satisfiedType.substitute(supertype));
}
typeParameterForBounds = refinedTP;
}
}
}
}
return makeTypeParameter(declarationModel.getName(), satisfiedTypesForBounds, typeParameterForBounds.isCovariant(), typeParameterForBounds.isContravariant());
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class AbstractTransformer method makeJavaType.
/**
* This function is used solely for method return types and parameters
*/
JCExpression makeJavaType(TypedDeclaration typeDecl, Type type, int flags) {
if (typeDecl instanceof Function && typeDecl.isParameter()) {
Function p = (Function) typeDecl;
Type pt = type;
for (int ii = 1; ii < p.getParameterLists().size(); ii++) {
pt = typeFact().getCallableType(pt);
}
return makeJavaType(typeFact().getCallableType(pt), flags);
} else {
boolean usePrimitives = CodegenUtil.isUnBoxed(typeDecl);
return makeJavaType(getPinnedType(typeDecl.getTypedReference(), type), flags | (usePrimitives ? 0 : AbstractTransformer.JT_NO_PRIMITIVES));
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class AbstractTransformer method getTypedReference.
TypedReference getTypedReference(TypedDeclaration decl) {
java.util.List<Type> typeArgs = Collections.<Type>emptyList();
if (decl instanceof Function) {
// For methods create type arguments for any type parameters it might have
Function m = (Function) decl;
if (!m.getTypeParameters().isEmpty()) {
typeArgs = new ArrayList<Type>(m.getTypeParameters().size());
for (TypeParameter p : m.getTypeParameters()) {
Type pt = p.getType();
typeArgs.add(pt);
}
}
}
if (decl.getContainer() instanceof TypeDeclaration) {
TypeDeclaration containerDecl = (TypeDeclaration) decl.getContainer();
return containerDecl.getType().getTypedMember(decl, typeArgs);
}
return decl.appliedTypedReference(null, typeArgs);
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class AbstractTransformer method supportsReified.
public static boolean supportsReified(Declaration declaration) {
if (declaration instanceof ClassOrInterface) {
// Java constructors don't support reified type arguments
return ModelUtil.isCeylonDeclaration((TypeDeclaration) declaration);
} else if (Decl.isConstructor(declaration)) {
// Java constructors don't support reified type arguments
return ModelUtil.isCeylonDeclaration(ModelUtil.getConstructor(declaration));
} else if (declaration instanceof Function) {
if (((Function) declaration).isParameter()) {
// those can never be parameterised
return false;
}
if (declaration.isToplevel())
return true;
// Java methods don't support reified type arguments
Function m = (Function) CodegenUtil.getTopmostRefinedDeclaration(declaration);
// See what its container is
ClassOrInterface container = ModelUtil.getClassOrInterfaceContainer(m);
// that must be Ceylon so it supports it
if (container == null)
return true;
return supportsReified(container);
} else {
throw BugException.unhandledDeclarationCase(declaration);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class AbstractTransformer method collectQualifyingTypeArguments.
/**
* Collects all the type parameters and arguments required for an interface that's been pulled up to the
* toplevel, including its containing type and method type parameters.
*/
private void collectQualifyingTypeArguments(java.util.List<TypeParameter> qualifyingTypeParameters, Map<TypeParameter, Type> qualifyingTypeArguments, java.util.List<Reference> qualifyingTypes) {
// make sure we only add type parameters with the same name once, as duplicates are erased from the target interface
// since they cannot be accessed
Set<String> names = new HashSet<String>();
// walk the qualifying types backwards to make sure we only add a TP with the same name once and the outer one wins
for (int i = qualifyingTypes.size() - 1; i >= 0; i--) {
Reference qualifiedType = qualifyingTypes.get(i);
Map<TypeParameter, Type> tas = qualifiedType.getTypeArguments();
java.util.List<TypeParameter> tps = qualifiedType.getDeclaration().getTypeParameters();
// add any type params for this type
if (tps != null) {
int index = 0;
for (TypeParameter tp : tps) {
// add it only once
if (names.add(tp.getName())) {
// start putting all these type parameters at 0 and then in order
// so that outer type params end up before inner type params but
// order is preserved within each type
qualifyingTypeParameters.add(index++, tp);
qualifyingTypeArguments.put(tp, tas.get(tp));
}
}
}
// add any container method TP
Declaration declaration = qualifiedType.getDeclaration();
if (Decl.isLocal(declaration)) {
Scope scope = declaration.getContainer();
// collect every container method until the next type or package
java.util.List<Function> methods = new LinkedList<Function>();
while (scope != null && scope instanceof ClassOrInterface == false && scope instanceof Package == false) {
if (scope instanceof Function) {
methods.add((Function) scope);
}
scope = scope.getContainer();
}
// methods are sorted inner to outer, which is the order we're following here for types
for (Function method : methods) {
java.util.List<TypeParameter> methodTypeParameters = method.getTypeParameters();
if (methodTypeParameters != null) {
int index = 0;
for (TypeParameter tp : methodTypeParameters) {
// add it only once
if (names.add(tp.getName())) {
// start putting all these type parameters at 0 and then in order
// so that outer type params end up before inner type params but
// order is preserved within each type
qualifyingTypeParameters.add(index++, tp);
qualifyingTypeArguments.put(tp, tp.getType());
}
}
}
}
}
}
}
Aggregations