mirror of
https://github.com/fadden/6502bench.git
synced 2025-04-14 16:37:08 +00:00
Add Problem List Viewer to debug menu
The analyzer sometimes runs into things that don't seem right, like hidden labels or references to non-existent symbols, but has no way to report them. This adds a problem viewer. I'm not quite ready to turn this into a real feature, so for now it's a free-floating window accessed from the debug menu. Also, updated some documentation.
This commit is contained in:
parent
c05c42bf21
commit
41cd30a8c6
@ -168,6 +168,9 @@ namespace SourceGen {
|
||||
// Project and platform symbols that are being referenced from code.
|
||||
public List<DefSymbol> ActiveDefSymbolList { get; private set; }
|
||||
|
||||
// List of problems detected during analysis.
|
||||
public ProblemList Problems { get; private set; }
|
||||
|
||||
#if DATA_PRESCAN
|
||||
// Data scan results.
|
||||
public TypedRangeSet RepeatedBytes { get; private set; }
|
||||
@ -230,6 +233,8 @@ namespace SourceGen {
|
||||
PlatformSyms = new List<PlatformSymbols>();
|
||||
ActiveDefSymbolList = new List<DefSymbol>();
|
||||
|
||||
Problems = new ProblemList();
|
||||
|
||||
// Default to 65816. This will be replaced with value from project file or
|
||||
// system definition.
|
||||
ProjectProps.CpuType = CpuDef.CpuType.Cpu65816;
|
||||
@ -645,6 +650,10 @@ namespace SourceGen {
|
||||
// the program will never generate bad data, and any bad project file contents
|
||||
// (possibly introduced by hand-editing) are identified at load time, called out
|
||||
// to the user, and discarded.
|
||||
//
|
||||
// We do want to collect the failures so we can present them to the user.
|
||||
Problems.Clear();
|
||||
|
||||
Debug.Assert(reanalysisRequired != UndoableChange.ReanalysisScope.None);
|
||||
reanalysisTimer.StartTask("DisasmProject.Analyze()");
|
||||
|
||||
@ -773,6 +782,7 @@ namespace SourceGen {
|
||||
//reanalysisTimer.DumpTimes("DisasmProject timers:", debugLog);
|
||||
|
||||
debugLog.LogI("Analysis complete");
|
||||
Problems.DebugDump();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -809,6 +819,7 @@ namespace SourceGen {
|
||||
/// </summary>
|
||||
/// <param name="genLog">Log for debug messages.</param>
|
||||
private void ApplyFormatDescriptors(DebugLog genLog) {
|
||||
// TODO: add these to ProblemList
|
||||
foreach (KeyValuePair<int, FormatDescriptor> kvp in OperandFormats) {
|
||||
int offset = kvp.Key;
|
||||
|
||||
@ -970,6 +981,13 @@ namespace SourceGen {
|
||||
if (!mAnattribs[offset].IsStart) {
|
||||
Debug.WriteLine("Stripping hidden label '" + kvp.Value.Label + "'");
|
||||
SymbolTable.Remove(kvp.Value);
|
||||
|
||||
Problems.Add(new ProblemList.ProblemEntry(
|
||||
ProblemList.ProblemEntry.SeverityLevel.Warning,
|
||||
offset,
|
||||
ProblemList.ProblemEntry.ProblemType.HiddenLabel,
|
||||
kvp.Value.Label,
|
||||
ProblemList.ProblemEntry.ProblemResolution.LabelIgnored));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1293,6 +1311,14 @@ namespace SourceGen {
|
||||
Debug.WriteLine("NOTE: not xrefing +" + offset.ToString("x6") +
|
||||
" " + sym);
|
||||
}
|
||||
} else {
|
||||
// Reference to non-existent symbol.
|
||||
Problems.Add(new ProblemList.ProblemEntry(
|
||||
ProblemList.ProblemEntry.SeverityLevel.Info,
|
||||
offset,
|
||||
ProblemList.ProblemEntry.ProblemType.UnresolvedWeakRef,
|
||||
dfd.SymbolRef.Label,
|
||||
ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored));
|
||||
}
|
||||
} else if (dfd.FormatSubType == FormatDescriptor.SubType.Address) {
|
||||
// not expecting this format on an instruction operand
|
||||
|
@ -74,6 +74,8 @@ namespace SourceGen {
|
||||
public bool IsDebugAnalysisTimersOpen { get { return mShowAnalysisTimersDialog != null; } }
|
||||
private Tools.WpfGui.ShowText mShowAnalyzerOutputDialog;
|
||||
public bool IsDebugAnalyzerOutputOpen { get { return mShowAnalyzerOutputDialog != null; } }
|
||||
private Tools.WpfGui.ProblemListViewer mShowProblemListDialog;
|
||||
public bool IsDebugProblemListOpen { get { return mShowProblemListDialog != null; } }
|
||||
private Tools.WpfGui.ShowText mShowUndoRedoHistoryDialog;
|
||||
public bool IsDebugUndoRedoHistoryOpen { get { return mShowUndoRedoHistoryDialog != null; } }
|
||||
|
||||
@ -855,6 +857,10 @@ namespace SourceGen {
|
||||
}
|
||||
}
|
||||
|
||||
if (mShowProblemListDialog != null) {
|
||||
mShowProblemListDialog.Update();
|
||||
}
|
||||
|
||||
if (FormatDescriptor.DebugCreateCount != 0) {
|
||||
Debug.WriteLine("FormatDescriptor total=" + FormatDescriptor.DebugCreateCount +
|
||||
" prefab=" + FormatDescriptor.DebugPrefabCount + " (" +
|
||||
@ -1201,6 +1207,7 @@ namespace SourceGen {
|
||||
mHexDumpDialog?.Close();
|
||||
mShowAnalysisTimersDialog?.Close();
|
||||
mShowAnalyzerOutputDialog?.Close();
|
||||
mShowProblemListDialog?.Close();
|
||||
mShowUndoRedoHistoryDialog?.Close();
|
||||
|
||||
while (mUnownedWindows.Count > 0) {
|
||||
@ -1242,6 +1249,7 @@ namespace SourceGen {
|
||||
mHexDumpDialog?.Close();
|
||||
mShowAnalysisTimersDialog?.Close();
|
||||
mShowAnalyzerOutputDialog?.Close();
|
||||
mShowProblemListDialog?.Close();
|
||||
mShowUndoRedoHistoryDialog?.Close();
|
||||
|
||||
// Discard all project state.
|
||||
@ -3531,6 +3539,22 @@ namespace SourceGen {
|
||||
}
|
||||
}
|
||||
|
||||
public void Debug_ShowProblemList() {
|
||||
if (mShowProblemListDialog == null) {
|
||||
Tools.WpfGui.ProblemListViewer dlg =
|
||||
new Tools.WpfGui.ProblemListViewer(null, mProject, mOutputFormatter);
|
||||
dlg.Closing += (sender, e) => {
|
||||
Debug.WriteLine("Problem list window closed");
|
||||
mShowProblemListDialog = null;
|
||||
};
|
||||
dlg.Show();
|
||||
mShowProblemListDialog = dlg;
|
||||
} else {
|
||||
// Ask the dialog to close. Do the cleanup in the event.
|
||||
mShowProblemListDialog.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void Debug_ShowUndoRedoHistory() {
|
||||
if (mShowUndoRedoHistoryDialog == null) {
|
||||
Tools.WpfGui.ShowText dlg = new Tools.WpfGui.ShowText(null,
|
||||
|
128
SourceGen/ProblemList.cs
Normal file
128
SourceGen/ProblemList.cs
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2019 faddenSoft
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SourceGen {
|
||||
/// <summary>
|
||||
/// List of problems noted during analysis of the project.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Could also make a place for load-time problems, though those tend to be resolved by
|
||||
/// discarding the offending data, so not much value in continuing to report them.
|
||||
/// </remarks>
|
||||
public class ProblemList : IEnumerable<ProblemList.ProblemEntry> {
|
||||
/// <summary>
|
||||
/// One problem entry.
|
||||
///
|
||||
/// Instances are immutable.
|
||||
/// </summary>
|
||||
public class ProblemEntry {
|
||||
public enum SeverityLevel {
|
||||
Unknown = 0,
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
}
|
||||
public SeverityLevel Severity { get; private set; }
|
||||
|
||||
public int Offset { get; private set; }
|
||||
|
||||
public enum ProblemType {
|
||||
Unknown = 0,
|
||||
HiddenLabel,
|
||||
UnresolvedWeakRef,
|
||||
}
|
||||
public ProblemType Problem { get; private set; }
|
||||
|
||||
// Context object. Could be a label string, a format descriptor, etc.
|
||||
public object Context { get; private set; }
|
||||
|
||||
public enum ProblemResolution {
|
||||
Unknown = 0,
|
||||
LabelIgnored,
|
||||
FormatDescriptorIgnored,
|
||||
}
|
||||
public ProblemResolution Resolution { get; private set; }
|
||||
|
||||
|
||||
public ProblemEntry(SeverityLevel severity, int offset, ProblemType problem,
|
||||
object context, ProblemResolution resolution) {
|
||||
Severity = severity;
|
||||
Offset = offset;
|
||||
Problem = problem;
|
||||
Context = context;
|
||||
Resolution = resolution;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return Severity.ToString() + " +" + Offset.ToString("x6") + " " +
|
||||
Problem + "(" + Context.ToString() + "): " + Resolution;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum file offset. Used to flag offsets as invalid.
|
||||
/// </summary>
|
||||
public int MaxOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of problems. This is not kept in sorted order, because the DataGrid used to
|
||||
/// display it will do the sorting for us.
|
||||
/// </summary>
|
||||
private List<ProblemEntry> mList;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public ProblemList() {
|
||||
mList = new List<ProblemEntry>();
|
||||
}
|
||||
|
||||
// IEnumerable
|
||||
public IEnumerator<ProblemEntry> GetEnumerator() {
|
||||
// .Values is documented as O(1)
|
||||
return mList.GetEnumerator();
|
||||
}
|
||||
|
||||
// IEnumerable
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return mList.GetEnumerator();
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get { return mList.Count; }
|
||||
}
|
||||
|
||||
public void Add(ProblemEntry entry) {
|
||||
mList.Add(entry);
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
mList.Clear();
|
||||
}
|
||||
|
||||
public void DebugDump() {
|
||||
Debug.WriteLine("Problem list:");
|
||||
foreach (ProblemEntry entry in mList) {
|
||||
Debug.WriteLine(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -229,6 +229,8 @@ not help you debug 6502 projects.</p>
|
||||
<ul>
|
||||
<li>Re-analyze (F5). Causes a full re-analysis. Useful if you think
|
||||
the display is out of sync.</li>
|
||||
<li>Show Problem List Viewer. Opens a floating window that shows some
|
||||
of the problems encountered during the last analysis pass.</li>
|
||||
<li>Show Undo/Redo History. Opens a floating window that lets you
|
||||
watch the contents of the undo buffer while you work.</li>
|
||||
<li>Show Analyzer Output. Opens a floating window with a text log from
|
||||
|
@ -33,27 +33,30 @@ This is explained in more detail <a href="#export-source">below</a>.
|
||||
<li><a href="#merlin32">Merlin 32</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a name="version">Version-Specific Code Generation</a></h3>
|
||||
|
||||
<p>Code generation must be tailored to the specific version of the
|
||||
assembler. This is most easily understood with an example.</p>
|
||||
<p>If you write <code>MVN $01,$02</code>, the assembler is expected to output
|
||||
<code>54 02 01</code>, with the arguments reversed. cc65 v2.17 doesn't
|
||||
do that; this is a bug that was fixed in a later version. So if you're
|
||||
generating code for v2.17, you want to create source code with the
|
||||
arguments the wrong way around.</p>
|
||||
<p>Having version-dependent source code is a bad idea, so SourceGen
|
||||
just outputs raw hex bytes for MVN/MVP instructions. This yields the
|
||||
correct code for all versions of the assembler, but is ugly and
|
||||
annoying. So we want to output actual MVN/MVP instructions when producing
|
||||
code for newer versions of the assembler.</p>
|
||||
<p>If the code has a statement like <code>MVN #$01,#$02</code>, the
|
||||
assembler is expected to output <code>54 02 01</code>, with the arguments
|
||||
reversed. cc65 v2.17 got it backward; the behavior was fixed in v2.18. The
|
||||
bug means we can't generate the same <code>MVN</code>/<code>MVP</code>
|
||||
instructions for both versions of the assembler.</p>
|
||||
<p>Having version-dependent source code is a bad idea. If we generated
|
||||
reversed operands (<code>MVN #$02,#$01</code>), we'd get the correct
|
||||
output with v2.17, but the wrong output for v2.18. Unambiguous code can
|
||||
be generated for all versions of the assembler by just outputting raw hex
|
||||
bytes, but that's ugly and annoying, so we don't want to be stuck doing
|
||||
that forever. We want to detect which version of the assembler is in
|
||||
use, and output actual <code>MVN</code>/<code>MVP</code> instructions
|
||||
when producing code for newer versions of the assembler.</p>
|
||||
<p>When you configure a cross-assembler, SourceGen runs the executable with
|
||||
version query args, and extracts the version information from the output
|
||||
stream. This is used by the generator to ensure that the output will compile.
|
||||
If no assembler is configured, SourceGen will produce code optimized
|
||||
for the latest version of the assembler.</p>
|
||||
|
||||
|
||||
<h2><a name="generate">Generating Source Code</a></h2>
|
||||
|
||||
<p>Cross assemblers tend to generate additional files, either compiler
|
||||
@ -73,8 +76,8 @@ of a version number.</p>
|
||||
<p>The Settings button will take you directly to the assembler configuration
|
||||
tab in the application settings dialog.</p>
|
||||
<p>Hit the Generate button to generate the source code into a file on disk.
|
||||
The file will use the project name, with the ".dis65" replaced by
|
||||
"_<assembler>.S".</p>
|
||||
The file will use the project name, with the <code>.dis65</code> extension
|
||||
replaced by <code>_<assembler>.S</code>.</p>
|
||||
<p>The first 64KiB of each generated file will be shown in the preview
|
||||
window. If multiple files were generated, you can use the "preview file"
|
||||
drop-down to select between them. Line numbers are
|
||||
@ -95,6 +98,15 @@ disabled from the
|
||||
<a href="settings.html#app-settings">application settings</a>.</p>
|
||||
|
||||
|
||||
<h3><a name="reserved-labels">Reserved Label Names</a></h3>
|
||||
<p>Some label names aren't allowed. For example, 64tass reserves the
|
||||
use of labels that begin with two underscores. Most assemblers will
|
||||
also prevent you from using opcode mnemonics as labels (which means
|
||||
you can't assemble <code>jmp jmp jmp</code>).</p>
|
||||
<p>If a label doesn't appear to be legal, the generated code will have
|
||||
a suitable replacement (e.g. <code>jmp_1 jmp jmp_1</code>).</p>
|
||||
|
||||
|
||||
<h2><a name="assemble">Cross-Assembling Generated Code</a></h2>
|
||||
|
||||
<p>After generating sources, if you have a cross-assembler executable
|
||||
@ -152,8 +164,8 @@ code, but also needs to know how to handle the corner cases.</p>
|
||||
the load address. The <code>--nostart</code> flag is used to
|
||||
suppress this.</li>
|
||||
<li>By default, 64tass is case-insensitive, but SourceGen treats labels
|
||||
as case-sensitive. The <code>--case-sensitive</code> must be passed to
|
||||
the assembler.</li>
|
||||
as case-sensitive. The <code>--case-sensitive</code> flag must be passed
|
||||
to the assembler.</li>
|
||||
<li>If you set the <code>--case-sensitive</code> flag, <b>all</b> opcodes
|
||||
and operands must be lower-case. Most of the SourceGen options that
|
||||
cause things to appear in upper case must be disabled.</li>
|
||||
@ -172,15 +184,6 @@ code, but also needs to know how to handle the corner cases.</p>
|
||||
an explicit character encoding definition must be provided.</li>
|
||||
</ul>
|
||||
|
||||
<p>Notes:</p>
|
||||
<ul>
|
||||
<li>The "default text encoding" project property is used by SourceGen
|
||||
to set the text encoding for the entire source file. For non-ASCII
|
||||
projects, a small encoding table is generated at the top of the output.
|
||||
This works for C64 PETSCII and C64 screen codes, but not for high
|
||||
ASCII. This is done without passing "--ascii" on the command line.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a name="acme">ACME</a></h3>
|
||||
|
||||
@ -326,7 +329,7 @@ with links.</p>
|
||||
<li><b>Include only selected lines</b>. This allows you to choose between
|
||||
exporting all or part of a file. If no lines are selected, the entire
|
||||
file will exported. This setting does <b>not</b> affect link generation
|
||||
for HTML output, so you my have some dead internal links if you don't
|
||||
for HTML output, so you may have some dead internal links if you don't
|
||||
export the entire file.</li>
|
||||
<li><b>Include notes</b>. Notes are normally excluded from generated
|
||||
sources. Check this to include them.</li>
|
||||
|
@ -272,10 +272,18 @@ use the symbol. To make the difference clear, the lines in the references
|
||||
window will either show "Sym" (to indicate that the symbol at the selected
|
||||
line was referenced) or "Oth" (to indicate that some other symbol, or no
|
||||
symbol, was used).</p>
|
||||
<p>This is also relevant for project and platform symbols. If the
|
||||
DATA0/1 labels were project symbols, the entry for <code>DATA1</code>
|
||||
would not be included in the list of equates, because the symbol is
|
||||
never used.</p>
|
||||
|
||||
<p>When an equate directive (generated for platform and project
|
||||
symbols) or local variable assignment is selected, the References
|
||||
window will show all references to that symbol. Unlike in-file
|
||||
references, only the uses of that symbol are shown. So if you have
|
||||
both a project symbol and a local variable for address $30, they
|
||||
will show disjoint sets of references. Furthermore, if you explicitly
|
||||
format an instruction operand as hex, e.g. <code>LDA $30</code>, it will
|
||||
not appear in either set because it's not a symbolic reference.</p>
|
||||
<p>The cross-reference data is used to generate the set of equate
|
||||
directives at the top of the listing. If nothing references a platform
|
||||
or project symbol, an equate directive will not be generated for it.</p>
|
||||
|
||||
<p>Double-clicking on a reference moves the code list selection to that
|
||||
reference, and adds the previous selection to the navigation stack.</p>
|
||||
|
@ -79,6 +79,7 @@
|
||||
<Compile Include="Exporter.cs" />
|
||||
<Compile Include="FormattedOperandCache.cs" />
|
||||
<Compile Include="LocalVariableLookup.cs" />
|
||||
<Compile Include="ProblemList.cs" />
|
||||
<Compile Include="Tests\GenTest.cs" />
|
||||
<Compile Include="Tests\ProgressMessage.cs" />
|
||||
<Compile Include="Tests\WpfGui\GenTestRunner.xaml.cs">
|
||||
@ -88,6 +89,9 @@
|
||||
<Compile Include="Tools\WpfGui\AsciiChart.xaml.cs">
|
||||
<DependentUpon>AsciiChart.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Tools\WpfGui\ProblemListViewer.xaml.cs">
|
||||
<DependentUpon>ProblemListViewer.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Tools\WpfGui\ShowText.xaml.cs">
|
||||
<DependentUpon>ShowText.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -242,6 +246,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Tools\WpfGui\ProblemListViewer.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Tools\WpfGui\ShowText.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -17,8 +17,6 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SourceGen {
|
||||
/// <summary>
|
||||
|
61
SourceGen/Tools/WpfGui/ProblemListViewer.xaml
Normal file
61
SourceGen/Tools/WpfGui/ProblemListViewer.xaml
Normal file
@ -0,0 +1,61 @@
|
||||
<!--
|
||||
Copyright 2019 faddenSoft
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<Window x:Class="SourceGen.Tools.WpfGui.ProblemListViewer"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SourceGen.Tools.WpfGui"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||
mc:Ignorable="d"
|
||||
Title="Problems" ShowInTaskbar="True"
|
||||
Height="500" Width="500" ResizeMode="CanResizeWithGrip"
|
||||
Loaded="Window_Loaded">
|
||||
|
||||
<Window.Resources>
|
||||
<system:String x:Key="str_HiddenLabel">Hidden label</system:String>
|
||||
<system:String x:Key="str_UnresolvedWeakRef">Ref'd symbol not found</system:String>
|
||||
|
||||
<system:String x:Key="str_LabelIgnored">Label ignored</system:String>
|
||||
<system:String x:Key="str_FormatDescriptorIgnored">Format ignored</system:String>
|
||||
</Window.Resources>
|
||||
|
||||
<DockPanel Margin="8">
|
||||
<TextBlock DockPanel.Dock="Top" Text="Problems detected during analysis:"/>
|
||||
|
||||
<DataGrid DockPanel.Dock="Bottom" Name="problemsGrid" Margin="0,4,0,0"
|
||||
IsReadOnly="True"
|
||||
ItemsSource="{Binding FormattedProblems}"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"
|
||||
SnapsToDevicePixels="True"
|
||||
GridLinesVisibility="Vertical"
|
||||
VerticalGridLinesBrush="#FF7F7F7F"
|
||||
AutoGenerateColumns="False"
|
||||
HeadersVisibility="Column"
|
||||
CanUserReorderColumns="False"
|
||||
SelectionMode="Single">
|
||||
<!-- should probably add ellipsis: https://stackoverflow.com/a/12880111/294248 -->
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Severity" Width="64" Binding="{Binding Severity}"/>
|
||||
<DataGridTextColumn Header="Offset" Width="53" Binding="{Binding Offset}"/>
|
||||
<DataGridTextColumn Header="Type" Width="119" Binding="{Binding Type}"/>
|
||||
<DataGridTextColumn Header="Context" Width="119" Binding="{Binding Context}"/>
|
||||
<DataGridTextColumn Header="Resolution" Width="119" Binding="{Binding Resolution}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</DockPanel>
|
||||
</Window>
|
127
SourceGen/Tools/WpfGui/ProblemListViewer.xaml.cs
Normal file
127
SourceGen/Tools/WpfGui/ProblemListViewer.xaml.cs
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2019 faddenSoft
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
|
||||
namespace SourceGen.Tools.WpfGui {
|
||||
/// <summary>
|
||||
/// Floating problem list window.
|
||||
/// </summary>
|
||||
public partial class ProblemListViewer : Window, INotifyPropertyChanged {
|
||||
public class ProblemsListItem {
|
||||
public string Severity { get; private set; }
|
||||
public string Offset { get; private set; }
|
||||
public string Type { get; private set; }
|
||||
public string Context { get; private set; }
|
||||
public string Resolution { get; private set; }
|
||||
|
||||
public ProblemsListItem(string severity, string offset, string type, string context,
|
||||
string resolution) {
|
||||
Severity = severity;
|
||||
Offset = offset;
|
||||
Type = type;
|
||||
Context = context;
|
||||
Resolution = resolution;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reference to project.
|
||||
/// </summary>
|
||||
private DisasmProject mProject;
|
||||
|
||||
/// <summary>
|
||||
/// Text formatter.
|
||||
/// </summary>
|
||||
private Asm65.Formatter mFormatter;
|
||||
|
||||
/// <summary>
|
||||
/// ItemsSource for DataGrid.
|
||||
/// </summary>
|
||||
public ObservableCollection<ProblemsListItem> FormattedProblems { get; private set; } =
|
||||
new ObservableCollection<ProblemsListItem>();
|
||||
|
||||
// INotifyPropertyChanged implementation
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
|
||||
public ProblemListViewer(Window owner, DisasmProject project, Asm65.Formatter formatter) {
|
||||
InitializeComponent();
|
||||
Owner = owner;
|
||||
DataContext = this;
|
||||
|
||||
mProject = project;
|
||||
mFormatter = formatter;
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
Update();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the contents of the DataGrid to the current values in mProject.Problems.
|
||||
/// </summary>
|
||||
public void Update() {
|
||||
FormattedProblems.Clear();
|
||||
|
||||
foreach (ProblemList.ProblemEntry entry in mProject.Problems) {
|
||||
ProblemsListItem newItem = FormatEntry(entry);
|
||||
FormattedProblems.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
private ProblemsListItem FormatEntry(ProblemList.ProblemEntry entry) {
|
||||
string severity = entry.Severity.ToString(); // enum
|
||||
string offset = mFormatter.FormatOffset24(entry.Offset);
|
||||
|
||||
string problem;
|
||||
switch (entry.Problem) {
|
||||
case ProblemList.ProblemEntry.ProblemType.HiddenLabel:
|
||||
problem = (string)FindResource("str_HiddenLabel");
|
||||
break;
|
||||
case ProblemList.ProblemEntry.ProblemType.UnresolvedWeakRef:
|
||||
problem = (string)FindResource("str_UnresolvedWeakRef");
|
||||
break;
|
||||
default:
|
||||
problem = "???";
|
||||
break;
|
||||
}
|
||||
|
||||
string context = entry.Context.ToString();
|
||||
|
||||
string resolution;
|
||||
switch (entry.Resolution) {
|
||||
case ProblemList.ProblemEntry.ProblemResolution.LabelIgnored:
|
||||
resolution = (string)FindResource("str_LabelIgnored");
|
||||
break;
|
||||
case ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored:
|
||||
resolution = (string)FindResource("str_FormatDescriptorIgnored");
|
||||
break;
|
||||
default:
|
||||
resolution = "???";
|
||||
break;
|
||||
}
|
||||
|
||||
return new ProblemsListItem(severity, offset, problem, context, resolution);
|
||||
}
|
||||
}
|
||||
}
|
@ -164,6 +164,7 @@ limitations under the License.
|
||||
<RoutedUICommand x:Key="Debug_ExtensionScriptInfoCmd" Text="Extension Script Info..."/>
|
||||
<RoutedUICommand x:Key="Debug_ShowAnalysisTimersCmd" Text="Show Analysis Timers"/>
|
||||
<RoutedUICommand x:Key="Debug_ShowAnalyzerOutputCmd" Text="Show Analyzer Output"/>
|
||||
<RoutedUICommand x:Key="Debug_ShowProblemListCmd" Text="Show Problem List Viewer"/>
|
||||
<RoutedUICommand x:Key="Debug_ShowUndoRedoHistoryCmd" Text="Show Undo/Redo History"/>
|
||||
<RoutedUICommand x:Key="Debug_SourceGenerationTestsCmd" Text="Source Generation Tests..."/>
|
||||
<RoutedUICommand x:Key="Debug_ToggleCommentRulersCmd" Text="Show Comment Rulers"/>
|
||||
@ -279,6 +280,8 @@ limitations under the License.
|
||||
CanExecute="IsProjectOpen" Executed="Debug_ShowAnalysisTimersCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource Debug_ShowAnalyzerOutputCmd}"
|
||||
CanExecute="IsProjectOpen" Executed="Debug_ShowAnalyzerOutputCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource Debug_ShowProblemListCmd}"
|
||||
CanExecute="IsProjectOpen" Executed="Debug_ShowProblemListCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource Debug_ShowUndoRedoHistoryCmd}"
|
||||
CanExecute="IsProjectOpen" Executed="Debug_ShowUndoRedoHistoryCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource Debug_ToggleCommentRulersCmd}"
|
||||
@ -361,6 +364,8 @@ limitations under the License.
|
||||
<MenuItem Header="_DEBUG" Name="DebugMenu" SubmenuOpened="DebugMenu_SubmenuOpened"
|
||||
Visibility="{Binding ShowDebugMenu, Converter={StaticResource BoolToVis}}">
|
||||
<MenuItem Command="Refresh" Header="Re-analyze"/>
|
||||
<MenuItem Name="debugProblemListMenuItem"
|
||||
Command="{StaticResource Debug_ShowProblemListCmd}" IsCheckable="True"/>
|
||||
<MenuItem Name ="debugUndoRedoHistoryMenuItem"
|
||||
Command="{StaticResource Debug_ShowUndoRedoHistoryCmd}" IsCheckable="True"/>
|
||||
<MenuItem Name="debugAnalyzerOutputMenuItem"
|
||||
|
@ -1278,6 +1278,10 @@ namespace SourceGen.WpfGui {
|
||||
mMainCtrl.Debug_ShowAnalyzerOutput();
|
||||
}
|
||||
|
||||
private void Debug_ShowProblemListCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
|
||||
mMainCtrl.Debug_ShowProblemList();
|
||||
}
|
||||
|
||||
private void Debug_ShowUndoRedoHistoryCmd_Executed(object sender,
|
||||
ExecutedRoutedEventArgs e) {
|
||||
mMainCtrl.Debug_ShowUndoRedoHistory();
|
||||
@ -1384,6 +1388,7 @@ namespace SourceGen.WpfGui {
|
||||
debugKeepAliveHackMenuItem.IsChecked = Sandbox.ScriptManager.UseKeepAliveHack;
|
||||
debugAnalysisTimersMenuItem.IsChecked = mMainCtrl.IsDebugAnalysisTimersOpen;
|
||||
debugAnalyzerOutputMenuItem.IsChecked = mMainCtrl.IsDebugAnalyzerOutputOpen;
|
||||
debugProblemListMenuItem.IsChecked = mMainCtrl.IsDebugProblemListOpen;
|
||||
debugUndoRedoHistoryMenuItem.IsChecked = mMainCtrl.IsDebugUndoRedoHistoryOpen;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user