GP-5085 Functionality for unifying the color of external function names across the listing and decompiler views.

This commit is contained in:
ghidravision
2024-12-06 14:31:06 +00:00
parent 16388dc261
commit 6ed50fa085
9 changed files with 77 additions and 39 deletions

View File

@@ -4,9 +4,9 @@
* 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.
@@ -87,6 +87,10 @@ public abstract class CodeComparisonPanel extends JPanel
// to avoid java's constructor ordering problem
}
public PluginTool getTool() {
return tool;
}
/**
* Displays a comparison of two ComparisonData objects
*
@@ -317,10 +321,14 @@ public abstract class CodeComparisonPanel extends JPanel
// Set the MINIMUM_PANEL_WIDTH for the left and right panel to prevent the split pane's
// divider from becoming locked (can't be moved) due to extra long title names.
titlePanels.get(LEFT).setMinimumSize(
new Dimension(MINIMUM_PANEL_WIDTH, titlePanels.get(LEFT).getMinimumSize().height));
titlePanels.get(RIGHT).setMinimumSize(
new Dimension(MINIMUM_PANEL_WIDTH, titlePanels.get(RIGHT).getMinimumSize().height));
titlePanels.get(LEFT)
.setMinimumSize(
new Dimension(MINIMUM_PANEL_WIDTH,
titlePanels.get(LEFT).getMinimumSize().height));
titlePanels.get(RIGHT)
.setMinimumSize(
new Dimension(MINIMUM_PANEL_WIDTH,
titlePanels.get(RIGHT).getMinimumSize().height));
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, titlePanels.get(LEFT),
titlePanels.get(RIGHT));

View File

@@ -4,9 +4,9 @@
* 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.
@@ -26,6 +26,7 @@ import ghidra.app.decompiler.DecompileOptions;
import ghidra.app.decompiler.component.*;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
@@ -38,6 +39,7 @@ import ghidra.program.util.ProgramLocation;
public class CDisplay {
private final static String OPTIONS_TITLE = "Decompiler";
private ServiceProvider serviceProvider;
private DecompilerController controller;
private DecompileOptions decompileOptions;
private FieldLocation lastCursorPosition;
@@ -46,10 +48,12 @@ public class CDisplay {
private DecompilerProgramListener programListener;
public CDisplay(DecompilerCodeComparisonOptions comparisonOptions,
public CDisplay(ServiceProvider serviceProvider,
DecompilerCodeComparisonOptions comparisonOptions,
DecompileResultsListener decompileListener,
Consumer<ProgramLocation> locationConsumer) {
this.serviceProvider = serviceProvider;
highlightController = new DiffClangHighlightController(comparisonOptions);
decompileOptions = new DecompileOptions();
@@ -61,7 +65,7 @@ public class CDisplay {
}
};
controller = new DecompilerController(handler, decompileOptions, null) {
controller = new DecompilerController(serviceProvider, handler, decompileOptions, null) {
@Override
public void setDecompileData(DecompileData decompileData) {
super.setDecompileData(decompileData);

View File

@@ -4,9 +4,9 @@
* 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.
@@ -226,7 +226,7 @@ public class DecompilerCodeComparisonPanel
}
private CDisplay buildCDisplay(Side side) {
return new CDisplay(comparisonOptions,
return new CDisplay(getTool(), comparisonOptions,
decompileData -> decompileDataSet(side, decompileData),
l -> locationChanged(side, l));
}

View File

@@ -4,7 +4,6 @@ color.bg.decompiler = color.bg
color.fg.decompiler = color.fg
color.fg.decompiler.keyword = color.palette.blue
color.fg.decompiler.function.name = color.palette.blue
color.fg.decompiler.comment = color.palette.blueviolet
color.fg.decompiler.error = color.palette.crimson
color.fg.decompiler.variable = color.palette.olive

View File

@@ -4,9 +4,9 @@
* 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.
@@ -417,10 +417,7 @@ public class DecompileOptions {
private final static String HIGHLIGHT_KEYWORD_MSG = "Display.Color for Keywords";
private final static GColor HIGHLIGHT_KEYWORD_COLOR = new GColor("color.fg.decompiler.keyword");
private final static String HIGHLIGHT_FUNCTION_MSG = "Display.Color for Function names";
private final static GColor HIGHLIGHT_FUNCTION_COLOR = new GColor("color.fg.decompiler.function.name");
private final static String HIGHLIGHT_COMMENT_MSG = "Display.Color for Comments";
private final static GColor HIGHLIGHT_COMMENT_COLOR = new GColor( "color.fg.decompiler.comment");
@@ -751,9 +748,6 @@ public class DecompileOptions {
opt.registerThemeColorBinding(HIGHLIGHT_TYPE_MSG, HIGHLIGHT_TYPE_COLOR.getId(),
new HelpLocation(HelpTopics.DECOMPILER, "DisplayTokenColor"),
"Color used for highlighting types.");
opt.registerThemeColorBinding(HIGHLIGHT_FUNCTION_MSG, HIGHLIGHT_FUNCTION_COLOR.getId(),
new HelpLocation(HelpTopics.DECOMPILER, "DisplayTokenColor"),
"Color used for highlighting function names.");
opt.registerThemeColorBinding(HIGHLIGHT_COMMENT_MSG, HIGHLIGHT_COMMENT_COLOR.getId(),
new HelpLocation(HelpTopics.DECOMPILER, "DisplayTokenColor"),
"Color used for highlighting comments.");
@@ -1054,13 +1048,6 @@ public class DecompileOptions {
return HIGHLIGHT_TYPE_COLOR;
}
/**
* @return color associated with a function name token
*/
public Color getFunctionColor() {
return HIGHLIGHT_FUNCTION_COLOR;
}
/**
* @return color used to display comments
*/

