use of org.eclipse.ceylon.model.typechecker.model.SiteVariance 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.model.typechecker.model.SiteVariance in project ceylon by eclipse.
the class AnalyzerUtil method getVariances.
static List<SiteVariance> getVariances(Tree.TypeArguments tas, List<TypeParameter> typeParameters) {
if (tas instanceof Tree.TypeArgumentList) {
Tree.TypeArgumentList tal = (Tree.TypeArgumentList) tas;
int size = typeParameters.size();
List<SiteVariance> variances = new ArrayList<SiteVariance>(size);
List<Tree.Type> types = tal.getTypes();
int count = types.size();
for (int i = 0; i < count; i++) {
Tree.Type type = types.get(i);
if (type instanceof Tree.StaticType) {
Tree.StaticType st = (Tree.StaticType) type;
TypeVariance tv = st.getTypeVariance();
if (tv != null) {
boolean contra = tv.getText().equals("in");
variances.add(contra ? IN : OUT);
} else {
variances.add(null);
}
} else {
variances.add(null);
}
}
return variances;
} else {
return emptyList();
}
}
use of org.eclipse.ceylon.model.typechecker.model.SiteVariance in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.BaseType that) {
super.visit(that);
final Scope scope = that.getScope();
final String name = name(that.getIdentifier());
if (inExtends) {
final Tree.TypeArgumentList tal = that.getTypeArgumentList();
final boolean packageQualified = that.getPackageQualified();
Type t = new LazyType(unit) {
@Override
public TypeDeclaration initDeclaration() {
return packageQualified ? getPackageTypeDeclaration(name, null, false, unit) : getTypeDeclaration(scope, name, null, false, unit);
}
@Override
public Map<TypeParameter, Type> initTypeArguments() {
TypeDeclaration dec = getDeclaration();
List<TypeParameter> tps = dec.getTypeParameters();
return getTypeArgumentMap(dec, null, AnalyzerUtil.getTypeArguments(tal, null, tps));
}
@Override
public Map<TypeParameter, SiteVariance> initVarianceOverrides() {
TypeDeclaration dec = getDeclaration();
List<TypeParameter> tps = dec.getTypeParameters();
return getVarianceMap(dec, null, AnalyzerUtil.getVariances(tal, tps));
}
};
that.setTypeModel(t);
}
}
use of org.eclipse.ceylon.model.typechecker.model.SiteVariance in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.QualifiedType that) {
super.visit(that);
final String name = name(that.getIdentifier());
final Tree.StaticType outerType = that.getOuterType();
if (inExtends) {
final Tree.TypeArgumentList tal = that.getTypeArgumentList();
Type t = new LazyType(unit) {
@Override
public TypeDeclaration initDeclaration() {
if (outerType == null) {
return null;
} else {
TypeDeclaration dec = outerType.getTypeModel().getDeclaration();
return AnalyzerUtil.getTypeMember(dec, name, null, false, unit, scope);
}
}
@Override
public Map<TypeParameter, Type> initTypeArguments() {
if (outerType == null) {
return emptyMap();
} else {
TypeDeclaration dec = getDeclaration();
List<TypeParameter> tps = dec.getTypeParameters();
Type ot = outerType.getTypeModel();
return getTypeArgumentMap(dec, ot, AnalyzerUtil.getTypeArguments(tal, ot, tps));
}
}
@Override
public Map<TypeParameter, SiteVariance> initVarianceOverrides() {
TypeDeclaration dec = getDeclaration();
List<TypeParameter> tps = dec.getTypeParameters();
Type ot = outerType.getTypeModel();
return getVarianceMap(dec, ot, AnalyzerUtil.getVariances(tal, tps));
}
};
that.setTypeModel(t);
}
}
use of org.eclipse.ceylon.model.typechecker.model.SiteVariance in project ceylon by eclipse.
the class MetamodelGenerator method putTypeArguments.
private void putTypeArguments(Map<String, Object> container, Type pt, Declaration from) {
int tparmSize = 0;
Type t = pt;
while (t != null) {
tparmSize += t.getTypeArgumentList() == null ? 0 : t.getTypeArgumentList().size();
t = t.getQualifyingType();
}
if (tparmSize > 0) {
final Map<String, Map<String, Object>> targs = new HashMap<>(tparmSize);
t = pt;
while (t != null) {
final Map<TypeParameter, SiteVariance> usv = t.getVarianceOverrides();
if (t.getTypeArgumentList() != null && !t.getTypeArgumentList().isEmpty()) {
for (Map.Entry<TypeParameter, Type> targ : t.getTypeArguments().entrySet()) {
final Map<String, Object> tpmap = typeMap(targ.getValue(), from);
final SiteVariance variance = usv.get(targ.getKey());
if (variance != null) {
tpmap.put(MetamodelGenerator.KEY_US_VARIANCE, variance.ordinal());
}
targs.put(partiallyQualifiedName(targ.getKey().getDeclaration()) + "." + targ.getKey().getName(), tpmap);
}
}
t = t.getQualifyingType();
}
container.put(KEY_TYPE_ARGS, targs);
}
}
Aggregations