use of com.redhat.ceylon.model.typechecker.model.Functional in project ceylon-compiler by ceylon.
the class AnnotationInvocationVisitor method transformConstructorArgument.
public static JCExpression transformConstructorArgument(ExpressionTransformer exprGen, Tree.InvocationExpression invocation, Parameter classParameter, AnnotationArgument argument, com.sun.tools.javac.util.List<AnnotationFieldName> fieldPath) {
AnnotationInvocation anno = annoCtorModel(invocation);
AnnotationInvocationVisitor visitor = new AnnotationInvocationVisitor(exprGen, invocation, anno);
visitor.parameter = classParameter;
AnnotationTerm term = argument.getTerm();
if (term instanceof ParameterAnnotationTerm) {
ParameterAnnotationTerm parameterArgument = (ParameterAnnotationTerm) term;
Parameter sp = parameterArgument.getSourceParameter();
int argumentIndex = ((Functional) sp.getDeclaration()).getFirstParameterList().getParameters().indexOf(sp);
if (invocation.getPositionalArgumentList() != null) {
java.util.List<Tree.PositionalArgument> positionalArguments = invocation.getPositionalArgumentList().getPositionalArguments();
if (parameterArgument.isSpread()) {
visitor.transformSpreadArgument(positionalArguments.subList(argumentIndex, positionalArguments.size()), classParameter);
} else {
if (0 <= argumentIndex && argumentIndex < positionalArguments.size()) {
Tree.PositionalArgument pargument = positionalArguments.get(argumentIndex);
if (pargument.getParameter().isSequenced()) {
visitor.transformVarargs(argumentIndex, positionalArguments);
} else {
visitor.transformArgument(pargument);
}
} else if (sp.isDefaulted()) {
visitor.makeDefaultExpr(invocation, parameterArgument, sp);
} else if (sp.isSequenced()) {
visitor.appendBuiltArray(visitor.startArray());
}
}
} else if (invocation.getNamedArgumentList() != null) {
boolean found = false;
for (Tree.NamedArgument na : invocation.getNamedArgumentList().getNamedArguments()) {
Parameter parameter = na.getParameter();
int parameterIndex = anno.indexOfConstructorParameter(parameter);
if (parameterIndex == argumentIndex) {
visitor.transformArgument(na);
found = true;
break;
}
}
if (!found) {
if (sp.isDefaulted()) {
visitor.makeDefaultExpr(invocation, parameterArgument, sp);
} else if (sp.isSequenced()) {
visitor.appendBuiltArray(visitor.startArray());
} else {
visitor.append(exprGen.makeErroneous(invocation, "Unable to find argument"));
}
}
}
} else if (term instanceof LiteralAnnotationTerm) {
visitor.append(term.makeAnnotationArgumentValue(visitor.exprGen, visitor.anno, fieldPath.append(argument)));
} else if (term instanceof InvocationAnnotationTerm) {
AnnotationInvocation instantiation = ((InvocationAnnotationTerm) term).getInstantiation();
visitor.append(transformConstructor(visitor.exprGen, invocation, instantiation, fieldPath.append(argument)));
} else {
visitor.append(visitor.exprGen.makeErroneous(invocation, "Unable to find argument"));
}
return visitor.getExpression();
}
use of com.redhat.ceylon.model.typechecker.model.Functional in project ceylon-compiler by ceylon.
the class BoxingDeclarationVisitor method setBoxingState.
private void setBoxingState(TypedDeclaration declaration, TypedDeclaration refinedDeclaration, Node that) {
Type type = declaration.getType();
if (type == null) {
// an error must have already been reported
return;
}
// fetch the real refined declaration if required
if (Decl.equal(declaration, refinedDeclaration) && declaration instanceof FunctionOrValue && ((FunctionOrValue) declaration).isParameter() && declaration.getContainer() instanceof Class) {
// maybe it is really inherited from a field?
FunctionOrValue methodOrValueForParam = (FunctionOrValue) declaration;
if (methodOrValueForParam != null) {
// make sure we get the refined version of that member
refinedDeclaration = (TypedDeclaration) methodOrValueForParam.getRefinedDeclaration();
}
}
// inherit underlying type constraints
if (!Decl.equal(refinedDeclaration, declaration) && type.getUnderlyingType() == null && refinedDeclaration.getType() != null)
type.setUnderlyingType(refinedDeclaration.getType().getUnderlyingType());
// abort if our boxing state has already been set
if (declaration.getUnboxed() != null)
return;
// functional parameter return values are always boxed if we're not creating a method for them
if (declaration instanceof Function && ((Function) declaration).isParameter() && !JvmBackendUtil.createMethod((Function) declaration)) {
declaration.setUnboxed(false);
return;
}
if (!Decl.equal(refinedDeclaration, declaration)) {
// make sure refined declarations have already been set
if (refinedDeclaration.getUnboxed() == null)
setBoxingState(refinedDeclaration, refinedDeclaration, that);
// inherit
declaration.setUnboxed(refinedDeclaration.getUnboxed());
} else if (declaration instanceof Function && CodegenUtil.isVoid(declaration.getType()) && Strategy.useBoxedVoid((Function) declaration) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
declaration.setUnboxed(false);
} else if ((isCeylonBasicType(type) || Decl.isUnboxedVoid(declaration)) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && (refinedDeclaration.getContainer() instanceof Declaration == false || !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration)) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
boolean unbox = !forceBoxedLocals || !(declaration instanceof Value) || !Decl.isLocal(declaration) || Decl.isParameter(declaration) || Decl.isTransient(declaration);
declaration.setUnboxed(unbox);
} else if (Decl.isValueParameter(declaration) && CodegenUtil.isContainerFunctionalParameter(declaration) && JvmBackendUtil.createMethod((FunctionOrValue) declaration.getContainer())) {
Function functionalParameter = (Function) declaration.getContainer();
TypedDeclaration refinedFrom = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(functionalParameter, optimisedMethodSpecifiersToMethods);
if (Decl.equal(refinedFrom, functionalParameter)) {
// not a method return type (where void would be considered unboxed).
if (declaration.getUnit().getAnythingType().isExactly(declaration.getType()) || declaration.getUnit().isOptionalType(declaration.getType())) {
declaration.setUnboxed(false);
} else {
declaration.setUnboxed(true);
}
} else {
// make sure refined declarations have already been set
if (refinedFrom.getUnboxed() == null)
setBoxingState(refinedFrom, refinedFrom, that);
// inherit
declaration.setUnboxed(refinedFrom.getUnboxed());
}
} else {
declaration.setUnboxed(false);
}
// Any "@boxed" or "@unboxed" compiler annotation overrides
boxFromAnnotation(declaration, that);
}
Aggregations