use of org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType in project ceylon by eclipse.
the class CeylonModelLoader method getFunctionalInterfaceType.
@Override
protected FunctionalInterfaceType getFunctionalInterfaceType(TypeMirror typeMirror) throws ModelResolutionException {
if (typeMirror.getKind() != TypeKind.DECLARED)
throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror);
// FIXME: possibly apply other optimisations to lighten the lookup cost? see what javac does
Type type = ((JavacType) typeMirror).type;
try {
Type descriptorType = types.findDescriptorType(type);
// Let's be honest I've no idea what this means, but it happens and Javac seems to refuse it too
if (descriptorType.hasTag(TypeTag.FORALL))
throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror);
MethodType methodDescriptorType = (MethodType) descriptorType;
MethodSymbol methodSymbol = (MethodSymbol) types.findDescriptorSymbol(type.tsym);
List<Type> parameterTypes = methodDescriptorType.getParameterTypes();
ListBuffer<TypeMirror> mirrorParameterTypes = new ListBuffer<>();
for (int i = 0; i < parameterTypes.size(); i++) {
Type parameterType = parameterTypes.get(i);
if (methodSymbol.isVarArgs() && i == parameterTypes.size() - 1)
parameterType = ((ArrayType) parameterType).getComponentType();
mirrorParameterTypes.add(new JavacType(parameterType));
}
return new FunctionalInterfaceType(new JavacMethod(new JavacClass(methodSymbol.enclClass()), methodSymbol), new JavacType(methodDescriptorType.getReturnType()), mirrorParameterTypes.toList(), methodSymbol.isVarArgs());
} catch (Symbol.CompletionFailure err) {
// bad luck
throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror, err);
} catch (FunctionDescriptorLookupError err) {
throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror, err);
}
}
use of org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType in project ceylon by eclipse.
the class AbstractModelLoader method loadFunctionCoercionParameter.
@SuppressWarnings("incomplete-switch")
private Function loadFunctionCoercionParameter(Declaration decl, String paramName, TypeMirror typeMirror, Module moduleScope, Scope scope) {
Function method = new Function();
method.setName(paramName);
method.setUnit(decl.getUnit());
try {
FunctionalInterfaceType functionalInterfaceType = getFunctionalInterfaceType(typeMirror);
MethodMirror functionalMethod = functionalInterfaceType.getMethod();
Type returnType = obtainType(moduleScope, functionalInterfaceType.getReturnType(), scope, TypeLocation.TOPLEVEL);
switch(getUncheckedNullPolicy(false, functionalInterfaceType.getReturnType(), functionalMethod)) {
case Optional:
case UncheckedNull:
returnType = makeOptionalTypePreserveUnderlyingType(returnType, moduleScope);
break;
}
method.setType(returnType);
ParameterList pl = new ParameterList();
// List<VariableMirror> functionalParameters = functionalMethod.getParameters();
List<TypeMirror> parameterTypes = functionalInterfaceType.getParameterTypes();
Map<String, Integer> used = new HashMap<String, Integer>();
for (TypeMirror parameterType : parameterTypes) {
String name;
if (parameterTypes.size() == 1) {
name = "it";
} else {
switch(parameterType.getKind()) {
case ARRAY:
name = "array";
break;
case BOOLEAN:
name = "boolean";
break;
case CHAR:
name = "character";
break;
case BYTE:
name = "byte";
break;
case INT:
case LONG:
case SHORT:
name = "integer";
break;
case FLOAT:
case DOUBLE:
name = "float";
break;
case DECLARED:
String typeName = parameterType.getDeclaredClass().getName();
int first = typeName.codePointAt(0);
name = String.valueOf(Character.toChars(Character.toLowerCase(first))) + typeName.substring(Character.charCount(first));
break;
default:
name = "arg";
}
Integer count = used.get(name);
if (count == null) {
used.put(name, 1);
} else {
int next = count + 1;
used.put(name, next);
name += next;
}
}
Type modelParameterType = obtainType(moduleScope, parameterType, scope, TypeLocation.TOPLEVEL);
Parameter p = new Parameter();
Value v = new Value();
p.setName(name);
v.setName(name);
v.setContainer(method);
v.setScope(method);
p.setModel(v);
v.setInitializerParameter(p);
// Java parameters are all optional unless primitives or annotated as such
switch(getUncheckedNullPolicy(false, parameterType, functionalMethod)) {
case Optional:
modelParameterType = makeOptionalTypePreserveUnderlyingType(modelParameterType, moduleScope);
break;
case UncheckedNull:
v.setUncheckedNullType(true);
break;
}
v.setType(modelParameterType);
pl.getParameters().add(p);
method.addMember(v);
}
method.addParameterList(pl);
} catch (ModelResolutionException x) {
method.setType(logModelResolutionException(x, scope, "Failure to turn functional interface to Callable type"));
}
return method;
}
use of org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType in project ceylon by eclipse.
the class AbstractModelLoader method getFunctionalInterfaceAsCallable.
private Type getFunctionalInterfaceAsCallable(Module moduleScope, Scope scope, TypeMirror typeMirror) {
try {
FunctionalInterfaceType functionalInterfaceType = getFunctionalInterfaceType(typeMirror);
Type returnType = obtainType(moduleScope, functionalInterfaceType.getReturnType(), scope, TypeLocation.TOPLEVEL);
java.util.List<Type> modelParameterTypes = new ArrayList<Type>(functionalInterfaceType.getParameterTypes().size());
for (TypeMirror parameterType : functionalInterfaceType.getParameterTypes()) {
Type modelParameterType = obtainType(moduleScope, parameterType, scope, TypeLocation.TOPLEVEL);
modelParameterTypes.add(modelParameterType);
}
org.eclipse.ceylon.model.typechecker.model.Type parameterTuple = typeFactory.getTupleType(modelParameterTypes, functionalInterfaceType.isVariadic(), false, -1);
org.eclipse.ceylon.model.typechecker.model.Type callableType = typeFactory.getCallableDeclaration().appliedType(null, Arrays.asList(returnType, parameterTuple));
return callableType;
} catch (ModelResolutionException x) {
return logModelResolutionException(x, scope, "Failure to turn functional interface to Callable type");
}
}
Aggregations