use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.
the class CallableBuilder method buildTypeConstructor.
protected JCExpression buildTypeConstructor(Type callableType, JCNewClass callableInstance) {
JCExpression result;
// Wrap in an anonymous TypeConstructor subcla
MethodDefinitionBuilder rawApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.apply.toString());
rawApply.modifiers(Flags.PUBLIC);
rawApply.isOverride(true);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
rawApply.resultType(new TransformedType(gen.makeJavaType(callableType, AbstractTransformer.JT_RAW)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
rawApply.parameter(pdb);
}
rawApply.body(List.<JCStatement>of(gen.make().Return(gen.make().Apply(null, gen.naming.makeUnquotedIdent(Naming.Unfix.$apply$.toString()), List.<JCExpression>of(gen.naming.makeUnquotedIdent("applied"))))));
MethodDefinitionBuilder typedApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.$apply$.toString());
typedApply.modifiers(Flags.PRIVATE);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
typedApply.resultType(new TransformedType(gen.makeJavaType(callableType)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
typedApply.parameter(pdb);
}
ListBuffer<JCTypeParameter> typeParameters = new ListBuffer<JCTypeParameter>();
for (TypeParameter typeParameter : Strategy.getEffectiveTypeParameters(typeModel.getDeclaration())) {
Type typeArgument = typeModel.getTypeArguments().get(typeParameter);
typeParameters.add(gen.makeTypeParameter(typeParameter, null));
typedApply.body(gen.makeVar(Flags.FINAL, gen.naming.getTypeArgumentDescriptorName(typeParameter), gen.make().Type(gen.syms().ceylonTypeDescriptorType), gen.make().Indexed(gen.makeUnquotedIdent("applied"), gen.make().Literal(typeModel.getTypeArgumentList().indexOf(typeArgument)))));
}
typedApply.body(gen.make().Return(callableInstance));
// typedApply.body(body.toList());
MethodDefinitionBuilder ctor = MethodDefinitionBuilder.constructor(gen, false);
ctor.body(gen.make().Exec(gen.make().Apply(null, gen.naming.makeSuper(), List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))))));
SyntheticName n = gen.naming.synthetic(typeModel.getDeclaration().getName());
JCClassDecl classDef = gen.make().ClassDef(gen.make().Modifiers(0, List.<JCAnnotation>nil()), // name,
n.asName(), typeParameters.toList(), // extending
gen.make().QualIdent(gen.syms().ceylonAbstractTypeConstructorType.tsym), // implementing,
List.<JCExpression>nil(), List.<JCTree>of(ctor.build(), rawApply.build(), typedApply.build()));
result = gen.make().LetExpr(List.<JCStatement>of(classDef), gen.make().NewClass(null, null, n.makeIdent(), List.<JCExpression>nil(), // List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))),
null));
return result;
}
use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.
the class CallableBuilder method getParameterTypesFromParameterModels.
private java.util.List<Type> getParameterTypesFromParameterModels() {
java.util.List<Type> parameterTypes = new ArrayList<Type>(numParams);
// get them from our declaration
for (Parameter p : paramLists.getParameters()) {
Type pt;
FunctionOrValue pm = p.getModel();
if (pm instanceof Function && ((Function) pm).isParameter())
pt = gen.getTypeForFunctionalParameter((Function) pm);
else
pt = p.getType();
parameterTypes.add(pt);
}
return parameterTypes;
}
use of org.eclipse.ceylon.model.typechecker.model.Type 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.model.typechecker.model.Type in project ceylon by eclipse.
the class CallableBuilder method makeCallMethod.
protected final MethodDefinitionBuilder makeCallMethod(List<JCStatement> body, int arity) {
MethodDefinitionBuilder callMethod = MethodDefinitionBuilder.callable(gen);
// we only override it if we're not building a functional interface class
callMethod.isOverride(functionalInterfaceMethod == null);
callMethod.modifiers(Flags.PUBLIC);
Type returnType = gen.getReturnTypeOfCallable(typeModel);
callMethod.resultType(gen.makeJavaType(returnType, JT_NO_PRIMITIVES), null);
// Now append formal parameters
switch(arity) {
case 3:
callMethod.parameter(makeCallableCallParam(0, arity - 3));
// fall through
case 2:
callMethod.parameter(makeCallableCallParam(0, arity - 2));
// fall through
case 1:
callMethod.parameter(makeCallableCallParam(0, arity - 1));
break;
case 0:
break;
default:
// use varargs
callMethod.parameter(makeCallableCallParam(Flags.VARARGS, 0));
}
// Return the call result, or null if a void method
callMethod.body(body);
return callMethod;
}
use of org.eclipse.ceylon.model.typechecker.model.Type 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());
}
Aggregations