use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror 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;
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method loadCompiledModule.
private boolean loadCompiledModule(Module module, ClassMirror moduleClass, boolean loadModuleImports) {
String moduleClassName = moduleClass.getQualifiedName();
String name = getAnnotationStringValue(moduleClass, CEYLON_MODULE_ANNOTATION, "name");
String version = getAnnotationStringValue(moduleClass, CEYLON_MODULE_ANNOTATION, "version");
if (name == null || name.isEmpty()) {
logWarning("Module class " + moduleClassName + " contains no name, ignoring it");
return false;
}
if (!name.equals(module.getNameAsString())) {
logWarning("Module class " + moduleClassName + " declares an invalid name: " + name + ". It should be: " + module.getNameAsString());
return false;
}
if (version == null || version.isEmpty()) {
logWarning("Module class " + moduleClassName + " contains no version, ignoring it");
return false;
}
if (!version.equals(module.getVersion())) {
logWarning("Module class " + moduleClassName + " declares an invalid version: " + version + ". It should be: " + module.getVersion());
return false;
}
// String label = getAnnotationStringValue(moduleClass, CEYLON_MODULE_ANNOTATION, "label");
// module.setLabel(label);
int major = getAnnotationIntegerValue(moduleClass, CEYLON_CEYLON_ANNOTATION, "major", 0);
int minor = getAnnotationIntegerValue(moduleClass, CEYLON_CEYLON_ANNOTATION, "minor", 0);
module.setJvmMajor(major);
module.setJvmMinor(minor);
// no need to load the "nativeBackends" annotation value, it's loaded from annotations
setAnnotations(module, moduleClass, false);
if (loadModuleImports) {
List<AnnotationMirror> imports = getAnnotationArrayValue(moduleClass, CEYLON_MODULE_ANNOTATION, "dependencies");
if (imports != null) {
boolean supportsNamespaces = ModuleUtil.supportsImportsWithNamespaces(major, minor);
for (AnnotationMirror importAttribute : imports) {
String dependencyName = (String) importAttribute.getValue("name");
if (dependencyName != null) {
String namespace;
if (supportsNamespaces) {
namespace = (String) importAttribute.getValue("namespace");
if (namespace != null && namespace.isEmpty()) {
namespace = null;
}
} else {
if (ModuleUtil.isMavenModule(dependencyName)) {
namespace = "maven";
} else {
namespace = null;
}
}
String dependencyVersion = (String) importAttribute.getValue("version");
Module dependency = moduleManager.getOrCreateModule(ModuleManager.splitModuleName(dependencyName), dependencyVersion);
Boolean optionalVal = (Boolean) importAttribute.getValue("optional");
Boolean exportVal = (Boolean) importAttribute.getValue("export");
List<String> nativeBackends = (List<String>) importAttribute.getValue("nativeBackends");
Backends backends = nativeBackends == null ? Backends.ANY : Backends.fromAnnotations(nativeBackends);
ModuleImport moduleImport = moduleManager.findImport(module, dependency);
if (moduleImport == null) {
boolean optional = optionalVal != null && optionalVal;
boolean export = exportVal != null && exportVal;
moduleImport = new ModuleImport(namespace, dependency, optional, export, backends);
module.addImport(moduleImport);
}
}
}
}
}
module.setAvailable(true);
modules.getListOfModules().add(module);
Module languageModule = modules.getLanguageModule();
module.setLanguageModule(languageModule);
if (loadModuleImports) {
if (!ModelUtil.equalModules(module, languageModule)) {
boolean found = false;
for (ModuleImport mi : module.getImports()) {
if (mi.getModule().isLanguageModule()) {
found = true;
break;
}
}
if (!found) {
// It's not really a LazyModule because we're not loading
// it lazily. It's only here for module version analysis.
// But other stuff expects non-source modules to be lazy.
LazyModule oldLangMod = new LazyModule() {
@Override
protected AbstractModelLoader getModelLoader() {
return AbstractModelLoader.this;
}
};
oldLangMod.setLanguageModule(oldLangMod);
oldLangMod.setName(Arrays.asList("ceylon", "language"));
oldLangMod.setVersion(getJvmLanguageModuleVersion(major, minor));
oldLangMod.setNativeBackends(Backends.JAVA);
oldLangMod.setJvmMajor(major);
oldLangMod.setJvmMinor(minor);
ModuleImport moduleImport = new ModuleImport(null, oldLangMod, false, false);
module.addImport(moduleImport);
}
}
}
return true;
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method completeLazyAlias.
private void completeLazyAlias(TypeDeclaration alias, ClassMirror mirror, String aliasAnnotationName) {
// now resolve the extended type
AnnotationMirror aliasAnnotation = mirror.getAnnotation(aliasAnnotationName);
String extendedTypeString = (String) aliasAnnotation.getValue();
Type extendedType = decodeType(extendedTypeString, alias, ModelUtil.getModuleContainer(alias), "alias target");
alias.setExtendedType(extendedType);
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method getRepeatableContainer.
public Interface getRepeatableContainer(Class c) {
if (c instanceof AnnotationProxyClass) {
AnnotationMirror mirror = ((AnnotationProxyClass) c).iface.classMirror.getAnnotation("java.lang.annotation.Repeatable");
if (mirror != null) {
TypeMirror m = (TypeMirror) mirror.getValue();
Module module = findModuleForClassMirror(m.getDeclaredClass());
return (Interface) convertDeclaredTypeToDeclaration(module, m, DeclarationType.TYPE);
}
}
return null;
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method makeLazyClass.
protected LazyClass makeLazyClass(ClassMirror classMirror, Class superClass, MethodMirror initOrDefaultConstructor, boolean isNativeHeader) {
LazyClass klass = new LazyClass(classMirror, this, superClass, initOrDefaultConstructor);
AnnotationMirror objectAnnotation = classMirror.getAnnotation(CEYLON_OBJECT_ANNOTATION);
if (objectAnnotation != null) {
klass.setAnonymous(true);
// isFalse will only consider non-null arguments, and we default to true if null
if (BooleanUtil.isFalse((Boolean) objectAnnotation.getValue("named")))
klass.setNamed(false);
}
klass.setAnnotation(classMirror.getAnnotation(CEYLON_LANGUAGE_ANNOTATION_ANNOTATION) != null);
if (klass.isCeylon())
klass.setAbstract(classMirror.getAnnotation(CEYLON_LANGUAGE_ABSTRACT_ANNOTATION) != null || // the model annotation
(!classMirror.isInnerClass() && !classMirror.isLocalClass() && classMirror.isAbstract()));
else
klass.setAbstract(classMirror.isAbstract() && !classMirror.isEnum());
klass.setFormal(classMirror.getAnnotation(CEYLON_LANGUAGE_FORMAL_ANNOTATION) != null);
klass.setDefault(classMirror.getAnnotation(CEYLON_LANGUAGE_DEFAULT_ANNOTATION) != null);
klass.setSerializable(classMirror.getAnnotation(CEYLON_LANGUAGE_SERIALIZABLE_ANNOTATION) != null || classMirror.getQualifiedName().equals("ceylon.language.Array") || classMirror.getQualifiedName().equals("ceylon.language.Tuple"));
// hack to make Throwable sealed until ceylon/ceylon.language#408 is fixed
klass.setSealed(classMirror.getAnnotation(CEYLON_LANGUAGE_SEALED_ANNOTATION) != null || CEYLON_LANGUAGE.equals(classMirror.getPackage().getQualifiedName()) && "Throwable".equals(classMirror.getName()));
boolean actual = classMirror.getAnnotation(CEYLON_LANGUAGE_ACTUAL_ANNOTATION) != null;
klass.setActual(actual);
klass.setActualCompleter(this);
klass.setFinal(classMirror.isFinal());
klass.setStatic(classMirror.isStatic());
if (objectAnnotation == null) {
manageNativeBackend(klass, classMirror, isNativeHeader);
} else {
manageNativeBackend(klass, getGetterMethodMirror(klass, klass.classMirror, true), isNativeHeader);
}
return klass;
}
Aggregations