diff --git a/Ghidra/Features/Jython/jython-src/ghidradoc.py b/Ghidra/Features/Jython/jython-src/ghidradoc.py index 38b6d6f569..54066b9f8d 100644 --- a/Ghidra/Features/Jython/jython-src/ghidradoc.py +++ b/Ghidra/Features/Jython/jython-src/ghidradoc.py @@ -1,17 +1,17 @@ ## ### -# IP: GHIDRA -# -# 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. +# IP: GHIDRA +# +# 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. ## """ Ties the Ghidra documentation into the builtin Python help. @@ -123,6 +123,8 @@ class _Helper: sig = "%s %s" % (field["type_long"], field["name"]) if field["static"]: sig = "static " + sig + if field["access"]: + sig = field["access"] + " " + sig if field["constant_value"]: sig += " = " + field["constant_value"] sig += "\n" @@ -143,6 +145,8 @@ class _Helper: sig = "%s %s(%s)\n" % (method["return"]["type_short"], method["name"], paramsig) if method["static"]: sig = "static " + sig + if method["access"]: + sig = method["access"] + " " + sig desc = " %s\n\n" % (method["comment"]) if len(method["comment"]) > 0 else "" ret = "" if method["return"]["type_short"] != "void": diff --git a/Ghidra/Features/PyGhidra/src/main/py/README.md b/Ghidra/Features/PyGhidra/src/main/py/README.md index 1099a18291..628adf8a59 100644 --- a/Ghidra/Features/PyGhidra/src/main/py/README.md +++ b/Ghidra/Features/PyGhidra/src/main/py/README.md @@ -567,6 +567,10 @@ import pdb # imports Python's pdb import pdb_ # imports Ghidra's pdb ``` ## Change History +__3.2.0__ +* PyGhidra's `help()` override can now show `public/private/protected` on Ghidra Java fields and + methods (available in Ghidra 12.2 and later). + __3.1.0__ * PyGhidra will now, by default, restore `sys.modules` to its prior state after a PyGhidra script is run (or the interactive interpreter is reset) so the next time a script is run, it freshly loads diff --git a/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/__init__.py b/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/__init__.py index 7d6bfe7e41..0121f52864 100644 --- a/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/__init__.py +++ b/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/__init__.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. ## -__version__ = "3.1.0" +__version__ = "3.2.0" # stub for documentation and typing # this is mostly to hide the function parameter diff --git a/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/ghidradoc.py b/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/ghidradoc.py index 1423309d6f..8aeb87e0c1 100644 --- a/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/ghidradoc.py +++ b/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/ghidradoc.py @@ -103,6 +103,8 @@ class _Helper: sig = f"{field['type_long']} {field['name']}" if field['static']: sig = "static " + sig + if field.get("access"): + sig = field.get("access") + " " + sig if constant_value := field['constant_value']: sig += " = " + constant_value sig += "\n" @@ -124,6 +126,8 @@ class _Helper: sig = f"{method['return']['type_short']} {method['name']}({paramsig})\n" if method['static']: sig = "static " + sig + if method.get("access"): + sig = method.get("access") + " " + sig if comment := method['comment']: desc = f" {comment}\n\n" else: diff --git a/GhidraBuild/BuildFiles/Doclets/src/main/java/ghidra/doclets/json/JsonDoclet.java b/GhidraBuild/BuildFiles/Doclets/src/main/java/ghidra/doclets/json/JsonDoclet.java index 2392b39f41..d3bde96150 100644 --- a/GhidraBuild/BuildFiles/Doclets/src/main/java/ghidra/doclets/json/JsonDoclet.java +++ b/GhidraBuild/BuildFiles/Doclets/src/main/java/ghidra/doclets/json/JsonDoclet.java @@ -157,6 +157,7 @@ public class JsonDoclet implements Doclet { classObj.addProperty("comment", getComment(docTrees.getDocCommentTree(classElement))); classObj.addProperty("javadoc", getJavadoc(docTrees.getDocCommentTree(classElement))); classObj.addProperty("static", classElement.getModifiers().contains(Modifier.STATIC)); + classObj.addProperty("access", getAccessModifier(classElement)); addInterfaces(classElement, classObj); addSuperClass(classElement, classObj); } @@ -220,6 +221,7 @@ public class JsonDoclet implements Doclet { obj.addProperty("comment", getComment(docTrees.getDocCommentTree(el))); obj.addProperty("javadoc", getJavadoc(docTrees.getDocCommentTree(el))); obj.addProperty("static", el.getModifiers().contains(Modifier.STATIC)); + obj.addProperty("access", getAccessModifier(el)); switch (el.getKind()) { case FIELD: @@ -445,6 +447,25 @@ public class JsonDoclet implements Doclet { return ""; } + /** + * {@return the access modifier for the given {@link Element}} + * + * @param el The {@link Element} to get the access modifier of + */ + private String getAccessModifier(Element el) { + Set mods = el.getModifiers(); + if (mods.contains(Modifier.PUBLIC)) { + return "public"; + } + if (mods.contains(Modifier.PRIVATE)) { + return "private"; + } + if (mods.contains(Modifier.PROTECTED)) { + return "protected"; + } + return ""; + } + /** * Writes the given json to a filename based on the given qualified class name. *