use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
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(null, gen.makeJavaType(callableType, AbstractTransformer.JT_RAW));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType)), null);
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(null, gen.makeJavaType(callableType));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType)), null);
typedApply.parameter(pdb);
}
ListBuffer<JCTypeParameter> typeParameters = ListBuffer.<JCTypeParameter>lb();
for (Map.Entry<TypeParameter, Type> ta : typeModel.getTypeArguments().entrySet()) {
Type typeArgument = ta.getValue();
TypeParameter typeParameter = ta.getKey();
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);
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 com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class CallableBuilder method unboundFunctionalMemberReference.
/**
* Used for "static" method or class references. For example:
* <pre>
* value x = Integer.plus;
* value y = Foo.method;
* value z = Outer.Inner;
* </pre>
*/
public static CallableBuilder unboundFunctionalMemberReference(CeylonTransformer gen, Tree.QualifiedMemberOrTypeExpression qmte, Type typeModel, final Functional methodClassOrCtor, Reference producedReference) {
final ParameterList parameterList = methodClassOrCtor.getFirstParameterList();
Type type = typeModel;
JCExpression target;
boolean hasOuter = !(Decl.isConstructor((Declaration) methodClassOrCtor) && gen.getNumParameterLists(typeModel) == 1);
if (!hasOuter) {
type = typeModel;
target = null;
} else {
type = gen.getReturnTypeOfCallable(type);
Type qualifyingType = qmte.getTarget().getQualifyingType();
target = gen.naming.makeUnquotedIdent(Unfix.$instance$);
target = gen.expressionGen().applyErasureAndBoxing(target, producedReference.getQualifyingType(), true, BoxingStrategy.BOXED, qualifyingType);
}
CallableBuilder inner = new CallableBuilder(gen, null, type, parameterList);
//FromParameterModels();
inner.parameterTypes = inner.getParameterTypesFromCallableModel();
if (hasOuter) {
inner.defaultValueCall = inner.new MemberReferenceDefaultValueCall(methodClassOrCtor);
}
CallBuilder callBuilder = CallBuilder.instance(gen);
Type accessType = gen.getParameterTypeOfCallable(typeModel, 0);
if (Decl.isConstructor((Declaration) methodClassOrCtor)) {
Constructor ctor = Decl.getConstructor((Declaration) methodClassOrCtor);
Class cls = Decl.getConstructedClass(ctor);
if (Strategy.generateInstantiator(ctor)) {
callBuilder.invoke(gen.naming.makeInstantiatorMethodName(target, cls));
} else {
callBuilder.instantiate(gen.makeJavaType(gen.getReturnTypeOfCallable(typeModel), JT_CLASS_NEW));
if (!ctor.isShared()) {
accessType = Decl.getPrivateAccessType(qmte);
}
}
} else if (methodClassOrCtor instanceof Function && ((Function) methodClassOrCtor).isParameter()) {
callBuilder.invoke(gen.naming.makeQualifiedName(target, (Function) methodClassOrCtor, Naming.NA_MEMBER));
} else if (methodClassOrCtor instanceof Function) {
callBuilder.invoke(gen.naming.makeQualifiedName(target, (Function) methodClassOrCtor, Naming.NA_MEMBER));
if (!((TypedDeclaration) methodClassOrCtor).isShared()) {
accessType = Decl.getPrivateAccessType(qmte);
}
} else if (methodClassOrCtor instanceof Class) {
Class cls = (Class) methodClassOrCtor;
if (Strategy.generateInstantiator(cls)) {
callBuilder.invoke(gen.naming.makeInstantiatorMethodName(target, cls));
} else {
callBuilder.instantiate(new ExpressionAndType(target, null), gen.makeJavaType(cls.getType(), JT_CLASS_NEW | AbstractTransformer.JT_NON_QUALIFIED));
if (!cls.isShared()) {
accessType = Decl.getPrivateAccessType(qmte);
}
}
} else {
throw BugException.unhandledDeclarationCase((Declaration) methodClassOrCtor, qmte);
}
ListBuffer<ExpressionAndType> reified = ListBuffer.lb();
DirectInvocation.addReifiedArguments(gen, producedReference, reified);
for (ExpressionAndType reifiedArgument : reified) {
callBuilder.argument(reifiedArgument.expression);
}
if (Decl.isConstructor((Declaration) methodClassOrCtor) && !Decl.isDefaultConstructor(Decl.getConstructor((Declaration) methodClassOrCtor))) {
// invoke the param class ctor
Constructor ctor = Decl.getConstructor((Declaration) methodClassOrCtor);
callBuilder.argument(gen.naming.makeNamedConstructorName(ctor, false));
}
for (Parameter parameter : parameterList.getParameters()) {
callBuilder.argument(gen.naming.makeQuotedIdent(Naming.getAliasedParameterName(parameter)));
}
JCExpression innerInvocation = callBuilder.build();
// Need to worry about boxing for Function and FunctionalParameter
if (methodClassOrCtor instanceof TypedDeclaration && !Decl.isConstructor((Declaration) methodClassOrCtor)) {
// use the method return type since the function is actually applied
Type returnType = gen.getReturnTypeOfCallable(type);
innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, returnType, // expression is a Callable
CodegenUtil.hasTypeErased((TypedDeclaration) methodClassOrCtor), !CodegenUtil.isUnBoxed((TypedDeclaration) methodClassOrCtor), BoxingStrategy.BOXED, returnType, 0);
} else if (methodClassOrCtor instanceof Class && Strategy.isInstantiatorUntyped((Class) methodClassOrCtor)) {
// $new method declared to return Object, so needs typecast
innerInvocation = gen.make().TypeCast(gen.makeJavaType(((Class) methodClassOrCtor).getType()), innerInvocation);
}
List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
inner.useDefaultTransformation(innerBody);
if (!hasOuter) {
return inner;
}
ParameterList outerPl = new ParameterList();
Parameter instanceParameter = new Parameter();
instanceParameter.setName(Naming.name(Unfix.$instance$));
Value valueModel = new Value();
instanceParameter.setModel(valueModel);
valueModel.setName(instanceParameter.getName());
valueModel.setInitializerParameter(instanceParameter);
valueModel.setType(accessType);
valueModel.setUnboxed(false);
outerPl.getParameters().add(instanceParameter);
CallableBuilder outer = new CallableBuilder(gen, null, typeModel, outerPl);
outer.parameterTypes = outer.getParameterTypesFromParameterModels();
List<JCStatement> outerBody = List.<JCStatement>of(gen.make().Return(inner.build()));
outer.useDefaultTransformation(outerBody);
outer.companionAccess = Decl.isPrivateAccessRequiringCompanion(qmte);
return outer;
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class CallableBuilder method javaStaticMethodReference.
public static CallableBuilder javaStaticMethodReference(CeylonTransformer gen, Type typeModel, final Functional methodOrClass, Reference producedReference) {
final ParameterList parameterList = methodOrClass.getFirstParameterList();
CallableBuilder inner = new CallableBuilder(gen, null, typeModel, parameterList);
ArrayList<Type> pt = new ArrayList<>();
for (Parameter p : methodOrClass.getFirstParameterList().getParameters()) {
pt.add(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);
return inner;
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class CallableBuilder method anonymous.
/**
* Constructs an {@code AbstractCallable} suitable for an anonymous function.
*/
public static CallableBuilder anonymous(CeylonTransformer gen, Node node, FunctionOrValue model, Tree.Expression expr, java.util.List<Tree.ParameterList> parameterListTree, Type callableTypeModel, boolean delegateDefaultedCalls) {
boolean prevSyntheticClassBody = gen.expressionGen().withinSyntheticClassBody(true);
JCExpression transformedExpr = gen.expressionGen().transformExpression(expr, BoxingStrategy.BOXED, gen.getReturnTypeOfCallable(callableTypeModel));
gen.expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
final List<JCStatement> stmts = List.<JCStatement>of(gen.make().Return(transformedExpr));
return methodArgument(gen, null, model, callableTypeModel, parameterListTree, stmts, delegateDefaultedCalls);
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeGetterBlock.
JCBlock makeGetterBlock(TypedDeclaration declarationModel, final Tree.Block block, final Tree.SpecifierOrInitializerExpression expression) {
List<JCStatement> stats;
if (block != null) {
stats = statementGen().transformBlock(block);
} else {
BoxingStrategy boxing = CodegenUtil.getBoxingStrategy(declarationModel);
Type type = declarationModel.getType();
JCStatement transStat;
HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getExpression());
if (error != null) {
transStat = this.makeThrowUnresolvedCompilationError(error);
} else {
transStat = make().Return(expressionGen().transformExpression(expression.getExpression(), boxing, type));
}
stats = List.<JCStatement>of(transStat);
}
JCBlock getterBlock = make().Block(0, stats);
return getterBlock;
}
Aggregations