use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class PartialImpl method initializeObject.
protected <Id> void initializeObject(TypeDescriptor $reified$Id, DeserializationContextImpl<Id> context, Serializable instance) {
NativeMap<ReachableReference, Id> state = (NativeMap<ReachableReference, Id>) getState();
// TODO If it were a map of java.lang.String we'd avoid pointless extra boxing
java.util.Collection<ReachableReference> reachables = instance.$references$();
int numLate = 0;
for (ReachableReference r : reachables) {
if (r instanceof Member && ((Member) r).getAttribute().getLate()) {
numLate++;
} else if (r instanceof Outer) {
numLate++;
}
}
if (state.getSize() < reachables.size() - numLate) {
HashSet<ReachableReference> missingNames = new HashSet<ReachableReference>();
java.util.Iterator<ReachableReference> it = reachables.iterator();
while (it.hasNext()) {
missingNames.add(it.next());
}
ceylon.language.Iterator<? extends ReachableReference> it2 = state.getKeys().iterator();
Object next;
while (((next = it2.next()) instanceof ReachableReference)) {
missingNames.remove(next);
}
throw insufficiantState(missingNames);
}
for (ReachableReference reference : reachables) {
if (reference instanceof Member) {
Member member = (Member) reference;
if (member.getAttribute().getLate() && !state.contains(member) || state.get(member) == uninitializedLateValue_.get_()) {
continue;
}
TypeDescriptor.Class classTypeDescriptor = getClassTypeDescriptor();
Entry<TypeDescriptor.Class, String> cacheKey = new Entry<TypeDescriptor.Class, String>(TypeDescriptor.klass(TypeDescriptor.Class.class), String.$TypeDescriptor$, classTypeDescriptor, String.instance(member.getAttribute().getQualifiedName()));
Type memberType = (Type) context.getMemberTypeCache().get(cacheKey);
if (memberType == null) {
Type pt = Metamodel.getModuleManager().getCachedType(classTypeDescriptor);
while (!pt.getDeclaration().getQualifiedNameString().equals(((ClassDeclaration) member.getAttribute().getContainer()).getQualifiedName())) {
pt = pt.getExtendedType();
}
FunctionOrValue attributeDeclaration = (FunctionOrValue) ((TypeDeclaration) pt.getDeclaration()).getMember(member.getAttribute().getName(), null, false);
TypedReference attributeType = pt.getTypedMember(attributeDeclaration, Collections.<Type>emptyList(), true);
memberType = attributeType.getType();
context.getMemberTypeCache().put(cacheKey, memberType);
}
Object referredInstance = getReferredInstance(context, state, member);
if (referredInstance instanceof Tuple) {
// Because tuples are special wrt reified types...
Id referredId = state.get(member);
Object r = context.leakInstance(referredId);
if (r instanceof PartialImpl) {
((PartialImpl) r).initialize($reified$Id, context);
}
}
Type instanceType = Metamodel.getModuleManager().getCachedType(Metamodel.getTypeDescriptor(referredInstance));
if (!instanceType.isSubtypeOf(memberType)) {
throw notAssignable(member, memberType, instanceType);
}
instance.$set$(member, referredInstance);
// the JVM will check the assignability, but we need to
// check assignability at the ceylon level, so we need to know
// / type of the attribute an the type that we're assigning.
// XXX this check is really expensive!
// we should cache the attribute type on the context
// when can we avoid this check.
// XXX we can cache MethodHandle setters on the context!
} else if (reference instanceof Outer) {
// instantiating member classes
continue;
} else {
throw new AssertionError("unexpected ReachableReference " + reference);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionVisitor method visitQualifiedMemberExpression.
private void visitQualifiedMemberExpression(Tree.QualifiedMemberExpression that, Type receivingType, TypedDeclaration member, List<Type> typeArgs, Tree.TypeArguments tal) {
checkMemberOperator(receivingType, that);
Tree.Primary primary = that.getPrimary();
if (isConstructor(member) && !(primary instanceof Tree.BaseTypeExpression || primary instanceof Tree.QualifiedTypeExpression)) {
primary.addError("constructor reference must be qualified by a type expression");
}
Type receiverType = accountForStaticReferenceReceiverType(that, unwrap(receivingType, that));
if (acceptsTypeArguments(member, receiverType, typeArgs, tal, that) || true) {
TypedReference ptr = receiverType.getTypedMember(member, typeArgs, that.getAssigned());
/*if (ptr==null) {
that.addError("method or attribute is not defined: " +
member.getName(unit) + " of type " +
receiverType.getDeclaration().getName(unit));
}
else {*/
that.setTarget(ptr);
checkSpread(member, that);
boolean direct = that.getDirectlyInvoked();
Type fullType = accountForGenericFunctionRef(direct, tal, receivingType, typeArgs, ptr.getFullType(wrap(ptr.getType(), receivingType, that)));
Scope scope = that.getScope();
if (!dynamic && !isNativeForWrongBackend(scope, unit) && !isAbstraction(member) && isTypeUnknown(fullType) && !hasError(that)) {
// this occurs with an ambiguous reference
// to a member of an intersection type
String rtname = receiverType.getDeclaration().getName(unit);
that.addError("could not determine type of method or attribute reference: '" + member.getName(unit) + "' of '" + rtname + "' is ambiguous" + getTypeUnknownError(fullType));
}
that.setTypeModel(accountForStaticReferenceType(that, member, fullType));
// }
}
if (that.getStaticMethodReference()) {
handleStaticReferenceImplicitTypeArguments(that);
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class TypeArgumentInference method inferFunctionRefTypeArgs.
/**
* Infer type arguments for a direct function
* ref (i.e. not a value ref with a type
* constructor type) that occurs as an argument
* to a callable parameter.
*/
private List<Type> inferFunctionRefTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, boolean secondList, Declaration reference, List<TypeParameter> typeParameters, TypedReference paramTypedRef, Declaration paramDec, Declaration parameterizedDec) {
Reference arg = appliedReference(smte);
Functional fun = (Functional) reference;
List<ParameterList> apls = fun.getParameterLists();
Functional pfun = (Functional) paramDec;
List<ParameterList> ppls = pfun.getParameterLists();
if (apls.isEmpty() || ppls.isEmpty()) {
// TODO: to give a nicer error
return null;
} else {
ParameterList aplf = apls.get(secondList ? 1 : 0);
ParameterList pplf = ppls.get(0);
List<Parameter> apl = aplf.getParameters();
List<Parameter> ppl = pplf.getParameters();
boolean[] specifiedParams = specifiedParameters(apl.size(), ppl.size());
List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
for (TypeParameter tp : typeParameters) {
boolean findUpperBounds = isEffectivelyContravariant(tp, reference, specifiedParams, secondList);
Type it = inferFunctionRefTypeArg(smte, tp, typeParameters, paramTypedRef, parameterizedDec, arg, apl, ppl, findUpperBounds);
inferredTypes.add(it);
}
return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionVisitor method checkPositionalArgument.
private void checkPositionalArgument(Parameter p, Reference pr, Tree.ListedArgument a) {
FunctionOrValue paramModel = p.getModel();
if (paramModel != null) {
a.setParameter(p);
TypedReference paramRef = pr.getTypedParameterWithWildcardCaputure(p);
Type paramType = paramType(a.getScope(), paramRef, paramModel);
Type at = a.getTypeModel();
if (!isTypeUnknown(at) && !isTypeUnknown(paramType)) {
checkAssignable(at, paramType, a, "argument must be assignable to parameter " + argdesc(p, pr), 2100);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class FunctionDeclarationImpl method getAppliedMethod.
<Container, Type, Arguments extends ceylon.language.Sequential<? extends Object>> ceylon.language.meta.model.Method<Container, Type, Arguments> getAppliedMethod(@Ignore TypeDescriptor $reifiedContainer, @Ignore TypeDescriptor $reifiedType, @Ignore TypeDescriptor $reifiedArguments, Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments, ceylon.language.meta.model.Type<? extends Object> container) {
List<org.eclipse.ceylon.model.typechecker.model.Type> producedTypes = Metamodel.getProducedTypes(typeArguments);
org.eclipse.ceylon.model.typechecker.model.Type containerType = Metamodel.getModel(container);
Metamodel.checkQualifyingType(containerType, declaration);
Metamodel.checkTypeArguments(containerType, declaration, producedTypes);
// find the proper qualifying type
org.eclipse.ceylon.model.typechecker.model.Type memberQualifyingType = containerType.getSupertype((TypeDeclaration) declaration.getContainer());
final TypedReference appliedFunction = ((org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) declaration).appliedTypedReference(memberQualifyingType, producedTypes);
TypeDescriptor reifiedType = Metamodel.getTypeDescriptorForFunction(appliedFunction);
TypeDescriptor reifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.getUnit(), (Functional) declaration, appliedFunction);
TypeDescriptor reifiedContainer = Metamodel.getTypeDescriptorForProducedType(containerType);
if (getStatic()) {
producedTypes.addAll(0, containerType.getTypeArgumentList());
}
Metamodel.checkReifiedTypeArgument("memberApply", "Method<$1,$2,$3>", Variance.IN, containerType, $reifiedContainer, Variance.OUT, appliedFunction.getType(), $reifiedType, Variance.IN, Metamodel.getProducedTypeForArguments(declaration.getUnit(), (Functional) declaration, appliedFunction), $reifiedArguments);
return new MethodImpl<Container, Type, Arguments>(reifiedContainer, reifiedType, reifiedArguments, appliedFunction, this, container);
}
Aggregations