use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class AbstractTransformer method getTypeForParameter.
Type getTypeForParameter(Parameter parameter, Reference producedReference, int flags) {
/* this method is bogus: It's really trying to answer
* "what's the type of the java declaration of the given parameter",
* but using the ceylon type system to do so.
*/
boolean functional = parameter.getModel() instanceof Function;
if (producedReference == null) {
return parameter.getType();
}
final TypedReference producedTypedReference = producedReference.getTypedParameter(parameter);
final Type type = functional ? producedTypedReference.getFullType() : producedTypedReference.getType();
final TypedDeclaration producedParameterDecl = producedTypedReference.getDeclaration();
final Type declType = producedParameterDecl.getType();
// be more resilient to upstream errors
if (declType == null)
return typeFact.getUnknownType();
if (Decl.isJavaVariadicIncludingInheritance(parameter) && (flags & TP_SEQUENCED_TYPE) == 0) {
// type of param must be Iterable<T>
Type elementType = typeFact.getIteratedType(type);
if (elementType == null) {
log.error("ceylon", "Invalid type for Java variadic parameter: " + type.asString());
return type;
}
return elementType;
}
if (declType.isClassOrInterface()) {
return type;
} else if ((declType.isTypeParameter()) && (flags & TP_TO_BOUND) != 0) {
if (!declType.getSatisfiedTypes().isEmpty()) {
// use upper bound
Type upperBound = declType.getSatisfiedTypes().get(0);
// make sure we apply the type arguments
upperBound = substituteTypeArgumentsForTypeParameterBound(producedReference, upperBound);
Type self = upperBound.getDeclaration().getSelfType();
if (self != null) {
// make sure we apply the type arguments
Type selfUpperBound = self.substitute(upperBound);
if (!willEraseToObject(selfUpperBound) && (willEraseToObject(type) || expressionGen().needsCast(type, selfUpperBound, false, false, false))) {
return selfUpperBound;
}
}
if (!willEraseToObject(upperBound) && (willEraseToObject(type) || expressionGen().needsCast(type, upperBound, false, false, false))) {
return upperBound;
}
}
}
return type;
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionVisitor method setMetamodelType.
private void setMetamodelType(Tree.MemberLiteral that, Declaration result) {
Type outerType;
if (result.isClassOrInterfaceMember()) {
Tree.StaticType type = that.getType();
outerType = type == null ? that.getScope().getDeclaringType(result) : type.getTypeModel();
} else {
outerType = null;
}
boolean constructor = isConstructor(result);
if (result instanceof Function) {
Function method = (Function) result;
if (method.isAbstraction()) {
that.addError("method is overloaded");
} else {
Tree.TypeArgumentList tal = that.getTypeArgumentList();
if (explicitTypeArguments(method, tal)) {
List<Type> typeArgs = getTypeArguments(tal, outerType, method.getTypeParameters());
if (tal != null) {
tal.setTypeModels(typeArgs);
}
if (acceptsTypeArguments(method, outerType, typeArgs, tal, that) || true) {
TypedReference pr = outerType == null ? method.appliedTypedReference(null, typeArgs) : outerType.getTypedMember(method, typeArgs);
that.setTarget(pr);
Type metatype = constructor ? unit.getConstructorMetatype(pr) : unit.getFunctionMetatype(pr);
that.setTypeModel(metatype);
}
} else {
that.addError("missing type arguments to generic declaration: '" + method.getName(unit) + "'");
}
}
} else if (result instanceof Value) {
Value value = (Value) result;
if (that.getTypeArgumentList() != null) {
that.addError("does not accept type arguments: '" + result.getName(unit) + "' is a value");
} else {
TypedReference reference = value.appliedTypedReference(outerType, NO_TYPE_ARGS);
that.setTarget(reference);
Type metatype = constructor ? unit.getValueConstructorMetatype(reference) : unit.getValueMetatype(reference);
that.setTypeModel(metatype);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionVisitor method visitBaseMemberExpression.
private void visitBaseMemberExpression(Tree.StaticMemberOrTypeExpression that, TypedDeclaration member, List<Type> typeArgs, Tree.TypeArguments tal, Type receivingType) {
if (acceptsTypeArguments(member, null, typeArgs, tal, that) || true) {
Scope scope = that.getScope();
Type outerType = scope.getDeclaringType(member);
if (outerType == null) {
outerType = receivingType;
}
TypedReference pr = member.appliedTypedReference(outerType, typeArgs, that.getAssigned());
that.setTarget(pr);
boolean direct = that.getDirectlyInvoked();
Type fullType = accountForGenericFunctionRef(direct, tal, outerType, typeArgs, pr.getFullType());
if (!dynamic && !isNativeForWrongBackend(scope, unit) && !isAbstraction(member) && isTypeUnknown(fullType) && !hasError(that)) {
that.addError("could not determine type of function or value reference: the type of '" + member.getName(unit) + "' is not known" + getTypeUnknownError(fullType));
}
if (dynamic && isTypeUnknown(fullType)) {
// type information we have
return;
}
that.setTypeModel(fullType);
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionVisitor method checkNamedArgument.
private void checkNamedArgument(Tree.NamedArgument arg, Reference reference, Parameter param) {
arg.setParameter(param);
Type argType = null;
if (arg instanceof Tree.SpecifiedArgument) {
Tree.SpecifiedArgument sa = (Tree.SpecifiedArgument) arg;
Tree.Expression e = sa.getSpecifierExpression().getExpression();
if (e != null) {
argType = e.getTypeModel();
}
} else if (arg instanceof Tree.TypedArgument) {
Tree.TypedArgument typedArg = (Tree.TypedArgument) arg;
TypedDeclaration argDec = typedArg.getDeclarationModel();
argType = argumentType(arg.getScope(), argDec);
checkArgumentToVoidParameter(param, typedArg);
if (!dynamic && isTypeUnknown(argType) && !hasError(arg)) {
arg.addError("could not determine type of named argument: the type of '" + param.getName() + "' is not known");
}
}
FunctionOrValue paramModel = param.getModel();
if (paramModel != null) {
TypedReference paramRef = reference.getTypedParameter(param);
Type paramType = paramType(arg.getScope(), paramRef, paramModel);
if (!isTypeUnknown(argType) && !isTypeUnknown(paramType)) {
Node node;
if (arg instanceof Tree.SpecifiedArgument) {
Tree.SpecifiedArgument specifiedArg = (Tree.SpecifiedArgument) arg;
node = specifiedArg.getSpecifierExpression();
} else {
node = arg;
}
checkAssignable(argType, paramType, node, "named argument must be assignable to parameter " + argdesc(param, reference), 2100);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedReference in project ceylon by eclipse.
the class ExpressionVisitor method visitGenericQualifiedMemberReference.
private void visitGenericQualifiedMemberReference(Tree.QualifiedMemberExpression that, Type receiverType, TypedDeclaration member) {
if (member instanceof Function && member.isParameterized()) {
Function generic = (Function) member;
Scope scope = that.getScope();
TypedReference target = receiverType.getTypedMember(member, NO_TYPE_ARGS);
that.setTarget(target);
Type functionType = genericFunctionType(generic, scope, member, target, unit);
that.setTypeModel(functionType);
checkNotJvm(that, "type functions are not supported on the JVM: '" + member.getName(unit) + "' is generic (specify explicit type arguments)");
}
}
Aggregations