use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class BoxingVisitor method visit.
@Override
public void visit(QualifiedMemberExpression that) {
super.visit(that);
// handle errors gracefully
if (that.getDeclaration() == null)
return;
if (that.getMemberOperator() instanceof Tree.SafeMemberOp) {
TypedDeclaration decl = (TypedDeclaration) that.getDeclaration();
if (CodegenUtil.isRaw(decl))
CodegenUtil.markRaw(that);
if (CodegenUtil.hasTypeErased(decl))
CodegenUtil.markTypeErased(that);
if (CodegenUtil.hasUntrustedType(decl) || hasTypeParameterWithConstraintsOutsideScope(decl.getType(), that.getScope()))
CodegenUtil.markUntrustedType(that);
// we must be boxed, since safe member op "?." returns an optional type
//return;
} else if (that.getMemberOperator() instanceof Tree.MemberOp && Decl.isValueTypeDecl(that.getPrimary()) && CodegenUtil.isUnBoxed(that.getPrimary())) {
// it's unboxed if it's an unboxable type or it's declared void
if (Decl.isValueTypeDecl((TypedDeclaration) that.getDeclaration()) || (that.getDeclaration() instanceof Function && ((Function) that.getDeclaration()).isDeclaredVoid()))
CodegenUtil.markUnBoxed(that);
if (CodegenUtil.isRaw((TypedDeclaration) that.getDeclaration()))
CodegenUtil.markRaw(that);
if (CodegenUtil.hasTypeErased((TypedDeclaration) that.getDeclaration()))
CodegenUtil.markTypeErased(that);
} else {
propagateFromDeclaration(that, (TypedDeclaration) that.getDeclaration());
}
// be (ex: <String>), and in that case we will generate a proper Sequential<String> which is not raw at all
if (that.getMemberOperator() instanceof Tree.SpreadOp) {
// find the return element type
Type elementType = that.getTarget().getType();
CodegenUtil.markTypeErased(that, hasErasure(elementType));
}
if (ExpressionTransformer.isSuperOrSuperOf(that.getPrimary())) {
// if the target is an interface whose type arguments have been turned to raw, make this expression
// as erased
Reference target = that.getTarget();
if (target != null && target.getQualifyingType() != null && target.getQualifyingType().getDeclaration() instanceof Interface) {
if (isRaw(target.getQualifyingType())) {
CodegenUtil.markTypeErased(that);
} else // See note in ClassTransformer.makeDelegateToCompanion for a similar test
{
TypeDeclaration declaration = target.getQualifyingType().getDeclaration();
if (needsRawCastForMixinSuperCall(declaration, target.getType()))
CodegenUtil.markTypeErased(that);
}
}
}
Type primaryType;
if (that.getPrimary() instanceof Tree.Package || that.getTarget() == null) {
primaryType = that.getPrimary().getTypeModel();
} else {
primaryType = that.getTarget().getQualifyingType();
}
if (primaryType != null && (isRaw(primaryType) || willEraseToSequence(primaryType)) && that.getTarget() != null && that.getTarget().getDeclaration() instanceof TypedDeclaration && CodegenUtil.containsTypeParameter(((TypedDeclaration) that.getTarget().getDeclaration()).getType())) {
CodegenUtil.markTypeErased(that);
}
if (isRaw(primaryType) && !that.getTypeModel().getDeclaration().getTypeParameters().isEmpty()) {
CodegenUtil.markRaw(that);
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeTypedDeclarationTypeDescriptorResolved.
private JCExpression makeTypedDeclarationTypeDescriptorResolved(TypedDeclaration declaration) {
// figure out the method name
String methodName = declaration.getPrefixedName();
List<JCExpression> arguments;
if (declaration instanceof Function)
arguments = makeReifiedTypeArgumentsResolved(getTypeArguments((Function) declaration), true);
else
arguments = List.nil();
if (declaration.isToplevel()) {
JCExpression getterClassNameExpr;
if (declaration instanceof Function) {
getterClassNameExpr = naming.makeName(declaration, Naming.NA_FQ | Naming.NA_WRAPPER);
} else {
String getterClassName = Naming.getAttrClassName(declaration, 0);
getterClassNameExpr = naming.makeUnquotedIdent(getterClassName);
}
arguments = arguments.prepend(makeSelect(getterClassNameExpr, "class"));
} else
arguments = arguments.prepend(make().Literal(methodName));
JCMethodInvocation typedDeclarationDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "functionOrValue"), arguments);
// see if the declaration has a container too
Declaration enclosingDeclaration = getDeclarationContainer(declaration);
JCExpression containerType = null;
if (enclosingDeclaration instanceof TypedDeclaration)
containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration);
else if (enclosingDeclaration instanceof TypeDeclaration) {
Type qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
containerType = makeReifiedTypeArgumentResolved(qualifyingType, true);
}
if (containerType == null) {
return typedDeclarationDescriptor;
} else {
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, typedDeclarationDescriptor));
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class AbstractTransformer method collectQualifyingTypeArguments.
/**
* Collects all the type parameters and arguments required for an interface that's been pulled up to the
* toplevel, including its containing type and method type parameters.
*/
private void collectQualifyingTypeArguments(java.util.List<TypeParameter> qualifyingTypeParameters, Map<TypeParameter, Type> qualifyingTypeArguments, java.util.List<Reference> qualifyingTypes) {
// make sure we only add type parameters with the same name once, as duplicates are erased from the target interface
// since they cannot be accessed
Set<String> names = new HashSet<String>();
// walk the qualifying types backwards to make sure we only add a TP with the same name once and the outer one wins
for (int i = qualifyingTypes.size() - 1; i >= 0; i--) {
Reference qualifiedType = qualifyingTypes.get(i);
Map<TypeParameter, Type> tas = qualifiedType.getTypeArguments();
java.util.List<TypeParameter> tps = ((Generic) qualifiedType.getDeclaration()).getTypeParameters();
// add any type params for this type
if (tps != null) {
int index = 0;
for (TypeParameter tp : tps) {
// add it only once
if (names.add(tp.getName())) {
// start putting all these type parameters at 0 and then in order
// so that outer type params end up before inner type params but
// order is preserved within each type
qualifyingTypeParameters.add(index++, tp);
qualifyingTypeArguments.put(tp, tas.get(tp));
}
}
}
// add any container method TP
Declaration declaration = qualifiedType.getDeclaration();
if (Decl.isLocal(declaration)) {
Scope scope = declaration.getContainer();
// collect every container method until the next type or package
java.util.List<Function> methods = new LinkedList<Function>();
while (scope != null && scope instanceof ClassOrInterface == false && scope instanceof Package == false) {
if (scope instanceof Function) {
methods.add((Function) scope);
}
scope = scope.getContainer();
}
// methods are sorted inner to outer, which is the order we're following here for types
for (Function method : methods) {
java.util.List<TypeParameter> methodTypeParameters = method.getTypeParameters();
if (methodTypeParameters != null) {
int index = 0;
for (TypeParameter tp : methodTypeParameters) {
// add it only once
if (names.add(tp.getName())) {
// start putting all these type parameters at 0 and then in order
// so that outer type params end up before inner type params but
// order is preserved within each type
qualifyingTypeParameters.add(index++, tp);
qualifyingTypeArguments.put(tp, tp.getType());
}
}
}
}
}
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class AnnotationInvocation method encode.
/**
* Encode this invocation into a {@code @AnnotationInstantiation}
* (if the annotation constructors just calls the annotation class)
* or {@code @AnnotationInstantiationTree}
* (if the annotation constructor calls another annotation constructor)
*/
public JCAnnotation encode(AbstractTransformer gen, ListBuffer<JCExpression> instantiations) {
ListBuffer<JCExpression> arguments = ListBuffer.lb();
for (AnnotationArgument argument : getAnnotationArguments()) {
arguments.append(gen.make().Literal(argument.getTerm().encode(gen, instantiations)));
}
JCExpression primary;
if (isInstantiation()) {
primary = gen.makeJavaType(getAnnotationClassType());
} else {
primary = gen.naming.makeName((Function) getPrimary(), Naming.NA_FQ | Naming.NA_WRAPPER);
}
JCAnnotation atInstantiation = gen.make().Annotation(gen.make().Type(gen.syms().ceylonAtAnnotationInstantiationType), com.sun.tools.javac.util.List.<JCExpression>of(gen.make().Assign(gen.naming.makeUnquotedIdent("arguments"), gen.make().NewArray(null, null, arguments.toList())), gen.make().Assign(gen.naming.makeUnquotedIdent("primary"), gen.naming.makeQualIdent(primary, "class"))));
if (instantiations.isEmpty()) {
return atInstantiation;
} else {
return gen.make().Annotation(gen.make().Type(gen.syms().ceylonAtAnnotationInstantiationTreeType), com.sun.tools.javac.util.List.<JCExpression>of(gen.make().NewArray(null, null, instantiations.prepend(atInstantiation).toList())));
}
}
use of com.redhat.ceylon.model.typechecker.model.Function in project ceylon-compiler by ceylon.
the class AnnotationInvocationVisitor method annoClass.
public static Class annoClass(Tree.InvocationExpression invocation) {
Declaration declaration = ((Tree.BaseMemberOrTypeExpression) invocation.getPrimary()).getDeclaration();
Set<Declaration> ctors = new HashSet<Declaration>();
while (declaration instanceof Function) {
if (!ctors.add(declaration)) {
throw new BugException(invocation, "recursive annotation constructor");
}
declaration = ((AnnotationInvocation) ((Function) declaration).getAnnotationConstructor()).getPrimary();
}
if (declaration instanceof Class) {
return (Class) declaration;
} else {
throw new BugException(invocation, "invocation primary has unexpected declaration: " + declaration);
}
}
Aggregations