]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/AbstractRuntimeJavaReferenceValidator.java
(refs #7586) Allow always conversion to Object in SCL-Java interface
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / types / AbstractRuntimeJavaReferenceValidator.java
index 5ea30643a52675c7522122576ea50cc4f3a84924..d186584d4e395c6bdf6863cb41ac2124d9154381 100644 (file)
-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.equals(from) || to.equals(TypeDesc.OBJECT))
+            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);
+    }
+
+}