use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
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 com.redhat.ceylon.model.typechecker.model.Function 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.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class AnnotationInvocationVisitor method transformConstructor.
private static JCAnnotation transformConstructor(ExpressionTransformer exprGen, Tree.InvocationExpression invocation, AnnotationInvocation ai, com.sun.tools.javac.util.List<AnnotationFieldName> fieldPath) {
Map<Parameter, ListBuffer<JCExpression>> args = new LinkedHashMap<Parameter, ListBuffer<JCExpression>>();
List<Parameter> classParameters = ai.getClassParameters();
// The class parameter's we've not yet figured out the value for
ArrayList<Parameter> unbound = new ArrayList<Parameter>(classParameters);
for (Parameter classParameter : classParameters) {
for (AnnotationArgument argument : ai.findAnnotationArgumentForClassParameter(classParameter)) {
JCExpression expr = transformConstructorArgument(exprGen, invocation, classParameter, argument, fieldPath);
appendArgument(args, classParameter, expr);
unbound.remove(classParameter);
}
}
outer: for (Parameter classParameter : ((ArrayList<Parameter>) unbound.clone())) {
// Defaulted argument
if (ai.isInstantiation()) {
if (classParameter.isDefaulted()) {
// That's OK, we'll pick up the default argument from
// the Java Annotation type
unbound.remove(classParameter);
continue outer;
}
} else {
Function ac2 = (Function) ai.getPrimary();
AnnotationInvocation i = (AnnotationInvocation) ac2.getAnnotationConstructor();
for (AnnotationArgument aa : i.getAnnotationArguments()) {
if (aa.getParameter().equals(classParameter)) {
appendArgument(args, classParameter, aa.getTerm().makeAnnotationArgumentValue(exprGen, i, com.sun.tools.javac.util.List.<AnnotationFieldName>of(aa)));
unbound.remove(classParameter);
continue outer;
}
}
}
if (Strategy.hasEmptyDefaultArgument(classParameter)) {
appendArgument(args, classParameter, exprGen.make().NewArray(null, null, com.sun.tools.javac.util.List.<JCExpression>nil()));
unbound.remove(classParameter);
continue outer;
}
}
for (Parameter classParameter : unbound) {
appendArgument(args, classParameter, exprGen.makeErroneous(invocation, "compiler bug: unbound annotation class parameter " + classParameter.getName()));
}
ListBuffer<JCExpression> assignments = ListBuffer.<JCExpression>lb();
for (Map.Entry<Parameter, ListBuffer<JCExpression>> entry : args.entrySet()) {
ListBuffer<JCExpression> exprs = entry.getValue();
if (exprs.size() == 1) {
assignments.append(makeArgument(exprGen, invocation, entry.getKey(), exprs.first()));
} else {
assignments.append(makeArgument(exprGen, invocation, entry.getKey(), exprGen.make().NewArray(null, null, exprs.toList())));
}
}
JCAnnotation annotation = exprGen.at(invocation).Annotation(ai.makeAnnotationType(exprGen), assignments.toList());
return annotation;
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class BoxingVisitor method visit.
@Override
public void visit(Expression that) {
Stack<Boolean> npebs = setPEB();
super.visit(that);
resetPEB(npebs);
Term term = that.getTerm();
propagateFromTerm(that, term);
// which will need to be marked boxed
if (term instanceof MemberOrTypeExpression) {
Tree.MemberOrTypeExpression expr = (Tree.MemberOrTypeExpression) term;
if (expr.getDeclaration() instanceof Function) {
that.setUnboxed(false);
}
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class BoxingVisitor method visit.
@Override
public void visit(InvocationExpression that) {
super.visit(that);
if (isIndirectInvocation(that) && !Decl.isJavaStaticOrInterfacePrimary(that.getPrimary())) {
// if the Callable is raw the invocation will be erased
if (that.getPrimary().getTypeModel() != null && isRaw(that.getPrimary().getTypeModel()))
CodegenUtil.markTypeErased(that);
// These are always boxed
return;
}
if (isByteLiteral(that))
CodegenUtil.markUnBoxed(that);
else
propagateFromTerm(that, that.getPrimary());
// then we mark the expression itself as erased as well
if (that.getPrimary() instanceof StaticMemberOrTypeExpression) {
StaticMemberOrTypeExpression expr = (StaticMemberOrTypeExpression) that.getPrimary();
if (expr.getDeclaration() instanceof Function) {
Function mth = (Function) expr.getDeclaration();
if (isTypeParameter(mth.getType()) && (hasErasedTypeParameter(expr.getTarget(), expr.getTypeArguments()) || CodegenUtil.isRaw(that))) {
CodegenUtil.markTypeErased(that);
CodegenUtil.markUntrustedType(that);
}
}
}
}
Aggregations