use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class AbstractTransformer method isInheritedWithDifferentTypeArguments.
protected Type isInheritedWithDifferentTypeArguments(Scope container, Type currentType) {
// only interfaces can be inherited twice
if (container instanceof Interface == false)
return null;
if (currentType.getDeclaration() instanceof ClassOrInterface == false)
return null;
Interface iface = (Interface) container;
// if we have no type parameter there's no problem
if (iface.getTypeParameters().isEmpty())
return null;
Type[] arg = new Type[1];
return findFirstInheritedTypeIfInheritedTwiceWithDifferentTypeArguments(iface, currentType, arg);
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class AbstractTransformer method makeJavaType.
JCExpression makeJavaType(final Type ceylonType, final int flags) {
Type type = ceylonType;
if (type == null || type.isUnknown())
return make().Erroneous();
if (type.isConstructor()) {
type = type.getExtendedType();
}
// resolve aliases
if ((flags & JT_CLASS_LITERAL) == 0)
type = type.resolveAliases();
if ((flags & __JT_RAW_TP_BOUND) != 0 && type.isTypeParameter()) {
type = type.getExtendedType();
}
if (type.isUnion()) {
for (Type pt : type.getCaseTypes()) {
if (pt.getDeclaration().isAnonymous()) {
// found one, let's try to make it simpler
Type simplerType = typeFact().denotableType(type);
if (!simplerType.isNothing() && !simplerType.isUnion()) {
type = simplerType;
} else if (isCeylonBoolean(simplifyType(simplerType))) {
type = simplerType;
}
break;
}
}
}
if (type.isTypeConstructor()) {
return make().QualIdent(syms().ceylonAbstractTypeConstructorType.tsym);
}
// ERASURE
if ((flags & JT_CLASS_LITERAL) == 0 && // literals to the alias class
willEraseToObject(type)) {
// - The Ceylon type U|V results in the Java type Object
if ((flags & JT_SATISFIES) != 0) {
return null;
} else {
return make().Type(syms().objectType);
}
} else if (willEraseToAnnotation(type)) {
return make().Type(syms().annotationType);
} else if (willEraseToException(type)) {
if ((flags & JT_CLASS_NEW) != 0 || (flags & JT_EXTENDS) != 0) {
return makeIdent(syms().ceylonExceptionType);
} else {
return make().Type(syms().exceptionType);
}
} else if (willEraseToThrowable(type)) {
if ((flags & JT_CLASS_NEW) != 0 || (flags & JT_EXTENDS) != 0) {
return makeIdent(syms().throwableType);
} else {
return make().Type(syms().throwableType);
}
} else if (willEraseToSequence(type)) {
if ((flags & (JT_CLASS_NEW | JT_EXTENDS | JT_IS)) == 0) {
Type typeArg = simplifyType(type).getTypeArgumentList().get(0);
Type seqType = typeFact.getSequenceType(typeArg);
if (typeFact.isOptionalType(type)) {
type = typeFact.getOptionalType(seqType);
} else {
type = seqType;
}
}
} else if ((flags & (JT_SATISFIES | JT_EXTENDS | JT_NO_PRIMITIVES | JT_CLASS_NEW)) == 0 && ((isCeylonBasicType(type) && !isOptional(type)) || isJavaString(type))) {
if (isCeylonString(type) || isJavaString(type)) {
return make().Type(syms().stringType);
} else if (isCeylonBoolean(type)) {
return make().TypeIdent(TypeTag.BOOLEAN);
} else if (isCeylonInteger(type)) {
if ("short".equals(type.getUnderlyingType())) {
return make().TypeIdent(TypeTag.SHORT);
} else if ((flags & JT_SMALL) != 0 || "int".equals(type.getUnderlyingType())) {
return make().TypeIdent(TypeTag.INT);
} else {
return make().TypeIdent(TypeTag.LONG);
}
} else if (isCeylonFloat(type)) {
if ((flags & JT_SMALL) != 0 || "float".equals(type.getUnderlyingType())) {
return make().TypeIdent(TypeTag.FLOAT);
} else {
return make().TypeIdent(TypeTag.DOUBLE);
}
} else if (isCeylonCharacter(type)) {
if ((flags & JT_SMALL) != 0 || "char".equals(type.getUnderlyingType())) {
return make().TypeIdent(TypeTag.CHAR);
} else {
return make().TypeIdent(TypeTag.INT);
}
} else if (isCeylonByte(type)) {
return make().TypeIdent(TypeTag.BYTE);
}
} else if (isCeylonBoolean(type) && !isTypeParameter(type)) {
// && (flags & TYPE_ARGUMENT) == 0){
// special case to get rid of $true and $false types
type = typeFact.getBooleanType();
} else if ((flags & JT_VALUE_TYPE) == 0 && isJavaArray(type)) {
return getJavaArrayElementType(type, flags);
}
JCExpression jt = null;
Type simpleType;
if ((flags & JT_CLASS_LITERAL) == 0)
simpleType = simplifyType(type);
else
simpleType = type;
// see if we need to cross methods when looking up container types
// this is required to properly collect all the type parameters for local interfaces
// which we pull up to the toplevel and capture all the container type parameters
boolean needsQualifyingTypeArgumentsFromLocalContainers = ModelUtil.isCeylonDeclaration(simpleType.getDeclaration()) && simpleType.getDeclaration() instanceof Interface && // this is only valid for interfaces, not for their companion which stay where they are
(flags & JT_COMPANION) == 0;
java.util.List<Reference> qualifyingTypes = null;
Reference qType = simpleType;
boolean hasTypeParameters = false;
while (qType != null) {
hasTypeParameters |= !qType.getTypeArguments().isEmpty();
if (qualifyingTypes != null)
qualifyingTypes.add(qType);
Declaration typeDeclaration = qType.getDeclaration();
// all the containing type parameters that it captures
if (// local or anonymous
(Decl.isLocal(typeDeclaration) || !typeDeclaration.isNamed()) && needsQualifyingTypeArgumentsFromLocalContainers && typeDeclaration instanceof ClassOrInterface) {
Declaration container = Decl.getDeclarationScope(typeDeclaration.getContainer());
while (container instanceof Function) {
qType = ((Function) container).getReference();
if (qualifyingTypes == null) {
qualifyingTypes = new java.util.ArrayList<Reference>();
qualifyingTypes.add(simpleType);
}
hasTypeParameters = true;
qualifyingTypes.add(qType);
container = Decl.getDeclarationScope(container.getContainer());
}
if (container instanceof TypeDeclaration) {
qType = ((TypeDeclaration) container).getType();
} else {
qType = null;
}
} else if (typeDeclaration.isNamed()) {
// avoid anonymous types which may pretend that they have a qualifying type
Reference oldType = qType;
qType = qType.getQualifyingType();
if (qType != null && qType.getDeclaration() instanceof ClassOrInterface == false) {
// sometimes the typechecker throws qualifying intersections at us and
// we can't make anything of them, since some members may be unrelated to
// the qualified declaration. This happens with "extends super.Foo()"
// for example. See https://github.com/ceylon/ceylon-compiler/issues/1478
qType = ((Type) qType).getSupertype((TypeDeclaration) typeDeclaration.getContainer());
}
if (qType != null && !qType.equals(ceylonType) && // ceylonType.getDeclaration().getContainer() instanceof Interface &&
oldType.getDeclaration().getContainer() instanceof Interface && // !ceylonType.getDeclaration().getContainer().equals(ceylonType.getQualifyingType().getDeclaration()) &&
!oldType.getDeclaration().getContainer().equals(oldType.getQualifyingType().getDeclaration()) && (flags & JT_EXTENDS) == 0) {
qType = oldType.getQualifyingType().getSupertype(((Interface) (oldType.getDeclaration().getContainer())));
}
} else {
// skip local declaration containers
qType = null;
}
// delayed allocation if we have a qualifying type
if (qualifyingTypes == null && qType != null) {
qualifyingTypes = new java.util.ArrayList<Reference>();
qualifyingTypes.add(simpleType);
}
}
int firstQualifyingTypeWithTypeParameters = qualifyingTypes != null ? qualifyingTypes.size() - 1 : 0;
// find the first static one, from the right to the left
if (qualifyingTypes != null) {
for (Reference pt : qualifyingTypes) {
Declaration declaration = pt.getDeclaration();
if (declaration instanceof TypeDeclaration && Decl.isStatic((TypeDeclaration) declaration)) {
break;
}
firstQualifyingTypeWithTypeParameters--;
}
if (firstQualifyingTypeWithTypeParameters < 0)
firstQualifyingTypeWithTypeParameters = 0;
// put them in outer->inner order
Collections.reverse(qualifyingTypes);
}
if (((flags & JT_RAW) == 0) && hasTypeParameters && !rawSupertype(ceylonType, flags)) {
// special case for interfaces because we pull them into toplevel types
if (ModelUtil.isCeylonDeclaration(simpleType.getDeclaration()) && qualifyingTypes != null && qualifyingTypes.size() > 1 && simpleType.getDeclaration() instanceof Interface && // this is only valid for interfaces, not for their companion which stay where they are
(flags & JT_COMPANION) == 0) {
JCExpression baseType;
TypeDeclaration tdecl = simpleType.getDeclaration();
// collect all the qualifying type args we'd normally have
java.util.List<TypeParameter> qualifyingTypeParameters = new java.util.ArrayList<TypeParameter>();
java.util.Map<TypeParameter, Type> qualifyingTypeArguments = new java.util.HashMap<TypeParameter, Type>();
collectQualifyingTypeArguments(qualifyingTypeParameters, qualifyingTypeArguments, qualifyingTypes);
ListBuffer<JCExpression> typeArgs = makeTypeArgs(isCeylonCallable(simpleType), flags, qualifyingTypeArguments, qualifyingTypeParameters, simpleType);
if (isCeylonCallable(type) && (flags & JT_CLASS_NEW) != 0) {
baseType = makeIdent(syms().ceylonAbstractCallableType);
} else {
baseType = naming.makeDeclarationName(tdecl, DeclNameFlag.QUALIFIED);
}
if (typeArgs != null && typeArgs.size() > 0) {
jt = make().TypeApply(baseType, typeArgs.toList());
} else {
jt = baseType;
}
} else if ((flags & JT_NON_QUALIFIED) == 0) {
int index = 0;
if (qualifyingTypes != null) {
for (Reference qualifyingType : qualifyingTypes) {
if (!qualifyingType.getDeclaration().equals(simpleType.getDeclaration()) && simpleType.getDeclaration().isStatic()) {
jt = makeRawType(flags, (Type) qualifyingType, (Type) qualifyingType);
} else {
jt = makeParameterisedType(qualifyingType.getType(), type, flags | (simpleType.getDeclaration().isStatic() ? JT_RAW : 0), jt, qualifyingTypes, firstQualifyingTypeWithTypeParameters, index);
}
index++;
}
} else {
jt = makeParameterisedType(simpleType, type, flags, jt, qualifyingTypes, firstQualifyingTypeWithTypeParameters, index);
}
} else {
jt = makeParameterisedType(type, type, flags, jt, qualifyingTypes, 0, 0);
}
} else {
jt = makeRawType(flags, type, simpleType);
}
return (jt != null) ? jt : makeErroneous(null, "compiler bug: the java type corresponding to " + ceylonType + " could not be computed");
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class IndexDoc method indexMembers.
private void indexMembers(Scope container, List<Declaration> members) throws IOException {
for (Declaration decl : members) {
if (!tool.shouldInclude(decl)) {
continue;
}
if (decl instanceof ClassOrInterface) {
ClassOrInterface classOrInterface = (ClassOrInterface) decl;
indexMembers(classOrInterface, classOrInterface.getMembers());
}
if (indexDecl(container, decl)) {
write(",\n");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class CeylonDocTool method collectSubclasses.
private void collectSubclasses() throws IOException {
for (Module module : modules) {
for (Package pkg : getPackages(module)) {
for (Declaration decl : pkg.getMembers()) {
if (!shouldInclude(decl)) {
continue;
}
if (decl instanceof ClassOrInterface) {
ClassOrInterface c = (ClassOrInterface) decl;
// subclasses map
if (c instanceof Class) {
Type superclass = c.getExtendedType();
if (superclass != null) {
TypeDeclaration superdec = superclass.getDeclaration();
if (subclasses.get(superdec) == null) {
subclasses.put(superdec, new ArrayList<Class>());
}
subclasses.get(superdec).add((Class) c);
}
}
List<Type> satisfiedTypes = new ArrayList<Type>(c.getSatisfiedTypes());
if (satisfiedTypes != null && satisfiedTypes.isEmpty() == false) {
// satisfying classes or interfaces map
for (Type satisfiedType : satisfiedTypes) {
TypeDeclaration superdec = satisfiedType.getDeclaration();
if (satisfyingClassesOrInterfaces.get(superdec) == null) {
satisfyingClassesOrInterfaces.put(superdec, new ArrayList<ClassOrInterface>());
}
satisfyingClassesOrInterfaces.get(superdec).add(c);
}
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class GenerateJsVisitor method referenceOuter.
void referenceOuter(TypeDeclaration d) {
if (!d.isToplevel() && !d.isStatic()) {
final ClassOrInterface coi = ModelUtil.getContainingClassOrInterface(d.getContainer());
if (coi != null) {
out(names.self(d), ".outer$");
if (d.isClassOrInterfaceMember()) {
if (d.isStatic()) {
out("=", names.name(coi));
} else {
out("=this");
}
} else {
out("=", names.self(coi));
}
endLine(true);
}
}
}
Aggregations