From 2e78f534d5ac0a0b0f3998ac317dbebb690b366b Mon Sep 17 00:00:00 2001 From: scott Date: Thu, 31 Mar 2022 23:25:06 -0400 Subject: [PATCH] https://github.com/manifold-systems/manifold/issues/349 - support calls to non-public extension methods --- .../ext/NonPublicExtensionMethodTest.java | 47 +++++++++++++++++++ .../java/lang/Object/MyObjectExt.java | 29 ++++++++++++ .../manifold/ext/ExtensionTransformer.java | 14 ++++++ 3 files changed, 90 insertions(+) create mode 100644 manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/NonPublicExtensionMethodTest.java create mode 100644 manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/extensions/java/lang/Object/MyObjectExt.java diff --git a/manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/NonPublicExtensionMethodTest.java b/manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/NonPublicExtensionMethodTest.java new file mode 100644 index 000000000..5160b24e9 --- /dev/null +++ b/manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/NonPublicExtensionMethodTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 - Manifold Systems LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package manifold.ext; + +import junit.framework.TestCase; + +public class NonPublicExtensionMethodTest extends TestCase +{ + public void testProtectedMethodDirectly() + { + Foo foo = new Foo(); + assertEquals( "protected method", foo.callDirectly() ); + } + + public void testProtectedMethodIndirectly() + { + Foo foo = new Foo(); + assertEquals( "protected method", foo.callIndirectly() ); + } + + static class Foo + { + public String callDirectly() + { + return myProtectedMethod(); + } + + public String callIndirectly() + { + return new Foo().myProtectedMethod(); + } + } +} diff --git a/manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/extensions/java/lang/Object/MyObjectExt.java b/manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/extensions/java/lang/Object/MyObjectExt.java new file mode 100644 index 000000000..42c1d1206 --- /dev/null +++ b/manifold-deps-parent/manifold-ext-test/src/test/java/manifold/ext/extensions/java/lang/Object/MyObjectExt.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 - Manifold Systems LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package manifold.ext.extensions.java.lang.Object; + +import manifold.ext.rt.api.Extension; +import manifold.ext.rt.api.This; + +@Extension +public class MyObjectExt +{ + protected static String myProtectedMethod( @This Object thiz ) + { + return "protected method"; + } +} diff --git a/manifold-deps-parent/manifold-ext/src/main/java/manifold/ext/ExtensionTransformer.java b/manifold-deps-parent/manifold-ext/src/main/java/manifold/ext/ExtensionTransformer.java index 01a4efde0..d107bfd8f 100644 --- a/manifold-deps-parent/manifold-ext/src/main/java/manifold/ext/ExtensionTransformer.java +++ b/manifold-deps-parent/manifold-ext/src/main/java/manifold/ext/ExtensionTransformer.java @@ -2520,6 +2520,13 @@ private JCTree.JCMethodInvocation replaceExtCall( JCTree.JCMethodInvocation tree newArgs.add( 0, thisArg ); tree.args = List.from( newArgs ); } + + boolean isPublic = (method.flags_field & Flags.AccessFlags) == PUBLIC; + if( !isPublic ) + { + tree = replaceWithReflection( tree ); + } + return tree; } else if( methodSelect instanceof JCTree.JCIdent ) @@ -2547,6 +2554,13 @@ else if( methodSelect instanceof JCTree.JCIdent ) newMethodSelect.type = method.type; newMethodSelect.pos = tree.pos; assignTypes( newMethodSelect.selected, method.owner ); + + boolean isPublic = (method.flags_field & Flags.AccessFlags) == PUBLIC; + if( !isPublic ) + { + extCall = replaceWithReflection( extCall ); + } + return extCall; } return tree;