diff --git a/translator/src/main/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslator.java b/translator/src/main/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslator.java index 5f51f1caa8..ddfcd4dedd 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslator.java +++ b/translator/src/main/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslator.java @@ -26,6 +26,7 @@ import com.google.devtools.j2objc.ast.Block; import com.google.devtools.j2objc.ast.BodyDeclaration; import com.google.devtools.j2objc.ast.CastExpression; +import com.google.devtools.j2objc.ast.ClassInstanceCreation; import com.google.devtools.j2objc.ast.CompilationUnit; import com.google.devtools.j2objc.ast.EnumDeclaration; import com.google.devtools.j2objc.ast.Expression; @@ -42,6 +43,7 @@ import com.google.devtools.j2objc.ast.SingleVariableDeclaration; import com.google.devtools.j2objc.ast.Statement; import com.google.devtools.j2objc.ast.ThisExpression; +import com.google.devtools.j2objc.ast.TreeVisitor; import com.google.devtools.j2objc.ast.TypeDeclaration; import com.google.devtools.j2objc.ast.UnitTreeVisitor; import com.google.devtools.j2objc.types.ExecutablePair; @@ -164,9 +166,37 @@ public ObjectiveCKmpMethodTranslator(CompilationUnit unit) { // originally executed in the translator pipeline. @Override public void run() { + Set existingTypes = new HashSet<>(unit.getTypes()); super.run(); new LambdaTypeElementAdder(unit).run(); new LambdaRewriter(unit).run(); + new InnerClassExtractor(unit).run(); + + Functionizer functionizer = new Functionizer(unit); + var unused = functionizer.visit(unit); + InitializationNormalizer initNormalizer = new InitializationNormalizer(unit); + + // Pass 1: Run Functionizer and InitializationNormalizer exclusively over newly introduced + // lambda type declarations created during this translation pass. + for (AbstractTypeDeclaration type : unit.getTypes()) { + if (!existingTypes.contains(type)) { + type.accept(functionizer); + type.accept(initNormalizer); + } + } + + // Pass 2: Run Functionizer specifically on ClassInstanceCreation nodes across the unit. + // This updates newly generated lambda instantiations (e.g., inside generated adapter methods). + unit.accept( + new TreeVisitor() { + @Override + public void endVisit(ClassInstanceCreation node) { + functionizer.endVisit(node); + } + }); + + new StaticVarRewriter(unit).run(); + new PrivateDeclarationResolver(unit).run(); } private String getOverrideSignature(ExecutablePair method) { diff --git a/translator/src/test/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslatorTest.java b/translator/src/test/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslatorTest.java index b81dd1408a..f9101a25ef 100644 --- a/translator/src/test/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslatorTest.java +++ b/translator/src/test/java/com/google/devtools/j2objc/translate/ObjectiveCKmpMethodTranslatorTest.java @@ -1658,7 +1658,14 @@ public void setBooleanSet(Set set) {} impl, """ - (void)setBooleanSet:(NSSet *)set { - [self setBooleanSetWithJavaUtilSet:(id) [Adapter toJavaUtilSetWithId:set withJavaUtilFunctionFunction:TestSetOfBoolean_$Lambda$1_instance]]; + [self setBooleanSetWithJavaUtilSet:(id) [Adapter toJavaUtilSetWithId:set withJavaUtilFunctionFunction:JreLoadStatic(TestSetOfBoolean_$Lambda$1, instance)]]; + } + """); + assertInTranslation( + impl, + """ + - (id)applyWithId:(id)elem { + return Adapter_toBooleanWithId_(elem); } """); } @@ -1682,7 +1689,14 @@ public void setBooleanSet(Set set) {} impl, """ - (void)setBooleanSet:(NSSet *)set { - [self setBooleanSetWithJavaUtilSet:(id) [Adapter toJavaUtilSetWithId:set withJavaUtilFunctionFunction:TestSetLeaf_$Lambda$1_instance]]; + [self setBooleanSetWithJavaUtilSet:(id) [Adapter toJavaUtilSetWithId:set withJavaUtilFunctionFunction:JreLoadStatic(TestSetLeaf_$Lambda$1, instance)]]; + } + """); + assertInTranslation( + impl, + """ + - (id)applyWithId:(id)elem { + return Adapter_toBooleanWithId_(elem); } """); } @@ -1706,7 +1720,14 @@ public void setBooleanList(List list) {} impl, """ - (void)setBooleanList:(NSArray *)list { - [self setBooleanListWithJavaUtilList:(id) [Adapter toJavaUtilListWithId:list withJavaUtilFunctionFunction:TestListParam_$Lambda$1_instance]]; + [self setBooleanListWithJavaUtilList:(id) [Adapter toJavaUtilListWithId:list withJavaUtilFunctionFunction:JreLoadStatic(TestListParam_$Lambda$1, instance)]]; + } + """); + assertInTranslation( + impl, + """ + - (id)applyWithId:(id)elem { + return Adapter_toBooleanWithId_(elem); } """); } @@ -1731,7 +1752,14 @@ public void setListSet(Set> set) {} impl, """ - (void)setListSet:(NSSet *> *)set { - [self setListSetWithJavaUtilSet:(id) [Adapter toJavaUtilSetWithId:set withJavaUtilFunctionFunction:TestSetOfList_$Lambda$1_instance]]; + [self setListSetWithJavaUtilSet:(id) [Adapter toJavaUtilSetWithId:set withJavaUtilFunctionFunction:JreLoadStatic(TestSetOfList_$Lambda$1, instance)]]; + } + """); + assertInTranslation( + impl, + """ + - (id)applyWithId:(id)elem { + return (id) Adapter_toJavaUtilListWithId_(elem); } """); } @@ -1989,7 +2017,14 @@ public void verifyList(List>> list) {} """ - (void)verifyList:(NSArray *> *> *)list { [self verifyListWithJavaUtilList:(id) [Adapter toJavaUtilListWithId:list \ - withJavaUtilFunctionFunction:TestClass_$Lambda$1_instance]]; + withJavaUtilFunctionFunction:JreLoadStatic(TestClass_$Lambda$1, instance)]]; + } + """); + assertInTranslation( + impl, + """ + - (id)applyWithId:(id)elem { + return (id) Adapter_toJavaUtilList_JavaUtilList_WithId_(elem); } """); }