use of org.eclipse.ceylon.model.typechecker.model.UnknownType in project ceylon by eclipse.
the class DeclarationVisitor method initFunctionOverload.
// An overloaded function is represented in
// the model with multiple Function objects
private static boolean initFunctionOverload(Function model, Function member, Scope scope, Unit unit) {
Function abstraction;
Function method = (Function) member;
Function newMethod = (Function) model;
newMethod.setOverloaded(true);
if (method.isAbstraction()) {
abstraction = method;
abstraction.getOverloads().add(model);
return abstraction.isActual() && !model.isActual();
} else {
String name = model.getName();
// create the "abstraction"
// for the overloaded method
method.setOverloaded(true);
abstraction = new Function();
abstraction.setAbstraction(true);
abstraction.setType(new UnknownType(unit).getType());
abstraction.setName(name);
abstraction.setShared(true);
abstraction.setActual(method.isActual());
abstraction.setFormal(method.isFormal());
abstraction.setDefault(method.isDefault());
abstraction.setContainer(scope);
abstraction.setScope(scope);
abstraction.setUnit(unit);
abstraction.initOverloads(method, newMethod);
scope.addMember(abstraction);
// put the abstraction first
// TODO: is this hack really necessary?
scope.getMembers().remove(method);
scope.getMembers().add(method);
return true;
}
}
use of org.eclipse.ceylon.model.typechecker.model.UnknownType in project ceylon by eclipse.
the class TypeVisitor method getTupleType.
static Type getTupleType(List<Tree.Type> ets, Unit unit) {
List<Type> args = new ArrayList<Type>(ets.size());
boolean sequenced = false;
boolean atleastone = false;
int firstDefaulted = -1;
for (int i = 0; i < ets.size(); i++) {
Tree.Type st = ets.get(i);
Type arg = st == null ? null : st.getTypeModel();
if (arg == null) {
arg = new UnknownType(unit).getType();
} else if (st instanceof Tree.SpreadType) {
// X, Y, *Zs
return st.getTypeModel();
} else if (st instanceof Tree.DefaultedType) {
if (firstDefaulted == -1) {
firstDefaulted = i;
}
} else if (st instanceof Tree.SequencedType) {
if (i != ets.size() - 1) {
st.addError("variant element must occur last in a tuple type");
} else {
sequenced = true;
Tree.SequencedType sst = (Tree.SequencedType) st;
atleastone = sst.getAtLeastOne();
arg = sst.getType().getTypeModel();
}
if (firstDefaulted != -1 && atleastone) {
st.addError("nonempty variadic element must occur after defaulted elements in a tuple type");
}
} else {
if (firstDefaulted != -1) {
st.addError("required element must occur after defaulted elements in a tuple type");
}
}
args.add(arg);
}
return getTupleType(args, sequenced, atleastone, firstDefaulted, unit);
}
use of org.eclipse.ceylon.model.typechecker.model.UnknownType in project ceylon by eclipse.
the class TypeVisitor method visit.
@Override
public void visit(Tree.ExtendedType that) {
inExtendsOrClassAlias = that.getInvocationExpression() != null;
super.visit(that);
inExtendsOrClassAlias = false;
inheritedType(that.getType());
checkExtendedTypeExpression(that.getType());
TypeDeclaration td = (TypeDeclaration) that.getScope();
if (!td.isAlias()) {
Tree.SimpleType et = that.getType();
if (et != null) {
Type type = et.getTypeModel();
if (type != null) {
TypeDeclaration etd = et.getDeclarationModel();
if (etd != null && !(etd instanceof UnknownType)) {
if (etd instanceof Constructor) {
type = type.getExtendedType();
etd = etd.getExtendedType().getDeclaration();
}
if (etd == td) {
// unnecessary, handled by SupertypeVisitor
// et.addError("directly extends itself: '" +
// td.getName() + "'");
} else if (etd instanceof TypeParameter) {
et.addError("directly extends a type parameter: '" + type.getDeclaration().getName(unit) + "'");
} else if (etd instanceof Interface) {
et.addError("extends an interface: '" + type.getDeclaration().getName(unit) + "'");
} else if (etd instanceof TypeAlias) {
et.addError("extends a type alias: '" + type.getDeclaration().getName(unit) + "'");
} else if (etd instanceof NothingType) {
et.addError("extends the bottom type 'Nothing'");
} else {
td.setExtendedType(type);
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.UnknownType in project ceylon by eclipse.
the class AbstractModelLoader method obtainTypeParameterBound.
private Type obtainTypeParameterBound(Module moduleScope, TypeMirror type, Scope scope, Set<TypeDeclaration> rawDeclarationsSeen) {
// type variables are never mapped
if (type.getKind() == TypeKind.TYPEVAR) {
TypeParameterMirror typeParameter = type.getTypeParameter();
if (!typeParameter.getBounds().isEmpty()) {
List<Type> bounds = new ArrayList<Type>(typeParameter.getBounds().size());
for (TypeMirror bound : typeParameter.getBounds()) {
Type boundModel = obtainTypeParameterBound(moduleScope, bound, scope, rawDeclarationsSeen);
bounds.add(boundModel);
}
return intersection(bounds, getUnitForModule(moduleScope));
} else
// no bound is Object
return typeFactory.getObjectType();
} else {
TypeMirror mappedType = applyTypeMapping(type, TypeLocation.TYPE_PARAM);
TypeDeclaration declaration = (TypeDeclaration) convertNonPrimitiveTypeToDeclaration(moduleScope, mappedType, scope, DeclarationType.TYPE);
if (declaration == null) {
throw new RuntimeException("Failed to find declaration for " + type);
}
if (declaration instanceof UnknownType)
return declaration.getType();
Type ret = applyTypeArguments(moduleScope, declaration, type, scope, TypeMappingMode.GENERATOR, rawDeclarationsSeen);
if (ret.isCached()) {
ret = ret.clone();
}
if (ret.getUnderlyingType() == null) {
ret.setUnderlyingType(getUnderlyingType(type, TypeLocation.TYPE_PARAM));
}
return ret;
}
}
use of org.eclipse.ceylon.model.typechecker.model.UnknownType in project ceylon by eclipse.
the class AbstractModelLoader method setExtendedType.
private void setExtendedType(ClassOrInterface klass, ClassMirror classMirror) {
// look at its super type
TypeMirror superClass = classMirror.getSuperclass();
Type extendedType;
if (klass instanceof Interface) {
// interfaces need to have their superclass set to Object
if (superClass == null || superClass.getKind() == TypeKind.NONE)
extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_OBJECT_TYPE, klass);
else
extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
} else if (klass instanceof Class && ((Class) klass).isOverloaded()) {
// if the class is overloaded we already have it stored
extendedType = klass.getExtendedType();
} else {
String className = classMirror.getQualifiedName();
String superClassName = superClass == null ? null : superClass.getQualifiedName();
if (className.equals("ceylon.language.Anything")) {
// ceylon.language.Anything has no super type
extendedType = null;
} else if (className.equals("java.lang.Object")) {
// we pretend its superclass is something else, but note that in theory we shouldn't
// be seeing j.l.Object at all due to unerasure
extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
} else {
// read it from annotation first
String annotationSuperClassName = getAnnotationStringValue(classMirror, CEYLON_CLASS_ANNOTATION, "extendsType");
if (annotationSuperClassName != null && !annotationSuperClassName.isEmpty()) {
extendedType = decodeType(annotationSuperClassName, klass, ModelUtil.getModuleContainer(klass), "extended type");
} else {
// now deal with type erasure, avoid having Object as superclass
if ("java.lang.Object".equals(superClassName)) {
extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
} else if (superClass != null) {
try {
extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
} catch (ModelResolutionException x) {
extendedType = logModelResolutionException(x, klass, "Error while resolving extended type of " + klass.getQualifiedNameString());
}
} else {
// FIXME: should this be UnknownType?
extendedType = null;
}
}
}
}
if (extendedType != null)
klass.setExtendedType(extendedType);
}
Aggregations