Skip to content

Commit

Permalink
Fixes related to #750
Browse files Browse the repository at this point in the history
  • Loading branch information
tombentley committed Sep 30, 2015
1 parent 0d3bcc3 commit 9fec25f
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 57 deletions.
Expand Up @@ -609,7 +609,7 @@ ceylon.language.meta.model.Attribute<Container, Get, Set> getDeclaredAttribute(@
FreeValue decl = (FreeValue) it;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(decl, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(decl, annotationTypeDescriptors))
continue;

addAttributeIfCompatible($reifiedContainer, $reifiedGet, $reifiedSet, members, decl, this.producedType,
Expand Down Expand Up @@ -692,7 +692,7 @@ private <Container,Get,Set> void addAttributeIfCompatible(@Ignore TypeDescriptor
continue;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
continue;

addAttributeIfCompatible($reifiedContainer, $reifiedGet, $reifiedSet, members, lookup.declaration,
Expand Down Expand Up @@ -759,7 +759,7 @@ private <Container,Get,Set> void addAttributeIfCompatible(@Ignore TypeDescriptor
continue;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(decl, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(decl, annotationTypeDescriptors))
continue;

addMethodIfCompatible($reifiedContainer, $reifiedType, $reifiedArguments, members, decl, producedType,
Expand Down Expand Up @@ -826,7 +826,7 @@ private <Container,Get,Set> void addAttributeIfCompatible(@Ignore TypeDescriptor
continue;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
continue;

addMethodIfCompatible($reifiedContainer, $reifiedType, $reifiedArguments, members, lookup.declaration, lookup.qualifyingType,
Expand Down Expand Up @@ -914,7 +914,7 @@ private <Container,Type,Arguments extends Sequential<? extends Object>> void add
continue;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(decl, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(decl, annotationTypeDescriptors))
continue;

addClassIfCompatible($reifiedContainer, $reifiedType, $reifiedArguments, members, decl,
Expand Down Expand Up @@ -981,7 +981,7 @@ private <Container,Type,Arguments extends Sequential<? extends Object>> void add
continue;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
continue;

addClassIfCompatible($reifiedContainer, $reifiedType, $reifiedArguments, members, lookup.declaration,
Expand Down Expand Up @@ -1065,7 +1065,7 @@ private <Container,Type,Arguments extends Sequential<? extends Object>> void add
continue;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(decl, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(decl, annotationTypeDescriptors))
continue;

addInterfaceIfCompatible($reifiedContainer, $reifiedType, members, decl, producedType,
Expand Down Expand Up @@ -1128,7 +1128,7 @@ private <Container,Type,Arguments extends Sequential<? extends Object>> void add
continue;

// ATM this is an AND WRT annotation types: all must be present
if(!hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
if(!Metamodel.hasAllAnnotations(lookup.declaration, annotationTypeDescriptors))
continue;

addInterfaceIfCompatible($reifiedContainer, $reifiedType, members, lookup.declaration, lookup.qualifyingType,
Expand Down Expand Up @@ -1156,17 +1156,6 @@ private <Container,Type> void addInterfaceIfCompatible(@Ignore TypeDescriptor $r
members.add(decl.<Container,Type>memberInterfaceApply($reifiedContainer, $reifiedType, containerMetamodel));
}

@Ignore
protected boolean hasAllAnnotations(AnnotatedDeclaration decl, TypeDescriptor[] annotationTypeDescriptors) {
for(TypeDescriptor annotationTypeDescriptor : annotationTypeDescriptors){
if(decl.annotations(annotationTypeDescriptor).getEmpty()){
// skip this declaration
return false;
}
}
return true;
}

@Override
public String toString() {
return Metamodel.toTypeString(this);
Expand Down
Expand Up @@ -13,9 +13,12 @@
import ceylon.language.meta.model.CallableConstructor;
import ceylon.language.meta.model.ClassModel;

import com.redhat.ceylon.compiler.java.runtime.model.ReifiedType;
import com.redhat.ceylon.compiler.java.runtime.model.TypeDescriptor;
import com.redhat.ceylon.model.typechecker.model.Parameter;

public class AppliedInitializer<Type, Arguments extends Sequential<? extends Object>> implements CallableConstructor<Type, Arguments>{
public class AppliedInitializer<Type, Arguments extends Sequential<? extends Object>>
implements CallableConstructor<Type, Arguments>, ReifiedType {

private AppliedClass<Type, Arguments> clazz;
private List<com.redhat.ceylon.model.typechecker.model.Type> parameterProducedTypes;
Expand Down Expand Up @@ -200,4 +203,9 @@ public boolean equals(Object obj) {
public java.lang.String toString() {
return clazz.toString();
}

@Override
public TypeDescriptor $getType$() {
return TypeDescriptor.klass(AppliedInitializer.class, clazz.$reifiedType, clazz.$reifiedArguments);
}
}
Expand Up @@ -21,6 +21,7 @@
import com.redhat.ceylon.compiler.java.metadata.TypeParameter;
import com.redhat.ceylon.compiler.java.metadata.TypeParameters;
import com.redhat.ceylon.compiler.java.metadata.Variance;
import com.redhat.ceylon.compiler.java.runtime.model.ReifiedType;
import com.redhat.ceylon.compiler.java.runtime.model.TypeDescriptor;
import com.redhat.ceylon.model.typechecker.model.Parameter;
import com.redhat.ceylon.model.typechecker.model.Reference;
Expand All @@ -36,7 +37,7 @@
})
public class AppliedMemberInitializer<Container, Type, Arguments extends Sequential<? extends Object>>
extends AppliedMember<Container, ceylon.language.meta.model.CallableConstructor<? extends Type, ? super Arguments>>
implements MemberClassCallableConstructor<Container, Type, Arguments>{
implements MemberClassCallableConstructor<Container, Type, Arguments>, ReifiedType {

//protected final FreeCallableConstructor declaration;
//private Reference appliedFunction;
Expand Down
Expand Up @@ -134,15 +134,15 @@ public ClassDeclaration getContainer() {
@Ignore
public java.lang.annotation.Annotation[] $getJavaAnnotations$() {
ArrayList<java.lang.annotation.Annotation> result = new ArrayList<java.lang.annotation.Annotation>(3);
java.lang.annotation.Annotation[] l = Metamodel.getJavaConstructor((Class)declaration, null).getAnnotations();
java.lang.annotation.Annotation[] l = Metamodel.getJavaClass((Class)declaration).getAnnotations();
for (java.lang.annotation.Annotation a : l) {
if (a instanceof SharedAnnotation$annotation$
|| a instanceof DeprecationAnnotation$annotation$
|| a instanceof ThrownExceptionAnnotation$annotation$) {
|| a instanceof ceylon.language.ThrownExceptionAnnotation$annotations$) {
result.add(a);
}
}
return result.toArray(new java.lang.annotation.Annotation[3]);
return result.toArray(new java.lang.annotation.Annotation[result.size()]);
}

@Override
Expand Down
Expand Up @@ -35,6 +35,7 @@
import ceylon.language.meta.declaration.OpenClassOrInterfaceType;
import ceylon.language.meta.declaration.OpenType;
import ceylon.language.meta.declaration.Package;
import ceylon.language.meta.model.ClassModel;
import ceylon.language.meta.model.ClassOrInterface;
import ceylon.language.meta.model.FunctionModel;
import ceylon.language.meta.model.Generic;
Expand Down Expand Up @@ -1883,6 +1884,15 @@ public static ceylon.language.meta.declaration.Variance getModelVariance(TypePar
throw Metamodel.newModelError("Underlying declaration is neither invariant, covariant nor contravariant");
}

static boolean hasAllAnnotations(AnnotatedDeclaration decl, TypeDescriptor[] annotationTypeDescriptors) {
for(TypeDescriptor annotationTypeDescriptor : annotationTypeDescriptors){
if(decl.annotations(annotationTypeDescriptor).getEmpty()){
// skip this declaration
return false;
}
}
return true;
}

static <Type> Sequential getConstructors(
AppliedClassOrInterface<Type> cls,
Expand All @@ -1893,40 +1903,56 @@ static <Type> Sequential getConstructors(
ArrayList<Object> ctors = new ArrayList<>();
com.redhat.ceylon.model.typechecker.model.Type reifiedArguments = $reified$Arguments == null ? null : Metamodel.getProducedType($reified$Arguments);
TypeDescriptor[] annotationTypeDescriptors = Metamodel.getTypeDescriptors(annotations);
for (ceylon.language.meta.declaration.Declaration d : ((FreeClass)cls.declaration).constructors()) {
Declaration dd = null;
if (d instanceof FreeCallableConstructor
&& callableConstructors) {
dd = ((FreeCallableConstructor)d).declaration;
} else if (d instanceof FreeValueConstructor
&& !callableConstructors) {
dd = ((FreeValueConstructor)d).declaration;
} else {
continue;
if (cls.declaration instanceof FreeClassWithInitializer) {

Reference producedReference = cls.declaration.declaration.appliedReference(cls.producedType, Collections.<com.redhat.ceylon.model.typechecker.model.Type>emptyList());
com.redhat.ceylon.model.typechecker.model.Type argumentsType = Metamodel.getProducedTypeForArguments(
cls.declaration.declaration.getUnit(),
(Functional) cls.declaration.declaration,
producedReference);
if(reifiedArguments.isSubtypeOf(argumentsType)) {
if(hasAllAnnotations(((FreeClassWithInitializer)cls.declaration).getDefaultConstructor(), annotationTypeDescriptors)) {
// TODO test for arguments too
//ctors.add(new AppliedInitializer((AppliedClass)cls));
ctors.add(((ClassModel<?, ?>)cls).getDefaultConstructor());
}
}
// ATM this is an AND WRT annotation types: all must be present
if(!cls.hasAllAnnotations((AnnotatedDeclaration)d, annotationTypeDescriptors))
continue;
if (dd instanceof Functional
&& reifiedArguments != null) {
// CallableConstructor need a check on the <Arguments>
Reference producedReference = dd.appliedReference(cls.producedType, Collections.<com.redhat.ceylon.model.typechecker.model.Type>emptyList());
com.redhat.ceylon.model.typechecker.model.Type argumentsType = Metamodel.getProducedTypeForArguments(
dd.getUnit(),
(Functional) dd,
producedReference);
if(!reifiedArguments.isSubtypeOf(argumentsType))
} else {
for (ceylon.language.meta.declaration.Declaration d : ((FreeClass)cls.declaration).constructors()) {
Declaration dd = null;
if (d instanceof FreeCallableConstructor
&& callableConstructors) {
dd = ((FreeCallableConstructor)d).declaration;
} else if (d instanceof FreeValueConstructor
&& !callableConstructors) {
dd = ((FreeValueConstructor)d).declaration;
} else {
continue;
}
if (!justShared || (d instanceof NestableDeclaration
&& ((NestableDeclaration)d).getShared())) {
Object ctor;
if (cls instanceof AppliedClass<?,?>) {
ctor = ((AppliedClass<?,?>)cls).getDeclaredConstructor(TypeDescriptor.NothingType, d.getName());
} else {//if (cls instanceof AppliedMemberClass<?,?,?>) {
ctor = ((AppliedMemberClass<?,?,?>)cls).getDeclaredConstructor(TypeDescriptor.NothingType, d.getName());
}
ctors.add(ctor);
// ATM this is an AND WRT annotation types: all must be present
if(!Metamodel.hasAllAnnotations((AnnotatedDeclaration)d, annotationTypeDescriptors))
continue;
if (dd instanceof Functional
&& reifiedArguments != null) {
// CallableConstructor need a check on the <Arguments>
Reference producedReference = dd.appliedReference(cls.producedType, Collections.<com.redhat.ceylon.model.typechecker.model.Type>emptyList());
com.redhat.ceylon.model.typechecker.model.Type argumentsType = Metamodel.getProducedTypeForArguments(
dd.getUnit(),
(Functional) dd,
producedReference);
if(!reifiedArguments.isSubtypeOf(argumentsType))
continue;
}
if (!justShared || (d instanceof NestableDeclaration
&& ((NestableDeclaration)d).getShared())) {
Object ctor;
if (cls instanceof AppliedClass<?,?>) {
ctor = ((AppliedClass<?,?>)cls).getDeclaredConstructor(TypeDescriptor.NothingType, d.getName());
} else {//if (cls instanceof AppliedMemberClass<?,?,?>) {
ctor = ((AppliedMemberClass<?,?,?>)cls).getDeclaredConstructor(TypeDescriptor.NothingType, d.getName());
}
ctors.add(ctor);
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/ceylon/language/meta/model/Class.ceylon
Expand Up @@ -25,6 +25,9 @@ shared sealed interface Class<out Type=Anything, in Arguments=Nothing>
shared actual formal Value<Type>? getValueConstructor(String name);*/

"A model of the default constructor (for a class with constructors)
or class initializer (for a class with a parameter list), or null
if the class has constructors, but lacks a default constructor."
shared actual formal CallableConstructor<Type, Arguments>? defaultConstructor;

"The constructor with the given name, or null if this class lacks
Expand Down
35 changes: 33 additions & 2 deletions test/metamodel/bug750.ceylon
@@ -1,5 +1,11 @@
import ceylon.language.meta.declaration{...}
import ceylon.language.meta.model{CallableConstructor, TypeApplicationException}
import ceylon.language.meta.model{
CallableConstructor,
TypeApplicationException
}
import ceylon.language.meta{
type
}


class Bug750Init<T>(String s) {
Expand Down Expand Up @@ -110,6 +116,19 @@ shared void bug750() {
assert(exists aaa = appliedCtor.container,
`Bug750Init<String>` == aaa);

assert([`Bug750Init<String>`.defaultConstructor] == `Bug750Init<String>`.getCallableConstructors<[String]>());
assert([`Bug750Init<String>`.defaultConstructor] == `Bug750Init<String>`.getCallableConstructors<Nothing>());
assert(`Bug750Init<String>`.getCallableConstructors<[Integer]>().empty);
assert(`Bug750Init<String>`.getCallableConstructors<[String]>(`SharedAnnotation`).empty);
assert(`Bug750Init<String>`.getCallableConstructors<[String]>(`DocAnnotation`).empty);
assert(`Bug750Init<String>`.getCallableConstructors<[String]>(`DeprecationAnnotation`).empty);
assert(!`Bug750Anno`.getCallableConstructors<[]>(`SharedAnnotation`).empty);
assert(`Bug750Anno`.getCallableConstructors<[]>(`DocAnnotation`).empty);
assert(!`Bug750Anno`.getCallableConstructors<[]>(`DeprecationAnnotation`).empty);
assert(!`Bug750Anno`.getCallableConstructors<[]>(`ThrownExceptionAnnotation`).empty);

type(`Bug750Init<String>`.defaultConstructor);

Bug750Outer().bug750();
}

Expand Down Expand Up @@ -214,10 +233,22 @@ class Bug750Outer() {

assert(exists zzz = `Bug750Init<String>`.defaultConstructor,
appliedCtor == zzz);
print("££££££££££££££££ `` appliedCtor.parameterTypes``");
assert([`String`] == appliedCtor.parameterTypes);
assert(init == appliedCtor.declaration);

assert(`Bug750Init<String>` == appliedCtor.container);

assert([`Bug750Init<String>`.defaultConstructor] == `Bug750Init<String>`.getCallableConstructors<[String]>());
assert([`Bug750Init<String>`.defaultConstructor] == `Bug750Init<String>`.getCallableConstructors<Nothing>());
assert(`Bug750Init<String>`.getCallableConstructors<[Integer]>().empty);
assert(`Bug750Init<String>`.getCallableConstructors<[String]>(`SharedAnnotation`).empty);
assert(`Bug750Init<String>`.getCallableConstructors<[String]>(`DocAnnotation`).empty);
assert(`Bug750Init<String>`.getCallableConstructors<[String]>(`DeprecationAnnotation`).empty);
assert(!`Bug750Anno`.getCallableConstructors<[]>(`SharedAnnotation`).empty);
assert(`Bug750Anno`.getCallableConstructors<[]>(`DocAnnotation`).empty);
assert(!`Bug750Anno`.getCallableConstructors<[]>(`DeprecationAnnotation`).empty);
assert(!`Bug750Anno`.getCallableConstructors<[]>(`ThrownExceptionAnnotation`).empty);

type(`Bug750Init<String>`.defaultConstructor);
}
}

0 comments on commit 9fec25f

Please sign in to comment.