use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ClassTransformer method addAtMembers.
private void addAtMembers(ClassDefinitionBuilder classBuilder, ClassOrInterface model, Tree.ClassOrInterface def) {
List<JCExpression> members = List.nil();
for (Declaration member : model.getMembers()) {
if (member instanceof ClassOrInterface == false && member instanceof TypeAlias == false) {
continue;
}
TypeDeclaration innerType = (TypeDeclaration) member;
Tree.Declaration innerTypeTree = findInnerType(def, innerType.getName());
if (innerTypeTree != null) {
TransformationPlan plan = errors().hasDeclarationAndMarkBrokenness(innerTypeTree);
if (plan instanceof Drop) {
continue;
}
}
if (innerType.isAlias() && innerTypeTree != null && Decl.isAncestorLocal(innerTypeTree.getDeclarationModel()))
// for the same reason we do not generate aliases in transform(ClassOrInterface def) let's not list them
continue;
JCAnnotation atMember;
// interfaces are moved to toplevel so they can lose visibility of member types if they are local
if (Decl.isLocal(model) && model instanceof Interface)
atMember = makeAtMember(innerType.getName());
else
atMember = makeAtMember(innerType.getType());
members = members.prepend(atMember);
}
classBuilder.annotations(makeAtMembers(members));
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class CeylonVisitor method visit.
public void visit(Tree.ExtendedType extendedType) {
ClassOrInterface forDefinition = classBuilder.getForDefinition();
Type thisType = forDefinition != null ? forDefinition.getType() : null;
Type extended = extendedType.getType().getTypeModel();
if (extended.isConstructor()) {
extended = extended.getQualifyingType();
}
classBuilder.extending(thisType, extended);
gen.expressionGen().transformSuperInvocation(extendedType, classBuilder);
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ExpressionTransformer method transform.
public JCExpression transform(Tree.IndexExpression indexedExpr) {
// depends on the operator
Tree.ElementOrRange elementOrRange = indexedExpr.getElementOrRange();
if (elementOrRange instanceof Tree.Element) {
// foo[index] -- foo could be a Correspondence, Java List or Java Map
final AbstractIndexTransformer transformer;
final Type primaryType = indexedExpr.getPrimary().getTypeModel().resolveAliases();
Type leftType = primaryType.getSupertype(typeFact().getCorrespondenceDeclaration());
if (leftType != null) {
Type rightType = getTypeArgument(leftType, 0);
transformer = new CorrespondenceIndexTransformer(indexedExpr, leftType, rightType, getTypeArgument(leftType, 1));
} else {
leftType = primaryType.getSupertype(typeFact().getJavaListDeclaration());
if (leftType != null) {
Type rightType = typeFact().getIntegerType();
if (rightType.isCached()) {
rightType = rightType.clone();
}
rightType.setUnderlyingType("int");
transformer = new JavaListIndexTransformer(indexedExpr, leftType, rightType, getTypeArgument(leftType, 0));
} else {
leftType = primaryType.getSupertype(typeFact().getJavaMapDeclaration());
if (leftType != null) {
Type rightType = getTypeArgument(leftType, 0);
transformer = new JavaMapIndexTransformer(indexedExpr, leftType, rightType, getTypeArgument(leftType, 1));
} else if (isJavaArray(primaryType)) {
Type rightType = typeFact().getIntegerType();
if (rightType.isCached()) {
rightType = rightType.clone();
}
rightType.setUnderlyingType("int");
Type elementType;
if (isJavaObjectArray(primaryType)) {
leftType = primaryType.getSupertype(typeFact().getJavaObjectArrayDeclaration());
elementType = getTypeArgument(leftType, 0);
} else if (JvmBackendUtil.isJavaBooleanArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaBooleanArrayDeclaration().getType();
elementType = typeFact().getBooleanType();
} else if (JvmBackendUtil.isJavaByteArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaByteArrayDeclaration().getType();
elementType = typeFact().getByteType();
} else if (JvmBackendUtil.isJavaShortArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaShortArrayDeclaration().getType();
elementType = typeFact().getIntegerType();
} else if (JvmBackendUtil.isJavaIntArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaIntArrayDeclaration().getType();
elementType = typeFact().getIntegerType();
} else if (JvmBackendUtil.isJavaLongArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaLongArrayDeclaration().getType();
elementType = typeFact().getIntegerType();
} else if (JvmBackendUtil.isJavaFloatArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaFloatArrayDeclaration().getType();
elementType = typeFact().getFloatType();
} else if (JvmBackendUtil.isJavaDoubleArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaDoubleArrayDeclaration().getType();
elementType = typeFact().getFloatType();
} else if (JvmBackendUtil.isJavaCharArray(primaryType.getDeclaration())) {
leftType = typeFact().getJavaCharArrayDeclaration().getType();
elementType = typeFact().getCharacterType();
} else {
return makeErroneous(indexedExpr, "Unsupported primary for indexed expression");
}
transformer = new JavaArrayIndexTransformer(indexedExpr, leftType, rightType, elementType);
} else {
return makeErroneous(indexedExpr, "Unsupported primary for indexed expression");
}
}
}
return transformer.transform(indexedExpr);
} else {
// foo[start:end] or foo[start:length]
Type primaryType = indexedExpr.getPrimary().getTypeModel();
Type leftType = primaryType.getSupertype(typeFact().getRangedDeclaration());
Type rightType = getTypeArgument(leftType, 0);
Tree.ElementRange range = (Tree.ElementRange) indexedExpr.getElementOrRange();
// do the indices
JCExpression start = transformExpression(range.getLowerBound(), BoxingStrategy.BOXED, rightType);
// is this a span or segment?
String method;
final List<JCExpression> args;
if (range.getLowerBound() != null && range.getLength() != null) {
method = "measure";
JCExpression length = transformExpression(range.getLength(), BoxingStrategy.UNBOXED, typeFact().getIntegerType());
args = List.of(start, length);
} else if (range.getLowerBound() == null) {
method = "spanTo";
JCExpression end = transformExpression(range.getUpperBound(), BoxingStrategy.BOXED, rightType);
args = List.of(end);
} else if (range.getUpperBound() == null) {
method = "spanFrom";
args = List.of(start);
} else if (range.getLowerBound() != null && range.getUpperBound() != null) {
method = "span";
JCExpression end = transformExpression(range.getUpperBound(), BoxingStrategy.BOXED, rightType);
args = List.of(start, end);
} else {
method = "unknown";
args = List.<JCExpression>of(makeErroneous(range, "compiler bug: unhandled range"));
}
JCExpression lhs;
Tree.Primary primary = indexedExpr.getPrimary();
boolean isSuper = isSuper(primary);
if (isSuper || isSuperOf(primary)) {
Declaration member = primaryType.getDeclaration().getMember(method, null, false);
TypeDeclaration leftDeclaration = (TypeDeclaration) member.getContainer();
if (isSuper)
lhs = transformSuper(indexedExpr, leftDeclaration);
else
lhs = transformSuperOf(indexedExpr, indexedExpr.getPrimary(), method);
} else {
int flags = 0;
// See https://github.com/ceylon/ceylon/issues/6365
if (leftType.getDeclaration() instanceof ClassOrInterface && // even more disgusting: https://github.com/ceylon/ceylon/issues/6450
!isCeylonString(primaryType) && hasConstrainedTypeParameters(leftType.getDeclaration().getType()))
flags |= EXPR_EXPECTED_TYPE_HAS_CONSTRAINED_TYPE_PARAMETERS;
lhs = transformExpression(indexedExpr.getPrimary(), BoxingStrategy.BOXED, leftType, flags);
}
JCExpression result;
// Because tuple open span access has the type of the indexed element
// (not a sequential of the union of types in the ranged) a typecast may be required.
Type rangedSpanType = getTypeArgument(leftType, 2);
Type expectedType = indexedExpr.getTypeModel();
int flags = 0;
if (!expectedType.isExactly(rangedSpanType)) {
flags |= EXPR_DOWN_CAST;
// make sure we barf properly if we missed a heuristics
if (method.equals("spanFrom")) {
// make a "Util.<method>(lhs, start, end)" call
at(indexedExpr);
result = utilInvocation().tuple_spanFrom(args.prepend(lhs));
} else {
result = makeErroneous(indexedExpr, "compiler bug: only the spanFrom method should be specialised for Tuples");
}
} else {
// make a "lhs.<method>(start, end)" call
result = at(indexedExpr).Apply(List.<JCTree.JCExpression>nil(), makeSelect(lhs, method), args);
}
result = applyErasureAndBoxing(result, rangedSpanType, CodegenUtil.hasTypeErased(indexedExpr), true, BoxingStrategy.BOXED, expectedType, flags);
return result;
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ExpressionTransformer method makeTypeParameterDeclaration.
/**
* Makes an expression equivalent to the result of {@code `given T`}
* @param node
* @param declaration
* @return
*/
JCExpression makeTypeParameterDeclaration(Node node, TypeParameter declaration) {
Scope container = declaration.getContainer();
if (container instanceof Declaration) {
JCExpression containerExpr;
Declaration containerDeclaration = (Declaration) container;
if (containerDeclaration instanceof ClassOrInterface || containerDeclaration instanceof TypeAlias) {
JCExpression metamodelCall = makeTypeDeclarationLiteral((TypeDeclaration) containerDeclaration);
JCExpression metamodelCast = makeJavaType(typeFact().getLanguageModuleDeclarationTypeDeclaration("GenericDeclaration").getType(), JT_NO_PRIMITIVES);
containerExpr = make().TypeCast(metamodelCast, metamodelCall);
} else if (containerDeclaration.isToplevel()) {
containerExpr = makeTopLevelValueOrFunctionDeclarationLiteral(containerDeclaration);
} else {
containerExpr = makeMemberValueOrFunctionDeclarationLiteral(node, containerDeclaration);
}
// now it must be a ClassOrInterfaceDeclaration or a FunctionDeclaration, both of which have the method we need
return at(node).Apply(null, makeSelect(containerExpr, "getTypeParameterDeclaration"), List.of(ceylonLiteral(declaration.getName())));
} else {
return makeErroneous(node, "compiler bug: " + container + " is not a supported type parameter container");
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class InterfaceVisitor method visit.
@Override
public void visit(Tree.ClassOrInterface that) {
ClassOrInterface model = that.getDeclarationModel();
// and they are useless at runtime
if (!model.isAlias()) {
// we never need to collect other local declaration names since only interfaces compete in the $impl name range
if (model instanceof Interface)
collect(that, (Interface) model);
Set<String> old = localCompanionClasses;
localCompanionClasses = new HashSet<String>();
super.visit(that);
localCompanionClasses = old;
}
if (model instanceof Interface) {
((Interface) model).setCompanionClassNeeded(isInterfaceWithCode(model));
}
}
Aggregations