use of org.eclipse.ceylon.model.typechecker.model.Module in project ceylon by eclipse.
the class AbstractModelLoader method findLanguageModuleDeclarationForBootstrap.
private Declaration findLanguageModuleDeclarationForBootstrap(String name) {
// make sure we don't return anything for ceylon.language
if (name.equals(CEYLON_LANGUAGE))
return null;
// we're bootstrapping ceylon.language so we need to return the ProducedTypes straight from the model we're compiling
Module languageModule = modules.getLanguageModule();
int lastDot = name.lastIndexOf(".");
if (lastDot == -1)
return null;
String pkgName = name.substring(0, lastDot);
String simpleName = name.substring(lastDot + 1);
// Nothing is a special case with no real decl
if (name.equals("ceylon.language.Nothing"))
return typeFactory.getNothingDeclaration();
// find the right package
Package pkg = languageModule.getDirectPackage(pkgName);
if (pkg != null) {
Declaration member = pkg.getDirectMember(simpleName, null, false);
// if we get a value, we want its type
if (JvmBackendUtil.isValue(member) && ((Value) member).getTypeDeclaration().getName().equals(simpleName)) {
member = ((Value) member).getTypeDeclaration();
}
if (member != null)
return member;
}
throw new ModelResolutionException("Failed to look up given type in language module while bootstrapping: " + name);
}
use of org.eclipse.ceylon.model.typechecker.model.Module in project ceylon by eclipse.
the class AbstractModelLoader method addValue.
private JavaBeanValue addValue(ClassOrInterface klass, MethodMirror methodMirror, String methodName, boolean isCeylon, boolean isNativeHeader) {
JavaBeanValue value = new JavaBeanValue(methodMirror);
value.setGetterName(methodMirror.getName());
value.setContainer(klass);
value.setScope(klass);
value.setUnit(klass.getUnit());
Type type = null;
try {
setMethodOrValueFlags(klass, methodMirror, value, isCeylon);
} catch (ModelResolutionException x) {
// collect an error in its type
type = logModelResolutionException(x, klass, "getter '" + methodName + "' (checking if it is an overriding method");
}
value.setName(JvmBackendUtil.strip(methodName, isCeylon, value.isShared()));
Module module = ModelUtil.getModuleContainer(klass);
// do not log an additional error if we had one from checking if it was overriding
if (type == null)
type = obtainType(methodMirror.getReturnType(), methodMirror, klass, module, "getter '" + methodName + "'", klass);
if (type.isCached()) {
type = type.clone();
}
// special case for hash attributes which we want to pretend are of type long internally
if (value.isShared() && methodName.equals("hash"))
type.setUnderlyingType("long");
NullStatus nullPolicy = getUncheckedNullPolicy(isCeylon, methodMirror.getReturnType(), methodMirror);
switch(nullPolicy) {
case Optional:
if (!isCeylon) {
type = makeOptionalTypePreserveUnderlyingType(type, module);
}
break;
case UncheckedNull:
value.setUncheckedNullType(true);
break;
}
value.setType(type);
type.setRaw(isRaw(module, methodMirror.getReturnType()));
markUnboxed(value, methodMirror, methodMirror.getReturnType());
markSmall(value, methodMirror.getReturnType());
markTypeErased(value, methodMirror, methodMirror.getReturnType());
markUntrustedType(value, methodMirror, methodMirror.getReturnType());
value.setDeprecated(isDeprecated(methodMirror));
setAnnotations(value, methodMirror, isNativeHeader);
klass.addMember(value);
ModelUtil.setVisibleScope(value);
return value;
}
use of org.eclipse.ceylon.model.typechecker.model.Module 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.typechecker.model.Module in project ceylon by eclipse.
the class AbstractModelLoader method setCaseTypes.
private void setCaseTypes(ClassOrInterface klass, ClassMirror classMirror) {
if (classMirror.isEnum()) {
ArrayList<Type> caseTypes = new ArrayList<Type>();
for (Declaration member : klass.getMembers()) {
if (member instanceof FieldValue && ((FieldValue) member).isEnumValue()) {
caseTypes.add(((FieldValue) member).getType());
}
}
klass.setCaseTypes(caseTypes);
} else {
String selfType = getSelfTypeFromAnnotations(classMirror);
Module moduleScope = ModelUtil.getModuleContainer(klass);
if (selfType != null && !selfType.isEmpty()) {
Type type = decodeType(selfType, klass, moduleScope, "self type");
if (!type.isTypeParameter()) {
logError("Invalid type signature for self type of " + klass.getQualifiedNameString() + ": " + selfType + " is not a type parameter");
} else {
klass.setSelfType(type);
List<Type> caseTypes = new LinkedList<Type>();
caseTypes.add(type);
klass.setCaseTypes(caseTypes);
}
} else {
List<String> caseTypes = getCaseTypesFromAnnotations(classMirror);
if (caseTypes != null && !caseTypes.isEmpty()) {
klass.setCaseTypes(getTypesList(caseTypes, klass, moduleScope, "case types", klass.getQualifiedNameString()));
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Module in project ceylon by eclipse.
the class AbstractModelLoader method addValue.
private Value addValue(ClassOrInterface klass, String ceylonName, FieldMirror fieldMirror, boolean isCeylon, boolean isNativeHeader) {
// make sure it's a FieldValue so we can figure it out in the backend
Value value = new FieldValue(fieldMirror.getName());
value.setContainer(klass);
value.setScope(klass);
// use the name annotation if present (used by Java arrays)
String nameAnnotation = getAnnotationStringValue(fieldMirror, CEYLON_NAME_ANNOTATION);
value.setName(nameAnnotation != null ? nameAnnotation : ceylonName);
value.setUnit(klass.getUnit());
value.setShared(fieldMirror.isPublic() || fieldMirror.isProtected() || fieldMirror.isDefaultAccess());
value.setProtectedVisibility(fieldMirror.isProtected());
value.setPackageVisibility(fieldMirror.isDefaultAccess());
value.setStatic(fieldMirror.isStatic());
setDeclarationAliases(value, fieldMirror);
setDeclarationRestrictions(value, fieldMirror);
// field can't be abstract or interface, so not formal
// can we override fields? good question. Not really, but from an external point of view?
// FIXME: figure this out: (default)
// FIXME: for the same reason, can it be an overriding field? (actual)
value.setVariable(!fieldMirror.isFinal());
// figure out if it's an enum subtype in a final static field
if (fieldMirror.getType().getKind() == TypeKind.DECLARED && fieldMirror.getType().getDeclaredClass() != null && fieldMirror.getType().getDeclaredClass().isEnum() && fieldMirror.isFinal() && fieldMirror.isStatic())
value.setEnumValue(true);
Module module = ModelUtil.getModuleContainer(klass);
Type type = obtainType(fieldMirror.getType(), fieldMirror, klass, module, "field '" + value.getName() + "'", klass);
if (type.isCached()) {
type = type.clone();
}
if (value.isEnumValue()) {
Constructor enumValueType = new Constructor();
enumValueType.setJavaEnum(true);
enumValueType.setExtendedType(type);
Scope scope = value.getContainer();
enumValueType.setContainer(scope);
enumValueType.setScope(scope);
enumValueType.setDeprecated(value.isDeprecated());
enumValueType.setName(value.getName());
enumValueType.setUnit(value.getUnit());
enumValueType.setStatic(value.isStatic());
value.setType(enumValueType.getType());
value.setUncheckedNullType(false);
} else {
NullStatus nullPolicy = getUncheckedNullPolicy(isCeylon, fieldMirror.getType(), fieldMirror);
switch(nullPolicy) {
case Optional:
if (!isCeylon) {
type = makeOptionalTypePreserveUnderlyingType(type, module);
}
break;
case UncheckedNull:
value.setUncheckedNullType(true);
break;
}
value.setType(type);
}
type.setRaw(isRaw(module, fieldMirror.getType()));
markUnboxed(value, null, fieldMirror.getType());
markSmall(value, fieldMirror.getType());
markTypeErased(value, fieldMirror, fieldMirror.getType());
markUntrustedType(value, fieldMirror, fieldMirror.getType());
value.setDeprecated(isDeprecated(fieldMirror));
setAnnotations(value, fieldMirror, isNativeHeader);
klass.addMember(value);
ModelUtil.setVisibleScope(value);
return value;
}
Aggregations