From 61e00711428a68444d40008a84b95664c432e262 Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Tue, 13 May 2025 22:02:02 +0200 Subject: [PATCH] =?UTF-8?q?=C3=A2dd=20new=20mago=20options=20debug=20helpe?= =?UTF-8?q?r=20try=20full=20analysis=20after=20edit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES | 13 ++ VERSION | 2 +- doc/CompileCommands.dd | 4 +- vdc/dmdserver/dmd | 2 +- vdc/dmdserver/dmdlocation.d | 304 ++++++++++++++++++------------------ vdc/dmdserver/dmdserver.d | 4 + vdc/dmdserver/semanalysis.d | 98 ++++++++++-- visuald/intellisense.d | 5 +- visuald/propertypage.d | 27 +++- visuald_vs10.sln | 1 - 10 files changed, 278 insertions(+), 182 deletions(-) diff --git a/CHANGES b/CHANGES index c7850449..88b25d5c 100644 --- a/CHANGES +++ b/CHANGES @@ -1421,3 +1421,16 @@ Version history * mago: improved stability when displaying arrays from invalid memory address * dmdserver: fixed a couple of assertions causing the server to restart * dmdserver: replaced new location storage to avoid leaking memory + +2025-05-04 version 1.4.1-beta3 + * mago: + - the option "Expand strings to show array of characters" had no effect + - the call stack now displays D expression if "Parameter values" is enabled + - issue #253: mago: with option "Shorten type names and function names in call stack" + module names are removed when displayed + - issue #305: mago: with option "Call property methods implicitly in expression evaluation" + methods annotated with @property and without arguments are evaluated without parentheses + - format options could be erratic when execution function for expression evaluation + - fixed selecting the zero-argument method in case multiple overloads + - added format specifiers 'd' (decimmal), 'x' (hex), '@' (evaluate function automatically) + - added a couple of caches for better responsiveness diff --git a/VERSION b/VERSION index 39e81088..91272250 100644 --- a/VERSION +++ b/VERSION @@ -2,4 +2,4 @@ #define VERSION_MINOR 4 #define VERSION_REVISION 1 #define VERSION_BETA -beta -#define VERSION_BUILD 2 +#define VERSION_BUILD 3 diff --git a/doc/CompileCommands.dd b/doc/CompileCommands.dd index 9f0302d7..cc50d27d 100644 --- a/doc/CompileCommands.dd +++ b/doc/CompileCommands.dd @@ -78,7 +78,7 @@ $(H3 DMD/Win32) $(PRE obj2asm -x "$(DOLLAR)(InputFile)" >"$(DOLLAR)(TargetPath)") -This assumes obj2asm can be found in through PATH. If this is not the case, please add +This assumes obj2asm can be found through PATH. If this is not the case, please add the full path to it. The same replacement macros can be used as in the project configurations. @@ -110,7 +110,7 @@ use LLVM tools for other architectures, you'll have to change the default settin $(PRE llvm-objdump -disassemble -x86-asm-syntax=intel -no-show-raw-insn "$(DOLLAR)(InputPath)" >"$(DOLLAR)(TargetPath)" ) -You'll have to add the path the LLVM tools to the "Executable Paths" or to the +You'll have to add the path to the LLVM tools to the "Executable Paths" or to the llvm-objdump command. $(H3 GDC) diff --git a/vdc/dmdserver/dmd b/vdc/dmdserver/dmd index 1ce5bf17..82d33907 160000 --- a/vdc/dmdserver/dmd +++ b/vdc/dmdserver/dmd @@ -1 +1 @@ -Subproject commit 1ce5bf171d70dce5312e001e5276cbdc359ac201 +Subproject commit 82d33907b3390915ead9b18c896a179313b4365e diff --git a/vdc/dmdserver/dmdlocation.d b/vdc/dmdserver/dmdlocation.d index f6b6b39b..437643bb 100644 --- a/vdc/dmdserver/dmdlocation.d +++ b/vdc/dmdserver/dmdlocation.d @@ -14,9 +14,9 @@ import dmd.root.stringtable; /// How code locations are formatted for diagnostic reporting enum MessageStyle : ubyte { - digitalmars, /// filename.d(line): message - gnu, /// filename.d:line: message, see https://www.gnu.org/prep/standards/html_node/Errors.html - sarif /// JSON SARIF output, see https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html + digitalmars, /// filename.d(line): message + gnu, /// filename.d:line: message, see https://www.gnu.org/prep/standards/html_node/Errors.html + sarif /// JSON SARIF output, see https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html } /** A source code location @@ -26,90 +26,90 @@ debug info etc. */ struct Loc { - private ulong data = 0; // bitfield of file, line and column + private ulong data = 0; // bitfield of file, line and column - static immutable Loc initial; /// use for default initialization of Loc's + static immutable Loc initial; /// use for default initialization of Loc's - extern (C++) __gshared bool showColumns; - extern (C++) __gshared MessageStyle messageStyle; + extern (C++) __gshared bool showColumns; + extern (C++) __gshared MessageStyle messageStyle; nothrow: - /******************************* + /******************************* * Configure how display is done * Params: * showColumns = when to display columns * messageStyle = digitalmars or gnu style messages */ - extern (C++) static void set(bool showColumns, MessageStyle messageStyle) - { - this.showColumns = showColumns; - this.messageStyle = messageStyle; - } - - /// Returns: a Loc that simply holds a filename, with no line / column info - extern (C++) static Loc singleFilename(const char* filename) - { - return singleFilename(filename.toDString); - } - - /// Returns: a Loc that simply holds a filename, with no line / column info - static Loc singleFilename(const(char)[] filename) - { + extern (C++) static void set(bool showColumns, MessageStyle messageStyle) + { + this.showColumns = showColumns; + this.messageStyle = messageStyle; + } + + /// Returns: a Loc that simply holds a filename, with no line / column info + extern (C++) static Loc singleFilename(const char* filename) + { + return singleFilename(filename.toDString); + } + + /// Returns: a Loc that simply holds a filename, with no line / column info + static Loc singleFilename(const(char)[] filename) + { ulong fileIndex = toLocFileIndex(filename); - return Loc((fileIndex << 48) | 1); // default to charnum 1 - } - - /// utf8 code unit index relative to start of line, starting from 1 - extern (C++) uint charnum() const @nogc @safe - { - return data & 0xffff; - } - - /// line number, starting from 1 - extern (C++) uint linnum() const @nogc @trusted - { - return (data >> 16) & 0xffff_ffff; - } - - /*** + return Loc((fileIndex << 48) | 1); // default to charnum 1 + } + + /// utf8 code unit index relative to start of line, starting from 1 + extern (D) uint charnum() const @nogc @safe @property + { + return data & 0xffff; + } + + /// line number, starting from 1 + extern (D) uint linnum() const @nogc @trusted @property + { + return (data >> 16) & 0xffff_ffff; + } + + /*** * Returns: filename for this location, null if none */ - extern (C++) const(char)* filename() const @nogc - { - return locFileName[data >> 48].ptr; - } - - /// Advance this location to the first column of the next line - void nextLine() @safe pure @nogc - { - data = (data & ~0xffffL) + 0x10001; - } - - bool isValid() const pure @safe - { - return data != 0; - } + extern (D) const(char)* filename() const @nogc @property + { + return locFileName[data >> 48].ptr; + } + + /// Advance this location to the first column of the next line + void nextLine() @safe pure @nogc + { + data = (data & ~0xffffL) + 0x10001; + } + + bool isValid() const pure @safe @property + { + return data != 0; + } extern (C++) const(char)* toChars(bool showColumns = Loc.showColumns, - MessageStyle messageStyle = Loc.messageStyle) const nothrow + MessageStyle messageStyle = Loc.messageStyle) const nothrow { return SourceLoc(this).toChars(showColumns, messageStyle); } - /** + /** * Checks for equivalence by comparing the filename contents (not the pointer) and character location. * * Note: * - Uses case-insensitive comparison on Windows * - Ignores `charnum` if `Columns` is false. */ - extern (C++) bool equals(Loc loc) const - { + extern (C++) bool equals(Loc loc) const + { auto this_data = showColumns ? data : data & ~0xffff; auto loc_data = showColumns ? loc.data : loc.data & ~0xffff; return this_data == loc_data; - } + } - /** + /** * `opEquals()` / `toHash()` for AA key usage * * Compare filename contents (case-sensitively on Windows too), not @@ -117,16 +117,16 @@ nothrow: * may lead to multiple equivalent filenames (`foo.d-mixin-`), * e.g., for test/runnable/test18880.d. */ - extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc - { - return this.data == loc.data; - } - - /// ditto - extern (D) size_t toHash() const @trusted nothrow - { - return hashOf(this.data); - } + extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc + { + return this.data == loc.data; + } + + /// ditto + extern (D) size_t toHash() const @trusted nothrow + { + return hashOf(this.data); + } } /** @@ -141,37 +141,37 @@ nothrow: void writeSourceLoc(ref OutBuffer buf, SourceLoc loc, bool showColumns, MessageStyle messageStyle) nothrow { auto filename = loc.filename; - if (filename is null) - return; - buf.writestring(loc.filename); - if (loc.linnum == 0) - return; - - final switch (messageStyle) - { - case MessageStyle.digitalmars: - buf.writeByte('('); - buf.print(loc.linnum); - if (showColumns && loc.charnum) - { - buf.writeByte(','); - buf.print(loc.charnum); - } - buf.writeByte(')'); - break; - case MessageStyle.gnu: // https://www.gnu.org/prep/standards/html_node/Errors.html - buf.writeByte(':'); - buf.print(loc.linnum); - if (showColumns && loc.charnum) - { - buf.writeByte(':'); - buf.print(loc.charnum); - } - break; - case MessageStyle.sarif: // https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html - // No formatting needed here for SARIF - break; - } + if (filename is null) + return; + buf.writestring(loc.filename); + if (loc.linnum == 0) + return; + + final switch (messageStyle) + { + case MessageStyle.digitalmars: + buf.writeByte('('); + buf.print(loc.linnum); + if (showColumns && loc.charnum) + { + buf.writeByte(','); + buf.print(loc.charnum); + } + buf.writeByte(')'); + break; + case MessageStyle.gnu: // https://www.gnu.org/prep/standards/html_node/Errors.html + buf.writeByte(':'); + buf.print(loc.linnum); + if (showColumns && loc.charnum) + { + buf.writeByte(':'); + buf.print(loc.charnum); + } + break; + case MessageStyle.sarif: // https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html + // No formatting needed here for SARIF + break; + } } // Global string table to make file names comparable via `is` @@ -186,12 +186,12 @@ size_t toLocFileIndex(const(char)[] fname) nothrow @trusted locFileName ~= null; locFileNameIndex.insert("", 0); // for loc.initial } - if (auto p = locFileNameIndex.lookup(fname)) - return p.value; + if (auto p = locFileNameIndex.lookup(fname)) + return p.value; size_t idx = locFileName.length; locFileName ~= fname.xarraydup; - locFileNameIndex.insert(fname, idx); - return idx; + locFileNameIndex.insert(fname, idx); + return idx; } const(char)[] toLocFilename(const(char)[] fname) nothrow @@ -201,7 +201,7 @@ const(char)[] toLocFilename(const(char)[] fname) nothrow const(char)[] toLocFilename(const(char)* fname) nothrow { - return toLocFilename(fname.toDString); + return toLocFilename(fname.toDString); } void location_init() @@ -216,18 +216,18 @@ struct SourceLoc //alias loc this; - // aliases for backwards compatibility - alias linnum = loc.linnum; - alias line = loc.linnum; - alias charnum = loc.charnum; - alias column = loc.charnum; + // aliases for backwards compatibility + alias linnum = loc.linnum; + alias line = loc.linnum; + alias charnum = loc.charnum; + alias column = loc.charnum; this(Loc oloc) nothrow @safe { loc = oloc; } - this(const(char)[] filename, uint line, uint column, + this(const(char)[] filename, uint line, uint column, uint fileOffset = 0, const(char)[] fileContent = null) nothrow @safe { if (column > 0xffff) @@ -239,7 +239,7 @@ struct SourceLoc void filename(const(char)[] fname) nothrow { ulong fileIndex = toLocFileIndex(fname); - loc.data = (loc.data & ((1L << 48) - 1)) | (fileIndex << 48); + loc.data = (loc.data & ((1L << 48) - 1)) | (fileIndex << 48); } const(char)[] filename() const nothrow @nogc { @@ -262,13 +262,13 @@ struct SourceLoc return 0; // only for error messages with context } - bool opEquals(SourceLoc other) const nothrow - { - return loc == other.loc; - } + bool opEquals(SourceLoc other) const nothrow + { + return loc == other.loc; + } extern (C++) const(char)* toChars(bool showColumns = Loc.showColumns, - MessageStyle messageStyle = Loc.messageStyle) const nothrow + MessageStyle messageStyle = Loc.messageStyle) const nothrow { OutBuffer buf; writeSourceLoc(buf, this, showColumns, messageStyle); @@ -283,7 +283,7 @@ struct BaseLoc uint startLine; uint startOffset; uint lastLineOffset; - BaseLoc[] substitutions; /// Substitutions from #line / #file directives + BaseLoc[] substitutions; /// Substitutions from #line / #file directives alias loc this; @@ -294,60 +294,60 @@ nothrow: this.startLine = startLine; } - Loc getLoc(uint offset) @nogc + Loc getLoc(uint offset) @nogc { Loc nloc; nloc.data = loc.loc.data + offset - lastLineOffset; // add char offset return nloc; } - /** + /** * Register a new file/line mapping from #file and #line directives * Params: * offset = byte offset in the source file at which the substitution starts * filename = new filename from this point on (null = unchanged) * line = line number from this point on */ - void addSubstitution(uint offset, const(char)* filename, uint line) @system - { - auto fname = filename.toDString; - if (substitutions.length == 0) - substitutions ~= BaseLoc(this.filename, 0); - - if (fname.length == 0) - fname = substitutions[$ - 1].filename; - substitutions ~= BaseLoc(fname, startLine + line); // cast(int) (line - lines.length + startLine - 2)); - } - - /// Returns: `loc` modified by substitutions from #file / #line directives - SourceLoc substitute(SourceLoc loc) - { - if (substitutions.length == 0) - return loc; - - const i = 0; // todo: getSubstitutionIndex(loc.fileOffset); - if (substitutions[i].filename.length > 0) - loc.filename = substitutions[i].filename; - return SourceLoc(loc.filename, loc.line + substitutions[i].startLine, loc.column); - } - void newLine(uint offset) @safe - { + void addSubstitution(uint offset, const(char)* filename, uint line) @system + { + auto fname = filename.toDString; + if (substitutions.length == 0) + substitutions ~= BaseLoc(this.filename, 0); + + if (fname.length == 0) + fname = substitutions[$ - 1].filename; + substitutions ~= BaseLoc(fname, startLine + line); // cast(int) (line - lines.length + startLine - 2)); + } + + /// Returns: `loc` modified by substitutions from #file / #line directives + SourceLoc substitute(SourceLoc loc) + { + if (substitutions.length == 0) + return loc; + + const i = 0; // todo: getSubstitutionIndex(loc.fileOffset); + if (substitutions[i].filename.length > 0) + loc.filename = substitutions[i].filename; + return SourceLoc(loc.filename, loc.line + substitutions[i].startLine, loc.column); + } + void newLine(uint offset) @safe + { lastLineOffset = offset; - loc.loc.nextLine(); - } + loc.loc.nextLine(); + } } BaseLoc* newBaseLoc(const(char)* filename, const(char)[] fileContent) nothrow { - return new BaseLoc(filename.toDString, 0); + return new BaseLoc(filename.toDString, 0); } // for a language server, lowered expression should not reuse the original source location // as internal names might get exposed to the user ref const(Loc) loweredLoc(return ref const Loc loc) { - version(LanguageServer) - return Loc.initial; - else - return loc; + version(LanguageServer) + return Loc.initial; + else + return loc; } diff --git a/vdc/dmdserver/dmdserver.d b/vdc/dmdserver/dmdserver.d index e1df66d1..011b48d5 100644 --- a/vdc/dmdserver/dmdserver.d +++ b/vdc/dmdserver/dmdserver.d @@ -322,6 +322,10 @@ class DMDServer : ComObject, IVDServer { try { + import core.exception; + debug assertHandler(function(string file, ulong line, string msg){ + throw new AssertError(msg, file, line); + }); dg(); } catch(Exception e) diff --git a/vdc/dmdserver/semanalysis.d b/vdc/dmdserver/semanalysis.d index cbb99e19..8da4051f 100644 --- a/vdc/dmdserver/semanalysis.d +++ b/vdc/dmdserver/semanalysis.d @@ -29,6 +29,8 @@ import std.algorithm; import std.path; import std.conv; +// version = ReinitSemanticAll; + // debug version = traceGC; __gshared AnalysisContext lastContext; @@ -200,38 +202,64 @@ Module analyzeModule(Module parsedModule, const ref Options opts) Module.loadModuleHandler = &ctxt.loadModuleHandler; + void semantic(Module m) + { + m.dsymbolSemantic(null); + Module.runDeferredSemantic(); + m.semantic2(null); + Module.runDeferredSemantic2(); + m.semantic3(null); + Module.runDeferredSemantic3(); + } + if (needsReinit) { reinitSemanticModules(); - // analyze other modules lazily - ctxt.modules[rootModuleIndex].createSemanticModule(true); + version(ReinitSemanticAll) + { + Module.rootModule = ctxt.modules[rootModuleIndex].semanticModule; + + foreach(ref mi; ctxt.modules) + mi.createSemanticModule(true); - version(none) // do this lazily foreach(ref mi; ctxt.modules) - { mi.semanticModule.importAll(null); - } + foreach(ref mi; ctxt.modules) + semantic(mi.semanticModule); + + return Module.rootModule; + } + else + { + // analyze other modules lazily + ctxt.modules[rootModuleIndex].createSemanticModule(true); + + version(none) // do this lazily + foreach(ref mi; ctxt.modules) + { + mi.semanticModule.importAll(null); + } + } } - Module.rootModule = ctxt.modules[rootModuleIndex].semanticModule; - Module.rootModule.importAll(null); - Module.rootModule.dsymbolSemantic(null); - Module.runDeferredSemantic(); - Module.rootModule.semantic2(null); - Module.runDeferredSemantic2(); - Module.rootModule.semantic3(null); - Module.runDeferredSemantic3(); + auto mi = ctxt.modules[rootModuleIndex]; + Module.rootModule = mi.semanticModule; + mi.semanticModule.importAll(null); + semantic(mi.semanticModule); return Module.rootModule; } debug { - auto __debugOverview(Identifier id) => id ? id.toString : null; - auto __debugOverview(Dsymbol s) => s && s.ident ? s.ident.toString : null; - auto __debugOverview(ref const Loc loc) => loc.toChars(); - auto __debugExpanded(ref const Loc loc) => loc.toChars(); + auto __debugOverview(Identifier id) => id ? id.toString : null; + auto __debugOverview(Dsymbol s) => s && s.ident ? s.ident.toString : null; + auto __debugOverview(ref const Loc loc) => loc.toChars(); + auto __debugExpanded(ref const Loc loc) => { + struct S { const(char)* filename; int line; } + return S(loc.filename, loc.linnum); + }(); } //////////////////////////////////////////////////////////////// @@ -1967,6 +1995,41 @@ void do_unittests() } }; m = checkErrors(source, ""); + + /////////////////////////////////////////////////////////// + // check array initializer + auto tmpl_source = q{ + T func(T)(T x) + { + return x; // Line 4 + } + T func2(T)(T x) + { + return x; // Line 8 + } + }; + filename = "source.d"; + auto tmpl_m = checkErrors(tmpl_source, ""); + source = q{ + import source; + int foo() + { + return func(3); + } + }; + filename = "invoke.d"; + m = checkErrors(source, ""); + + checkTip(tmpl_m, 4, 11, "(parameter) `int x`"); + filename = "source.d"; + + version(ReinitSemanticAll) + { + // parsing the template source file again forgets all instantiations + tmpl_m = checkErrors(tmpl_source, ""); + checkTip(tmpl_m, 4, 11, "(parameter) `int x`"); + //checkTip(tmpl_m, 8, 11, "(parameter) `T x`"); + } } unittest @@ -2202,6 +2265,7 @@ void test_ana_dmd() void test_std() { + filename = "re.d"; bool dump = false; string source = q{ import std; diff --git a/visuald/intellisense.d b/visuald/intellisense.d index bb014d37..0b689e4c 100644 --- a/visuald/intellisense.d +++ b/visuald/intellisense.d @@ -593,9 +593,10 @@ struct ParameterInfo } int braceLevel = 1; - pos--; string ident; - int endpos = lineInfo[pos].EndIndex; + int endpos = pos <= 0 ? lineInfo[0].StartIndex : lineInfo[pos-1].EndIndex; + if (pos > 0) + pos--; void prependParam() { diff --git a/visuald/propertypage.d b/visuald/propertypage.d index d47014fe..c92f44b6 100644 --- a/visuald/propertypage.d +++ b/visuald/propertypage.d @@ -3118,8 +3118,10 @@ struct MagoOptions bool hideReferencePointers; bool removeLeadingHexZeroes; bool recombineTuples; + bool shortenTypeNames; bool callDebuggerFunctions; bool callDebuggerRanges; + bool callPropertyMethods; bool callDebuggerUseMagoGC; bool showDArrayLengthInType; uint maxArrayElements; @@ -3135,8 +3137,10 @@ struct MagoOptions keyMago.Set("hideReferencePointers", hideReferencePointers); keyMago.Set("removeLeadingHexZeroes", removeLeadingHexZeroes); keyMago.Set("recombineTuples", recombineTuples); + keyMago.Set("shortenTypeNames", shortenTypeNames); keyMago.Set("callDebuggerFunctions", callDebuggerFunctions); keyMago.Set("callDebuggerRanges", callDebuggerRanges); + keyMago.Set("callPropertyMethods", callPropertyMethods); keyMago.Set("callDebuggerUseMagoGC", callDebuggerUseMagoGC); keyMago.Set("showDArrayLengthInType", showDArrayLengthInType); keyMago.Set("maxArrayElements", maxArrayElements); @@ -3154,8 +3158,10 @@ struct MagoOptions hideReferencePointers = (keyMago.GetDWORD("hideReferencePointers", 1) != 0); removeLeadingHexZeroes = (keyMago.GetDWORD("removeLeadingHexZeroes", 0) != 0); recombineTuples = (keyMago.GetDWORD("recombineTuples", 1) != 0); + shortenTypeNames = (keyMago.GetDWORD("shortenTypeNames", 1) != 0); callDebuggerFunctions = (keyMago.GetDWORD("callDebuggerFunctions", 1) != 0); callDebuggerRanges = (keyMago.GetDWORD("callDebuggerRanges", 0) != 0); + callPropertyMethods = (keyMago.GetDWORD("callPropertyMethods", 0) != 0); callDebuggerUseMagoGC = (keyMago.GetDWORD("callDebuggerUseMagoGC", 1) != 0); showDArrayLengthInType = (keyMago.GetDWORD("showDArrayLengthInType", 0) != 0); maxArrayElements = keyMago.GetDWORD("maxArrayElements", 1000); @@ -3171,23 +3177,26 @@ class MagoPropertyPage : ResizablePropertyPage override void CreateControls() { - AddLabel("Changes to these settings only apply to new debugging sessions"); + // AddLabel("Changes to these settings apply with the next execution step"); AddControl("", mHideInternalNames = new CheckBox(mCanvas, "Hide compiler generated symbols")); AddControl("", mShowStaticsInAggr = new CheckBox(mCanvas, "Show static fields in structs and classes")); AddControl("", mShowVTable = new CheckBox(mCanvas, "Show virtual function table as field of classes")); AddControl("", mFlatClassFields = new CheckBox(mCanvas, "Show base class fields as direct fields")); AddControl("", mRecombineTuples = new CheckBox(mCanvas, "Rebuild tuples from compiler generated fields")); + AddControl("", mShortenTypeNames = new CheckBox(mCanvas, "Shorten type names and function names in call stack")); AddControl("", mExpandableStrings = new CheckBox(mCanvas, "Expand strings to show array of characters")); AddControl("", mHideRefPointers = new CheckBox(mCanvas, "Hide pointers for class references and slices")); - AddControl("", mCallDebuggerFuncs = new CheckBox(mCanvas, "Call struct/class methods __debug[Overview|Expanded|StringView]")); - AddControl("", mCallDebuggerRange = new CheckBox(mCanvas, "Call range methods to show elements in overview/expansion")); - AddControl("", mCallDebugSwitchGC = new CheckBox(mCanvas, "Switch GC while executing debugger functions")); - AddControl("", mShowLengthInType = new CheckBox(mCanvas, "Show length of dynamic array in type column")); AddControl("", mRemoveHexZeroes = new CheckBox(mCanvas, "Remove leading zeroes from hex values")); + AddControl("", mShowLengthInType = new CheckBox(mCanvas, "Show length of dynamic array in type column")); auto saveWidth = kLabelWidth; - kLabelWidth = kPageWidth * 4 / 5; + kLabelWidth = kPageWidth * 3 / 4; AddControl("Limit array elements shown in expansions to", mMaxArrayElements = new Text(mCanvas)); kLabelWidth = saveWidth; + AddTitleLine("Function Execution"); + AddControl("", mCallDebuggerFuncs = new CheckBox(mCanvas, "Call struct/class methods __debug[Overview|Expanded|StringView]")); + AddControl("", mCallDebuggerRange = new CheckBox(mCanvas, "Call range methods to show elements in overview/expansion")); + AddControl("", mCallPropertyMethods = new CheckBox(mCanvas, "Call property methods implicitly in expression evaluation")); + AddControl("", mCallDebugSwitchGC = new CheckBox(mCanvas, "Switch GC while executing debugger functions")); } override void UpdateDirty(bool bDirty) @@ -3238,8 +3247,10 @@ class MagoPropertyPage : ResizablePropertyPage mHideRefPointers.setChecked(mOptions.hideReferencePointers); mRemoveHexZeroes.setChecked(mOptions.removeLeadingHexZeroes); mRecombineTuples.setChecked(mOptions.recombineTuples); + mShortenTypeNames.setChecked(mOptions.shortenTypeNames); mCallDebuggerFuncs.setChecked(mOptions.callDebuggerFunctions); mCallDebuggerRange.setChecked(mOptions.callDebuggerRanges); + mCallPropertyMethods.setChecked(mOptions.callPropertyMethods); mCallDebugSwitchGC.setChecked(mOptions.callDebuggerUseMagoGC); mShowLengthInType.setChecked(mOptions.showDArrayLengthInType); mMaxArrayElements.setText(to!string(mOptions.maxArrayElements)); @@ -3256,8 +3267,10 @@ class MagoPropertyPage : ResizablePropertyPage changes += changeOption(mHideRefPointers.isChecked(), opts.hideReferencePointers, refopts.hideReferencePointers); changes += changeOption(mRemoveHexZeroes.isChecked(), opts.removeLeadingHexZeroes, refopts.removeLeadingHexZeroes); changes += changeOption(mRecombineTuples.isChecked(), opts.recombineTuples, refopts.recombineTuples); + changes += changeOption(mShortenTypeNames.isChecked(), opts.shortenTypeNames, refopts.shortenTypeNames); changes += changeOption(mCallDebuggerFuncs.isChecked(), opts.callDebuggerFunctions, refopts.callDebuggerFunctions); changes += changeOption(mCallDebuggerRange.isChecked(), opts.callDebuggerRanges, refopts.callDebuggerRanges); + changes += changeOption(mCallPropertyMethods.isChecked(), opts.callPropertyMethods, refopts.callPropertyMethods); changes += changeOption(mCallDebugSwitchGC.isChecked(), opts.callDebuggerUseMagoGC, refopts.callDebuggerUseMagoGC); changes += changeOption(mShowLengthInType.isChecked(), opts.showDArrayLengthInType, refopts.showDArrayLengthInType); @@ -3277,8 +3290,10 @@ class MagoPropertyPage : ResizablePropertyPage CheckBox mHideRefPointers; CheckBox mRemoveHexZeroes; CheckBox mRecombineTuples; + CheckBox mShortenTypeNames; CheckBox mCallDebuggerFuncs; CheckBox mCallDebuggerRange; + CheckBox mCallPropertyMethods; CheckBox mCallDebugSwitchGC; CheckBox mShowLengthInType; Text mMaxArrayElements; diff --git a/visuald_vs10.sln b/visuald_vs10.sln index 675c5b73..e5e7f6b3 100644 --- a/visuald_vs10.sln +++ b/visuald_vs10.sln @@ -79,7 +79,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{36148913-8F4 ProjectSection(SolutionItems) = preProject doc\BrowseInfo.dd = doc\BrowseInfo.dd doc\BuildFromSource.dd = doc\BuildFromSource.dd - doc\build_doc.bat = doc\build_doc.bat doc\CompileCommands.dd = doc\CompileCommands.dd doc\Coverage.dd = doc\Coverage.dd doc\CppConversion.dd = doc\CppConversion.dd