use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewArray in project ceylon by eclipse.
the class AbstractTransformer method makeReifiedTypeArgumentResolved.
private JCExpression makeReifiedTypeArgumentResolved(Type pt, boolean qualified, TypeArgumentAccessor typeArgumentAccessor, boolean wantsRaw) {
if (pt.isUnion()) {
// FIXME: refactor this shite
List<JCExpression> typeTestArguments = List.nil();
java.util.List<Type> typeParameters = pt.getCaseTypes();
if (typeParameters.size() == 2) {
Type alternative = null;
if (typeParameters.get(0).isEmpty())
alternative = typeParameters.get(1);
else if (typeParameters.get(1).isEmpty())
alternative = typeParameters.get(0);
if (alternative != null && alternative.isTuple()) {
JCExpression tupleType = makeTupleTypeDescriptor(alternative, true);
if (tupleType != null)
return tupleType;
}
}
for (int i = typeParameters.size() - 1; i >= 0; i--) {
typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
}
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "union"), typeTestArguments);
} else if (pt.isIntersection()) {
List<JCExpression> typeTestArguments = List.nil();
java.util.List<Type> typeParameters = pt.getSatisfiedTypes();
for (int i = typeParameters.size() - 1; i >= 0; i--) {
typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
}
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "intersection"), typeTestArguments);
} else if (pt.isNothing()) {
return makeNothingTypeDescriptor();
}
TypeDeclaration declaration = pt.getDeclaration();
if (declaration instanceof Constructor) {
pt = pt.getExtendedType();
declaration = pt.getDeclaration();
}
if (pt.isClassOrInterface()) {
// see if we have an alias for it
if (supportsReifiedAlias((ClassOrInterface) declaration)) {
JCExpression qualifier = naming.makeDeclarationName(declaration, DeclNameFlag.QUALIFIED);
return makeSelect(qualifier, naming.getTypeDescriptorAliasName());
}
if (pt.isTuple()) {
JCExpression tupleType = makeTupleTypeDescriptor(pt, false);
if (tupleType != null)
return tupleType;
}
// no alias, must build it
List<JCExpression> typeTestArguments;
JCExpression thisType = makeUnerasedClassLiteral(declaration);
if (!wantsRaw) {
typeTestArguments = makeReifiedTypeArgumentsResolved(pt.getTypeArgumentList(), qualified, typeArgumentAccessor);
// do we have variance overrides?
Map<TypeParameter, SiteVariance> varianceOverrides = pt.getVarianceOverrides();
if (!varianceOverrides.isEmpty()) {
// we need to pass them as second argument then, in an array
ListBuffer<JCExpression> varianceElements = new ListBuffer<JCExpression>();
for (TypeParameter typeParameter : declaration.getTypeParameters()) {
SiteVariance useSiteVariance = varianceOverrides.get(typeParameter);
String selector;
if (useSiteVariance != null) {
switch(useSiteVariance) {
case IN:
selector = "IN";
break;
case OUT:
selector = "OUT";
break;
default:
selector = "NONE";
break;
}
} else {
selector = "NONE";
}
JCExpression varianceElement = make().Select(makeIdent(syms().ceylonVarianceType), names().fromString(selector));
varianceElements.append(varianceElement);
}
JCNewArray varianceArray = make().NewArray(makeIdent(syms().ceylonVarianceType), List.<JCExpression>nil(), varianceElements.toList());
typeTestArguments = typeTestArguments.prepend(varianceArray);
}
} else {
typeTestArguments = List.nil();
}
typeTestArguments = typeTestArguments.prepend(thisType);
JCExpression classDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "klass"), typeTestArguments);
Type qualifyingType = pt.getQualifyingType();
JCExpression containerType = null;
if (qualifyingType == null) {
// it may be contained in a function or value, and we want its type
// or static class members may have no qualifying type but we want the TDs to treat
// them as members anyway
Declaration enclosingDeclaration = getDeclarationContainer(declaration);
if (enclosingDeclaration instanceof TypedDeclaration)
containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration, typeArgumentAccessor);
else if (enclosingDeclaration instanceof TypeDeclaration) {
qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
}
}
if (qualifyingType != null && qualifyingType.isConstructor()) {
qualifyingType = qualifyingType.getQualifyingType();
}
if (qualifyingType != null) {
if (declaration.isStatic() && supportsReified(declaration)) {
// There is no outer instance with a $reified$T field
final Type t = pt;
containerType = makeReifiedTypeArgumentResolved(qualifyingType, true, new TypeArgumentAccessor() {
public JCExpression getTypeDescriptor(TypeParameter tp, boolean qualified) {
return makeSelect(naming.makeQualifiedThis(makeJavaType(t, JT_RAW)), naming.getTypeArgumentDescriptorName(tp));
}
}, false);
} else {
containerType = makeReifiedTypeArgumentResolved(qualifyingType, true, typeArgumentAccessor, // we want raw containers, since we can't capture their TPs
declaration.isStatic());
}
}
if (containerType == null) {
return classDescriptor;
} else {
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, classDescriptor));
}
} else if (pt.isTypeParameter()) {
return typeArgumentAccessor.getTypeDescriptor((TypeParameter) declaration, qualified);
} else {
throw BugException.unhandledDeclarationCase(declaration);
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewArray in project ceylon by eclipse.
the class ExpressionTransformer method transformArgumentsForSimpleInvocation.
private List<ExpressionAndType> transformArgumentsForSimpleInvocation(SimpleInvocation invocation, CallBuilder callBuilder) {
final Constructor superConstructor = invocation.getConstructor();
CtorDelegation constructorDelegation;
if (invocation instanceof SuperInvocation) {
constructorDelegation = ((SuperInvocation) invocation).getDelegation();
} else {
constructorDelegation = null;
}
List<ExpressionAndType> result = List.<ExpressionAndType>nil();
if (!(invocation instanceof SuperInvocation) || !((SuperInvocation) invocation).isDelegationDelegation()) {
int numArguments = invocation.getNumArguments();
if (invocation.getNumParameters() == 0) {
// skip transforming arguments
// (Usually, numArguments would already be null, but it's possible to call a
// parameterless function with a *[] argument - see #1593.)
numArguments = 0;
}
boolean wrapIntoArray = false;
ListBuffer<JCExpression> arrayWrap = new ListBuffer<JCExpression>();
for (int argIndex = 0; argIndex < numArguments; argIndex++) {
BoxingStrategy boxingStrategy = invocation.getParameterBoxingStrategy(argIndex);
Type parameterType = invocation.getParameterType(argIndex);
// to avoid ambiguity of foo(1,2) for foo(int...) and foo(Object...) methods
if (!wrapIntoArray && invocation.isParameterJavaVariadic(argIndex) && boxingStrategy == BoxingStrategy.UNBOXED && willEraseToPrimitive(typeFact().getDefiniteType(parameterType)) && !invocation.isSpread())
wrapIntoArray = true;
ExpressionAndType exprAndType;
if (invocation.isArgumentSpread(argIndex)) {
if (!invocation.isParameterSequenced(argIndex)) {
result = transformSpreadTupleArgument(invocation, callBuilder, result, argIndex);
break;
}
if (invocation.isJavaVariadicMethod()) {
// if it's a java method we need a special wrapping
exprAndType = transformSpreadArgument(invocation, numArguments, argIndex, boxingStrategy, parameterType);
argIndex = numArguments;
} else {
Type argType = invocation.getArgumentType(argIndex);
if (argType.getSupertype(typeFact().getSequentialDeclaration()) != null) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
} else if (argType.getSupertype(typeFact().getIterableDeclaration()) != null) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
JCExpression sequential = iterableToSequential(exprAndType.expression);
if (invocation.isParameterVariadicPlus(argIndex)) {
Type iteratedType = typeFact().getIteratedType(argType);
sequential = utilInvocation().castSequentialToSequence(sequential, iteratedType);
}
exprAndType = new ExpressionAndType(sequential, exprAndType.type);
} else if (typeFact().isJavaArrayType(argType)) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
JCExpression iterable;
if (typeFact().isJavaPrimitiveArrayType(argType)) {
iterable = utilInvocation().toIterable(exprAndType.expression);
} else {
Type elementType = typeFact().getJavaArrayElementType(argType);
iterable = utilInvocation().toIterable(makeJavaType(elementType, JT_TYPE_ARGUMENT), makeReifiedTypeArgument(elementType), exprAndType.expression);
}
exprAndType = new ExpressionAndType(make().Apply(null, makeSelect(iterable, "sequence"), List.<JCExpression>nil()), makeJavaType(argType));
} else if (typeFact().isJavaIterableType(argType)) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
Type elementType = typeFact().getJavaIteratedType(argType);
JCExpression iterable = utilInvocation().toIterable(makeJavaType(elementType, JT_TYPE_ARGUMENT), makeReifiedTypeArgument(elementType), exprAndType.expression);
exprAndType = new ExpressionAndType(make().Apply(null, makeSelect(iterable, "sequence"), List.<JCExpression>nil()), makeJavaType(argType));
} else {
exprAndType = new ExpressionAndType(makeErroneous(invocation.getNode(), "compiler bug: unexpected spread argument"), makeErroneous(invocation.getNode(), "compiler bug: unexpected spread argument"));
}
}
} else if (!invocation.isParameterSequenced(argIndex) || // if it's sequenced, Java and there's no spread at all, pass it along
(invocation.isParameterJavaVariadic(argIndex) && !invocation.isSpread())) {
exprAndType = transformArgument(invocation, argIndex, boxingStrategy);
// This is not required for primitive arrays since they are not Object[]
if (numArguments == 1 && invocation.isIndirect()) {
Type argumentType = invocation.getArgumentType(0);
if (isJavaObjectArray(argumentType) || isNull(argumentType)) {
exprAndType = new ExpressionAndType(make().TypeCast(makeJavaType(typeFact().getObjectType()), exprAndType.expression), exprAndType.type);
}
} else if (invocation.isParameterJavaVariadic(argIndex) && !invocation.isSpread()) {
// in fact, the very same problem happens when passing null or object arrays to a java variadic method
Type argumentType = invocation.getArgumentType(argIndex);
if (isJavaObjectArray(argumentType) || isNull(argumentType)) {
// remove any ambiguity
exprAndType = new ExpressionAndType(make().TypeCast(makeJavaType(parameterType), exprAndType.expression), exprAndType.type);
}
}
} else {
// we must have a sequenced param
if (invocation.isSpread()) {
exprAndType = transformSpreadArgument(invocation, numArguments, argIndex, boxingStrategy, parameterType);
argIndex = numArguments;
} else {
exprAndType = transformVariadicArgument(invocation, numArguments, argIndex, parameterType);
argIndex = numArguments;
}
}
if (!wrapIntoArray) {
if (argIndex == 0 && invocation.isCallable() && !invocation.isArgumentSpread(numArguments - 1)) {
exprAndType = new ExpressionAndType(make().TypeCast(make().Type(syms().objectType), exprAndType.expression), make().Type(syms().objectType));
}
result = result.append(exprAndType);
} else {
arrayWrap.append(exprAndType.expression);
}
}
if (invocation.isIndirect() && invocation.getNumParameters() > numArguments && invocation.isParameterSequenced(numArguments) && !invocation.isArgumentSpread(numArguments - 1)) {
// Calling convention for indirect variadic invocation's requires
// explicit variadic argument (can't use the overloading trick)
result = result.append(new ExpressionAndType(makeEmptyAsSequential(true), make().Erroneous()));
}
if (wrapIntoArray) {
// must have at least one arg, so take the last one
Type parameterType = invocation.getParameterType(numArguments - 1);
JCExpression arrayType = makeJavaType(parameterType, JT_RAW);
JCNewArray arrayExpr = make().NewArray(arrayType, List.<JCExpression>nil(), arrayWrap.toList());
JCExpression arrayTypeExpr = make().TypeArray(makeJavaType(parameterType, JT_RAW));
result = result.append(new ExpressionAndType(arrayExpr, arrayTypeExpr));
}
} else {
for (Parameter p : constructorDelegation.getConstructor().getParameterList().getParameters()) {
result = result.append(new ExpressionAndType(naming.makeName(p.getModel(), Naming.NA_IDENT | Naming.NA_ALIASED), null));
}
}
boolean concreteDelegation = invocation instanceof SuperInvocation && ((SuperInvocation) invocation).getDelegation().isConcreteSelfDelegation();
if (superConstructor == null && concreteDelegation) {
Constructor delegateTo = ((SuperInvocation) invocation).getDelegation().getConstructor();
result = result.prepend(new ExpressionAndType(naming.makeNamedConstructorName(delegateTo, true), naming.makeNamedConstructorType(delegateTo, true)));
} else if (superConstructor != null && constructorDelegation != null && constructorDelegation.isSelfDelegation()) {
result = result.prepend(new ExpressionAndType(naming.makeNamedConstructorName(constructorDelegation.getExtendingConstructor(), concreteDelegation), naming.makeNamedConstructorType(constructorDelegation.getExtendingConstructor(), concreteDelegation)));
} else if (superConstructor != null && !Decl.isDefaultConstructor(superConstructor) && !Decl.isJavaArrayWith(superConstructor) && (invocation.getQmePrimary() instanceof Tree.QualifiedTypeExpression == false || !isCeylonCallable(((Tree.QualifiedTypeExpression) invocation.getQmePrimary()).getPrimary().getTypeModel()))) {
result = result.prepend(new ExpressionAndType(naming.makeNamedConstructorName(superConstructor, concreteDelegation), naming.makeNamedConstructorType(superConstructor, concreteDelegation)));
}
return result;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewArray in project ceylon by eclipse.
the class CollectionLiteralAnnotationTerm method makeDpmAnnotations.
@Override
public org.eclipse.ceylon.langtools.tools.javac.util.List<JCAnnotation> makeDpmAnnotations(ExpressionTransformer exprGen) {
if (factory == null) {
// A tuple
// TODO @TupleValue({elements...})
} else {
// A sequence
ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>();
for (AnnotationTerm term : elements) {
lb.add(((LiteralAnnotationTerm) term).makeLiteral(exprGen));
}
JCNewArray array = exprGen.make().NewArray(null, null, lb.toList());
return factory.makeAtValue(exprGen, null, array);
}
return org.eclipse.ceylon.langtools.tools.javac.util.List.<JCAnnotation>nil();
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewArray in project ceylon by eclipse.
the class CollectionLiteralAnnotationTerm method makeLiteral.
@Override
protected JCExpression makeLiteral(ExpressionTransformer exprGen) {
ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>();
for (AnnotationTerm term : elements) {
lb.add(((LiteralAnnotationTerm) term).makeLiteral(exprGen));
}
JCNewArray array = exprGen.make().NewArray(null, null, lb.toList());
return array;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewArray in project ceylon by eclipse.
the class JavaPositionsRetriever method getJavaSourceCodeWithCeylonPositions.
public String getJavaSourceCodeWithCeylonPositions() {
final CharArrayWriter writer = new CharArrayWriter();
Pretty printer = new Pretty(writer, true) {
int previousCeylonPosition = -1;
int previousPositionInString = 0;
private void outputCeylonPosition(JCTree tree) {
try {
int currentCeylonPosition = tree.getPreferredPosition();
int currentPositionInString = writer.size();
if (previousCeylonPosition != currentCeylonPosition || previousPositionInString != currentPositionInString) {
if (currentCeylonPosition != -1 && currentCeylonPosition != 0) {
writer.write("/* " + formatCeylonPosition(currentCeylonPosition) + " */");
}
previousCeylonPosition = currentCeylonPosition;
previousPositionInString = writer.size();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void visitTopLevel(JCCompilationUnit tree) {
outputCeylonPosition(tree);
super.visitTopLevel(tree);
}
@Override
public void visitImport(JCImport tree) {
outputCeylonPosition(tree);
super.visitImport(tree);
}
@Override
public void visitClassDef(JCClassDecl tree) {
outputCeylonPosition(tree);
super.visitClassDef(tree);
}
@Override
public void visitMethodDef(JCMethodDecl tree) {
outputCeylonPosition(tree);
super.visitMethodDef(tree);
}
@Override
public void visitVarDef(JCVariableDecl tree) {
outputCeylonPosition(tree);
super.visitVarDef(tree);
}
@Override
public void visitSkip(JCSkip tree) {
outputCeylonPosition(tree);
super.visitSkip(tree);
}
@Override
public void visitBlock(JCBlock tree) {
outputCeylonPosition(tree);
super.visitBlock(tree);
tree.endpos = currentPosition - 1;
}
@Override
public void visitDoLoop(JCDoWhileLoop tree) {
outputCeylonPosition(tree);
super.visitDoLoop(tree);
}
@Override
public void visitWhileLoop(JCWhileLoop tree) {
outputCeylonPosition(tree);
super.visitWhileLoop(tree);
}
@Override
public void visitForLoop(JCForLoop tree) {
outputCeylonPosition(tree);
super.visitForLoop(tree);
}
@Override
public void visitForeachLoop(JCEnhancedForLoop tree) {
outputCeylonPosition(tree);
super.visitForeachLoop(tree);
}
@Override
public void visitLabelled(JCLabeledStatement tree) {
outputCeylonPosition(tree);
super.visitLabelled(tree);
}
@Override
public void visitSwitch(JCSwitch tree) {
outputCeylonPosition(tree);
super.visitSwitch(tree);
}
@Override
public void visitCase(JCCase tree) {
outputCeylonPosition(tree);
super.visitCase(tree);
}
@Override
public void visitSynchronized(JCSynchronized tree) {
outputCeylonPosition(tree);
super.visitSynchronized(tree);
}
@Override
public void visitTry(JCTry tree) {
outputCeylonPosition(tree);
super.visitTry(tree);
}
@Override
public void visitCatch(JCCatch tree) {
outputCeylonPosition(tree);
super.visitCatch(tree);
}
@Override
public void visitConditional(JCConditional tree) {
outputCeylonPosition(tree);
super.visitConditional(tree);
}
@Override
public void visitIf(JCIf tree) {
outputCeylonPosition(tree);
super.visitIf(tree);
}
@Override
public void visitExec(JCExpressionStatement tree) {
outputCeylonPosition(tree);
super.visitExec(tree);
}
@Override
public void visitBreak(JCBreak tree) {
outputCeylonPosition(tree);
super.visitBreak(tree);
}
@Override
public void visitContinue(JCContinue tree) {
outputCeylonPosition(tree);
super.visitContinue(tree);
}
@Override
public void visitReturn(JCReturn tree) {
outputCeylonPosition(tree);
super.visitReturn(tree);
}
@Override
public void visitThrow(JCThrow tree) {
outputCeylonPosition(tree);
super.visitThrow(tree);
}
@Override
public void visitAssert(JCAssert tree) {
outputCeylonPosition(tree);
super.visitAssert(tree);
}
@Override
public void visitApply(JCMethodInvocation tree) {
outputCeylonPosition(tree);
super.visitApply(tree);
}
@Override
public void visitNewClass(JCNewClass tree) {
outputCeylonPosition(tree);
super.visitNewClass(tree);
}
@Override
public void visitNewArray(JCNewArray tree) {
outputCeylonPosition(tree);
super.visitNewArray(tree);
}
@Override
public void visitParens(JCParens tree) {
outputCeylonPosition(tree);
super.visitParens(tree);
}
@Override
public void visitAssign(JCAssign tree) {
outputCeylonPosition(tree);
super.visitAssign(tree);
}
@Override
public void visitAssignop(JCAssignOp tree) {
outputCeylonPosition(tree);
super.visitAssignop(tree);
}
@Override
public void visitUnary(JCUnary tree) {
outputCeylonPosition(tree);
super.visitUnary(tree);
}
@Override
public void visitBinary(JCBinary tree) {
outputCeylonPosition(tree);
super.visitBinary(tree);
}
@Override
public void visitTypeCast(JCTypeCast tree) {
outputCeylonPosition(tree);
super.visitTypeCast(tree);
}
@Override
public void visitTypeTest(JCInstanceOf tree) {
outputCeylonPosition(tree);
super.visitTypeTest(tree);
}
@Override
public void visitIndexed(JCArrayAccess tree) {
outputCeylonPosition(tree);
super.visitIndexed(tree);
}
@Override
public void visitSelect(JCFieldAccess tree) {
outputCeylonPosition(tree);
super.visitSelect(tree);
}
@Override
public void visitIdent(JCIdent tree) {
outputCeylonPosition(tree);
super.visitIdent(tree);
}
@Override
public void visitLiteral(JCLiteral tree) {
outputCeylonPosition(tree);
super.visitLiteral(tree);
}
@Override
public void visitTypeIdent(JCPrimitiveTypeTree tree) {
outputCeylonPosition(tree);
super.visitTypeIdent(tree);
}
@Override
public void visitTypeArray(JCArrayTypeTree tree) {
outputCeylonPosition(tree);
super.visitTypeArray(tree);
}
@Override
public void visitTypeApply(JCTypeApply tree) {
outputCeylonPosition(tree);
super.visitTypeApply(tree);
}
@Override
public void visitTypeParameter(JCTypeParameter tree) {
outputCeylonPosition(tree);
super.visitTypeParameter(tree);
}
@Override
public void visitWildcard(JCWildcard tree) {
outputCeylonPosition(tree);
super.visitWildcard(tree);
}
@Override
public void visitTypeBoundKind(TypeBoundKind tree) {
outputCeylonPosition(tree);
super.visitTypeBoundKind(tree);
}
@Override
public void visitErroneous(JCErroneous tree) {
outputCeylonPosition(tree);
super.visitErroneous(tree);
}
@Override
public void visitLetExpr(LetExpr tree) {
outputCeylonPosition(tree);
super.visitLetExpr(tree);
}
@Override
public void visitModifiers(JCModifiers mods) {
outputCeylonPosition(mods);
super.visitModifiers(mods);
}
@Override
public void visitAnnotation(JCAnnotation tree) {
outputCeylonPosition(tree);
super.visitAnnotation(tree);
}
@Override
public void visitTree(JCTree tree) {
outputCeylonPosition(tree);
super.visitTree(tree);
}
};
printer.visitTopLevel(unit);
return writer.toString();
}
Aggregations