use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class AbstractModelLoader method setInterfaceCompanionClass.
protected void setInterfaceCompanionClass(Declaration d, ClassOrInterface container, LazyPackage pkg) {
// find its companion class in its real container
ClassMirror containerMirror = null;
if (container instanceof LazyClass) {
containerMirror = ((LazyClass) container).classMirror;
} else if (container instanceof LazyInterface) {
// container must be a LazyInterface, as TypeAlias doesn't contain anything
containerMirror = ((LazyInterface) container).companionClass;
if (containerMirror == null) {
throw new ModelResolutionException("Interface companion class for " + container.getQualifiedNameString() + " not set up");
}
}
String companionName;
if (containerMirror != null)
companionName = containerMirror.getFlatName() + "$" + NamingBase.suffixName(NamingBase.Suffix.$impl, d.getName());
else {
// toplevel
String p = pkg.getNameAsString();
companionName = "";
if (!p.isEmpty())
companionName = p + ".";
companionName += NamingBase.suffixName(NamingBase.Suffix.$impl, d.getName());
}
ClassMirror companionClass = lookupClassMirror(pkg.getModule(), companionName);
if (companionClass == null) {
((Interface) d).setCompanionClassNeeded(false);
}
((LazyInterface) d).companionClass = companionClass;
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface 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.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ValueImpl method initField.
private void initField(Object instance, Type valueType) {
org.eclipse.ceylon.model.typechecker.model.Value decl = (org.eclipse.ceylon.model.typechecker.model.Value) declaration.declaration;
String name = decl.getName();
if (decl instanceof JavaBeanValue) {
java.lang.Class<?> javaClass = Metamodel.getJavaClass((org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) decl.getContainer());
if (javaClass == ceylon.language.Object.class || javaClass == ceylon.language.Basic.class || javaClass == ceylon.language.Identifiable.class) {
if ("string".equals(name) || "hash".equals(name)) {
// look it up on j.l.Object, getterName should work
javaClass = java.lang.Object.class;
} else {
throw Metamodel.newModelError("Object/Basic/Identifiable member not supported: " + name);
}
} else if (javaClass == ceylon.language.Throwable.class) {
if ("cause".equals(name) || "message".equals(name) || "suppressed".equals(name)) {
javaClass = instance.getClass();
isSuppressed = "suppressed".equals(name);
}
}
String getterName = ((JavaBeanValue) decl).getGetterName();
try {
Class<?>[] params;
if (!declaration.getStatic()) {
params = NO_PARAMS;
} else {
int numCapturedTypeParams = ((ClassOrInterface) declaration.declaration.getContainer()).getTypeParameters().size();
params = new Class[numCapturedTypeParams];
Arrays.fill(params, TypeDescriptor.class);
}
boolean isJavaArray = MethodHandleUtil.isJavaArray(javaClass);
if (isJavaArray)
params = MethodHandleUtil.getJavaArrayGetArrayParameterTypes(javaClass, getterName);
// if it is shared we may want to get an inherited getter, but if it's private we need the declared method to return it
Method m = decl.isShared() ? javaClass.getMethod(getterName, params) : javaClass.getDeclaredMethod(getterName, params);
m.setAccessible(true);
getter = MethodHandles.lookup().unreflect(m);
java.lang.Class<?> getterType = m.getReturnType();
getter = MethodHandleUtil.boxReturnValue(getter, getterType, valueType);
if (instance != null && // XXXArray.getArray is static but requires an instance as first param
(isJavaArray || !Modifier.isStatic(m.getModifiers()))) {
getter = getter.bindTo(instance);
}
if (declaration.getStatic()) {
getter = getter.asType(MethodType.methodType(Object.class, params));
TypeDescriptor[] typeArguments = ((TypeDescriptor.Class) ((ClassOrInterfaceImpl<?>) container).$reifiedType).getTypeArguments();
getter = getter.asSpreader(TypeDescriptor[].class, typeArguments.length);
getter = getter.bindTo(typeArguments);
} else {
// we need to cast to Object because this is what comes out when calling it in $call
getter = getter.asType(MethodType.methodType(Object.class));
}
initSetter(decl, javaClass, getterType, instance, valueType);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {
throw Metamodel.newModelError("Failed to find getter method " + getterName + " for: " + decl, e);
}
} else if (decl instanceof LazyValue) {
LazyValue lazyDecl = (LazyValue) decl;
java.lang.Class<?> javaClass = ((ReflectionClass) lazyDecl.classMirror).klass;
// FIXME: we should really save the getter name in the LazyDecl
String getterName = NamingBase.getGetterName(lazyDecl);
try {
// toplevels don't have inheritance
Method m = javaClass.getDeclaredMethod(getterName);
m.setAccessible(true);
getter = MethodHandles.lookup().unreflect(m);
java.lang.Class<?> getterType = m.getReturnType();
getter = MethodHandleUtil.boxReturnValue(getter, getterType, valueType);
// we need to cast to Object because this is what comes out when calling it in $call
getter = getter.asType(MethodType.methodType(Object.class));
initSetter(decl, javaClass, getterType, null, valueType);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {
throw Metamodel.newModelError("Failed to find getter method " + getterName + " for: " + decl, e);
}
} else if (decl instanceof FieldValue) {
FieldValue fieldDecl = (FieldValue) decl;
java.lang.Class<?> javaClass = Metamodel.getJavaClass((org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) decl.getContainer());
String fieldName = fieldDecl.getRealName();
if (MethodHandleUtil.isJavaArray(javaClass)) {
try {
Method method = Array.class.getDeclaredMethod("getLength", Object.class);
getter = MethodHandles.lookup().unreflect(method);
java.lang.Class<?> getterType = method.getReturnType();
getter = MethodHandleUtil.boxReturnValue(getter, getterType, valueType);
// this one is static but requires an instance a first param
if (instance != null)
getter = getter.bindTo(instance);
// we need to cast to Object because this is what comes out when calling it in $call
getter = getter.asType(MethodType.methodType(Object.class));
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {
throw Metamodel.newModelError("Failed to find Array.getLength method for: " + decl, e);
}
} else {
try {
// fields are not inherited
Field f = javaClass.getDeclaredField(fieldName);
f.setAccessible(true);
getter = MethodHandles.lookup().unreflectGetter(f);
java.lang.Class<?> getterType = f.getType();
getter = MethodHandleUtil.boxReturnValue(getter, getterType, valueType);
if (instance != null && !Modifier.isStatic(f.getModifiers()))
getter = getter.bindTo(instance);
// we need to cast to Object because this is what comes out when calling it in $call
getter = getter.asType(MethodType.methodType(Object.class));
initSetter(decl, javaClass, getterType, instance, valueType);
} catch (NoSuchFieldException | SecurityException | IllegalAccessException e) {
throw Metamodel.newModelError("Failed to find field " + fieldName + " for: " + decl, e);
}
}
} else if (ModelUtil.isEnumeratedConstructor(decl)) {
java.lang.Class<?> javaClass = Metamodel.getJavaClass((org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) decl.getContainer());
String getterName = NamingBase.getGetterName(decl);
try {
Class<?>[] params = NO_PARAMS;
// if it is shared we may want to get an inherited getter, but if it's private we need the declared method to return it
Method m = decl.isShared() ? javaClass.getMethod(getterName, params) : javaClass.getDeclaredMethod(getterName, params);
m.setAccessible(true);
getter = MethodHandles.lookup().unreflect(m);
java.lang.Class<?> getterType = m.getReturnType();
getter = MethodHandleUtil.boxReturnValue(getter, getterType, valueType);
if (instance != null && // XXXArray.getArray is static but requires an instance as first param
(!Modifier.isStatic(m.getModifiers()))) {
getter = getter.bindTo(instance);
}
// we need to cast to Object because this is what comes out when calling it in $call
getter = getter.asType(MethodType.methodType(Object.class));
initSetter(decl, javaClass, getterType, instance, valueType);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {
throw Metamodel.newModelError("Failed to find getter method " + getterName + " for: " + decl, e);
}
} else
throw new StorageException("Attribute " + name + " is neither captured nor shared so it has no physical storage allocated and cannot be read by the metamodel");
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ExpressionVisitor method refineAttribute.
private void refineAttribute(Tree.SpecifierStatement that) {
Value refinedValue = (Value) that.getRefined();
Value value = (Value) that.getDeclaration();
ClassOrInterface ci = (ClassOrInterface) value.getContainer();
Declaration root = refinedValue.getRefinedDeclaration();
TypeDeclaration td = (TypeDeclaration) root.getContainer();
List<Declaration> interveningRefinements = getInterveningRefinements(value, root, ci, td);
accountForIntermediateRefinements(that, refinedValue, value, ci, interveningRefinements);
}
use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.
the class ExpressionVisitor method paramdesc.
private String paramdesc(Parameter p) {
Declaration dec = p.getDeclaration();
String result = "'" + p.getName() + "' of '" + dec.getName(unit) + "'";
if (dec.isClassOrInterfaceMember()) {
ClassOrInterface ci = (ClassOrInterface) dec.getContainer();
result += " in '" + ci.getName(unit) + "'";
}
return result;
}
Aggregations