use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class CallableBuilder method build.
public JCExpression build() {
// Generate a subclass of Callable
ListBuffer<JCTree> classBody = new ListBuffer<JCTree>();
gen.at(node);
if (parameterDefaultValueMethods != null) {
for (MethodDefinitionBuilder mdb : parameterDefaultValueMethods) {
classBody.append(mdb.build());
}
}
transformation.appendMethods(classBody);
gen.at(node);
JCClassDecl classDef = gen.make().AnonymousClassDef(gen.make().Modifiers(0, annotations != null ? annotations : List.<JCAnnotation>nil()), classBody.toList());
int variadicIndex = isVariadic ? numParams - 1 : -1;
Type callableType;
if (typeModel.isTypeConstructor()) {
callableType = typeModel.getDeclaration().getExtendedType();
} else {
callableType = typeModel;
}
JCNewClass callableInstance;
if (functionalInterface == null) {
callableInstance = gen.at(node).NewClass(null, null, gen.makeJavaType(callableType, JT_EXTENDS | JT_CLASS_NEW), List.<JCExpression>of(gen.makeReifiedTypeArgument(callableType.getTypeArgumentList().get(0)), gen.makeReifiedTypeArgument(callableType.getTypeArgumentList().get(1)), gen.make().Literal(callableType.asString(true)), gen.make().TypeCast(gen.syms().shortType, gen.makeInteger(variadicIndex))), classDef);
} else {
callableInstance = gen.make().NewClass(null, null, gen.makeJavaType(functionalInterface, JT_EXTENDS | JT_CLASS_NEW), List.<JCExpression>nil(), classDef);
}
JCExpression result;
if (typeModel.isTypeConstructor()) {
result = buildTypeConstructor(callableType, callableInstance);
} else {
result = callableInstance;
}
gen.at(null);
if (instanceSubstitution != null) {
instanceSubstitution.close();
}
return result;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class CallableBuilder method makeCallableCallParam.
private ParameterDefinitionBuilder makeCallableCallParam(long flags, int ii) {
JCExpression type = gen.makeIdent(gen.syms().objectType);
if ((flags & Flags.VARARGS) != 0) {
type = gen.make().TypeArray(type);
}
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, getParamName(ii));
pdb.modifiers(Flags.FINAL | flags);
pdb.type(new TransformedType(type));
return pdb;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class CallableBuilder method methodReference.
/**
* Constructs an {@code AbstractCallable} suitable for wrapping a
* method reference. For example:
* <pre>
* void someMethod() { ... }
* Anything() ref = someMethod;
* </pre>
*/
public static JCExpression methodReference(CeylonTransformer gen, final Tree.StaticMemberOrTypeExpression forwardCallTo, ParameterList parameterList, Type expectedType, Type callableType, boolean useParameterTypesFromCallableModel) {
ListBuffer<JCStatement> letStmts = new ListBuffer<JCStatement>();
CallableBuilder cb = new CallableBuilder(gen, forwardCallTo, callableType, parameterList);
cb.parameterTypes = useParameterTypesFromCallableModel ? cb.getParameterTypesFromCallableModel() : cb.getParameterTypesFromParameterModels();
Naming.SyntheticName instanceFieldName;
boolean instanceFieldIsBoxed = false;
if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression && !ExpressionTransformer.isSuperOrSuperOf(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary()) && !ExpressionTransformer.isPackageQualified((Tree.QualifiedMemberOrTypeExpression) forwardCallTo)) {
if ((((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SpreadOp)) {
instanceFieldIsBoxed = true;
instanceFieldName = null;
} else {
Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) forwardCallTo;
boolean prevCallableInv = gen.expressionGen().withinSyntheticClassBody(true);
try {
instanceFieldName = gen.naming.synthetic(Unfix.$instance$);
int varTypeFlags = Decl.isPrivateAccessRequiringCompanion(qmte) ? JT_COMPANION : 0;
Type primaryType;
if (Decl.isValueTypeDecl(qmte.getPrimary().getTypeModel())) {
primaryType = qmte.getPrimary().getTypeModel();
} else {
primaryType = qmte.getTarget().getQualifyingType();
}
if (((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SafeMemberOp) {
primaryType = gen.typeFact().getOptionalType(primaryType);
}
JCExpression primaryExpr = gen.expressionGen().transformQualifiedMemberPrimary(qmte);
Declaration dec = qmte.getDeclaration();
if (Decl.isPrivateAccessRequiringCompanion(qmte)) {
primaryExpr = gen.naming.makeCompanionAccessorCall(primaryExpr, (Interface) dec.getContainer());
}
Type varType = dec.isShared() ? primaryType : Decl.getPrivateAccessType(qmte);
if (qmte.getPrimary().getUnboxed() == false) {
varTypeFlags |= JT_NO_PRIMITIVES;
instanceFieldIsBoxed = true;
}
letStmts.add(gen.makeVar(Flags.FINAL, instanceFieldName, gen.makeJavaType(varType, varTypeFlags), primaryExpr));
if (qmte.getPrimary() instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration() instanceof TypedDeclaration) {
cb.instanceSubstitution = gen.naming.addVariableSubst((TypedDeclaration) ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration(), instanceFieldName.getName());
}
} finally {
gen.expressionGen().withinSyntheticClassBody(prevCallableInv);
}
}
} else {
instanceFieldName = null;
}
CallableTransformation tx;
cb.defaultValueCall = new DefaultValueMethodTransformation() {
@Override
public JCExpression makeDefaultValueMethod(AbstractTransformer gen, Parameter defaultedParam, List<JCExpression> defaultMethodArgs) {
JCExpression fn = null;
if (forwardCallTo instanceof Tree.BaseMemberOrTypeExpression) {
fn = gen.naming.makeDefaultedParamMethod(null, defaultedParam);
} else if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression) {
JCExpression qualifier = gen.expressionGen().transformTermForInvocation(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary(), null);
fn = gen.naming.makeDefaultedParamMethod(qualifier, defaultedParam);
}
return gen.make().Apply(null, fn, defaultMethodArgs);
}
};
if (cb.isVariadic) {
tx = cb.new VariadicCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, false, callableType));
} else {
tx = cb.new FixedArityCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, true, callableType), null);
}
cb.useTransformation(tx);
cb.checkForFunctionalInterface(expectedType);
return letStmts.isEmpty() ? cb.build() : gen.make().LetExpr(letStmts.toList(), cb.build());
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class CallableBuilder method makeCallTypedMethod.
/**
* Makes the {@code call$typed()} method, using the given body.
*/
private MethodDefinitionBuilder makeCallTypedMethod(List<JCStatement> body) {
// make the method
MethodDefinitionBuilder methodBuilder = MethodDefinitionBuilder.systemMethod(gen, Naming.getCallableTypedMethodName());
methodBuilder.noAnnotations();
methodBuilder.modifiers(Flags.PRIVATE);
Type returnType = gen.getReturnTypeOfCallable(typeModel);
methodBuilder.resultType(gen.makeJavaType(returnType, JT_NO_PRIMITIVES), null);
// add all parameters
int i = 0;
for (Parameter param : paramLists.getParameters()) {
ParameterDefinitionBuilder parameterBuilder = ParameterDefinitionBuilder.systemParameter(gen, Naming.getAliasedParameterName(param));
JCExpression paramType = gen.makeJavaType(parameterTypes.get(i));
parameterBuilder.modifiers(Flags.FINAL);
parameterBuilder.type(new TransformedType(paramType));
methodBuilder.parameter(parameterBuilder);
i++;
}
// Return the call result, or null if a void method
methodBuilder.body(body);
return methodBuilder;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class CallableBuilder method javaStaticMethodReference.
public static CallableBuilder javaStaticMethodReference(CeylonTransformer gen, Node node, Type typeModel, final Functional methodOrClass, Reference producedReference, Type expectedType) {
final ParameterList parameterList = methodOrClass.getFirstParameterList();
CallableBuilder inner = new CallableBuilder(gen, node, typeModel, parameterList);
ArrayList<Type> pt = new ArrayList<>();
for (Parameter p : methodOrClass.getFirstParameterList().getParameters()) {
pt.add(((Tree.MemberOrTypeExpression) node).getTarget().getTypedParameter(p).getType());
}
inner.parameterTypes = pt;
inner.defaultValueCall = inner.new MemberReferenceDefaultValueCall(methodOrClass);
JCExpression innerInvocation = gen.expressionGen().makeJavaStaticInvocation(gen, methodOrClass, producedReference, parameterList);
// Need to worry about boxing for Function and FunctionalParameter
if (methodOrClass instanceof TypedDeclaration) {
innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, methodOrClass.getType(), !CodegenUtil.isUnBoxed((TypedDeclaration) methodOrClass), BoxingStrategy.BOXED, methodOrClass.getType());
} else if (Strategy.isInstantiatorUntyped((Class) methodOrClass)) {
// $new method declared to return Object, so needs typecast
innerInvocation = gen.make().TypeCast(gen.makeJavaType(((Class) methodOrClass).getType()), innerInvocation);
}
List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
inner.useDefaultTransformation(innerBody);
if (expectedType != null)
inner.checkForFunctionalInterface(expectedType);
return inner;
}
Aggregations