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

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 4e94e97e8 fix(java): handle private final map codegen (#3504)
4e94e97e8 is described below

commit 4e94e97e860bb6ac10deb97963d1fc4a4c61600a
Author: Shawn Yang <[email protected]>
AuthorDate: Tue Mar 24 20:00:45 2026 +0800

    fix(java): handle private final map codegen (#3504)
    
    ## Why?
    
    
    
    ## What does this PR do?
    - use a source-accessible local type when generated map chunk code
    handles monomorphic private final keys or values
    - keep serializer selection and wire behavior based on the declared
    private final type
    - add regression coverage for private final map keys and values under
    codegen with and without ref tracking
    
    
    ## Related issues
    
    Closes #3503
    
    
    ## AI Contribution Checklist
    
    
    
    - [ ] Substantial AI assistance was used in this PR: `yes` / `no`
    - [ ] If `yes`, I included a completed [AI Contribution
    
Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs)
    in this PR description and the required `AI Usage Disclosure`.
    
    
    
    ## Does this PR introduce any user-facing change?
    
    
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
---
 .../fory/builder/BaseObjectCodecBuilder.java       | 20 ++++++++++---
 .../serializer/collection/MapSerializersTest.java  | 34 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 4 deletions(-)

diff --git 
a/java/fory-core/src/main/java/org/apache/fory/builder/BaseObjectCodecBuilder.java
 
b/java/fory-core/src/main/java/org/apache/fory/builder/BaseObjectCodecBuilder.java
index 6b7a61466..de0769166 100644
--- 
a/java/fory-core/src/main/java/org/apache/fory/builder/BaseObjectCodecBuilder.java
+++ 
b/java/fory-core/src/main/java/org/apache/fory/builder/BaseObjectCodecBuilder.java
@@ -1504,6 +1504,14 @@ public abstract class BaseObjectCodecBuilder extends 
CodecBuilder {
     return Tuple2.of(keySerializer, valueSerializer);
   }
 
+  private TypeRef<?> getMapChunkLocalType(TypeRef<?> typeRef) {
+    Class<?> rawType = typeRef.getRawType();
+    if (sourcePublicAccessible(rawType)) {
+      return typeRef;
+    }
+    return 
TypeRef.of(CodeGenerator.getSourcePublicAccessibleParentClass(rawType));
+  }
+
   protected Expression writeChunk(
       Expression buffer,
       Expression entry,
@@ -1515,11 +1523,15 @@ public abstract class BaseObjectCodecBuilder extends 
CodecBuilder {
     boolean valueMonomorphic = isMonomorphic(valueType);
     Class<?> keyTypeRawType = keyType.getRawType();
     Class<?> valueTypeRawType = valueType.getRawType();
+    TypeRef<?> keyLocalType = keyMonomorphic ? getMapChunkLocalType(keyType) : 
keyType;
+    TypeRef<?> valueLocalType = valueMonomorphic ? 
getMapChunkLocalType(valueType) : valueType;
     Expression key =
-        keyMonomorphic ? new Variable("key", keyType) : invoke(entry, 
"getKey", "key", keyType);
+        keyMonomorphic
+            ? new Variable("key", keyLocalType)
+            : invoke(entry, "getKey", "key", keyType);
     Expression value =
         valueMonomorphic
-            ? new Variable("value", valueType)
+            ? new Variable("value", valueLocalType)
             : invoke(entry, "getValue", "value", valueType);
     Expression keyTypeExpr =
         keyMonomorphic
@@ -1642,9 +1654,9 @@ public abstract class BaseObjectCodecBuilder extends 
CodecBuilder {
         new While(
             Literal.ofBoolean(true),
             () -> {
-              Expression keyAssign = new Assign(key, invokeInline(entry, 
"getKey", keyType));
+              Expression keyAssign = new Assign(key, invokeInline(entry, 
"getKey", keyLocalType));
               Expression valueAssign =
-                  new Assign(value, invokeInline(entry, "getValue", 
valueType));
+                  new Assign(value, invokeInline(entry, "getValue", 
valueLocalType));
               Expression breakCondition;
               if (keyMonomorphic && valueMonomorphic) {
                 breakCondition = or(eqNull(key), eqNull(value));
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/serializer/collection/MapSerializersTest.java
 
b/java/fory-core/src/test/java/org/apache/fory/serializer/collection/MapSerializersTest.java
index c5df70595..ca52e0e47 100644
--- 
a/java/fory-core/src/test/java/org/apache/fory/serializer/collection/MapSerializersTest.java
+++ 
b/java/fory-core/src/test/java/org/apache/fory/serializer/collection/MapSerializersTest.java
@@ -1078,6 +1078,40 @@ public class MapSerializersTest extends ForyTestBase {
     serDeCheck(fory, struct1);
   }
 
+  @Data
+  public static class PrivateFinalMapFieldStruct {
+    private final Map<String, PrivateFinalValue> valueMap = new 
LinkedHashMap<>();
+    private final Map<PrivateFinalKey, String> keyMap = new LinkedHashMap<>();
+  }
+
+  @Data
+  private static final class PrivateFinalKey {
+    private int id;
+  }
+
+  @Data
+  private static final class PrivateFinalValue {
+    private int id;
+  }
+
+  @Test(dataProvider = "referenceTrackingConfig")
+  public void testPrivateFinalMapFieldCodegen(boolean referenceTrackingConfig) 
{
+    Fory fory =
+        builder()
+            .withRefTracking(referenceTrackingConfig)
+            .withCodegen(true)
+            .requireClassRegistration(false)
+            .build();
+    PrivateFinalMapFieldStruct struct = new PrivateFinalMapFieldStruct();
+    PrivateFinalValue value = new PrivateFinalValue();
+    value.setId(1);
+    PrivateFinalKey key = new PrivateFinalKey();
+    key.setId(2);
+    struct.getValueMap().put("k1", value);
+    struct.getKeyMap().put(key, "v1");
+    serDeCheck(fory, struct);
+  }
+
   @Data
   static class Wildcard<T> {
     public int c = 9;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to