use of org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType in project ceylon by eclipse.
the class LambdaToMethod method makeMetafactoryIndyCall.
/**
* Generate an indy method call to the meta factory
*/
private JCExpression makeMetafactoryIndyCall(LambdaAnalyzerPreprocessor.TranslationContext<?> context, int refKind, Symbol refSym, List<JCExpression> indy_args) {
JCFunctionalExpression tree = context.tree;
// determine the static bsm args
MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
List<Object> staticArgs = List.<Object>of(typeToMethodType(samSym.type), new Pool.MethodHandle(refKind, refSym, types), typeToMethodType(tree.getDescriptorType(types)));
// computed indy arg types
ListBuffer<Type> indy_args_types = new ListBuffer<>();
for (JCExpression arg : indy_args) {
indy_args_types.append(arg.type);
}
// finally, compute the type of the indy call
MethodType indyType = new MethodType(indy_args_types.toList(), tree.type, List.<Type>nil(), syms.methodClass);
Name metafactoryName = context.needsAltMetafactory() ? names.altMetafactory : names.metafactory;
if (context.needsAltMetafactory()) {
ListBuffer<Object> markers = new ListBuffer<>();
for (Type t : tree.targets.tail) {
if (t.tsym != syms.serializableType.tsym) {
markers.append(t.tsym);
}
}
int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0;
boolean hasMarkers = markers.nonEmpty();
boolean hasBridges = context.bridges.nonEmpty();
if (hasMarkers) {
flags |= FLAG_MARKERS;
}
if (hasBridges) {
flags |= FLAG_BRIDGES;
}
staticArgs = staticArgs.append(flags);
if (hasMarkers) {
staticArgs = staticArgs.append(markers.length());
staticArgs = staticArgs.appendList(markers.toList());
}
if (hasBridges) {
staticArgs = staticArgs.append(context.bridges.length() - 1);
for (Symbol s : context.bridges) {
Type s_erasure = s.erasure(types);
if (!types.isSameType(s_erasure, samSym.erasure(types))) {
staticArgs = staticArgs.append(s.erasure(types));
}
}
}
if (context.isSerializable()) {
int prevPos = make.pos;
try {
make.at(kInfo.clazz);
addDeserializationCase(refKind, refSym, tree.type, samSym, tree, staticArgs, indyType);
} finally {
make.at(prevPos);
}
}
}
return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args, samSym.name);
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType in project ceylon by eclipse.
the class LambdaToMethod method deserTest.
private JCExpression deserTest(JCExpression prev, String func, String lit) {
MethodType eqmt = new MethodType(List.of(syms.objectType), syms.booleanType, List.<Type>nil(), syms.methodClass);
Symbol eqsym = rs.resolveQualifiedMethod(null, attrEnv, syms.objectType, names.equals, List.of(syms.objectType), List.<Type>nil());
JCMethodInvocation eqtest = make.Apply(List.<JCExpression>nil(), make.Select(deserGetter(func, syms.stringType), eqsym).setType(eqmt), List.<JCExpression>of(make.Literal(lit)));
eqtest.setType(syms.booleanType);
JCBinary compound = make.Binary(JCTree.Tag.AND, prev, eqtest);
compound.operator = rs.resolveBinaryOperator(null, JCTree.Tag.AND, attrEnv, syms.booleanType, syms.booleanType);
compound.setType(syms.booleanType);
return compound;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType in project ceylon by eclipse.
the class LambdaToMethod method deserGetter.
private JCExpression deserGetter(String func, Type type, List<Type> argTypes, List<JCExpression> args) {
MethodType getmt = new MethodType(argTypes, type, List.<Type>nil(), syms.methodClass);
Symbol getsym = rs.resolveQualifiedMethod(null, attrEnv, syms.serializedLambdaType, names.fromString(func), argTypes, List.<Type>nil());
return make.Apply(List.<JCExpression>nil(), make.Select(make.Ident(kInfo.deserParamSym).setType(syms.serializedLambdaType), getsym).setType(getmt), args).setType(type);
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType 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.langtools.tools.javac.code.Type.MethodType in project ceylon by eclipse.
the class LambdaToMethod method makeIndyCall.
/**
* Generate an indy method call with given name, type and static bootstrap
* arguments types
*/
private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName, List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs, Name methName) {
int prevPos = make.pos;
try {
make.at(pos);
List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType, syms.stringType, syms.methodTypeType).appendList(bsmStaticArgToTypes(staticArgs));
Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site, bsmName, bsm_staticArgs, List.<Type>nil());
DynamicMethodSymbol dynSym = new DynamicMethodSymbol(methName, syms.noSymbol, bsm.isStatic() ? ClassFile.REF_invokeStatic : ClassFile.REF_invokeVirtual, (MethodSymbol) bsm, indyType, staticArgs.toArray());
JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName);
qualifier.sym = dynSym;
qualifier.type = indyType.getReturnType();
JCMethodInvocation proxyCall = make.Apply(List.<JCExpression>nil(), qualifier, indyArgs);
proxyCall.type = indyType.getReturnType();
return proxyCall;
} finally {
make.at(prevPos);
}
}
Aggregations