use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method hasConstructors.
/**
* Returns:
* <ul>
* <li>true if the class has named constructors ({@code @Class(...constructors=true)}).</li>
* <li>false if the class has an initializer constructor.</li>
* <li>null if the class lacks {@code @Class} (i.e. is not a Ceylon class).</li>
* </ul>
* @param classMirror
* @return
*/
private Boolean hasConstructors(ClassMirror classMirror) {
AnnotationMirror a = classMirror.getAnnotation(CEYLON_CLASS_ANNOTATION);
Boolean hasConstructors;
if (a != null) {
hasConstructors = (Boolean) a.getValue("constructors");
if (hasConstructors == null) {
hasConstructors = false;
}
} else {
hasConstructors = null;
}
return hasConstructors;
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method setParameters.
private void setParameters(Functional decl, ClassMirror classMirror, MethodMirror methodMirror, boolean isCeylon, Scope container, boolean isCoercedMethod) {
ParameterList parameters = new ParameterList();
parameters.setNamedParametersSupported(isCeylon);
decl.addParameterList(parameters);
int parameterCount = methodMirror.getParameters().size();
int parameterIndex = 0;
for (VariableMirror paramMirror : methodMirror.getParameters()) {
// ignore some parameters
if (paramMirror.getAnnotation(CEYLON_IGNORE_ANNOTATION) != null)
continue;
boolean isLastParameter = parameterIndex == parameterCount - 1;
boolean isVariadic = isLastParameter && methodMirror.isVariadic();
String paramName = getAnnotationStringValue(paramMirror, CEYLON_NAME_ANNOTATION);
// use whatever param name we find as default
if (paramName == null)
paramName = paramMirror.getName();
Parameter parameter = new Parameter();
parameter.setName(paramName);
TypeMirror typeMirror = paramMirror.getType();
Scope scope = (Scope) decl;
Module module = ModelUtil.getModuleContainer(scope);
Type type;
boolean coercedParameter = false;
if (isVariadic) {
// possibly make it optional
TypeMirror variadicType = typeMirror.getComponentType();
// we pretend it's toplevel because we want to get magic string conversion for variadic methods
if (isCoercedMethod && isCoercedType(variadicType)) {
type = applyTypeCoercion(variadicType, paramMirror, methodMirror, paramName, (Declaration) decl, module, scope);
coercedParameter = true;
} else {
type = obtainType(module, variadicType, scope, TypeLocation.TOPLEVEL);
}
if (!isCeylon) {
// Java parameters are all optional unless primitives or annotated as such
if (getUncheckedNullPolicy(isCeylon, variadicType, paramMirror) != NullStatus.NonOptional) {
type = makeOptionalTypePreserveUnderlyingType(type, module);
}
}
// turn it into a Sequential<T>
type = typeFactory.getSequentialType(type);
} else {
if (isCoercedMethod && isCoercedType(typeMirror)) {
type = applyTypeCoercion(typeMirror, paramMirror, methodMirror, paramName, (Declaration) decl, module, scope);
coercedParameter = true;
} else {
type = obtainType(typeMirror, paramMirror, scope, module, "parameter '" + paramName + "' of method '" + methodMirror.getName() + "'", (Declaration) decl);
}
if (!isCeylon) {
// Java parameters are all optional unless primitives or annotated as such
if (getUncheckedNullPolicy(isCeylon, typeMirror, paramMirror) != NullStatus.NonOptional) {
type = makeOptionalTypePreserveUnderlyingType(type, module);
}
}
}
if (type.isCached()) {
type = type.clone();
}
if (!type.isRaw())
type.setRaw(isRaw(ModelUtil.getModuleContainer(container), typeMirror));
FunctionOrValue value = null;
boolean lookedup = false;
if (isCeylon && decl instanceof Class) {
// For a functional parameter to a class, we can just lookup the member
value = (FunctionOrValue) ((Class) decl).getDirectMember(paramName, null, false);
lookedup = value != null;
}
if (value == null) {
// So either decl is not a Class,
// or the method or value member of decl is not shared
AnnotationMirror functionalParameterAnnotation = paramMirror.getAnnotation(CEYLON_FUNCTIONAL_PARAMETER_ANNOTATION);
if (functionalParameterAnnotation != null) {
// A functional parameter to a method
Function method = loadFunctionalParameter((Declaration) decl, paramName, type, (String) functionalParameterAnnotation.getValue());
value = method;
parameter.setDeclaredAnything(method.isDeclaredVoid());
} else if (coercedParameter && isFunctionCercion(typeMirror)) {
Function method = loadFunctionCoercionParameter((Declaration) decl, paramName, typeMirror, module, scope);
value = method;
parameter.setDeclaredAnything(method.isDeclaredVoid());
} else {
// A value parameter to a method
value = isCeylon ? new Value() : new JavaParameterValue();
value.setType(type);
}
value.setContainer(scope);
value.setScope(scope);
ModelUtil.setVisibleScope(value);
value.setUnit(scope.getUnit());
value.setName(paramName);
} else {
// the method return type, so we try to detect this and fix it
if (value instanceof Function && isCeylon1Dot1(classMirror)) {
Type newType = getSimpleCallableReturnType(value.getType());
if (!newType.isUnknown())
value.setType(newType);
}
}
value.setInitializerParameter(parameter);
value.setCoercionPoint(coercedParameter);
parameter.setModel(value);
if (paramMirror.getAnnotation(CEYLON_SEQUENCED_ANNOTATION) != null || isVariadic)
parameter.setSequenced(true);
if (paramMirror.getAnnotation(CEYLON_DEFAULTED_ANNOTATION) != null)
parameter.setDefaulted(true);
if (parameter.isSequenced() && // FIXME: store info in Sequenced
"ceylon.language.Sequence".equals(paramMirror.getType().getQualifiedName())) {
parameter.setAtLeastOne(true);
}
// unboxed is already set if it's a real method
if (!lookedup) {
// if it's variadic, consider the array element type (T[] == T...) for boxing rules
markUnboxed(value, null, isVariadic ? paramMirror.getType().getComponentType() : paramMirror.getType());
markSmall(value, paramMirror.getType());
}
parameter.setDeclaration((Declaration) decl);
value.setDeprecated(value.isDeprecated() || isDeprecated(paramMirror));
setAnnotations(value, paramMirror, false);
parameters.getParameters().add(parameter);
if (!lookedup) {
parameter.getDeclaration().getMembers().add(parameter.getModel());
}
parameterIndex++;
}
if (decl instanceof Function) {
// Multiple parameter lists
AnnotationMirror functionalParameterAnnotation = methodMirror.getAnnotation(CEYLON_FUNCTIONAL_PARAMETER_ANNOTATION);
if (functionalParameterAnnotation != null) {
parameterNameParser.parseMpl((String) functionalParameterAnnotation.getValue(), ((Function) decl).getType().getFullType(), (Function) decl);
}
}
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method isCeylon1Dot1.
private boolean isCeylon1Dot1(ClassMirror classMirror) {
AnnotationMirror annotation = classMirror.getAnnotation(CEYLON_CEYLON_ANNOTATION);
if (annotation == null)
return false;
Integer major = (Integer) annotation.getValue("major");
if (major == null)
major = 0;
Integer minor = (Integer) annotation.getValue("minor");
if (minor == null)
minor = 0;
return major == Versions.V1_1_BINARY_MAJOR_VERSION && minor == Versions.V1_1_BINARY_MINOR_VERSION;
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method getContainer.
private ClassOrInterface getContainer(Module module, ClassMirror classMirror) {
AnnotationMirror containerAnnotation = classMirror.getAnnotation(CEYLON_CONTAINER_ANNOTATION);
if (containerAnnotation != null) {
TypeMirror javaClassMirror = (TypeMirror) containerAnnotation.getValue("klass");
String javaClassName = javaClassMirror.getQualifiedName();
ClassOrInterface containerDecl = (ClassOrInterface) convertToDeclaration(module, javaClassName, DeclarationType.TYPE);
if (containerDecl == null)
throw new ModelResolutionException("Failed to load outer type " + javaClassName + " for inner type " + classMirror.getQualifiedName().toString());
return containerDecl;
} else {
return (ClassOrInterface) convertToDeclaration(module, classMirror.getEnclosingClass(), DeclarationType.TYPE);
}
}
use of org.eclipse.ceylon.model.loader.mirror.AnnotationMirror in project ceylon by eclipse.
the class AbstractModelLoader method setTypeParametersFromAnnotations.
// from our annotation
private void setTypeParametersFromAnnotations(Scope scope, List<TypeParameter> params, AnnotatedMirror mirror, List<AnnotationMirror> typeParameterAnnotations, List<TypeParameterMirror> typeParameterMirrors) {
// We must first add every type param, before we resolve the bounds, which can
// refer to type params.
String selfTypeName = getSelfTypeFromAnnotations(mirror);
int i = 0;
for (AnnotationMirror typeParamAnnotation : typeParameterAnnotations) {
TypeParameter param = new TypeParameter();
param.setUnit(scope.getUnit());
param.setContainer(scope);
param.setScope(scope);
ModelUtil.setVisibleScope(param);
param.setDeclaration((Declaration) scope);
// let's not trigger the lazy-loading if we're completing a LazyClass/LazyInterface
if (scope instanceof LazyContainer)
((LazyContainer) scope).addMember(param);
else
// must be a method
scope.addMember(param);
param.setName((String) typeParamAnnotation.getValue("value"));
param.setExtendedType(typeFactory.getAnythingType());
if (i < typeParameterMirrors.size()) {
TypeParameterMirror typeParameterMirror = typeParameterMirrors.get(i);
param.setNonErasedBounds(hasNonErasedBounds(typeParameterMirror));
}
String varianceName = (String) typeParamAnnotation.getValue("variance");
if (varianceName != null) {
if (varianceName.equals("IN")) {
param.setContravariant(true);
} else if (varianceName.equals("OUT"))
param.setCovariant(true);
}
// If this is a self type param then link it to its type's declaration
if (param.getName().equals(selfTypeName)) {
param.setSelfTypedDeclaration((TypeDeclaration) scope);
}
params.add(param);
i++;
}
Module moduleScope = ModelUtil.getModuleContainer(scope);
// Now all type params have been set, we can resolve the references parts
Iterator<TypeParameter> paramsIterator = params.iterator();
for (AnnotationMirror typeParamAnnotation : typeParameterAnnotations) {
TypeParameter param = paramsIterator.next();
@SuppressWarnings("unchecked") List<String> satisfiesAttribute = (List<String>) typeParamAnnotation.getValue("satisfies");
setListOfTypes(param.getSatisfiedTypes(), satisfiesAttribute, scope, moduleScope, "type parameter '" + param.getName() + "' satisfied types");
@SuppressWarnings("unchecked") List<String> caseTypesAttribute = (List<String>) typeParamAnnotation.getValue("caseTypes");
if (caseTypesAttribute != null && !caseTypesAttribute.isEmpty())
param.setCaseTypes(new LinkedList<Type>());
setListOfTypes(param.getCaseTypes(), caseTypesAttribute, scope, moduleScope, "type parameter '" + param.getName() + "' case types");
String defaultValueAttribute = (String) typeParamAnnotation.getValue("defaultValue");
if (defaultValueAttribute != null && !defaultValueAttribute.isEmpty()) {
Type decodedType = decodeType(defaultValueAttribute, scope, moduleScope, "type parameter '" + param.getName() + "' defaultValue");
param.setDefaultTypeArgument(decodedType);
param.setDefaulted(true);
}
}
}
Aggregations