-package org.simantics.scl.compiler.internal.codegen.types;\r
-\r
-import java.lang.reflect.Constructor;\r
-import java.lang.reflect.Field;\r
-import java.lang.reflect.Method;\r
-import java.lang.reflect.Modifier;\r
-import java.util.ArrayList;\r
-\r
-import org.cojen.classfile.TypeDesc;\r
-import org.simantics.scl.compiler.constants.generic.ClassRef;\r
-import org.simantics.scl.runtime.function.Function;\r
-\r
-public abstract class AbstractRuntimeJavaReferenceValidator \r
-implements JavaReferenceValidator<Class<?>, Method, Field, Constructor<?>> {\r
-\r
- @Override\r
- public abstract Class<?> findClass(TypeDesc name);\r
- \r
- @Override\r
- public boolean isInterface(Class<?> clazz) {\r
- return clazz.isInterface();\r
- }\r
- \r
- @Override\r
- public boolean isPublic(Class<?> clazz) {\r
- return Modifier.isPublic(clazz.getModifiers());\r
- }\r
-\r
- @Override\r
- public Method[] findCompatibleMethods(Class<?> clazz, boolean isStatic, String name, TypeDesc[] parameterTypes, TypeDesc returnType) {\r
- Class<?>[] parameterClasses = new Class[parameterTypes.length];\r
- for(int i=0;i<parameterTypes.length;++i)\r
- parameterClasses[i] = findClass(parameterTypes[i]);\r
- Class<?> returnClass = findClass(returnType);\r
- \r
- ArrayList<Method> methods = new ArrayList<Method>(2);\r
- \r
- methodLoop: \r
- for(Method method : clazz.getMethods()) {\r
- if(!method.getName().equals(name))\r
- continue;\r
- if(Modifier.isStatic(method.getModifiers()) != isStatic)\r
- continue;\r
- \r
- Class<?>[] parameters = method.getParameterTypes();\r
- if(parameters.length != parameterClasses.length)\r
- continue;\r
- for(int i=0;i<parameters.length;++i)\r
- if(!parameters[i].isAssignableFrom(parameterClasses[i]))\r
- continue methodLoop;\r
-\r
- if(!returnClass.isAssignableFrom(method.getReturnType()))\r
- continue; \r
- \r
- methods.add(method);\r
- } \r
- \r
- return methods.toArray(new Method[methods.size()]);\r
- }\r
-\r
- @Override\r
- public TypeDesc getReturnType(Method method) {\r
- return TypeDesc.forClass(method.getReturnType());\r
- }\r
-\r
- @Override\r
- public TypeDesc[] getParameterTypes(Method method) {\r
- Class<?>[] parameters = method.getParameterTypes();\r
- TypeDesc[] result = new TypeDesc[parameters.length];\r
- for(int i=0;i<parameters.length;++i)\r
- result[i] = TypeDesc.forClass(parameters[i]);\r
- return result;\r
- }\r
-\r
- @Override\r
- public Constructor<?>[] findCompatibleConstructors(Class<?> clazz,\r
- TypeDesc[] types) {\r
- Class<?>[] classes = new Class[types.length];\r
- for(int i=0;i<types.length;++i)\r
- classes[i] = findClass(types[i]);\r
- int maxArity = types.length-1;\r
- \r
- ArrayList<Constructor<?>> constructors = new ArrayList<Constructor<?>>(2);\r
- \r
- methodLoop: \r
- for(Constructor<?> constructor : clazz.getConstructors()) { \r
- Class<?>[] parameters = constructor.getParameterTypes();\r
- int arity = parameters.length;\r
- if(arity > maxArity)\r
- continue;\r
- for(int i=0;i<parameters.length;++i)\r
- if(!parameters[i].isAssignableFrom(classes[i]))\r
- continue methodLoop;\r
- \r
- if(arity == maxArity) {\r
- if(!classes[maxArity].isAssignableFrom(clazz))\r
- continue;\r
- }\r
- else {\r
- if(!Function.class.isAssignableFrom(clazz))\r
- continue;\r
- }\r
- \r
- constructors.add(constructor);\r
- } \r
- \r
- return constructors.toArray(new Constructor[constructors.size()]);\r
- }\r
-\r
- @Override\r
- public TypeDesc[] getConstructorParameterTypes(Constructor<?> constructor) {\r
- Class<?>[] parameters = constructor.getParameterTypes();\r
- TypeDesc[] result = new TypeDesc[parameters.length];\r
- for(int i=0;i<parameters.length;++i)\r
- result[i] = TypeDesc.forClass(parameters[i]);\r
- return result;\r
- }\r
-\r
- @Override\r
- public Field findField(Class<?> clazz, String name) {\r
- try {\r
- return clazz.getField(name);\r
- } catch(NoSuchFieldException e) {\r
- return null;\r
- }\r
- }\r
-\r
- @Override\r
- public boolean isStaticField(Field field) {\r
- return Modifier.isStatic(field.getModifiers());\r
- }\r
-\r
- @Override\r
- public TypeDesc getFieldType(Field field) {\r
- return TypeDesc.forClass(field.getType());\r
- }\r
-\r
- @Override\r
- public boolean isAssignableFrom(TypeDesc to, TypeDesc from) {\r
- if(to == from)\r
- return true;\r
- Class<?> toClass = findClass(to);\r
- Class<?> fromClass = findClass(from);\r
- if(toClass == null || fromClass == null)\r
- // Note: I added this branch when I noticed that type can be\r
- // one from the module under compilation.\r
- // Note2: A problem with this seems to be that also \r
- // some other type descs go to null, such as double[][]\r
- return false; \r
- else\r
- return toClass.isAssignableFrom(fromClass);\r
- }\r
-\r
- @Override\r
- public Method[] chooseBest(Method[] methods) {\r
- ArrayList<Method> newResult = new ArrayList<Method>();\r
- for(Method method : methods)\r
- if(!method.isSynthetic())\r
- newResult.add(method);\r
- return newResult.toArray(new Method[newResult.size()]);\r
- }\r
- \r
- @Override\r
- public ClassRef getClassRef(String className) {\r
- Class<?> clazz = findClass(TypeDesc.forClass(className));\r
- if(clazz == null)\r
- return null;\r
- return new ClassRef(clazz);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.internal.codegen.types;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.constants.generic.ClassRef;
+import org.simantics.scl.runtime.function.Function;
+
+public abstract class AbstractRuntimeJavaReferenceValidator
+implements JavaReferenceValidator<Class<?>, Method, Field, Constructor<?>> {
+
+ @Override
+ public abstract Class<?> findClass(TypeDesc name);
+
+ @Override
+ public boolean isInterface(Class<?> clazz) {
+ return clazz.isInterface();
+ }
+
+ @Override
+ public boolean isPublic(Class<?> clazz) {
+ return Modifier.isPublic(clazz.getModifiers());
+ }
+
+ @Override
+ public Method[] findCompatibleMethods(Class<?> clazz, boolean isStatic, String name, TypeDesc[] parameterTypes, TypeDesc returnType) {
+ Class<?>[] parameterClasses = new Class[parameterTypes.length];
+ for(int i=0;i<parameterTypes.length;++i)
+ parameterClasses[i] = findClass(parameterTypes[i]);
+ Class<?> returnClass = findClass(returnType);
+
+ ArrayList<Method> methods = new ArrayList<Method>(2);
+
+ methodLoop:
+ for(Method method : clazz.getMethods()) {
+ if(!method.getName().equals(name))
+ continue;
+ if(Modifier.isStatic(method.getModifiers()) != isStatic)
+ continue;
+
+ Class<?>[] parameters = method.getParameterTypes();
+ if(parameters.length != parameterClasses.length)
+ continue;
+ for(int i=0;i<parameters.length;++i)
+ if(!parameters[i].isAssignableFrom(parameterClasses[i]))
+ continue methodLoop;
+
+ if(!returnClass.isAssignableFrom(method.getReturnType()))
+ continue;
+
+ methods.add(method);
+ }
+
+ return methods.toArray(new Method[methods.size()]);
+ }
+
+ @Override
+ public TypeDesc getReturnType(Method method) {
+ return TypeDesc.forClass(method.getReturnType());
+ }
+
+ @Override
+ public TypeDesc[] getParameterTypes(Method method) {
+ Class<?>[] parameters = method.getParameterTypes();
+ TypeDesc[] result = new TypeDesc[parameters.length];
+ for(int i=0;i<parameters.length;++i)
+ result[i] = TypeDesc.forClass(parameters[i]);
+ return result;
+ }
+
+ @Override
+ public Constructor<?>[] findCompatibleConstructors(Class<?> clazz,
+ TypeDesc[] types) {
+ Class<?>[] classes = new Class[types.length];
+ for(int i=0;i<types.length;++i)
+ classes[i] = findClass(types[i]);
+ int maxArity = types.length-1;
+
+ ArrayList<Constructor<?>> constructors = new ArrayList<Constructor<?>>(2);
+
+ methodLoop:
+ for(Constructor<?> constructor : clazz.getConstructors()) {
+ Class<?>[] parameters = constructor.getParameterTypes();
+ int arity = parameters.length;
+ if(arity > maxArity)
+ continue;
+ for(int i=0;i<parameters.length;++i)
+ if(!parameters[i].isAssignableFrom(classes[i]))
+ continue methodLoop;
+
+ if(arity == maxArity) {
+ if(!classes[maxArity].isAssignableFrom(clazz))
+ continue;
+ }
+ else {
+ if(!Function.class.isAssignableFrom(clazz))
+ continue;
+ }
+
+ constructors.add(constructor);
+ }
+
+ return constructors.toArray(new Constructor[constructors.size()]);
+ }
+
+ @Override
+ public TypeDesc[] getConstructorParameterTypes(Constructor<?> constructor) {
+ Class<?>[] parameters = constructor.getParameterTypes();
+ TypeDesc[] result = new TypeDesc[parameters.length];
+ for(int i=0;i<parameters.length;++i)
+ result[i] = TypeDesc.forClass(parameters[i]);
+ return result;
+ }
+
+ @Override
+ public Field findField(Class<?> clazz, String name) {
+ try {
+ return clazz.getField(name);
+ } catch(NoSuchFieldException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isStaticField(Field field) {
+ return Modifier.isStatic(field.getModifiers());
+ }
+
+ @Override
+ public TypeDesc getFieldType(Field field) {
+ return TypeDesc.forClass(field.getType());
+ }
+
+ @Override
+ public boolean isAssignableFrom(TypeDesc to, TypeDesc from) {
+ if(to == from)
+ return true;
+ Class<?> toClass = findClass(to);
+ Class<?> fromClass = findClass(from);
+ if(toClass == null || fromClass == null)
+ // Note: I added this branch when I noticed that type can be
+ // one from the module under compilation.
+ // Note2: A problem with this seems to be that also
+ // some other type descs go to null, such as double[][]
+ return false;
+ else
+ return toClass.isAssignableFrom(fromClass);
+ }
+
+ @Override
+ public Method[] chooseBest(Method[] methods) {
+ ArrayList<Method> newResult = new ArrayList<Method>();
+ for(Method method : methods)
+ if(!method.isSynthetic())
+ newResult.add(method);
+ return newResult.toArray(new Method[newResult.size()]);
+ }
+
+ @Override
+ public ClassRef getClassRef(String className) {
+ Class<?> clazz = findClass(TypeDesc.forClass(className));
+ if(clazz == null)
+ return null;
+ return new ClassRef(clazz);
+ }
+
+}