use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class ExpressionTransformer method transform.
private List<JCAnnotation> transform(Object useSite, OutputElement target, Tree.AnnotationList annotationList, EnumSet<OutputElement> outputs) {
if (annotationList == null) {
return List.nil();
}
if ((gen().disableAnnotations & CeylonTransformer.DISABLE_USER_ANNOS) != 0) {
return List.nil();
}
LinkedHashMap<Class, ListBuffer<JCAnnotation>> annotationSet = new LinkedHashMap<>();
if (annotationList != null) {
if (annotationList.getAnonymousAnnotation() != null && AnnotationUtil.isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("doc"), useSite, target)) {
transformAnonymousAnnotation(annotationList.getAnonymousAnnotation(), annotationSet);
}
if (annotationList.getAnnotations() != null) {
for (Tree.Annotation annotation : annotationList.getAnnotations()) {
Function annoCtorDecl = ((Function) ((Tree.BaseMemberExpression) annotation.getPrimary()).getDeclaration());
if (annoCtorDecl != null) {
String aname = annoCtorDecl.getQualifiedNameString();
if ("java.lang::transient".equals(aname) || "java.lang::volatile".equals(aname) || "java.lang::synchronized".equals(aname) || "java.lang::native".equals(aname) || "java.lang::strictfp".equals(aname) || "java.lang::overloaded".equals(aname) || "java.lang::nonbean".equals(aname)) {
continue;
}
}
boolean isNaturalTarget = AnnotationUtil.isNaturalTarget(annoCtorDecl, useSite, target);
EnumSet<OutputElement> possibleTargets = AnnotationUtil.interopAnnotationTargeting(useSite instanceof Declaration ? isEe((Declaration) useSite) : false, outputs, annotation, false, false, useSite instanceof Declaration ? (Declaration) useSite : null);
if ((isNaturalTarget && possibleTargets == null) || (possibleTargets != null && possibleTargets.equals(EnumSet.of(target)))) {
transformAnnotation(annotation, annotationSet);
}
}
}
}
ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
for (Class annotationClass : annotationSet.keySet()) {
ListBuffer<JCAnnotation> annotations = annotationSet.get(annotationClass);
if (isSequencedAnnotation(annotationClass)) {
JCAnnotation wrapperAnnotation = make().Annotation(makeJavaType(annotationClass.getType(), JT_ANNOTATIONS), List.<JCExpression>of(make().NewArray(null, null, upcastExprList(annotations.toList()))));
result.append(wrapperAnnotation);
} else if (isRepeatableAnnotation(annotationClass)) {
Interface containerAnnotation = getRepeatableContainer(annotationClass);
JCAnnotation wrapperAnnotation = make().Annotation(makeJavaType(containerAnnotation.appliedType(null, Collections.<Type>emptyList())), List.<JCExpression>of(make().NewArray(null, null, upcastExprList(annotations.toList()))));
result.append(wrapperAnnotation);
} else {
if (annotations.size() > 1) {
makeErroneous(annotationList, "compiler bug: multiple occurances of non-sequenced annotation class " + annotationClass.getQualifiedNameString());
}
result.appendList(annotations);
}
}
// Special case: Generate a @java.lang.Deprecated() if Ceylon deprecated
if (annotationList != null) {
for (Tree.Annotation annotation : annotationList.getAnnotations()) {
if (AnnotationUtil.isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("deprecated"), useSite, target) && isDeprecatedAnnotation(annotation.getPrimary()) && !(useSite instanceof Function) && !(useSite instanceof Constructor)) {
result.appendList(makeAtDeprecated());
}
}
}
return result.toList();
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class LocalTypeVisitor method visit.
@Override
public void visit(Tree.BaseMemberOrTypeExpression that) {
Declaration model = that.getDeclaration();
if (model != null && (model instanceof Function || model instanceof Class) && !that.getAssigned() && // if it's a parameter we don't need to wrap it in a class
!model.isParameter() && (model instanceof Class == false || !that.getStaticMethodReferencePrimary()) && !that.getDirectlyInvoked()) {
String prefix = this.prefix;
enterAnonymousClass();
super.visit(that);
exitAnonymousClass();
this.prefix = prefix;
} else {
super.visit(that);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class LocalTypeVisitor method visit.
@Override
public void visit(Tree.QualifiedMemberOrTypeExpression that) {
Declaration model = that.getDeclaration();
if (model != null && (model instanceof Function || model instanceof Class) && !that.getAssigned() && // if it's a parameter we don't need to wrap it in a class
!model.isParameter() && (model instanceof Class == false || !that.getStaticMethodReferencePrimary()) && !that.getDirectlyInvoked()) {
String prefix = this.prefix;
enterAnonymousClass();
super.visit(that);
exitAnonymousClass();
this.prefix = prefix;
} else {
super.visit(that);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class MethodDefinitionBuilder method getNonWideningParam.
public NonWideningParam getNonWideningParam(TypedReference typedRef, WideningRules wideningRules) {
TypedDeclaration nonWideningDecl = null;
int flags = 0;
long modifiers = 0;
Type nonWideningType;
FunctionOrValue mov = (FunctionOrValue) typedRef.getDeclaration();
if (Decl.isValue(mov)) {
TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef).resolveAliases();
nonWideningDecl = nonWideningTypedRef.getDeclaration();
} else {
// Stef: So here's the thing. I know this is wrong for Function where we should do getFullType(), BUT
// lots of methods call this and then feed the output into AT.makeJavaType(TypedDeclaration typeDecl, Type type, int flags)
// which adds the Callable type, so if we fix it here we have to remove it from there and there's lots of callers of that
// function which rely on its behaviour and frankly I've had enough of this refactoring, so a few callers of this function
// have to add the Callable back. It sucks, yeah, but so far it works, which is amazing enough that I don't want to touch it
// any more. More ambitious/courageous people are welcome to fix this properly.
nonWideningType = typedRef.getType().resolveAliases();
nonWideningDecl = mov;
}
if (!CodegenUtil.isUnBoxed(nonWideningDecl))
flags |= AbstractTransformer.JT_NO_PRIMITIVES;
// make sure we don't accidentally narrow value parameters that would be erased in the topmost declaration
if (wideningRules != WideningRules.NONE && mov instanceof Value) {
TypedDeclaration refinedParameter = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(mov);
if (refinedParameter != null && refinedParameter instanceof Value && ((Value) refinedParameter).getInitializerParameter() != null && gen.isJavaVariadic(((Value) refinedParameter).getInitializerParameter())) {
modifiers |= Flags.VARARGS;
}
// mixin bridge methods have the same rules as when refining stuff except they are their own refined decl
if (wideningRules == WideningRules.FOR_MIXIN || !Decl.equal(refinedParameter, mov)) {
Type refinedParameterType;
// in the refined parameter type
if (refinedParameter instanceof Function)
refinedParameterType = refinedParameter.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType();
else
refinedParameterType = refinedParameter.getType();
// if the supertype method itself got erased to Object, we can't do better than this
if (gen.willEraseToObject(refinedParameterType) && !gen.willEraseToBestBounds(mov))
nonWideningType = gen.typeFact().getObjectType();
else if (CodegenUtil.isRaw(refinedParameter)) {
flags |= AbstractTransformer.JT_RAW;
} else {
flags |= AbstractTransformer.JT_NARROWED;
}
if ((flags & AbstractTransformer.JT_RAW) == 0 && !Decl.equal(refinedParameter, mov) && implementsRawParameter(mov)) {
flags |= AbstractTransformer.JT_RAW;
}
}
}
// keep in sync with gen.willEraseToBestBounds()
if (wideningRules != WideningRules.NONE && (gen.typeFact().isUnion(nonWideningType) || gen.typeFact().isIntersection(nonWideningType))) {
final Type refinedType = ((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(nonWideningDecl)).getType();
if (refinedType.isTypeParameter() && !refinedType.getSatisfiedTypes().isEmpty()) {
nonWideningType = refinedType.getSatisfiedTypes().get(0);
// Could be parameterized, and type param won't be in scope, so have to go raw
flags |= AbstractTransformer.JT_RAW;
}
}
// this is to be done on the parameter's containing method, to see if that method must have raw parameters
if (mov.isParameter() && mov.getContainer() instanceof Declaration && gen.rawParameters((Declaration) mov.getContainer())) {
flags |= AbstractTransformer.JT_RAW;
}
return new NonWideningParam(flags, modifiers, nonWideningType, nonWideningDecl);
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class Naming method quoteMethodNameIfProperty.
private static String quoteMethodNameIfProperty(Function method) {
String name = method.getName();
if (!method.isShared()) {
name = suffixName(Suffix.$priv$, name);
}
// Toplevel methods keep their original name because their names might be mangled
if (method instanceof LazyFunction) {
return ((LazyFunction) method).getRealName();
}
// since local methods have a $getter suffix
if (!method.isClassOrInterfaceMember())
return name;
// do not quote method names if we have a refined constraint
Function refinedMethod = (Function) method.getRefinedDeclaration();
if (refinedMethod instanceof JavaMethod) {
return ((JavaMethod) refinedMethod).getRealName();
}
// get/is with at least one more letter, no parameter and non-void type
if (((name.length() >= 4 && name.startsWith("get")) || name.length() >= 3 && name.startsWith("is")) && // not the total number of parameters
method.getFirstParameterList().getParameters().isEmpty() && !AbstractTransformer.isAnything(method.getType()))
return quote(name);
// set with one parameter and void type
if ((name.length() >= 4 && name.startsWith("set")) && // not the total number of parameters
method.getFirstParameterList().getParameters().size() == 1 && AbstractTransformer.isAnything(method.getType()))
return quote(name);
return name;
}
Aggregations