diff --git a/CHANGES b/CHANGES index 778691e9..1a0ea058 100644 --- a/CHANGES +++ b/CHANGES @@ -1242,7 +1242,7 @@ Version history - vcxproj: do not check referenced projects if the project itself already needs phobos to be linked - vcxproj: only print the filename in the "Compiling" message, not the path -unreleased version 1.0.0 +2020-07-04 version 1.0.0 * projects: - trailing \ now removed from $(WindowsSDKVersion)/$(UCRTVersion) for more consistency between autodetected version and as read from the environment @@ -1267,3 +1267,13 @@ unreleased version 1.0.0 - some performance improvements by caching some data while the debuggee is stopped * installer: - full installer now bundled with dmd 2.092.1 and LDC 1.22.0 + +unreleased version 1.0.1 + * projects: + - bugzilla 21024: VS2017/2019 new project: fixed unrelated files listed in New Project Dialog + - bugzilla 21028: project templates not visible when VS started as standard/restricted user + * dmdserver: + - updated to dmd 2.093 + - fixed showing documentation for template functions + * mago debugger expression evaluator: + - fixed wrong values displayed eventually when switching stack frames diff --git a/VERSION b/VERSION index b18fc173..9b4776e3 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 0 -#define VERSION_REVISION 0 -#define VERSION_BETA -#define VERSION_BUILD 0 +#define VERSION_REVISION 1 +#define VERSION_BETA -beta +#define VERSION_BUILD 1 diff --git a/doc/Debugging.dd b/doc/Debugging.dd index 7f630fbd..25d62033 100644 --- a/doc/Debugging.dd +++ b/doc/Debugging.dd @@ -88,8 +88,7 @@ $(P Using Mago's expression evaluator allowed to implement this for D pretty eas $(P The debugger engine needs to detect the source language of the code location. This information is added to the debug information starting with dmd 2.072 when compiled for COFF object files (-m64 or -m32mscoff) with -g, but not with --gc, i.e. you should select debug info for Mago even when using the VS debug engine.) Unfortunately, -LDC does not yet emit this source language information. +-gc, i.e. you should select debug info for Mago even when using the VS debug engine.) $(H3 Recommendation for VS 2015 or later) @@ -121,5 +120,48 @@ $(IMG_CENTER images/d_exceptions.png) Please note that these specific exception settings only apply to the Mago debug engine, not the Concord extension. + +$(H2 Debugger Customization) + +$(P Starting with Visual D 1.0 the display of structs and classes can be customized in the mago expression evaluator +for the Concord debugger engine (when using dmd as the copiler). This is done by enabling +"Call struct/class methods __debug[Overview|Expanded|Visualizer]" in the global mago Debugging options for mago +and adding some extra methods or fields to the declaration of the struct or class:) + +$(UL + $(LI `__debugOverview` will be evaluated to display the single line representation in the watch, locals or auto window.) + $(LI `__debugExpanded` will be evaluated to display the expanded list of members in the watch, locals or auto window.) + $(LI `__debugStringView` will be evaluated to populate the text visualizer window.) +) + +$(P The type of the return value determines what fields are displayed. Here is an example session:) + +
+ +$(P Instead of functions you can also define the __debug* properties as fields that are eagerly filled by the regular code. +You must not alias other members because that information is not available in the debug information.) + +$(P The JSON Visualizer window was opened by clicking the focused lense in the Autos window. +As with other special display functionality, the function evaluation can be disabled by appending ",!" to +the expression as shown in the watch window.) + +$(P While executing these functions for display, the GC is switched to a region allocator that discards all memory +when excution of the debuggee is resumed (this can be disabled in the global debugger options with setting +"Switch GC while executing debugger functions"). So you should +not keep references to memory allocated during execution of the __debug* functions.) + +$(H3 Displaying Ranges) + +$(P Enabling mago debugger option "Call range methods to show elements in overview/expansion" activates function evaluation of +methods `save`, `empty`, `front` and `popFront` if they all exist. This allows displaying forward ranges as +a list of their elements.) + +
+ +$(P This is currently considered experimental, because it is rather slow.) + +$(P Known issue: if `front` returns a reference to the element, the wrong value is displayed. This is caused by bad +debug information.) + Macros: TITLE=Debugging diff --git a/doc/images/debugeval.png b/doc/images/debugeval.png new file mode 100644 index 00000000..5e34fd4e Binary files /dev/null and b/doc/images/debugeval.png differ diff --git a/doc/images/debugranges.png b/doc/images/debugranges.png new file mode 100644 index 00000000..cfb4dd51 Binary files /dev/null and b/doc/images/debugranges.png differ diff --git a/nsis/Extensions_vs12/extension.vsixmanifest b/nsis/Extensions_vs12/extension.vsixmanifest index 4bf91adf..01afebd6 100644 --- a/nsis/Extensions_vs12/extension.vsixmanifest +++ b/nsis/Extensions_vs12/extension.vsixmanifest @@ -14,7 +14,7 @@ - + diff --git a/nsis/Extensions_vs15/extension.vsixmanifest b/nsis/Extensions_vs15/extension.vsixmanifest index 1ee20b12..7b9b6515 100644 --- a/nsis/Extensions_vs15/extension.vsixmanifest +++ b/nsis/Extensions_vs15/extension.vsixmanifest @@ -14,7 +14,7 @@ - + diff --git a/nsis/replaceinfile.nsh b/nsis/replaceinfile.nsh index df695cc5..c45efc47 100644 --- a/nsis/replaceinfile.nsh +++ b/nsis/replaceinfile.nsh @@ -85,7 +85,8 @@ Function RIF IfFileExists $2 +1 RIF_error ; knock-knock FileOpen $R0 $2 "r" ; open the door - GetTempFileName $R2 ; who's new? + GetFullPathName $R1 $2\.. ; same folder as source file + GetTempFileName $R2 $R1 ; Put temporary file in same folder to preserve access rights FileOpen $R1 $R2 "w" ; the escape, please! RIF_loop: ; round'n'round we go diff --git a/nsis/visuald.nsi b/nsis/visuald.nsi index 82f523a4..6d3dc6b5 100644 --- a/nsis/visuald.nsi +++ b/nsis/visuald.nsi @@ -29,7 +29,7 @@ ; define DMD source path to include dmd installation ; !define DMD -!define DMD_VERSION "2.092.1" +!define DMD_VERSION "2.093.0" !define DMD_SRC c:\d\dmd-${DMD_VERSION} ; define LDC to include ldc installation diff --git a/stdext/stdext.visualdproj b/stdext/stdext.visualdproj index 5bc8f963..fd202696 100644 --- a/stdext/stdext.visualdproj +++ b/stdext/stdext.visualdproj @@ -40,7 +40,6 @@ 0 0 0 - 0 0 0 0 @@ -164,7 +163,6 @@ 0 0 0 - 0 0 0 0 @@ -288,7 +286,6 @@ 0 0 0 - 0 0 0 0 @@ -412,7 +409,6 @@ 0 0 0 - 0 0 0 0 @@ -536,7 +532,6 @@ 0 0 0 - 0 0 0 0 @@ -660,7 +655,6 @@ 0 0 0 - 0 0 0 0 @@ -784,7 +778,6 @@ 0 0 0 - 0 0 0 0 @@ -908,7 +901,6 @@ 0 0 0 - 0 0 0 0 @@ -1032,7 +1024,6 @@ 0 0 0 - 0 0 0 0 @@ -1156,7 +1147,6 @@ 0 0 0 - 0 0 0 0 @@ -1280,7 +1270,6 @@ 0 0 0 - 0 0 0 0 @@ -1404,7 +1393,6 @@ 0 0 0 - 0 0 0 0 @@ -1524,11 +1512,10 @@ 0 0 1 - 0 + 1 0 0 0 - 0 0 0 0 @@ -1652,7 +1639,6 @@ 0 0 0 - 0 0 0 0 @@ -1776,7 +1762,6 @@ 0 0 0 - 0 0 0 0 @@ -1900,7 +1885,6 @@ 0 0 0 - 0 0 0 0 diff --git a/vdc/dmdserver/dmd b/vdc/dmdserver/dmd index d18229c6..a98a1099 160000 --- a/vdc/dmdserver/dmd +++ b/vdc/dmdserver/dmd @@ -1 +1 @@ -Subproject commit d18229c6d66628f565fcc77fe65bfad2d665d880 +Subproject commit a98a109995916a6512a2319f4b6cd53c5a149930 diff --git a/vdc/dmdserver/dmdserver.d b/vdc/dmdserver/dmdserver.d index 50cf510d..afbe5209 100644 --- a/vdc/dmdserver/dmdserver.d +++ b/vdc/dmdserver/dmdserver.d @@ -988,7 +988,7 @@ class DMDServer : ComObject, IVDServer Module.rootModule = rootModule.analyzedModule; Module.loadModuleHandler = (const ref Loc location, IdentifiersAtLoc* packages, Identifier ident) { - return Module.loadFromFile(location, packages, ident); + return Module.loadFromFile(location, packages, ident, 0, 0); }; for (size_t i = 0; i < mModules.length; i++) @@ -1190,7 +1190,10 @@ unittest } string tip = detachBSTR(bstrTip); - assert(tip == expected_tip); + if (expected_tip.endsWith("...")) + assert(tip.startsWith(expected_tip[0..$-3])); + else + assert(tip == expected_tip); } void checkDefinition(int line, int col, string expected_fname, int expected_line, int expected_col) @@ -1265,7 +1268,7 @@ unittest } checkTip(5, 9, "(local variable) `int xyz`"); - checkTip(6, 9, "`void std.stdio.writeln!(int, int, int)(int _param_0, int _param_1, int _param_2) @safe`"); + checkTip(6, 9, "`void std.stdio.writeln!(int, int, int)(int _param_0, int _param_1, int _param_2) @safe`..."); checkTip(7, 12, "(local variable) `int xyz`"); version(traceGC) diff --git a/vdc/dmdserver/dmdserver.visualdproj b/vdc/dmdserver/dmdserver.visualdproj index 5afe9e31..dc8916c2 100644 --- a/vdc/dmdserver/dmdserver.visualdproj +++ b/vdc/dmdserver/dmdserver.visualdproj @@ -316,7 +316,7 @@ 1 c:\l\d\dmd2\windows\bin\dmd.exe dmd\src ..\.. - dmd dmd\res + dmd dmd\src\dmd\res ..\..\bin\$(ConfigurationName)\$(PlatformName) $(OutDir)\$(ProjectName) @@ -439,7 +439,7 @@ 0 $(DMDInstallDir)windows\bin\dmd.exe dmd\src ..\.. - $(OutDir) ..\..\res + dmd dmd\src\dmd\res ..\..\bin\$(ConfigurationName)\$(PlatformName) $(OutDir)\$(ProjectName) @@ -685,7 +685,7 @@ 0 dmd\src ..\.. $(DMDInstallDir)\src\druntime\src - dmd dmd\res + dmd dmd\src\dmd\res ..\..\bin\$(ConfigurationName)\$(PlatformName) $(OutDir)\$(ProjectName) @@ -931,7 +931,7 @@ 0 c:\l\d\dmd2\windows\bin\dmd.exe dmd\src ..\.. - dmd dmd\res + dmd dmd\src\dmd\res ..\..\bin\$(ConfigurationName)\$(PlatformName) $(OutDir)\$(ProjectName) @@ -1177,7 +1177,7 @@ 0 c:\s\d\dlang\dmd\generated\Windows\Release\x64\dmd.exe dmd\src ..\.. $(DMDInstallDir)\src\druntime\src - dmd dmd\res + dmd dmd\src\dmd\res ..\..\bin\$(ConfigurationName)\$(PlatformName) $(OutDir)\$(ProjectName) @@ -1423,7 +1423,7 @@ 1 c:\s\d\rainers\windows\bin\dmd.exe dmd\src ..\.. $(DMDInstallDir)\src\druntime\src c:\s\d\dlang\druntime\src - dmd dmd\res + dmd dmd\src\dmd\res ..\..\bin\$(ConfigurationName)\$(PlatformName) $(OutDir)\$(ProjectName) @@ -1669,7 +1669,7 @@ 0 c:\s\d\dlang\dmd\generated\Windows\Release\x64\dmd.exe dmd\src ..\.. - dmd dmd\res + dmd dmd\src\dmd\res ..\..\bin\$(ConfigurationName)\$(PlatformName) $(OutDir)\$(ProjectName) diff --git a/vdc/dmdserver/semanalysis.d b/vdc/dmdserver/semanalysis.d index 16137b22..6c54f6cd 100644 --- a/vdc/dmdserver/semanalysis.d +++ b/vdc/dmdserver/semanalysis.d @@ -23,6 +23,8 @@ import dmd.identifier; import dmd.semantic2; import dmd.semantic3; +import std.algorithm; + // debug version = traceGC; __gshared AnalysisContext lastContext; @@ -93,7 +95,7 @@ class AnalysisContext return mi.createSemanticModule(false); } - return Module.loadFromFile(location, packages, ident); + return Module.loadFromFile(location, packages, ident, 1, 0); // enable doc comment parsing }; } @@ -309,7 +311,10 @@ void do_unittests() void checkTip(Module analyzedModule, int line, int col, string expected_tip, bool addlinks = false) { string tip = findTip(analyzedModule, line, col, line, col + 1, addlinks); - assert_equal(tip, expected_tip); + if (expected_tip.endsWith("...")) + assert(tip.startsWith(expected_tip[0..$-3])); + else + assert_equal(tip, expected_tip); } void checkDefinition(Module analyzedModule, int line, int col, string expected_fname, int expected_line, int expected_col) @@ -423,9 +428,9 @@ void do_unittests() checkTip(m, 5, 8, "(local variable) `int xyz`"); checkTip(m, 5, 10, "(local variable) `int xyz`"); - checkTip(m, 6, 4, "`void std.stdio.writeln!(int, int, int)(int _param_0, int _param_1, int _param_2) @safe`"); + checkTip(m, 6, 4, "`void std.stdio.writeln!(int, int, int)(int _param_0, int _param_1, int _param_2) @safe`\n..."); checkTip(m, 5, 11, ""); - checkTip(m, 6, 8, "`void std.stdio.writeln!(int, int, int)(int _param_0, int _param_1, int _param_2) @safe`"); + checkTip(m, 6, 8, "`void std.stdio.writeln!(int, int, int)(int _param_0, int _param_1, int _param_2) @safe`\n..."); checkTip(m, 7, 11, "(local variable) `int xyz`"); checkDefinition(m, 7, 11, "source.d", 5, 8); // xyz @@ -492,11 +497,11 @@ void do_unittests() checkTip(m, 1, 9, "(package) `pkg`"); checkTip(m, 1, 13, "(module) `pkg.source`"); checkTip(m, 24, 10, "(package) `core`"); - checkTip(m, 24, 15, "(module) `core.cpuid`"); + checkTip(m, 24, 15, "(module) `core.cpuid`\n..."); checkTip(m, 24, 23, "(alias) `pkg.source.cpu_vendor = string core.cpuid.vendor() pure nothrow @nogc @property @trusted`"); checkTip(m, 24, 36, "(alias) `pkg.source.cpu_vendor = string core.cpuid.vendor() pure nothrow @nogc @property @trusted`"); checkTip(m, 24, 44, "(alias) `pkg.source.processor = string core.cpuid.processor() pure nothrow @nogc @property @trusted`"); - checkTip(m, 28, 11, "`string core.cpuid.vendor() pure nothrow @nogc @property @trusted`"); + checkTip(m, 28, 11, "`string core.cpuid.vendor() pure nothrow @nogc @property @trusted`\n..."); source = q{ // Line 1 @@ -651,12 +656,12 @@ void do_unittests() m = checkErrors(source, ""); checkTip(m, 9, 20, "(local variable) `object.Exception e`"); - checkTip(m, 9, 10, "(class) `object.Exception`"); - checkTip(m, 11, 21, "(class) `object.Error`"); - checkTip(m, 12, 5, "(class) `object.Exception`"); - checkTip(m, 13, 11, "(class) `object.Exception`"); - checkTip(m, 2, 9, "(class) `object.Exception`"); - checkTip(m, 16, 10, "(class) `object.Throwable`"); + checkTip(m, 9, 10, "(class) `object.Exception`\n..."); + checkTip(m, 11, 21, "(class) `object.Error`\n..."); + checkTip(m, 12, 5, "(class) `object.Exception`\n..."); + checkTip(m, 13, 11, "(class) `object.Exception`\n..."); + checkTip(m, 2, 9, "(class) `object.Exception`\n..."); + checkTip(m, 16, 10, "(class) `object.Throwable`\n..."); source = q{ // Line 1 @@ -989,7 +994,8 @@ void do_unittests() } }; m = checkErrors(source, ""); - checkTip(m, 5, 13, "`string[] std.array.split!(string, string)(string range, string sep) pure nothrow @safe`"); + // todo: deal with "ditto" + checkTip(m, 5, 13, "`string[] std.array.split!(string, string)(string range, string sep) pure nothrow @safe`\n\nditto"); checkTip(m, 6, 13, "(template function) `std.array.split(S)(S s) if (isSomeString!S)`"); source = q{ // Line 1 @@ -1042,7 +1048,7 @@ void do_unittests() checkTip(m, 24, 19, "(thread local global) `source.TOK[source.Base] source.mapBaseTOK`"); checkTip(m, 24, 7, "(class) `source.Base`"); checkTip(m, 24, 3, "(enum) `source.TOK`"); - checkTip(m, 30, 10, "(class) `object.TypeInfo_Class`"); + checkTip(m, 30, 10, "(class) `object.TypeInfo_Class`\n..."); checkTip(m, 30, 25, "(enum) `object.TypeInfo_Class.ClassFlags`"); checkTip(m, 30, 36, "(enum value) `object.TypeInfo_Class.ClassFlags.isCOMclass = 1u`"); checkTip(m, 21, 43, "(constant) `ulong source.RightBase.sizeof = 8LU`"); @@ -1074,6 +1080,34 @@ void do_unittests() ]; checkIdentifierTypes(m, exp2); + source = q{ // Line 1 + /********************************** + * Read line from `stdin`. + */ + S readln(S = string)(dchar terminator = '\n') + { + return null; + } + void foo() + { // Line 10 + cast(void)readln(); + } + }; + m = checkErrors(source, ""); + checkTip(m, 11, 14, "`string source.readln!string(dchar terminator = '\\x0a') pure nothrow @nogc @safe`" + ~ "\n\nRead line from `stdin`."); + + source = q{ // Line 1 + import std.stdio; + void foo() + { + cast(void)readln(); // Line 5 + } + }; + m = checkErrors(source, ""); + checkTip(m, 5, 14, "`string std.stdio.readln!string(dchar terminator = '\\x0a') @system`" + ~ "\n\nRead line from `stdin`..."); + // string expressions with concat source = q{ void fun() @@ -1140,8 +1174,8 @@ void do_unittests() //dumpAST(m); checkTip(m, 6, 9, "(foreach variable) `object.ModuleInfo* m`"); checkTip(m, 5, 12, "(foreach variable) `object.ModuleInfo* m`"); - checkTip(m, 5, 15, "(module) `object`"); - checkTip(m, 5, 22, "(struct) `object.ModuleInfo`"); + checkTip(m, 5, 15, "(module) `object`\n..."); + checkTip(m, 5, 22, "(struct) `object.ModuleInfo`\n..."); exp2 = [ "fun": [ IdTypePos(TypeReferenceKind.Function) ], @@ -1240,9 +1274,9 @@ void do_unittests() }; m = checkErrors(source, ""); - checkTip(m, 2, 37, "(class) `object.Object`"); + checkTip(m, 2, 37, "(class) `object.Object`\n..."); checkTip(m, 2, 44, "(local variable) `object.Object o`"); - checkTip(m, 3, 47, "(class) `object.Object`"); + checkTip(m, 3, 47, "(class) `object.Object`\n..."); // check for semantics in unittest source = q{ @@ -1317,8 +1351,8 @@ void do_unittests() }; m = checkErrors(source, ""); - checkTip(m, 5, 9, "(module) `object`"); - checkTip(m, 5, 16, "(struct) `object.ModuleInfo`"); + checkTip(m, 5, 9, "(module) `object`\n..."); + checkTip(m, 5, 16, "(struct) `object.ModuleInfo`\n..."); exp2 = [ "fun": [ IdTypePos(TypeReferenceKind.Function) ], @@ -1356,9 +1390,9 @@ void do_unittests() checkTip(m, 2, 12, "(template) `source.Templ(T)`"); checkTip(m, 12, 4, "(template instance) `source.Templ!(object.ModuleInfo)`"); checkTip(m, 12, 23, "(struct) `source.Templ!(object.ModuleInfo).S`"); - checkTip(m, 12, 11, "(struct) `object.ModuleInfo`"); + checkTip(m, 12, 11, "(struct) `object.ModuleInfo`\n..."); checkTip(m, 13, 12, "(template instance) `source.Templ!(object.Object)`"); - checkTip(m, 13, 18, "(class) `object.Object`"); + checkTip(m, 13, 18, "(class) `object.Object`\n..."); checkTip(m, 13, 25, "(constant) `int source.Templ!(object.Object).value = 4`"); checkTip(m, 13, 25, "(constant) `int source.Templ!(object.Object).value = 4`"); checkTip(m, 16, 15, "`source.Templ!(Q).S source.tfun(source.Templ!int.S s)`"); // todo: Q not fqn @@ -1378,11 +1412,11 @@ void do_unittests() m = checkErrors(source, ""); //dumpAST(m); - checkTip(m, 2, 12, "(class) `object.Error`"); - checkTip(m, 4, 18, "(module) `object`"); - checkTip(m, 4, 25, "(class) `object.Exception`"); - checkTip(m, 5, 18, "(module) `object`"); - checkTip(m, 5, 25, "(class) `object.Exception`"); + checkTip(m, 2, 12, "(class) `object.Error`\n..."); + checkTip(m, 4, 18, "(module) `object`\n..."); + checkTip(m, 4, 25, "(class) `object.Exception`\n..."); + checkTip(m, 5, 18, "(module) `object`\n..."); + checkTip(m, 5, 25, "(class) `object.Exception`\n..."); exp2 = [ "foo": [ IdTypePos(TypeReferenceKind.Function) ], @@ -1629,16 +1663,16 @@ void do_unittests() } }; m = checkErrors(source, ""); - checkTip(m, 2, 18, "(class) `object.TypeInfo_Class`"); + checkTip(m, 2, 18, "(class) `object.TypeInfo_Class`\n..."); checkTip(m, 2, 33, "(enum) `object.TypeInfo_Class.ClassFlags`"); checkTip(m, 2, 44, "(enum value) `object.TypeInfo_Class.ClassFlags.isCOMclass = 1u`"); - checkTip(m, 5, 4, "(class) `object.TypeInfo_Class`"); + checkTip(m, 5, 4, "(class) `object.TypeInfo_Class`\n..."); checkTip(m, 5, 19, "(enum) `object.TypeInfo_Class.ClassFlags`"); checkTip(m, 5, 30, "(enum value) `object.TypeInfo_Class.ClassFlags.isCOMclass = 1u`"); - checkTip(m, 6, 8, "(class) `object.TypeInfo_Class`"); + checkTip(m, 6, 8, "(class) `object.TypeInfo_Class`\n..."); checkTip(m, 6, 23, "(enum) `object.TypeInfo_Class.ClassFlags`"); checkTip(m, 6, 34, "(enum value) `object.TypeInfo_Class.ClassFlags.isCOMclass = 1u`"); - checkTip(m, 8, 18, "(class) `object.TypeInfo_Class`"); + checkTip(m, 8, 18, "(class) `object.TypeInfo_Class`\n..."); checkTip(m, 8, 33, "(enum) `object.TypeInfo_Class.ClassFlags`"); checkTip(m, 8, 44, "(enum value) `object.TypeInfo_Class.ClassFlags.noPointers = 2u`"); checkTip(m, 11, 18, "(field) `ulong int[].length`"); @@ -1833,7 +1867,7 @@ unittest opts.msvcrt = true; opts.warnings = true; opts.importDirs = guessImportPaths() ~ srcdir ~ dirName(dirName(thisdir)); - opts.stringImportDirs ~= srcdir ~ "/../res"; + opts.stringImportDirs ~= srcdir ~ "/dmd/res"; opts.versionIds ~= "MARS"; //opts.versionIds ~= "NoBackend"; diff --git a/vdc/dmdserver/semvisitor.d b/vdc/dmdserver/semvisitor.d index 3e83a639..34d918e0 100644 --- a/vdc/dmdserver/semvisitor.d +++ b/vdc/dmdserver/semvisitor.d @@ -1268,6 +1268,31 @@ TipData tipForTemplate(TemplateExp te) return TipData(kind, tip); } +const(char)* docForSymbol(Dsymbol var) +{ + if (var.comment) + return var.comment; + if (var.parent) + { + const(char)* docForTemplateDeclaration(Dsymbol s) + { + if (s) + if (auto td = s.isTemplateDeclaration()) + if (td.comment && td.onemember) + return td.comment; + return null; + } + + if (auto doc = docForTemplateDeclaration(var.parent)) + return doc; + + if (auto ti = var.parent.isTemplateInstance()) + if (auto doc = docForTemplateDeclaration(ti.tempdecl)) + return doc; + } + return null; +} + TipData tipDataForObject(RootObject obj) { TipData tip; @@ -1284,11 +1309,11 @@ TipData tipDataForObject(RootObject obj) case TOK.variable: case TOK.symbolOffset: tip = tipForDeclaration((cast(SymbolExp)e).var); - doc = (cast(SymbolExp)e).var.comment; + doc = docForSymbol((cast(SymbolExp)e).var); break; case TOK.dotVariable: tip = tipForDeclaration((cast(DotVarExp)e).var); - doc = (cast(DotVarExp)e).var.comment; + doc = docForSymbol((cast(DotVarExp)e).var); break; case TOK.dotIdentifier: auto die = e.isDotIdExp(); @@ -1319,8 +1344,7 @@ TipData tipDataForObject(RootObject obj) tip.kind = s.kind().to!string; tip.code = s.toPrettyChars(true).to!string; } - if (s.comment) - doc = s.comment; + doc = docForSymbol(s); } else if (auto p = obj.isParameter()) { diff --git a/visuald/Templates/ProjectItems/VCProject/VCProject.vstemplate b/visuald/Templates/ProjectItems/VCProject/VCProject.vstemplate index 417f5af1..50652515 100644 --- a/visuald/Templates/ProjectItems/VCProject/VCProject.vstemplate +++ b/visuald/Templates/ProjectItems/VCProject/VCProject.vstemplate @@ -3,7 +3,7 @@ D/VC++ based Windows Application A Visual C++ project for creating a Win32 application, console application, DLL or static library. This is based on Visual C++'s vcxproj project type for seamless integration with C++ and msbuild. dwinproj.ico - VC + D 50 1 true diff --git a/visuald/register.d b/visuald/register.d index a0408cc3..1e27a9aa 100644 --- a/visuald/register.d +++ b/visuald/register.d @@ -658,13 +658,15 @@ HRESULT VSDllRegisterServerInternal(in wchar* pszRegRoot, in bool useRanu) // project wstring tmplprojectdir = ver < 10 ? "\\Projects_vs9"w : "\\Projects"w; - scope RegKey keyPrjTempl = new RegKey(keyRoot, registrationRoot ~ regPathPrjTemplates ~ "\\"w ~ packageGuid ~ "\\/1"); - keyPrjTempl.Set(null, g_languageName); - keyPrjTempl.Set("DeveloperActivity"w, g_languageName); - keyPrjTempl.Set("SortPriority"w, 20); if (ver < 15) // registered in vsixmanifest + { + scope RegKey keyPrjTempl = new RegKey(keyRoot, registrationRoot ~ regPathPrjTemplates ~ "\\"w ~ packageGuid ~ "\\/1"); + keyPrjTempl.Set(null, g_languageName); + keyPrjTempl.Set("DeveloperActivity"w, g_languageName); + keyPrjTempl.Set("SortPriority"w, 20); keyPrjTempl.Set("TemplatesDir"w, templatePath ~ tmplprojectdir); - keyPrjTempl.Set("Folder"w, "{152CDB9D-B85A-4513-A171-245CE5C61FCC}"w); // other languages + keyPrjTempl.Set("Folder"w, "{152CDB9D-B85A-4513-A171-245CE5C61FCC}"w); // other languages + } wstring projects = registrationRoot ~ "\\Projects\\"w ~ GUID2wstring(g_projectFactoryCLSID); scope RegKey keyProject = new RegKey(keyRoot, projects);