// 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(Naming.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
if(method.isConstructor()){
methodDecl = (LocalDeclarationContainer) containerDecl;
}else{
String name = method.getName();
// 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(name);
type = "attribute";
}else if(isSetter(method)) {
// simple attribute
name = getJavaAttributeName(name);
type = "attribute setter";
isSetter = true;
}else{
type = "method";
}
// strip any escaping or private suffix
// it can be foo$priv$canonical so get rid of that one first
if (name.endsWith(Naming.Suffix.$canonical$.toString())) {
name = name.substring(0, name.length()-11);
}
name = Util.strip(name, true, method.isPublic() || method.isProtected() || method.isDefaultAccess());
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 LazyMethod){
// local and toplevel methods
methodDecl = (LazyMethod)enclosingClassDeclaration;
}else if(enclosingClassDeclaration instanceof LazyValue){
// local and toplevel attributes
if(enclosingClassDeclaration.isToplevel() && method.getName().equals(Naming.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