Skip to content

Commit 76fe3c2

Browse files
committed
* bugzilla 13342: mixin error message now interpreted
* when running/unittesting from within visuald, exception/callstack locations can be jumped to * bugzilla 13213: there are now both "goto definition" and "goto declaration", where the former will try to find the forward declared symbols through the object browser (including C/C++) * object browser/symbol search: now filters out __unittest and __invariant symbols
1 parent 3c1f431 commit 76fe3c2

File tree

11 files changed

+204
-48
lines changed

11 files changed

+204
-48
lines changed

CHANGES

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,4 +690,9 @@ unreleased Version 0.3.40
690690
* DMD/x64 linker override settings not saved
691691
* revamped pipedmd: now uses tracker.exe from MSBuild or WinSDK to monitor dependencies
692692
* Win32/COFF support: check box on Compiler->Output page, new tab in global options
693-
* bugzilla 13817: VisualD cannot list members with utf-8 wide characters
693+
* bugzilla 13817: VisualD cannot list members with utf-8 wide characters
694+
* bugzilla 13342: mixin error message now interpreted
695+
* when running/unittesting from within visuald, exception/callstack locations can be jumped to
696+
* bugzilla 13213: there are now both "goto definition" and "goto declaration", where the former
697+
will try to find the forward declared symbols through the object browser (including C/C++)
698+
* object browser/symbol search: now filters out __unittest and __invariant symbols

TODO

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,6 @@ Unsorted
167167
- jump to assertion error
168168
+ import std.container: jump to package
169169
- renaming configuration does not change project config
170-
- win32coff support
170+
+ win32coff support
171171
- file search: replace . with \ in path search?
172-
- run cv2pdb disabled for GDC/x64
172+
+ run cv2pdb disabled for GDC/x64

