use of com.redhat.ceylon.model.typechecker.model.Interface in project ceylon-compiler by ceylon.
the class ExpressionTransformer method lostTypeParameterInInheritance.
private boolean lostTypeParameterInInheritance(ClassOrInterface exprDecl, ClassOrInterface commonDecl, boolean searchInterfaces, boolean lostTypeParameter) {
// stop if we found the common decl
if (Decl.equal(exprDecl, commonDecl))
return lostTypeParameter;
if (searchInterfaces) {
// find a match in interfaces
for (Type pt : exprDecl.getSatisfiedTypes()) {
// FIXME: this is very heavy-handed because we consider that once we've lost a type parameter we've lost them all
// but we could optimise this by checking:
// 1/ which type parameter we've really lost
// 2/ if the type parameters we're passing to our super type actually depend in any way from type parameters we've lost
boolean lostTypeParameter2 = lostTypeParameter || isTurnedToRaw(pt);
pt = simplifyType(pt);
// it has to be an interface
Interface interf = (Interface) pt.getDeclaration();
if (lostTypeParameterInInheritance(interf, commonDecl, searchInterfaces, lostTypeParameter2))
return true;
}
}
// search for super classes
Type extendedType = exprDecl.getExtendedType();
if (extendedType != null) {
// FIXME: see above
boolean lostTypeParameter2 = lostTypeParameter || isTurnedToRaw(extendedType);
extendedType = simplifyType(extendedType);
// it has to be a Class
Class extendedTypeDeclaration = (Class) extendedType.getDeclaration();
// looks like Object's superclass is Object, so stop right there
if (extendedTypeDeclaration != typeFact().getObjectDeclaration())
return lostTypeParameterInInheritance(extendedTypeDeclaration, commonDecl, searchInterfaces, lostTypeParameter2);
}
// didn't find it
return false;
}
use of com.redhat.ceylon.model.typechecker.model.Interface in project ceylon-compiler by ceylon.
the class ExpressionTransformer method addInterfaceImplAccessorIfRequired.
//
// Array access
private JCExpression addInterfaceImplAccessorIfRequired(JCExpression qualExpr, Tree.StaticMemberOrTypeExpression expr, Declaration decl) {
// For interfaces we sometimes need to access either the interface instance or its $impl class
if (decl instanceof Constructor) {
decl = (Class) Decl.container(decl);
}
Scope declContainer = Decl.container(decl);
if (qualExpr != null && // this is only for interface containers
declContainer instanceof Interface && // we only ever need the $impl if the declaration is not shared
!decl.isShared() && (!(expr instanceof Tree.QualifiedMemberExpression) || !isSuperOrSuperOf(((Tree.QualifiedMemberExpression) expr).getPrimary()))) {
Interface declaration = (Interface) declContainer;
// access the interface $impl instance
qualExpr = naming.makeCompanionAccessorCall(qualExpr, declaration);
// so we need to cast it to the type of the companion
if (Decl.isAncestorLocal(declaration)) {
Type type;
// try to find the best type
if (expr instanceof Tree.QualifiedMemberOrTypeExpression)
type = ((Tree.QualifiedMemberOrTypeExpression) expr).getPrimary().getTypeModel();
else
type = declaration.getType();
qualExpr = make().TypeCast(makeJavaType(type, JT_COMPANION), qualExpr);
}
}
return qualExpr;
}
use of com.redhat.ceylon.model.typechecker.model.Interface in project ceylon-compiler by ceylon.
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));
}
}
use of com.redhat.ceylon.model.typechecker.model.Interface in project ceylon-compiler by ceylon.
the class Naming method appendTypeDeclaration.
private void appendTypeDeclaration(final TypeDeclaration decl, EnumSet<DeclNameFlag> flags, TypeDeclarationBuilder<?> typeDeclarationBuilder, Scope scope, final boolean last) {
if (scope instanceof Class || scope instanceof TypeAlias || (scope instanceof Constructor && (scope.equals(decl) || !Decl.isLocalNotInitializerScope(scope)))) {
TypeDeclaration klass = (TypeDeclaration) scope;
if (klass.isAnonymous() && !klass.isNamed())
typeDeclarationBuilder.clear();
typeDeclarationBuilder.append(escapeClassName(klass.getName() != null ? klass.getName() : ""));
if (Decl.isCeylon(klass)) {
if (flags.contains(DeclNameFlag.COMPANION) && Decl.isLocalNotInitializer(klass) && last) {
typeDeclarationBuilder.append(IMPL_POSTFIX);
} else if (flags.contains(DeclNameFlag.ANNOTATION) && last) {
typeDeclarationBuilder.append(ANNO_POSTFIX);
} else if (flags.contains(DeclNameFlag.ANNOTATIONS) && last) {
typeDeclarationBuilder.append(ANNOS_POSTFIX);
} else if (flags.contains(DeclNameFlag.DELEGATION) && last) {
typeDeclarationBuilder.append(DELEGATION_POSTFIX);
}
}
} else if (scope instanceof Interface) {
Interface iface = (Interface) scope;
typeDeclarationBuilder.append(iface.getName());
if (Decl.isCeylon(iface) && ((decl instanceof Class || decl instanceof Constructor || decl instanceof TypeAlias || scope instanceof Constructor) || flags.contains(DeclNameFlag.COMPANION))) {
typeDeclarationBuilder.append(IMPL_POSTFIX);
}
} else if (Decl.isLocalNotInitializerScope(scope)) {
if (flags.contains(DeclNameFlag.COMPANION) || !(decl instanceof Interface)) {
typeDeclarationBuilder.clear();
} else if (flags.contains(DeclNameFlag.QUALIFIED) || (decl instanceof Interface)) {
Scope nonLocal = scope;
while (!(nonLocal instanceof Declaration)) {
nonLocal = nonLocal.getContainer();
}
typeDeclarationBuilder.append(((Declaration) nonLocal).getPrefixedName());
if (!Decl.equalScopes(scope, nonLocal)) {
typeDeclarationBuilder.append('$');
typeDeclarationBuilder.append(getLocalId(scope));
}
if (decl instanceof Interface) {
typeDeclarationBuilder.append('$');
} else {
if (flags.contains(DeclNameFlag.QUALIFIED)) {
typeDeclarationBuilder.selectAppended();
} else {
typeDeclarationBuilder.clear();
}
}
}
return;
} else if (scope instanceof TypedDeclaration && ((Declaration) scope).isToplevel()) {
// nothing? that's just weird
}
if (!last) {
if (decl instanceof Interface && Decl.isCeylon((TypeDeclaration) decl) && !flags.contains(DeclNameFlag.COMPANION)) {
typeDeclarationBuilder.append('$');
} else if (decl instanceof Constructor && ((Class) decl.getContainer()).isMember() && decl.getContainer().equals(scope)) {
typeDeclarationBuilder.append('$');
} else {
if (flags.contains(DeclNameFlag.QUALIFIED)) {
typeDeclarationBuilder.selectAppended();
} else {
typeDeclarationBuilder.clear();
}
}
} else {
typeDeclarationBuilder.selectAppended();
}
return;
}
use of com.redhat.ceylon.model.typechecker.model.Interface in project ceylon-compiler by ceylon.
the class TypeParserTests method testCallableAbbrev.
@Test
public void testCallableAbbrev() {
Type type = new TypeParser(MockLoader.instance).decodeType("a(b)", null, mockDefaultModule, mockPkgUnit);
Assert.assertNotNull(type);
TypeDeclaration declaration = type.getDeclaration();
Assert.assertNotNull(declaration);
Assert.assertTrue(declaration instanceof Interface);
Assert.assertEquals("ceylon.language::Callable", declaration.getQualifiedNameString());
Assert.assertEquals("a(b)", type.asString());
Assert.assertNull(type.getQualifyingType());
type = new TypeParser(MockLoader.instance).decodeType("a(b,pkg::u*)", null, mockPkgModule, mockPkgUnit);
Assert.assertNotNull(type);
declaration = type.getDeclaration();
Assert.assertNotNull(declaration);
Assert.assertTrue(declaration instanceof Interface);
Assert.assertEquals("ceylon.language::Callable", declaration.getQualifiedNameString());
Assert.assertEquals("ceylon.language::Callable<a,ceylon.language::Tuple<b|pkg::u,b,ceylon.language::Sequential<pkg::u>>>", printType(type));
Assert.assertNull(type.getQualifyingType());
type = new TypeParser(MockLoader.instance).decodeType("a(b=,pkg::u*)", null, mockPkgModule, mockPkgUnit);
Assert.assertNotNull(type);
declaration = type.getDeclaration();
Assert.assertNotNull(declaration);
Assert.assertTrue(declaration instanceof Interface);
Assert.assertEquals("ceylon.language::Callable", declaration.getQualifiedNameString());
Assert.assertEquals("ceylon.language::Callable<a,ceylon.language::Empty|ceylon.language::Tuple<b|pkg::u,b,ceylon.language::Sequential<pkg::u>>>", printType(type));
Assert.assertNull(type.getQualifyingType());
}
Aggregations