View File

@@ -4,9 +4,9 @@
* 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.
@@ -27,10 +27,14 @@ import docking.widgets.fieldpanel.listener.IndexMapper;
import docking.widgets.fieldpanel.listener.LayoutModelListener;
import docking.widgets.fieldpanel.support.*;
import ghidra.app.decompiler.*;
import ghidra.app.util.SymbolInspector;
import ghidra.app.util.viewer.field.CommentUtils;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.HighFunction;
import ghidra.program.model.symbol.Symbol;
import ghidra.util.UndefinedFunction;
/**
* Control the GUI layout for displaying tokenized C code
@@ -39,8 +43,9 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
private int maxWidth;
private int indentWidth;
private DecompileOptions options;
private SymbolInspector symbolInspector;
private DecompilerPanel decompilerPanel;
private DecompileOptions options;
private ClangTokenGroup docroot; // Root of displayed document
private Field[] fieldList; // Array of fields comprising layout
private FontMetrics metrics;
@@ -61,6 +66,10 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
this.hlFactory = hlFactory;
listeners = new ArrayList<>();
buildLayouts(null, null, null, false);
DecompilerController controller = decompilerPanel.getController();
ServiceProvider serviceProvider = controller.getServiceProvider();
symbolInspector = new SymbolInspector(serviceProvider, decompilerPanel);
}
public List<ClangLine> getLines() {
@@ -173,7 +182,8 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
int columnPosition = 0;
for (int i = 0; i < tokens.size(); ++i) {
ClangToken token = tokens.get(i);
Color color = syntaxColor[token.getSyntaxType()];
Color color = getTokenColor(token);
if (token instanceof ClangCommentToken) {
AttributedString prototype = new AttributedString("prototype", color, metrics);
Program program = decompilerPanel.getProgram();
@@ -190,6 +200,22 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
return elements;
}
private Color getTokenColor(ClangToken token) {
Color tokenColor = syntaxColor[token.getSyntaxType()];
if (token instanceof ClangFuncNameToken clangFunctionToken) {
Program program = decompilerPanel.getProgram();
Function function = DecompilerUtils.getFunction(program, clangFunctionToken);
if (function instanceof UndefinedFunction) {
return null;
}
Symbol symbol = function.getSymbol();
return symbolInspector.getColor(symbol);
}
return tokenColor;
}
/**
* Update to the current Decompiler display options
*/
@@ -198,8 +224,8 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
private void updateOptions() {
syntaxColor[ClangToken.KEYWORD_COLOR] = options.getKeywordColor();
syntaxColor[ClangToken.TYPE_COLOR] = options.getTypeColor();
syntaxColor[ClangToken.FUNCTION_COLOR] = options.getFunctionColor();
syntaxColor[ClangToken.COMMENT_COLOR] = options.getCommentColor();
syntaxColor[ClangToken.FUNCTION_COLOR] = null; // not used by the UI
syntaxColor[ClangToken.VARIABLE_COLOR] = options.getVariableColor();
syntaxColor[ClangToken.CONST_COLOR] = options.getConstantColor();
syntaxColor[ClangToken.PARAMETER_COLOR] = options.getParameterColor();

View File

@@ -4,9 +4,9 @@
* 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.
@@ -24,6 +24,7 @@ import com.google.common.cache.CacheBuilder;
import docking.widgets.fieldpanel.support.ViewerPosition;
import ghidra.app.decompiler.*;
import ghidra.app.plugin.core.decompile.DecompilerClipboardProvider;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.HighFunction;
@@ -38,6 +39,8 @@ import utility.function.Callback;
*/
public class DecompilerController {
private ServiceProvider serviceProvider;
private DecompilerPanel decompilerPanel;
private DecompilerManager decompilerMgr;
private final DecompilerCallbackHandler callbackHandler;
@@ -46,8 +49,10 @@ public class DecompilerController {
private Cache<Function, DecompileResults> decompilerCache;
private int cacheSize;
public DecompilerController(DecompilerCallbackHandler handler, DecompileOptions options,
public DecompilerController(ServiceProvider serviceProvider, DecompilerCallbackHandler handler,
DecompileOptions options,
DecompilerClipboardProvider clipboard) {
this.serviceProvider = serviceProvider;
this.cacheSize = options.getCacheSize();
this.callbackHandler = handler;
decompilerCache = buildCache();
@@ -58,6 +63,10 @@ public class DecompilerController {
decompilerPanel.setHoverMode(true);
}
public ServiceProvider getServiceProvider() {
return serviceProvider;
}
public DecompilerPanel getDecompilerPanel() {
return decompilerPanel;
}

View File

@@ -159,6 +159,10 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
}
}
public DecompilerController getController() {
return controller;
}
public List<ClangLine> getLines() {
return layoutController.getLines();
}

View File

@@ -134,7 +134,8 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
decompilerOptions = new DecompileOptions();
initializeDecompilerOptions();
controller = new DecompilerController(this, decompilerOptions, clipboardProvider);
controller =
new DecompilerController(getTool(), this, decompilerOptions, clipboardProvider);
DecompilerPanel decompilerPanel = controller.getDecompilerPanel();
// TODO move the hl controller into the panel