use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeReifiedTypeArgumentResolved.
private JCExpression makeReifiedTypeArgumentResolved(Type pt, boolean qualified) {
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()) {
if (declaration.isJavaEnum()) {
pt = pt.getExtendedType();
declaration = pt.getDeclaration();
}
// 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 = makeReifiedTypeArgumentsResolved(pt.getTypeArgumentList(), qualified);
JCExpression thisType = makeUnerasedClassLiteral(declaration);
// 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);
}
typeTestArguments = typeTestArguments.prepend(thisType);
JCExpression classDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "klass"), typeTestArguments);
Type qualifyingType = pt.getQualifyingType();
JCExpression containerType = null;
if (qualifyingType == null && // ignore qualifying types of static java declarations
(Decl.isCeylon(declaration) || !declaration.isStaticallyImportable())) {
// it may be contained in a function or value, and we want its type
Declaration enclosingDeclaration = getDeclarationContainer(declaration);
if (enclosingDeclaration instanceof TypedDeclaration)
containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration);
else if (enclosingDeclaration instanceof TypeDeclaration) {
qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
}
}
if (qualifyingType != null && qualifyingType.getDeclaration() instanceof Constructor) {
qualifyingType = qualifyingType.getQualifyingType();
}
if (qualifyingType != null) {
containerType = makeReifiedTypeArgumentResolved(qualifyingType, true);
}
if (containerType == null) {
return classDescriptor;
} else {
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, classDescriptor));
}
} else if (pt.isTypeParameter()) {
TypeParameter tp = (TypeParameter) declaration;
String name = naming.getTypeArgumentDescriptorName(tp);
if (!qualified || isTypeParameterSubstituted(tp))
return makeUnquotedIdent(name);
Scope container = tp.getContainer();
JCExpression qualifier = null;
if (container instanceof Class) {
qualifier = naming.makeQualifiedThis(makeJavaType(((Class) container).getType(), JT_RAW));
} else if (container instanceof Interface) {
qualifier = naming.makeQualifiedThis(makeJavaType(((Interface) container).getType(), JT_COMPANION | JT_RAW));
} else if (container instanceof Function) {
// name must be a unique name, as returned by getTypeArgumentDescriptorName
return makeUnquotedIdent(name);
} else {
throw BugException.unhandledCase(container);
}
return makeSelect(qualifier, name);
} else {
throw BugException.unhandledDeclarationCase(declaration);
}
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class AbstractTransformer method canUseFastFailTypeTest.
private boolean canUseFastFailTypeTest(Type type) {
if (type.getDeclaration() instanceof ClassOrInterface == false)
return false;
boolean isRaw = !type.getDeclaration().getTypeParameters().isEmpty();
Type qualifyingType = type.getQualifyingType();
if (qualifyingType == null && // ignore qualifying types of static java declarations
(Decl.isCeylon(type.getDeclaration()) || !type.getDeclaration().isStaticallyImportable())) {
Declaration declaration = type.getDeclaration();
boolean local = false;
do {
// getDeclarationContainer will skip some containers we don't want to consider, so it's not good
// for checking locality, rely on isLocal for that.
local |= Decl.isLocal(declaration);
// it may be contained in a function or value, and we want its type
Declaration enclosingDeclaration = getDeclarationContainer(declaration);
if (enclosingDeclaration instanceof TypedDeclaration) {
local = true;
// look up the containers
declaration = enclosingDeclaration;
} else if (enclosingDeclaration instanceof TypeDeclaration) {
// we can't do instanceof on a local whose outer types contain type parameters, unless the local is raw
if (enclosingDeclaration instanceof Generic && local && !isRaw && !((Generic) enclosingDeclaration).getTypeParameters().isEmpty())
return false;
// look up the containers
declaration = enclosingDeclaration;
} else {
// that's fucked up
break;
}
// go up every containing typed declaration
} while (declaration != null);
// we can fast-fail!
return true;
} else if (qualifyingType != null) {
// we can only fast-fail if the qualifying type can also be fast-failed
return canUseFastFailTypeTest(qualifyingType);
} else {
// we can fast-fail!
return true;
}
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class CeylonEnter method typeCheck.
private void typeCheck() {
final java.util.List<PhasedUnit> listOfUnits = phasedUnits.getPhasedUnits();
// Delegate to an external typechecker (e.g. the IDE build)
compilerDelegate.typeCheck(listOfUnits);
if (sp != null) {
sp.clearLine();
sp.log("Preparation phase");
}
int size = listOfUnits.size();
int i = 1;
// This phase is proper to the Java backend
ForcedCaptureVisitor fcv = new ForcedCaptureVisitor();
for (PhasedUnit pu : listOfUnits) {
if (sp != null)
progressPreparation(1, i++, size, pu);
Unit unit = pu.getUnit();
final CompilationUnit compilationUnit = pu.getCompilationUnit();
compilationUnit.visit(fcv);
for (Declaration d : unit.getDeclarations()) {
if (d instanceof TypedDeclaration && !(d instanceof Setter) && // skip already captured members
!d.isCaptured()) {
compilationUnit.visit(new MethodOrValueReferenceVisitor((TypedDeclaration) d));
}
}
}
UnsupportedVisitor uv = new UnsupportedVisitor();
JvmMissingNativeVisitor mnv = new JvmMissingNativeVisitor(modelLoader);
BoxingDeclarationVisitor boxingDeclarationVisitor = new CompilerBoxingDeclarationVisitor(gen);
BoxingVisitor boxingVisitor = new CompilerBoxingVisitor(gen);
DeferredVisitor deferredVisitor = new DeferredVisitor();
AnnotationModelVisitor amv = new AnnotationModelVisitor(gen);
DefiniteAssignmentVisitor dav = new DefiniteAssignmentVisitor();
TypeParameterCaptureVisitor tpCaptureVisitor = new TypeParameterCaptureVisitor();
InterfaceVisitor localInterfaceVisitor = new InterfaceVisitor();
// Extra phases for the compiler
// boxing visitor depends on boxing decl
i = 1;
for (PhasedUnit pu : listOfUnits) {
if (sp != null)
progressPreparation(2, i++, size, pu);
pu.getCompilationUnit().visit(uv);
}
i = 1;
for (PhasedUnit pu : listOfUnits) {
if (sp != null)
progressPreparation(3, i++, size, pu);
pu.getCompilationUnit().visit(boxingDeclarationVisitor);
}
i = 1;
// the others can run at the same time
for (PhasedUnit pu : listOfUnits) {
if (sp != null)
progressPreparation(4, i++, size, pu);
CompilationUnit compilationUnit = pu.getCompilationUnit();
compilationUnit.visit(mnv);
compilationUnit.visit(boxingVisitor);
compilationUnit.visit(deferredVisitor);
compilationUnit.visit(amv);
compilationUnit.visit(dav);
compilationUnit.visit(tpCaptureVisitor);
compilationUnit.visit(localInterfaceVisitor);
}
i = 1;
for (PhasedUnit pu : listOfUnits) {
if (sp != null)
progressPreparation(5, i++, size, pu);
CompilationUnit compilationUnit = pu.getCompilationUnit();
compilationUnit.visit(new WarningSuppressionVisitor<Warning>(Warning.class, pu.getSuppressedWarnings()));
}
collectTreeErrors(true, true);
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class MethodOrValueReferenceVisitor method capture.
private void capture(Tree.Primary that, boolean methodSpecifier) {
if (that instanceof Tree.MemberOrTypeExpression) {
final Declaration decl = ((Tree.MemberOrTypeExpression) that).getDeclaration();
if (!(decl instanceof TypedDeclaration)) {
return;
}
TypedDeclaration d = (TypedDeclaration) decl;
if (Decl.equal(d, declaration) || (d.isNativeHeader() && d.getOverloads().contains(declaration))) {
d = declaration;
if (Decl.isParameter(d)) {
// a reference from a default argument
// expression of the same parameter
// list does not capture a parameter
Scope s = that.getScope();
boolean sameScope = d.getContainer().equals(s) || (s instanceof Declaration && (Decl.isParameter((Declaration) s) || (s instanceof Value && !((Value) s).isTransient())) && d.getContainer().equals(s.getScope()));
if (!sameScope || methodSpecifier || inLazySpecifierExpression) {
((FunctionOrValue) d).setCaptured(true);
}
// Accessing another instance's member passed to a class initializer
if (that instanceof Tree.QualifiedMemberExpression) {
if (d instanceof TypedDeclaration && ((TypedDeclaration) d).getOtherInstanceAccess()) {
((FunctionOrValue) d).setCaptured(true);
}
}
if (isCapturableMplParameter(d)) {
((FunctionOrValue) d).setCaptured(true);
}
} else if (Decl.isValue(d) || Decl.isGetter(d)) {
Value v = (Value) d;
v.setCaptured(true);
if (Decl.isObjectValue(d)) {
v.setSelfCaptured(isSelfCaptured(that, d));
}
if (v.getSetter() != null) {
v.getSetter().setCaptured(true);
}
} else if (d instanceof Function) {
((Function) d).setCaptured(true);
}
/*if (d.isVariable() && !d.isClassMember() && !d.isToplevel()) {
that.addError("access to variable local from capturing scope: " + declaration.getName());
}*/
}
}
}
use of com.redhat.ceylon.model.typechecker.model.TypedDeclaration in project ceylon-compiler by ceylon.
the class ClassDoc method writeListOnSummary.
private void writeListOnSummary(String cssClass, String title, List<?> types) throws IOException {
if (!isEmpty(types)) {
open("div class='" + cssClass + " section'");
around("span class='title'", title);
boolean first = true;
for (Object type : types) {
if (!first) {
write(", ");
} else {
first = false;
}
if (type instanceof TypedDeclaration) {
TypedDeclaration decl = (TypedDeclaration) type;
linkRenderer().to(decl).useScope(klass).write();
} else if (type instanceof ClassOrInterface) {
ClassOrInterface coi = (ClassOrInterface) type;
linkRenderer().to(coi).useScope(klass).printAbbreviated(!isAbbreviatedType(coi)).write();
} else {
Type pt = (Type) type;
linkRenderer().to(pt).useScope(klass).printAbbreviated(!isAbbreviatedType(pt.getDeclaration())).write();
}
}
close("div");
}
}
Aggregations