]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CodeBuilderUtils.java
(refs #7090) Generated Function objects implement equals and hashCode
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / utils / CodeBuilderUtils.java
index cc8f3e0c5ab5a7f5dfefb8cf43b77b28b76c756e..81f7b117a82f61f7ade860cd1362d5b4a85559e3 100644 (file)
@@ -93,72 +93,75 @@ public class CodeBuilderUtils {
             tsmb.finish();
         }
         
-        if(generateEqualsAndHashCode) {
-            // Create equals
-            {
-                TypeDesc CLASS = TypeDesc.forClass(Class.class);
+        if(generateEqualsAndHashCode)
+            implementHashCodeAndEquals(classBuilder, recordName, fieldNamePrefix, types);
+    }
 
-                MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
-                LocalVariable parameter = tsmb.getParameter(0);
-                Label success = tsmb.createLabel();
-                Label failure = tsmb.createLabel();
+    public static void implementHashCodeAndEquals(ClassBuilder classBuilder, String recordName, String fieldNamePrefix, TypeDesc[] types) {
+        // Create equals
+        {
+            TypeDesc CLASS = TypeDesc.forClass(Class.class);
 
-                // Check type
-                tsmb.loadThis();
-                tsmb.loadLocal(parameter);
-                tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
-                tsmb.loadLocal(parameter);
-                tsmb.ifNullBranch(failure, true);
-                tsmb.loadLocal(parameter);
-                tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
-                tsmb.loadThis();
-                tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
-                tsmb.ifComparisonBranch(failure, "!=", CLASS);
-                tsmb.loadLocal(parameter);
-                tsmb.checkCast(classBuilder.getType());
-                LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
-                tsmb.storeLocal(other);
+            MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+            LocalVariable parameter = tsmb.getParameter(0);
+            Label success = tsmb.createLabel();
+            Label failure = tsmb.createLabel();
 
-                // Compare fields
-                for(int i=0;i<types.length;++i) {
-                    TypeDesc type = types[i];
-                    if(type.equals(TypeDesc.VOID))
-                        continue;
-                    tsmb.loadThis();
-                    tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
-                    tsmb.loadLocal(other);
-                    tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
-                    equals(tsmb, type, failure);
-                }
+            // Check type
+            tsmb.loadThis();
+            tsmb.loadLocal(parameter);
+            tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
+            tsmb.loadLocal(parameter);
+            tsmb.ifNullBranch(failure, true);
+            tsmb.loadLocal(parameter);
+            tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+            tsmb.loadThis();
+            tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+            tsmb.ifComparisonBranch(failure, "!=", CLASS);
+            tsmb.loadLocal(parameter);
+            tsmb.checkCast(classBuilder.getType());
+            LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
+            tsmb.storeLocal(other);
 
-                // Return
-                tsmb.setLocation(success);
-                tsmb.loadConstant(true);
-                tsmb.returnValue(TypeDesc.BOOLEAN);
-                tsmb.setLocation(failure);
-                tsmb.loadConstant(false);
-                tsmb.returnValue(TypeDesc.BOOLEAN);
-                tsmb.finish();
+            // Compare fields
+            for(int i=0;i<types.length;++i) {
+                TypeDesc type = types[i];
+                if(type.equals(TypeDesc.VOID))
+                    continue;
+                tsmb.loadThis();
+                tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+                tsmb.loadLocal(other);
+                tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+                equals(tsmb, type, failure);
             }
 
-            // Create hashCode
-            {
-                MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
-                tsmb.loadConstant(recordName.hashCode());
-                for(int i=0;i<types.length;++i) {
-                    TypeDesc type = types[i];
-                    if(type.equals(TypeDesc.VOID))
-                        continue;
-                    tsmb.loadConstant(31);
-                    tsmb.math(Opcodes.IMUL);
-                    tsmb.loadThis();
-                    tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
-                    hashCode(tsmb, type);
-                    tsmb.math(Opcodes.IADD);
-                }
-                tsmb.returnValue(TypeDesc.INT);
-                tsmb.finish();
+            // Return
+            tsmb.setLocation(success);
+            tsmb.loadConstant(true);
+            tsmb.returnValue(TypeDesc.BOOLEAN);
+            tsmb.setLocation(failure);
+            tsmb.loadConstant(false);
+            tsmb.returnValue(TypeDesc.BOOLEAN);
+            tsmb.finish();
+        }
+
+        // Create hashCode
+        {
+            MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+            tsmb.loadConstant(recordName.hashCode());
+            for(int i=0;i<types.length;++i) {
+                TypeDesc type = types[i];
+                if(type.equals(TypeDesc.VOID))
+                    continue;
+                tsmb.loadConstant(31);
+                tsmb.math(Opcodes.IMUL);
+                tsmb.loadThis();
+                tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+                hashCode(tsmb, type);
+                tsmb.math(Opcodes.IADD);
             }
+            tsmb.returnValue(TypeDesc.INT);
+            tsmb.finish();
         }
     }