GP-6669: JsonDoclet now outputs public/private/protected, which Jython

and PyGhidra will display in help()
This commit is contained in:
Ryan Kurtz
2026-04-16 19:14:08 -04:00
parent 5a209ba931
commit 7219427f69
5 changed files with 47 additions and 14 deletions

View File

@@ -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":

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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<Modifier> 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.
*