use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ClassOrInterfaceImpl method addClassIfCompatible.
@SuppressWarnings({ "hiding" })
private <Container, Type, Arguments extends Sequential<? extends Object>> void addClassIfCompatible(@Ignore TypeDescriptor $reifiedContainer, @Ignore TypeDescriptor $reifiedType, @Ignore TypeDescriptor $reifiedArguments, ArrayList<ceylon.language.meta.model.MemberClass<? super Container, ? extends Type, ? super Arguments>> members, ClassDeclarationImpl decl, org.eclipse.ceylon.model.typechecker.model.Type qualifyingType, ClassOrInterfaceImpl<Container> containerMetamodel, org.eclipse.ceylon.model.typechecker.model.Type reifiedType, org.eclipse.ceylon.model.typechecker.model.Type reifiedArguments) {
// now the types
Reference producedReference = decl.declaration.appliedReference(qualifyingType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
org.eclipse.ceylon.model.typechecker.model.Type type = producedReference.getType();
if (!type.isSubtypeOf(reifiedType))
return;
org.eclipse.ceylon.model.typechecker.model.Type argumentsType = Metamodel.getProducedTypeForArguments(decl.declaration.getUnit(), (Functional) decl.declaration, producedReference);
if (!reifiedArguments.isSubtypeOf(argumentsType))
return;
// it's compatible!
members.add(decl.<Container, Type, Arguments>memberClassApply($reifiedContainer, $reifiedType, $reifiedArguments, containerMetamodel));
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class Metamodel method getConstructors.
public static <Type> Sequential getConstructors(ClassOrInterfaceImpl<Type> cls, boolean justShared, boolean callableConstructors, TypeDescriptor $reified$Arguments, ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<? extends java.lang.annotation.Annotation>> annotations) {
ArrayList<Object> ctors = new ArrayList<>();
org.eclipse.ceylon.model.typechecker.model.Type reifiedArguments = $reified$Arguments == null ? null : Metamodel.getProducedType($reified$Arguments);
TypeDescriptor[] annotationTypeDescriptors = Metamodel.getTypeDescriptors(annotations);
if (cls.declaration instanceof ClassWithInitializerDeclarationImpl) {
Reference producedReference = cls.declaration.declaration.appliedReference(cls.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
org.eclipse.ceylon.model.typechecker.model.Type argumentsType = Metamodel.getProducedTypeForArguments(cls.declaration.declaration.getUnit(), (Functional) cls.declaration.declaration, producedReference);
if (reifiedArguments == null || reifiedArguments.isSubtypeOf(argumentsType)) {
if (hasAllAnnotations(((ClassWithInitializerDeclarationImpl) cls.declaration).getDefaultConstructor(), annotationTypeDescriptors)) {
// TODO test for arguments too
// ctors.add(new AppliedInitializer((AppliedClass)cls));
ctors.add(((ClassModel<?, ?>) cls).getDefaultConstructor());
}
}
} else {
for (ceylon.language.meta.declaration.Declaration d : ((ClassDeclarationImpl) cls.declaration).constructors()) {
Declaration dd = null;
AnnotatedDeclaration annotated;
if (d instanceof CallableConstructorDeclarationImpl && callableConstructors) {
dd = ((CallableConstructorDeclarationImpl) d).declaration;
annotated = (CallableConstructorDeclaration) d;
} else if (d instanceof ValueConstructorDeclarationImpl && !callableConstructors) {
dd = ((ValueConstructorDeclarationImpl) d).declaration;
annotated = (ValueConstructorDeclaration) d;
} else {
continue;
}
// ATM this is an AND WRT annotation types: all must be present
if (!hasAllAnnotations(annotated, annotationTypeDescriptors))
continue;
if (dd instanceof Functional && reifiedArguments != null) {
// CallableConstructor need a check on the <Arguments>
Reference producedReference = dd.appliedReference(cls.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
org.eclipse.ceylon.model.typechecker.model.Type argumentsType = Metamodel.getProducedTypeForArguments(dd.getUnit(), (Functional) dd, producedReference);
if (!reifiedArguments.isSubtypeOf(argumentsType))
continue;
}
// 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.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
org.eclipse.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 ClassImpl<?, ?>) {
ctor = ((ClassImpl<?, ?>) cls).getDeclaredConstructor(TypeDescriptor.NothingType, d.getName());
} else {
// if (cls instanceof AppliedMemberClass<?,?,?>) {
ctor = ((MemberClassImpl<?, ?, ?>) cls).getDeclaredConstructor(TypeDescriptor.NothingType, d.getName());
}
ctors.add(ctor);
}
}
}
Object[] array = ctors.toArray(new Object[ctors.size()]);
ObjectArrayIterable<ceylon.language.meta.declaration.Declaration> iterable = new ObjectArrayIterable<ceylon.language.meta.declaration.Declaration>(TypeDescriptor.union(TypeDescriptor.klass(FunctionModel.class, cls.$reifiedType, TypeDescriptor.NothingType), TypeDescriptor.klass(ValueModel.class, cls.$reifiedType, TypeDescriptor.NothingType)), (Object[]) array);
return (ceylon.language.Sequential) iterable.sequence();
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ExpressionVisitor method accountForStaticReferenceType.
private Type accountForStaticReferenceType(Tree.QualifiedMemberOrTypeExpression that, Declaration member, Type type) {
if (that.getStaticMethodReference()) {
Tree.MemberOrTypeExpression primary = (Tree.MemberOrTypeExpression) that.getPrimary();
if (isConstructor(member)) {
// Ceylon named constructor
if (primary instanceof Tree.QualifiedMemberOrTypeExpression) {
Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) primary;
Tree.MemberOperator mo = qmte.getMemberOperator();
if (!(mo instanceof Tree.MemberOp)) {
mo.addError("illegal operator qualifying constructor reference");
return null;
}
}
if (primary.getStaticMethodReference()) {
Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) primary;
if (qmte.getDeclaration().isStatic()) {
return type;
}
Tree.MemberOrTypeExpression pp = (Tree.MemberOrTypeExpression) qmte.getPrimary();
return accountForStaticReferenceType(qmte, pp.getDeclaration(), type);
} else {
return type;
}
} else {
// something other than a constructor
if (primary instanceof Tree.QualifiedMemberOrTypeExpression) {
Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) primary;
Tree.Primary pp = qmte.getPrimary();
if (!(pp instanceof Tree.BaseTypeExpression) && !(pp instanceof Tree.QualifiedTypeExpression) && !(pp instanceof Tree.Package)) {
pp.addError("non-static type expression qualifies static member reference");
}
}
if (member.isStatic()) {
// static member of Java type
if (primary.getStaticMethodReference()) {
Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) primary;
if (qmte.getDeclaration().isStatic()) {
return type;
} else {
Tree.MemberOrTypeExpression pp = (Tree.MemberOrTypeExpression) qmte.getPrimary();
return accountForStaticReferenceType(qmte, pp.getDeclaration(), type);
}
} else {
return type;
}
} else {
// ordinary non-static, non-constructor member
Reference target = primary.getTarget();
if (target == null) {
return unit.getUnknownType();
} else {
return getStaticReferenceType(type, target.getType());
}
}
}
} else {
return type;
}
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ExpressionVisitor method checkClassAliasParameters.
private void checkClassAliasParameters(Class alias, Tree.ClassDeclaration that, Tree.InvocationExpression ie) {
Tree.Primary primary = ie.getPrimary();
Tree.ExtendedTypeExpression smte = (Tree.ExtendedTypeExpression) primary;
Functional classOrConstructor = (Functional) smte.getDeclaration();
ParameterList cpl = classOrConstructor.getFirstParameterList();
ParameterList apl = alias.getParameterList();
if (cpl != null && apl != null) {
List<Parameter> cplps = cpl.getParameters();
List<Parameter> aplps = apl.getParameters();
int cps = cplps.size();
int aps = aplps.size();
if (cps != aps) {
that.getParameterList().addUnsupportedError("wrong number of initializer parameters declared by class alias: '" + alias.getName() + "'");
}
for (int i = 0; i < cps && i < aps; i++) {
Parameter ap = aplps.get(i);
Parameter cp = cplps.get(i);
Reference target = smte.getTarget();
FunctionOrValue apm = ap.getModel();
if (apm != null && target != null) {
Type pt = target.getTypedParameter(cp).getFullType();
Type apt = apm.getReference().getFullType();
if (!isTypeUnknown(pt) && !isTypeUnknown(apt) && !apt.isSubtypeOf(pt)) {
that.addUnsupportedError("alias parameter '" + ap.getName() + "' must be assignable to corresponding class parameter '" + cp.getName() + "'" + notAssignableMessage(apt, pt, that));
}
}
}
// temporary restrictions
checkAliasedClass(that, cpl, apl);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class RefinementVisitor method checkRefinedTypeAndParameterTypes.
/*private boolean refinesOverloaded(Declaration dec,
Declaration refined, Type st) {
Functional fun1 = (Functional) dec;
Functional fun2 = (Functional) refined;
if (fun1.getParameterLists().size()!=1 ||
fun2.getParameterLists().size()!=1) {
return false;
}
List<Parameter> pl1 = fun1.getParameterLists()
.get(0).getParameters();
List<Parameter> pl2 = fun2.getParameterLists()
.get(0).getParameters();
if (pl1.size()!=pl2.size()) {
return false;
}
for (int i=0; i<pl1.size(); i++) {
Parameter p1 = pl1.get(i);
Parameter p2 = pl2.get(i);
if (p1==null || p2==null ||
p1.getType()==null ||
p2.getType()==null) {
return false;
}
else {
Type p2st = p2.getType()
.substitute(st.getTypeArguments());
if (!matches(p1.getType(), p2st, dec.getUnit())) {
return false;
}
}
}
return true;
}*/
private void checkRefinedTypeAndParameterTypes(Tree.Declaration that, Declaration refining, ClassOrInterface ci, Declaration refined) {
List<TypeParameter> refinedTypeParams = refined.getTypeParameters();
List<TypeParameter> refiningTypeParams = refining.getTypeParameters();
checkRefiningMemberTypeParameters(that, refining, refined, refinedTypeParams, refiningTypeParams);
List<Type> typeArgs = checkRefiningMemberUpperBounds(that, ci, refined, refinedTypeParams, refiningTypeParams);
Type cit = ci.getType();
Reference refinedMember = cit.getTypedReference(refined, typeArgs);
Reference refiningMember = cit.getTypedReference(refining, typeArgs);
Declaration refinedMemberDec = refinedMember.getDeclaration();
Declaration refiningMemberDec = refiningMember.getDeclaration();
Node typeNode = getTypeErrorNode(that);
if (refinedMemberIsDynamicallyTyped(refinedMemberDec, refiningMemberDec)) {
checkRefiningMemberDynamicallyTyped(refined, refiningMemberDec, typeNode);
} else if (refiningMemberIsDynamicallyTyped(refinedMemberDec, refiningMemberDec)) {
checkRefinedMemberDynamicallyTyped(refined, refinedMemberDec, typeNode);
} else if (refinedMemberIsVariable(refinedMemberDec)) {
checkRefinedMemberTypeExactly(refiningMember, refinedMember, typeNode, refined, refining);
} else {
// note: this version checks return type and parameter types in one shot, but the
// resulting error messages aren't as friendly, so do it the hard way instead!
// checkAssignable(refiningMember.getFullType(), refinedMember.getFullType(), that,
checkRefinedMemberTypeAssignable(refiningMember, refinedMember, typeNode, refined, refining);
}
if (refining instanceof Functional && refined instanceof Functional) {
checkRefiningMemberParameters(that, refining, refined, refinedMember, refiningMember, false);
}
}
Aggregations