1 package org.simantics.scl.compiler.internal.codegen.types;
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.Method;
6 import java.lang.reflect.Modifier;
7 import java.util.ArrayList;
9 import org.cojen.classfile.TypeDesc;
10 import org.simantics.scl.compiler.constants.generic.ClassRef;
11 import org.simantics.scl.runtime.function.Function;
13 public abstract class AbstractRuntimeJavaReferenceValidator
14 implements JavaReferenceValidator<Class<?>, Method, Field, Constructor<?>> {
17 public abstract Class<?> findClass(TypeDesc name);
20 public boolean isInterface(Class<?> clazz) {
21 return clazz.isInterface();
25 public boolean isPublic(Class<?> clazz) {
26 return Modifier.isPublic(clazz.getModifiers());
30 public Method[] findCompatibleMethods(Class<?> clazz, boolean isStatic, String name, TypeDesc[] parameterTypes, TypeDesc returnType) {
31 Class<?>[] parameterClasses = new Class[parameterTypes.length];
32 for(int i=0;i<parameterTypes.length;++i)
33 parameterClasses[i] = findClass(parameterTypes[i]);
34 Class<?> returnClass = findClass(returnType);
36 ArrayList<Method> methods = new ArrayList<Method>(2);
39 for(Method method : clazz.getMethods()) {
40 if(!method.getName().equals(name))
42 if(Modifier.isStatic(method.getModifiers()) != isStatic)
45 Class<?>[] parameters = method.getParameterTypes();
46 if(parameters.length != parameterClasses.length)
48 for(int i=0;i<parameters.length;++i)
49 if(!parameters[i].isAssignableFrom(parameterClasses[i]))
52 if(!returnClass.isAssignableFrom(method.getReturnType()))
58 return methods.toArray(new Method[methods.size()]);
62 public TypeDesc getReturnType(Method method) {
63 return TypeDesc.forClass(method.getReturnType());
67 public TypeDesc[] getParameterTypes(Method method) {
68 Class<?>[] parameters = method.getParameterTypes();
69 TypeDesc[] result = new TypeDesc[parameters.length];
70 for(int i=0;i<parameters.length;++i)
71 result[i] = TypeDesc.forClass(parameters[i]);
76 public Constructor<?>[] findCompatibleConstructors(Class<?> clazz,
78 Class<?>[] classes = new Class[types.length];
79 for(int i=0;i<types.length;++i)
80 classes[i] = findClass(types[i]);
81 int maxArity = types.length-1;
83 ArrayList<Constructor<?>> constructors = new ArrayList<Constructor<?>>(2);
86 for(Constructor<?> constructor : clazz.getConstructors()) {
87 Class<?>[] parameters = constructor.getParameterTypes();
88 int arity = parameters.length;
91 for(int i=0;i<parameters.length;++i)
92 if(!parameters[i].isAssignableFrom(classes[i]))
95 if(arity == maxArity) {
96 if(!classes[maxArity].isAssignableFrom(clazz))
100 if(!Function.class.isAssignableFrom(clazz))
104 constructors.add(constructor);
107 return constructors.toArray(new Constructor[constructors.size()]);
111 public TypeDesc[] getConstructorParameterTypes(Constructor<?> constructor) {
112 Class<?>[] parameters = constructor.getParameterTypes();
113 TypeDesc[] result = new TypeDesc[parameters.length];
114 for(int i=0;i<parameters.length;++i)
115 result[i] = TypeDesc.forClass(parameters[i]);
120 public Field findField(Class<?> clazz, String name) {
122 return clazz.getField(name);
123 } catch(NoSuchFieldException e) {
129 public boolean isStaticField(Field field) {
130 return Modifier.isStatic(field.getModifiers());
134 public TypeDesc getFieldType(Field field) {
135 return TypeDesc.forClass(field.getType());
139 public boolean isAssignableFrom(TypeDesc to, TypeDesc from) {
142 Class<?> toClass = findClass(to);
143 Class<?> fromClass = findClass(from);
144 if(toClass == null || fromClass == null)
145 // Note: I added this branch when I noticed that type can be
146 // one from the module under compilation.
147 // Note2: A problem with this seems to be that also
148 // some other type descs go to null, such as double[][]
151 return toClass.isAssignableFrom(fromClass);
155 public Method[] chooseBest(Method[] methods) {
156 ArrayList<Method> newResult = new ArrayList<Method>();
157 for(Method method : methods)
158 if(!method.isSynthetic())
159 newResult.add(method);
160 return newResult.toArray(new Method[newResult.size()]);
164 public ClassRef getClassRef(String className) {
165 Class<?> clazz = findClass(TypeDesc.forClass(className));
168 return new ClassRef(clazz);