GP-5716: Port for FrontEnd. Changes per reivew.

This commit is contained in:
Dan 2025-08-25 20:00:18 +00:00
parent cd9a57d859
commit 2a14a5f201

View file

@ -15,7 +15,9 @@
*/
package ghidra.app.plugin.core.help;
import java.util.Map;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import docking.ActionContext;
import docking.action.DockingAction;
@ -34,13 +36,15 @@ import ghidra.framework.main.datatable.ProjectDataContext;
import ghidra.framework.model.DomainFile;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.Program;
import ghidra.program.util.DefaultLanguageService;
import ghidra.util.HelpLocation;
/**
* Display a pop-up dialog containing information about the Domain Object
* that is currently open in the tool.
* Display a pop-up dialog containing information about the Domain Object that is currently open in
* the tool.
*/
//@formatter:off
@PluginInfo(
@ -73,6 +77,106 @@ public class AboutProgramPlugin extends Plugin implements ApplicationLevelPlugin
super.dispose();
}
record LcspAndVersion(Language language, CompilerSpec compilerSpec, Integer languageVersion,
Integer languageMinorVersion) {
public static final Pattern LANG_PAT =
Pattern.compile("(?<id>\\S+) \\((?<major>\\d+)\\.(?<minor>\\d+)\\)");
static Language tryLang(String languageID) {
LanguageService langServ = DefaultLanguageService.getLanguageService();
try {
return langServ.getLanguage(new LanguageID(languageID));
}
catch (LanguageNotFoundException e) {
return null;
}
}
static Integer tryInt(String i) {
try {
return Integer.parseInt(i);
}
catch (NumberFormatException e) {
return null;
}
}
static CompilerSpec tryCompiler(Language language, String compilerSpecID) {
try {
return language.getCompilerSpecByID(new CompilerSpecID(compilerSpecID));
}
catch (CompilerSpecNotFoundException e) {
return null;
}
}
/**
* @see ProgramDB#getMetadata()
* @param metadata the metadata
* @return the parsed language, compiler spec, and language version
*/
public static LcspAndVersion fromMetadata(Map<String, String> metadata) {
String languageInfo = metadata.get("Language ID");
if (languageInfo == null) {
return null;
}
Matcher matcher = LANG_PAT.matcher(languageInfo);
Language language;
Integer languageVersion;
Integer languageMinorVersion;
if (matcher.matches()) {
language = tryLang(matcher.group("id"));
languageVersion = tryInt(matcher.group("major"));
languageMinorVersion = tryInt(matcher.group("minor"));
}
else {
language = tryLang(languageInfo);
languageVersion = null;
languageMinorVersion = null;
}
if (language == null) {
return null;
}
String compilerInfo = metadata.get("Compiler ID");
if (compilerInfo == null) {
return new LcspAndVersion(language, null, languageVersion, languageMinorVersion);
}
CompilerSpec compilerSpec = tryCompiler(language, compilerInfo);
return new LcspAndVersion(language, compilerSpec, languageVersion,
languageMinorVersion);
}
public boolean isMismatch() {
return !Objects.equals(language.getVersion(), languageVersion) ||
!Objects.equals(language.getMinorVersion(), languageMinorVersion);
}
public String getVersionDisplay() {
if (language == null) {
return "";
}
return " (%d.%d)".formatted(language.getVersion(), language.getMinorVersion());
}
}
private void addLanguageFileInfo(Map<String, String> metadata) {
LcspAndVersion lav = LcspAndVersion.fromMetadata(metadata);
if (lav == null || lav.language == null) {
return;
}
if (lav.language.getLanguageDescription() instanceof SleighLanguageDescription lDesc) {
metadata.put("Language Spec",
lDesc.getDefsFile() + (lav.isMismatch() ? lav.getVersionDisplay() : ""));
metadata.put("Processor Spec", lDesc.getSpecFile().getAbsolutePath());
metadata.put("Sleigh Spec", lDesc.getSlaFile().getAbsolutePath() + "spec");
}
if (lav.compilerSpec != null) {
metadata.put("Compiler Spec",
lav.compilerSpec.getCompilerSpecDescription().getSource());
}
}
private void setupActions() {
if (tool instanceof FrontEndTool) {
aboutAction = new FrontendProjectTreeAction(ACTION_NAME, PLUGIN_NAME) {
@ -80,8 +184,8 @@ public class AboutProgramPlugin extends Plugin implements ApplicationLevelPlugin
@Override
protected void actionPerformed(ProjectDataContext context) {
DomainFile domainFile = context.getSelectedFiles().get(0);
Map<String, String> metadata = domainFile.getMetadata();
Map<String, String> metadata = new LinkedHashMap<>(domainFile.getMetadata());
addLanguageFileInfo(metadata);
showAbout(domainFile, metadata);
}
@ -107,17 +211,8 @@ public class AboutProgramPlugin extends Plugin implements ApplicationLevelPlugin
@Override
public void actionPerformed(ProgramActionContext context) {
Program program = context.getProgram();
Map<String, String> metadata = program.getMetadata();
String cspec = program.getCompilerSpec().getCompilerSpecDescription().getSource();
metadata.put("Compiler Spec", cspec);
Language language = program.getLanguage();
LanguageDescription languageDescription = language.getLanguageDescription();
if (languageDescription instanceof SleighLanguageDescription sleighDescription) {
metadata.put("Sleigh Spec", sleighDescription.getSlaFile().toString() + "spec");
metadata.put("Processor Spec", sleighDescription.getSpecFile().toString());
}
Map<String, String> metadata = new LinkedHashMap<>(program.getMetadata());
addLanguageFileInfo(metadata);
showAbout(program.getDomainFile(), metadata);
}