This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git

commit 2c3d37e859a125d7521884cee711c03535731964
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Thu May 25 11:13:31 2023 +0200

    OPENJPA-2911 move PCSubclassValidator to ASM
---
 .../org/apache/openjpa/enhance/PCEnhancer.java     | 107 ++++++++++++++-------
 .../openjpa/enhance/PCSubclassValidator.java       |  10 +-
 2 files changed, 74 insertions(+), 43 deletions(-)

diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
index 092c8ef9b..1dd65d02f 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
@@ -682,6 +682,18 @@ public class PCEnhancer {
         }
     }
 
+    /**
+     * DELTEME
+     * Check if the fields are the same
+     * @deprecated should get removed after migration to ASM is done!
+     */
+    public static void assertSameField(Field field, BCField bcField) {
+        if (field == null && bcField != null || field != null && bcField == 
null ||
+                field != null && bcField != null && 
!field.getName().equals(bcField.getName())) {
+            throw new IllegalStateException("MSX ASMTODO " + bcField + " " + 
field);
+        }
+    }
+
     /**
      * Validate that the methods that use a property-access instance are
      * written correctly. This method also gathers information on each
@@ -694,8 +706,13 @@ public class PCEnhancer {
         else
             fmds = _meta.getDeclaredFields();
         Method meth;
-        BCMethod getter, setter;
-        BCField returned, assigned = null;
+
+        BCMethod bcGetter, bcSetter;
+        BCField bcReturned, bcAssigned = null;
+
+        Method getter, setter;
+        Field returned, assigned = null;
+
         for (FieldMetaData fmd : fmds) {
 
             if (!(fmd.getBackingMember() instanceof Method)) {
@@ -714,51 +731,61 @@ public class PCEnhancer {
             // ##### this will fail if we override and don't call super.
             BCClass declaringType = _managedType.getProject()
                     .loadClass(fmd.getDeclaringType());
-            getter = declaringType.getDeclaredMethod(meth.getName(),
+            bcGetter = declaringType.getDeclaredMethod(meth.getName(),
                     meth.getParameterTypes());
-            if (getter == null) {
+            if (bcGetter == null) {
                 addViolation("property-no-getter", new Object[]{fmd},
                         true);
                 continue;
             }
-            returned = getReturnedField_old(getter);
-            if (returned != null)
-                registerBackingFieldInfo(fmd, getter, returned);
+            bcReturned = getReturnedField_old(bcGetter);
+            returned = getReturnedField(meth);
+
+            //X TODO remove
+            PCEnhancer.assertSameField(returned, bcReturned);
+
+            if (bcReturned != null) {
+                registerBackingFieldInfo(fmd, bcGetter, bcReturned);
+            }
 
-            setter = declaringType.getDeclaredMethod(getSetterName(fmd),
+            bcSetter = declaringType.getDeclaredMethod(getSetterName(fmd),
                     new Class[]{fmd.getDeclaredType()});
-            if (setter == null) {
-                if (returned == null) {
+            if (bcSetter == null) {
+                if (bcReturned == null) {
                     addViolation("property-no-setter",
                             new Object[]{fmd}, true);
                     continue;
                 }
                 else if (!getRedefine()) {
                     // create synthetic setter
-                    setter = _managedType.declareMethod(getSetterName(fmd),
+                    bcSetter = _managedType.declareMethod(getSetterName(fmd),
                             void.class, new Class[]{fmd.getDeclaredType()});
-                    setter.makePrivate();
-                    Code code = setter.getCode(true);
+                    bcSetter.makePrivate();
+                    Code code = bcSetter.getCode(true);
                     code.aload().setThis();
                     code.xload().setParam(0);
-                    code.putfield().setField(returned);
+                    code.putfield().setField(bcReturned);
                     code.vreturn();
                     code.calculateMaxStack();
                     code.calculateMaxLocals();
                 }
             }
 
-            if (setter != null)
-                assigned = getAssignedField_old(setter);
+            if (bcSetter != null) {
+                bcAssigned = getAssignedField_old(bcSetter);
 
-            if (assigned != null) {
-                if (setter != null)
-                    registerBackingFieldInfo(fmd, setter, assigned);
+                assigned = getAssignedField(getMethod(fmd.getDeclaringType(), 
fmd.getSetterName(), new Class[]{fmd.getDeclaredType()}));
+                assertSameField(assigned, bcAssigned);
+            }
+
+            if (bcAssigned != null) {
+                if (bcSetter != null)
+                    registerBackingFieldInfo(fmd, bcSetter, bcAssigned);
 
-                if (assigned != returned)
+                if (bcAssigned != bcReturned)
                     addViolation("property-setter-getter-mismatch", new 
Object[]
-                            {fmd, assigned.getName(), (returned == null)
-                                    ? null : returned.getName()}, false);
+                            {fmd, bcAssigned.getName(), (bcReturned == null)
+                                    ? null : bcReturned.getName()}, false);
             }
         }
     }
@@ -962,8 +989,9 @@ public class PCEnhancer {
         }
 
         ClassReader cr;
-        try {
-            cr = new ClassReader(meth.getDeclaringClass().getName());
+        final String classResourceName = 
meth.getDeclaringClass().getName().replace(".", "/") + ".class";
+        try (final InputStream classBytesStream = 
meth.getDeclaringClass().getClassLoader().getResourceAsStream(classResourceName))
 {
+            cr = new ClassReader(classBytesStream);
         }
         catch (IOException e) {
             throw new RuntimeException(e);
@@ -987,7 +1015,9 @@ public class PCEnhancer {
                 return null;
             }
 
-            if (prevInsn.getOpcode() == Opcodes.INSTANCEOF && 
prevInsn.getPrevious() != null ) {
+            // skip a few non-functional ops like instanceof and checkcast
+            if ((prevInsn.getOpcode() == Opcodes.INSTANCEOF || 
prevInsn.getOpcode() == Opcodes.CHECKCAST)
+                    && prevInsn.getPrevious() != null ) {
                 prevInsn = prevInsn.getPrevious();
             }
 
@@ -1010,14 +1040,14 @@ public class PCEnhancer {
             if (!findAccessed && prevInsn.getOpcode() == Opcodes.GETFIELD) {
                 final FieldInsnNode fieldInsn = (FieldInsnNode) prevInsn;
 
-                cur = getField(meth.getDeclaringClass(), fieldInsn);
+                cur = getField(meth.getDeclaringClass(), fieldInsn.name);
 
                 // if the middle instruction was an xload_1, then the
                 // matched instruction is the field that's being set.
             } else if (findAccessed && AsmHelper.isLoadInsn(prevInsn)
                     && ((VarInsnNode) prevInsn).var == 1) {
                 final FieldInsnNode fieldInsn = (FieldInsnNode)insn;
-                cur = getField(meth.getDeclaringClass(), fieldInsn);
+                cur = getField(meth.getDeclaringClass(), fieldInsn.name);
             } else {
                 return null;
             }
@@ -1033,22 +1063,29 @@ public class PCEnhancer {
         return field;
     }
 
-    private static Field getField(Class<?> clazz, FieldInsnNode fieldInsn) {
+    private static Field getField(Class<?> clazz, String fieldName) {
         try {
-            final Class<?> fieldOwner = 
clazz.getClassLoader().loadClass(fieldInsn.owner.replace("/", "."));
-            return fieldOwner.getDeclaredField(fieldInsn.name);
+            return clazz.getDeclaredField(fieldName);
         }
         catch (NoSuchFieldException e) {
             if (clazz.getSuperclass() == Object.class) {
-                throw new IllegalStateException("Cannot find field " + 
fieldInsn + " in Class " + clazz);
+                throw new IllegalStateException("Cannot find field " + 
fieldName + " in Class " + clazz);
             }
-            return getField(clazz.getSuperclass(), fieldInsn);
-        }
-        catch (ClassNotFoundException e) {
-            throw new RuntimeException(e);
+            return getField(clazz.getSuperclass(), fieldName);
         }
     }
 
+    private static Method getMethod(Class<?> clazz, String methodName, 
Class<?>... paramTypes) {
+        try {
+            return clazz.getDeclaredMethod(methodName, paramTypes);
+        }
+        catch (NoSuchMethodException e) {
+            if (clazz.getSuperclass() == Object.class) {
+                throw new IllegalStateException("Cannot find method " + 
methodName + " in Class " + clazz);
+            }
+            return getMethod(clazz.getSuperclass(), methodName);
+        }
+    }
 
     /**
      * Record a violation of the property access restrictions.
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java
index 19018417e..a71a581ce 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCSubclassValidator.java
@@ -205,10 +205,7 @@ public class PCSubclassValidator {
         Field field = PCEnhancer.getReturnedField(meth);
 
         //X TODO remove
-        if (field == null && bcField != null || field != null && bcField == 
null ||
-            field != null && bcField != null && 
!field.getName().equals(bcField.getName())) {
-            throw new IllegalStateException("MSX ASMTODO " + bcField + " " + 
field);
-        }
+        PCEnhancer.assertSameField(field, bcField);
 
         if (bcField == null) {
             addContractViolation(loc.get("subclasser-invalid-getter", 
fmd.getName()), fmd);
@@ -230,10 +227,7 @@ public class PCSubclassValidator {
         Field field = PCEnhancer.getAssignedField(meth);
 
         //X TODO remove
-        if (field == null && bcField != null || field != null && bcField == 
null ||
-                field != null && bcField != null && 
!field.getName().equals(bcField.getName())) {
-            throw new IllegalStateException("MSX ASMTODO " + bcField + " " + 
field);
-        }
+        PCEnhancer.assertSameField(field, bcField);
 
         if (bcField == null) {
             addContractViolation(loc.get("subclasser-invalid-setter", 
fmd.getName()), fmd);

Reply via email to