use of org.eclipse.ceylon.model.loader.model.LazyFunction 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;
}
use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.
the class Metamodel method getTypeDescriptorForProducedType.
public static TypeDescriptor getTypeDescriptorForProducedType(org.eclipse.ceylon.model.typechecker.model.Type type) {
TypeDeclaration declaration = type.getDeclaration();
if (type.isNothing()) {
return TypeDescriptor.NothingType;
}
if (type.isUnion()) {
TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getCaseTypes());
return TypeDescriptor.union(tdArgs);
}
if (type.isIntersection()) {
TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getSatisfiedTypes());
return TypeDescriptor.intersection(tdArgs);
}
if (declaration instanceof LazyClass) {
ReflectionClass classMirror = (ReflectionClass) ((LazyClass) declaration).classMirror;
TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getTypeArgumentList());
TypeDescriptor ret = TypeDescriptor.klass(classMirror.klass, tdArgs);
if (type.getQualifyingType() != null)
return TypeDescriptor.member(getTypeDescriptorForProducedType(type.getQualifyingType()), ret);
return ret;
}
if (declaration instanceof LazyInterface) {
ReflectionClass classMirror = (ReflectionClass) ((LazyInterface) declaration).classMirror;
TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getTypeArgumentList());
TypeDescriptor ret = TypeDescriptor.klass(classMirror.klass, tdArgs);
if (type.getQualifyingType() != null)
return TypeDescriptor.member(getTypeDescriptorForProducedType(type.getQualifyingType()), ret);
return ret;
}
if (declaration instanceof FunctionOrValueInterface) {
TypedDeclaration underlyingDeclaration = ((FunctionOrValueInterface) declaration).getUnderlyingDeclaration();
TypeDescriptor[] tdArgs = getTypeDescriptorsForProducedTypes(type.getTypeArgumentList());
TypeDescriptor ret;
if (underlyingDeclaration.isToplevel()) {
ReflectionClass classMirror;
// type arguments
if (underlyingDeclaration instanceof Setter)
underlyingDeclaration = ((Setter) underlyingDeclaration).getGetter();
if (underlyingDeclaration instanceof LazyValue)
classMirror = (ReflectionClass) ((LazyValue) underlyingDeclaration).classMirror;
else if (underlyingDeclaration instanceof LazyFunction)
classMirror = (ReflectionClass) ((LazyFunction) underlyingDeclaration).classMirror;
else
throw Metamodel.newModelError("Unsupported underlying declaration type: " + underlyingDeclaration);
ret = TypeDescriptor.functionOrValue(classMirror.klass, tdArgs);
} else
ret = TypeDescriptor.functionOrValue(underlyingDeclaration.getPrefixedName(), tdArgs);
if (type.getQualifyingType() != null)
return TypeDescriptor.member(getTypeDescriptorForProducedType(type.getQualifyingType()), ret);
return ret;
}
if (declaration instanceof UnknownType) {
((UnknownType) declaration).reportErrors();
}
throw Metamodel.newModelError("Unsupported declaration type: " + (declaration == null ? "null" : declaration.getClass()));
}
use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.
the class AbstractModelLoader method findLocalContainerFromAnnotationAndSetCompanionClass.
private Scope findLocalContainerFromAnnotationAndSetCompanionClass(Package pkg, Interface declaration, AnnotationMirror localContainerAnnotation) {
@SuppressWarnings("unchecked") List<String> path = (List<String>) localContainerAnnotation.getValue("path");
// we start at the package
Scope scope = pkg;
for (String name : path) {
scope = (Scope) getDirectMember(scope, name);
}
String companionClassName = (String) localContainerAnnotation.getValue("companionClassName");
if (companionClassName == null || companionClassName.isEmpty()) {
declaration.setCompanionClassNeeded(false);
return scope;
}
ClassMirror container;
Scope javaClassScope;
if (scope instanceof TypedDeclaration && ((TypedDeclaration) scope).isMember())
javaClassScope = scope.getContainer();
else
javaClassScope = scope;
if (javaClassScope instanceof LazyInterface) {
container = ((LazyInterface) javaClassScope).companionClass;
} else if (javaClassScope instanceof LazyClass) {
container = ((LazyClass) javaClassScope).classMirror;
} else if (javaClassScope instanceof LazyValue) {
container = ((LazyValue) javaClassScope).classMirror;
} else if (javaClassScope instanceof LazyFunction) {
container = ((LazyFunction) javaClassScope).classMirror;
} else if (javaClassScope instanceof SetterWithLocalDeclarations) {
container = ((SetterWithLocalDeclarations) javaClassScope).classMirror;
} else {
throw new ModelResolutionException("Unknown scope class: " + javaClassScope);
}
String qualifiedCompanionClassName = container.getQualifiedName() + "$" + companionClassName;
ClassMirror companionClassMirror = lookupClassMirror(pkg.getModule(), qualifiedCompanionClassName);
if (companionClassMirror == null)
throw new ModelResolutionException("Could not find companion class mirror: " + qualifiedCompanionClassName);
((LazyInterface) declaration).companionClass = companionClassMirror;
return scope;
}
use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.
the class AbstractModelLoader method makeToplevelMethod.
protected LazyFunction makeToplevelMethod(ClassMirror classMirror, boolean isNativeHeader) {
LazyFunction method = new LazyFunction(classMirror, this);
manageNativeBackend(method, getFunctionMethodMirror(method), isNativeHeader);
return method;
}
use of org.eclipse.ceylon.model.loader.model.LazyFunction in project ceylon by eclipse.
the class AbstractModelLoader method getLocalContainer.
private Scope getLocalContainer(Package pkg, ClassMirror classMirror, Declaration declaration) {
AnnotationMirror localContainerAnnotation = classMirror.getAnnotation(CEYLON_LOCAL_CONTAINER_ANNOTATION);
String qualifier = getAnnotationStringValue(classMirror, CEYLON_LOCAL_DECLARATION_ANNOTATION, "qualifier");
// deal with types local to functions in the body of toplevel non-lazy attributes, whose container is ultimately the package
Boolean isPackageLocal = getAnnotationBooleanValue(classMirror, CEYLON_LOCAL_DECLARATION_ANNOTATION, "isPackageLocal");
if (BooleanUtil.isTrue(isPackageLocal)) {
// make sure it still knows it's a local
declaration.setQualifier(qualifier);
return null;
}
LocalDeclarationContainer methodDecl = null;
// we get a @LocalContainer annotation for local interfaces
if (localContainerAnnotation != null) {
methodDecl = (LocalDeclarationContainer) findLocalContainerFromAnnotationAndSetCompanionClass(pkg, (Interface) declaration, localContainerAnnotation);
} else {
// all the other cases stay where they belong
MethodMirror method = classMirror.getEnclosingMethod();
if (method == null)
return null;
// see where that method belongs
ClassMirror enclosingClass = method.getEnclosingClass();
while (enclosingClass.isAnonymous()) {
// this gives us the method in which the anonymous class is, which should be the one we're looking for
method = enclosingClass.getEnclosingMethod();
if (method == null)
return null;
// and the method's containing class
enclosingClass = method.getEnclosingClass();
}
// if we are in a setter class, the attribute is declared in the getter class, so look for its declaration there
TypeMirror getterClass = (TypeMirror) getAnnotationValue(enclosingClass, CEYLON_SETTER_ANNOTATION, "getterClass");
boolean isSetter = false;
// we use void.class as default value
if (getterClass != null && !getterClass.isPrimitive()) {
enclosingClass = getterClass.getDeclaredClass();
isSetter = true;
}
String javaClassName = enclosingClass.getQualifiedName();
// make sure we don't go looking in companion classes
if (javaClassName.endsWith(NamingBase.Suffix.$impl.name()))
javaClassName = javaClassName.substring(0, javaClassName.length() - 5);
// find the enclosing declaration
Declaration enclosingClassDeclaration = convertToDeclaration(pkg.getModule(), javaClassName, DeclarationType.TYPE);
if (enclosingClassDeclaration instanceof ClassOrInterface) {
ClassOrInterface containerDecl = (ClassOrInterface) enclosingClassDeclaration;
// now find the method's declaration
// FIXME: find the proper overload if any
String name = method.getName();
if (method.isConstructor() || name.startsWith(NamingBase.Prefix.$default$.toString())) {
methodDecl = (LocalDeclarationContainer) containerDecl;
} else {
// this is only for error messages
String type;
// lots of special cases
if (isStringAttribute(method)) {
name = "string";
type = "attribute";
} else if (isHashAttribute(method)) {
name = "hash";
type = "attribute";
} else if (isGetter(method)) {
// simple attribute
name = getJavaAttributeName(method);
type = "attribute";
} else if (isSetter(method)) {
// simple attribute
name = getJavaAttributeName(method);
type = "attribute setter";
isSetter = true;
} else {
type = "method";
}
// it can be foo$priv$canonical so get rid of that one first
if (name.endsWith(NamingBase.Suffix.$canonical$.toString())) {
name = name.substring(0, name.length() - 11);
}
name = JvmBackendUtil.strip(name, true, method.isPublic() || method.isProtected() || method.isDefaultAccess());
if (name.indexOf('$') > 0) {
// may be a default parameter expression? get the method name which is first
name = name.substring(0, name.indexOf('$'));
}
methodDecl = (LocalDeclarationContainer) containerDecl.getDirectMember(name, null, false);
if (methodDecl == null)
throw new ModelResolutionException("Failed to load outer " + type + " " + name + " for local type " + classMirror.getQualifiedName().toString());
// if it's a setter we wanted, let's get it
if (isSetter) {
LocalDeclarationContainer setter = (LocalDeclarationContainer) ((Value) methodDecl).getSetter();
if (setter == null)
throw new ModelResolutionException("Failed to load outer " + type + " " + name + " for local type " + classMirror.getQualifiedName().toString());
methodDecl = setter;
}
}
} else if (enclosingClassDeclaration instanceof LazyFunction) {
// local and toplevel methods
methodDecl = (LazyFunction) enclosingClassDeclaration;
} else if (enclosingClassDeclaration instanceof LazyValue) {
// local and toplevel attributes
if (enclosingClassDeclaration.isToplevel() && method.getName().equals(NamingBase.Unfix.set_.name()))
isSetter = true;
if (isSetter) {
LocalDeclarationContainer setter = (LocalDeclarationContainer) ((LazyValue) enclosingClassDeclaration).getSetter();
if (setter == null)
throw new ModelResolutionException("Failed to toplevel attribute setter " + enclosingClassDeclaration.getName() + " for local type " + classMirror.getQualifiedName().toString());
methodDecl = setter;
} else
methodDecl = (LazyValue) enclosingClassDeclaration;
} else {
throw new ModelResolutionException("Unknown container type " + enclosingClassDeclaration + " for local type " + classMirror.getQualifiedName().toString());
}
}
// we have the method, now find the proper local qualifier if any
if (qualifier == null)
return null;
declaration.setQualifier(qualifier);
methodDecl.addLocalDeclaration(declaration);
return methodDecl;
}
Aggregations