vdc/abothe/comserver/VDServer.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,16 @@ public void GetDefinition(string filename, int startLine, int startIndex, int en
314314
if (n == null)
315315
return;
316316

317-
_tipStart = n.Location;
317+
bool decl = false;
318+
var mthd = n as DMethod;
319+
if (mthd != null)
320+
decl = mthd.Body == null;
321+
else if (n.ContainsAttribute(DTokens.Extern))
322+
decl = true;
323+
if (decl)
324+
_tipText.Append("EXTERN:");
325+
326+
_tipStart = n.Location;
318327
_tipEnd = n.EndLocation;
319328
INode node = n.NodeRoot;
320329
if(node is DModule)

visuald/build.d

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,18 +1029,55 @@ bool parseOutputStringForTaskItem(string outputLine, out uint nPriority,
10291029
outputLine = strip(outputLine);
10301030

10311031
// DMD compile error
1032-
static Regex!char re1dmd, re1gdc, re2, re3, re4;
1032+
__gshared static Regex!char re1dmd, re1gdc, remixin, re2, re3, re4, re5, re6;
1033+
1034+
if(!isInitializedRE(remixin))
1035+
remixin = regex(r"^(.*?)-mixin-([0-9]+)\(([0-9]+)\):(.*)$");
1036+
1037+
auto rematch = match(outputLine, remixin);
1038+
if(!rematch.empty())
1039+
{
1040+
auto captures = rematch.captures();
1041+
filename = replace(captures[1], "\\\\", "\\");
1042+
string lineno = captures[2];
1043+
string lineno2 = captures[3];
1044+
nLineNum = to!uint(lineno);
1045+
uint nMixinLine = to!uint(lineno2) - nLineNum + 1;
1046+
itemText = "mixin(" ~ to!string(nMixinLine) ~ ") " ~ strip(captures[4]);
1047+
if(itemText.startsWith("Warning:")) // make these errors if not building with -wi?
1048+
nPriority = TP_NORMAL;
1049+
else
1050+
nPriority = TP_HIGH;
1051+
return true;
1052+
}
1053+
1054+
// exception/error when running
1055+
if(!isInitializedRE(re5))
1056+
re5 = regex(r"^[^ @]*@(.*?)\(([0-9]+)\):(.*)$");
1057+
1058+
rematch = match(outputLine, re5);
1059+
if(!rematch.empty())
1060+
{
1061+
auto captures = rematch.captures();
1062+
nPriority = TP_HIGH;
1063+
filename = replace(captures[1], "\\\\", "\\");
1064+
string lineno = captures[2];
1065+
nLineNum = to!uint(lineno);
1066+
itemText = strip(captures[3]);
1067+
return true;
1068+
}
1069+
10331070
if(!isInitializedRE(re1dmd))
10341071
re1dmd = regex(r"^(.*?)\(([0-9]+)\):(.*)$"); // replace . with [\x00-\x7f] for std.regex
10351072
if(!isInitializedRE(re1gdc))
10361073
re1gdc = regex(r"^(.*?):([0-9]+):(.*)$");
10371074

1038-
auto rematch = match(outputLine, compiler == Compiler.GDC ? re1gdc : re1dmd);
1075+
rematch = match(outputLine, compiler == Compiler.GDC ? re1gdc : re1dmd);
10391076
if(!rematch.empty())
10401077
{
10411078
auto captures = rematch.captures();
10421079
filename = replace(captures[1], "\\\\", "\\");
1043-
string lineno = replace(captures[2], "\\\\", "\\");
1080+
string lineno = captures[2];
10441081
nLineNum = to!uint(lineno);
10451082
itemText = strip(captures[3]);
10461083
if(itemText.startsWith("Warning:")) // make these errors if not building with -wi?
@@ -1074,7 +1111,7 @@ bool parseOutputStringForTaskItem(string outputLine, out uint nPriority,
10741111
auto captures = rematch.captures();
10751112
nPriority = TP_HIGH;
10761113
filename = replace(captures[1], "\\\\", "\\");
1077-
string lineno = replace(captures[2], "\\\\", "\\");
1114+
string lineno = captures[2];
10781115
nLineNum = to!uint(lineno);
10791116
itemText = strip(captures[3]);
10801117
return true;
@@ -1094,6 +1131,22 @@ bool parseOutputStringForTaskItem(string outputLine, out uint nPriority,
10941131
return true;
10951132
}
10961133

1134+
// entry in exception call stack
1135+
if(!isInitializedRE(re6))
1136+
re6 = regex(r"^0x[0-9a-fA-F]* in .* at (.*?)\(([0-9]+)\)(.*)$");
1137+
1138+
rematch = match(outputLine, re6);
1139+
if(!rematch.empty())
1140+
{
1141+
auto captures = rematch.captures();
1142+
nPriority = TP_LOW;
1143+
filename = replace(captures[1], "\\\\", "\\");
1144+
string lineno = captures[2];
1145+
nLineNum = to!uint(lineno);
1146+
itemText = strip(captures[3]);
1147+
return true;
1148+
}
1149+
10971150
return false;
10981151
}
10991152

@@ -1107,11 +1160,33 @@ unittest
11071160
assert(nLineNum == 37);
11081161
assert(strTaskItemText == "huhu");
11091162

1110-
rc = parseOutputStringForTaskItem("main.d(10): Error: undefined identifier A, did you mean B?", nPriority, strFilename, nLineNum, strTaskItemText, Compiler.DMD);
1163+
rc = parseOutputStringForTaskItem("main.d(10): Error: undefined identifier A, did you mean B?",
1164+
nPriority, strFilename, nLineNum, strTaskItemText, Compiler.DMD);
11111165
assert(rc);
11121166
assert(strFilename == "main.d");
11131167
assert(nLineNum == 10);
11141168
assert(strTaskItemText == "Error: undefined identifier A, did you mean B?");
1169+
1170+
rc = parseOutputStringForTaskItem(r"object.Exception@C:\tmp\d\forever.d(28): what?",
1171+
nPriority, strFilename, nLineNum, strTaskItemText, Compiler.DMD);
1172+
assert(rc);
1173+
assert(strFilename == r"C:\tmp\d\forever.d");
1174+
assert(nLineNum == 28);
1175+
assert(strTaskItemText == "what?");
1176+
1177+
rc = parseOutputStringForTaskItem(r"0x004020C8 in void test.__modtest() at C:\tmp\d\forever.d(34)",
1178+
nPriority, strFilename, nLineNum, strTaskItemText, Compiler.DMD);
1179+
assert(rc);
1180+
assert(strFilename == r"C:\tmp\d\forever.d");
1181+
assert(nLineNum == 34);
1182+
assert(strTaskItemText == "");
1183+
1184+
rc = parseOutputStringForTaskItem(r"D:\LuaD\luad\conversions\structs.d-mixin-36(36): Error: cast(MFVector)(*_this).x is not an lvalue",
1185+
nPriority, strFilename, nLineNum, strTaskItemText, Compiler.DMD);
1186+
assert(rc);
1187+
assert(strFilename == r"D:\LuaD\luad\conversions\structs.d");
1188+
assert(nLineNum == 36);
1189+
assert(strTaskItemText == "mixin(1) Error: cast(MFVector)(*_this).x is not an lvalue");
11151190
}
11161191

11171192
string unEscapeFilename(string file)

visuald/dlangsvc.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1615,7 +1615,7 @@ version(threadedOutlining) {} else
16151615
return rgns;
16161616
}
16171617

1618-
unittest
1618+
version(none) unittest
16191619
{
16201620
const(void)* p = typeid(NewHiddenRegion).rtInfo;
16211621
assert(p !is rtinfoNoPointers && p !is rtinfoHasPointers);

visuald/hierutil.d

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ HRESULT FindFileInSolution(string filename, string srcfile, out string absPath)
550550
return S_OK;
551551
}
552552

553-
HRESULT OpenFileInSolution(string filename, int line, string srcfile = "", bool adjustLineToChanges = false)
553+
HRESULT OpenFileInSolution(string filename, int line, int col = 0, string srcfile = "", bool adjustLineToChanges = false)
554554
{
555555
// Get the IVsUIShellOpenDocument service so we can ask it to open a doc window
556556
IVsUIShellOpenDocument pIVsUIShellOpenDocument = queryService!(IVsUIShellOpenDocument);
@@ -609,7 +609,7 @@ HRESULT OpenFileInSolution(string filename, int line, string srcfile = "", bool
609609
if(auto src = Package.GetLanguageService().GetSource(textBuffer))
610610
line = src.adjustLineNumberSinceLastBuild(line, false);
611611

612-
return NavigateTo(textBuffer, line, 0, line, 0);
612+
return NavigateTo(textBuffer, line, col, line, col);
613613
}
614614

615615
HRESULT NavigateTo(IVsTextBuffer textBuffer, int line1, int col1, int line2, int col2)
@@ -622,9 +622,9 @@ HRESULT NavigateTo(IVsTextBuffer textBuffer, int line1, int col1, int line2, int
622622
return textmgr.NavigateToLineAndColumn(textBuffer, &LOGVIEWID_Primary, line1, col1, line2, col2);
623623
}
624624

625-
HRESULT OpenFileInSolutionWithScope(string fname, int line, string scop, bool adjustLineToChanges = false)
625+
HRESULT OpenFileInSolutionWithScope(string fname, int line, int col, string scop, bool adjustLineToChanges = false)
626626
{
627-
HRESULT hr = OpenFileInSolution(fname, line, "", adjustLineToChanges);
627+
HRESULT hr = OpenFileInSolution(fname, line, col, "", adjustLineToChanges);
628628

629629
if(hr != S_OK && !isAbsolute(fname) && scop.length)
630630
{
@@ -642,7 +642,7 @@ HRESULT OpenFileInSolutionWithScope(string fname, int line, string scop, bool ad
642642
if(i < path.length)
643643
{
644644
fname = fname[i .. $];
645-
hr = OpenFileInSolution(fname, line, "", adjustLineToChanges);
645+
hr = OpenFileInSolution(fname, line, col, "", adjustLineToChanges);
646646
}
647647
}
648648
return hr;

visuald/intellisense.d

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import std.algorithm;
1818

1919
import std.regex;
2020
import std.array;
21+
import std.path : baseName, stripExtension;
2122
//import stdext.fred;
2223

2324
import stdext.path;
@@ -930,6 +931,8 @@ class BrowseInfo
930931
if(v.type == JSON_TYPE.STRING)
931932
n.file = v.str;
932933
node = n;
934+
if("name" !in memberobj)
935+
node.name = stripExtension(baseName(n.file));
933936
}
934937
else if (kind == "class" || kind == "interface")
935938
{
@@ -946,16 +949,22 @@ class BrowseInfo
946949
}
947950
else
948951
{
949-
node = new BrowseNode;
950-
version(v40)
951952
if(kind == "function")
953+
{
954+
if(JSONValue* n = "name" in memberobj)
955+
if(n.type == JSON_TYPE.STRING)
956+
if (n.str.startsWith("__unittest") || n.str.startsWith("__invariant"))
957+
return null;
958+
952959
if(!("endline" in memberobj))
953-
kind = "funcdecl";
960+
kind = "function decl";
961+
}
962+
node = new BrowseNode;
954963
}
955964

956965
node.kind = kind;
957966
getDeclarationInfo(node, memberobj);
958-
967+
959968
return node;
960969
}
961970

@@ -986,6 +995,9 @@ version(v40)
986995
void iterate(JSONValue[string] object, BrowseNode parent)
987996
{
988997
BrowseNode node = createNode(object);
998+
if(!node)
999+
return;
1000+
9891001
if(parent)
9901002
{
9911003
parent.members ~= node;

visuald/library.d

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ bool HasFunctionPrototype(string kind)
960960
case "deallocator":
961961
case "delegate":
962962
case "function":
963-
version(v40) case "funcdecl":
963+
case "function decl":
964964
return true;
965965
default:
966966
return false;
@@ -989,7 +989,7 @@ LIB_LISTTYPE2 GetListType(string kind)
989989
case "alias":
990990
case "typedef":
991991
case "delegate":
992-
version(v40) case "funcdecl":
992+
case "function decl":
993993
case "function": return LLT_MEMBERS;
994994

995995
// not expected to show up in json file
@@ -1317,7 +1317,7 @@ class ObjectList : DComObject, IVsSimpleObjectList2
13171317
case "destructor":
13181318
case "allocator":
13191319
case "deallocator":
1320-
version(v40) case "funcdecl":
1320+
case "function decl":
13211321
case "function": pData.Image = CSIMG_MEMBER; break;
13221322
case "delegate": pData.Image = CSIMG_MEMBER; break;
13231323
case "interface": pData.Image = CSIMG_INTERFACE; break;
@@ -1546,17 +1546,15 @@ version(v40) case "funcdecl":
15461546
/+[out]+/ BOOL *pfOK)
15471547
{
15481548
mixin(LogCallMix2);
1549-
version(v40) { if(SrcType != GS_ANY)
1549+
if(SrcType != GS_ANY)
15501550
{
1551-
if(SrcType == GS_DEFINITION && GetKind(Index) == "funcdecl")
1551+
if(SrcType == GS_DEFINITION && GetKind(Index) == "function decl")
15521552
return E_FAIL;
1553-
if(SrcType == GS_DECLARATION && GetKind(Index) != "funcdecl")
1553+
if(SrcType == GS_DECLARATION && GetKind(Index) != "function decl")
15541554
return E_FAIL;
15551555
if(SrcType != GS_DECLARATION && SrcType != GS_DEFINITION)
15561556
return E_FAIL;
15571557
}
1558-
} else { if(SrcType != GS_ANY && SrcType != GS_DEFINITION)
1559-
return E_FAIL; }
15601558
*pfOK = TRUE;
15611559
return S_OK;
15621560
}
@@ -1581,7 +1579,7 @@ version(v40) { if(SrcType != GS_ANY)
15811579
if(file.length == 0)
15821580
file = GetInfoFilename(obj);
15831581

1584-
return OpenFileInSolution(file, line, modname, true);
1582+
return OpenFileInSolution(file, line, 0, modname, true);
15851583
}
15861584

15871585
override HRESULT GetContextMenu(in ULONG Index,
@@ -1893,3 +1891,53 @@ private:
18931891
BOOL m_fIsCounterDirty;
18941892
VSTREELISTITEMCHANGE m_listChanges = { NULINDEX, TCT_NOCHANGE };
18951893
}
1894+
1895+
Definition[] GetObjectLibraryDefinitions(wstring word)
1896+
{
1897+
Definition[] defs;
1898+
1899+
if(auto objmgr = queryService!(IVsObjectManager))
1900+
{
1901+
scope(exit) release(objmgr);
1902+
if(auto objmgr2 = qi_cast!IVsObjectManager2(objmgr))
1903+
{
1904+
scope(exit) release(objmgr2);
1905+
IVsEnumLibraries2 enumLibs;
1906+
if(objmgr2.EnumLibraries(&enumLibs) == S_OK)
1907+
{
1908+
VSOBSEARCHCRITERIA2 searchOpts;
1909+
searchOpts.szName = _toUTF16zw(word);
1910+
searchOpts.eSrchType = SO_ENTIREWORD;
1911+
searchOpts.grfOptions = VSOBSO_CASESENSITIVE;
1912+
1913+
scope(exit) release(enumLibs);
1914+
DWORD fetched;
1915+
IVsLibrary2 lib;
1916+
while(enumLibs.Next(1, &lib, &fetched) == S_OK && fetched == 1)
1917+
{
1918+
scope(exit) release(lib);
1919+
if(auto slib = qi_cast!IVsSimpleLibrary2(lib))
1920+
{
1921+
scope(exit) release(slib);
1922+
IVsSimpleObjectList2 reslist;
1923+
if(slib.GetList2(LLT_MEMBERS, LLF_USESEARCHFILTER, &searchOpts, &reslist) == S_OK)
1924+
{
1925+
scope(exit) release(reslist);
1926+
ULONG items;
1927+
if(reslist.GetItemCount(&items) == S_OK && items > 0)
1928+
{
1929+
BOOL ok;
1930+
for(ULONG it = 0; it < items; it++)
1931+
if(reslist.CanGoToSource(it, GS_DEFINITION, &ok) == S_OK && ok)
1932+
{
1933+
1934+
}
1935+
}
1936+
}
1937+
}
1938+
}
1939+
}
1940+
}
1941+
}
1942+
return defs;
1943+
}

visuald/searchsymbol.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,7 @@ private:
11741174
HRESULT _OpenSolutionItem(string pszPath, int line, string scop)
11751175
{
11761176
HRESULT hr = S_OK;
1177-
hr = OpenFileInSolutionWithScope(pszPath, line, scop, true);
1177+
hr = OpenFileInSolutionWithScope(pszPath, line, 0, scop, true);
11781178
if(hr == S_OK && _closeOnReturn)
11791179
sWindowFrame.Hide();
11801180
return hr;

0 commit comments

Comments
 (0)