--- /dev/null
+package org.simantics.scl.compiler.elaboration.modules;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.JavaTypeClassMethod;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.util.MultiFunction;\r
+\r
+public class TypeClassMethod {\r
+ \r
+ TypeClass typeClass;\r
+ String name;\r
+ String javaName;\r
+ Type baseType;\r
+ int arity;\r
+ Name defaultImplementation;\r
+ public long location;\r
+ \r
+ public TypeClassMethod(TypeClass typeClass, String name, String javaName,\r
+ Type baseType, int arity, long location) {\r
+ if(typeClass == null) throw new NullPointerException();\r
+ if(name == null) throw new NullPointerException();\r
+ if(javaName == null) throw new NullPointerException();\r
+ if(baseType == null) throw new NullPointerException();\r
+ this.typeClass = typeClass;\r
+ this.name = name;\r
+ this.javaName = javaName;\r
+ this.baseType = baseType;\r
+ this.arity = arity;\r
+ this.location = location;\r
+ }\r
+\r
+ public void setDefaultImplementation(Name defaultImplementation) {\r
+ if(this.defaultImplementation != null)\r
+ throw new InternalCompilerError("Default method implementation already defined");\r
+ this.defaultImplementation = defaultImplementation;\r
+ }\r
+ \r
+ public Name getDefaultImplementation() {\r
+ return defaultImplementation;\r
+ }\r
+ \r
+ public String getName() {\r
+ return name;\r
+ }\r
+ \r
+ public String getJavaName() {\r
+ return javaName;\r
+ }\r
+ \r
+ public Type getBaseType() {\r
+ return baseType;\r
+ }\r
+ \r
+ public int getArity() {\r
+ return arity;\r
+ }\r
+\r
+ public Type getType() {\r
+ return Types.closure(Types.constrained(\r
+ typeClass.class_, \r
+ baseType));\r
+ }\r
+ \r
+ public TypeClass getTypeClass() {\r
+ return typeClass;\r
+ }\r
+\r
+ public SCLValue createValue() {\r
+ String moduleName = typeClass.name.module;\r
+ SCLValue value = new SCLValue(Name.create(moduleName, name));\r
+ MultiFunction mfun = Types.matchFunction(baseType);\r
+ Type[] parameterTypes = new Type[mfun.parameterTypes.length + 1];\r
+ System.arraycopy(mfun.parameterTypes, 0, parameterTypes, 1, mfun.parameterTypes.length);\r
+ parameterTypes[0] = typeClass.class_;\r
+ // FIXME totally incorrect type for the method\r
+ Constant constant = new JavaTypeClassMethod(\r
+ this,\r
+ typeClass.javaName, \r
+ javaName, \r
+ mfun.effect,\r
+ mfun.returnType, \r
+ parameterTypes);\r
+ value.setValue(constant);\r
+ value.setType(getType());\r
+ return value;\r
+ }\r
+ \r
+}\r