Skip to content

Commit 98a83d6

Browse files
committed
+Error redirection for VS IDE Error List
1 parent a86a883 commit 98a83d6

12 files changed

Lines changed: 228 additions & 97 deletions

File tree

vsSolutionBuildEvent/Actions/Binder.cs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ namespace net.r_eg.vsSBE.Actions
3232
/// </summary>
3333
public class Binder
3434
{
35+
private static readonly SemaphoreSlim semsync = new(initialCount: 1, maxCount: 1);
36+
3537
internal readonly CancelBuildState buildState = new CancelBuildState();
3638

3739
/// <summary>
@@ -47,7 +49,6 @@ public class Binder
4749

4850
protected ISobaCLoader cLoader;
4951

50-
private readonly object sync = new object();
5152
private readonly object _plock = new object();
5253

5354
/// <summary>
@@ -143,7 +144,7 @@ public int bindPost(int fSucceeded, int fModified, int fCancelCommand)
143144
Status._.add(SolutionEventType.Post, StatusType.Success);
144145
}
145146
catch(Exception ex) {
146-
Log.Error($"[{SolutionEventType.Post}] error: {ex.Message}");
147+
Log.Error($"[{SolutionEventType.Post}] error: {ex.Message}", new ExecLocator(item, SolutionEventType.Post));
147148
Log.Debug(ex.StackTrace);
148149
Status._.add(SolutionEventType.Post, StatusType.Fail);
149150
}
@@ -224,7 +225,7 @@ public int bindCancel()
224225
Status._.add(SolutionEventType.Cancel, StatusType.Success);
225226
}
226227
catch(Exception ex) {
227-
Log.Error($"[{SolutionEventType.Cancel}] error: {ex.Message}");
228+
Log.Error($"[{SolutionEventType.Cancel}] error: {ex.Message}", new ExecLocator(item, SolutionEventType.Cancel));
228229
Log.Debug(ex.StackTrace);
229230
Status._.add(SolutionEventType.Cancel, StatusType.Fail);
230231
}
@@ -299,7 +300,7 @@ public void bindBuildRaw(string data, string guid, string item = null)
299300
}
300301
}
301302
catch(Exception ex) {
302-
Log.Error($"[{SolutionEventType.Transmitter}] error: {ex.Message}");
303+
Log.Error($"[{SolutionEventType.Transmitter}] error: {ex.Message}", new ExecLocator(evt, SolutionEventType.Transmitter));
303304
Log.Debug(ex.StackTrace);
304305
}
305306
}
@@ -401,14 +402,15 @@ protected int sbeEW(ISolutionEventEW evt, Receiver.Output.EWType type)
401402
return Codes.Success;
402403
}
403404

405+
SolutionEventType setype = (type == Receiver.Output.EWType.Warnings) ? SolutionEventType.Warnings : SolutionEventType.Errors;
404406
try {
405-
if(Cmd.exec(evt, (type == Receiver.Output.EWType.Warnings)? SolutionEventType.Warnings : SolutionEventType.Errors)) {
407+
if(Cmd.exec(evt, setype)) {
406408
Log.Info($"[{type}] finished '{evt.Name}'");
407409
}
408410
return Codes.Success;
409411
}
410412
catch(Exception ex) {
411-
Log.Error($"[{type}] error: {ex.Message}");
413+
Log.Error($"[{type}] error: {ex.Message}", new ExecLocator(evt, setype));
412414
Log.Debug(ex.StackTrace);
413415
}
414416
return Codes.Failed;
@@ -439,7 +441,7 @@ protected int sbeOutput(ISolutionEventOWP evt, ref string raw, string guid, stri
439441
return Codes.Success;
440442
}
441443
catch(Exception ex) {
442-
Log.Error($"[{SolutionEventType.OWP}] error: {ex.Message}");
444+
Log.Error($"[{SolutionEventType.OWP}] error: {ex.Message}", new ExecLocator(evt, SolutionEventType.OWP));
443445
Log.Debug(ex.StackTrace);
444446
}
445447
return Codes.Failed;
@@ -520,7 +522,7 @@ protected void commandEvent(ICommandEvent item)
520522
Status._.add(SolutionEventType.CommandEvent, StatusType.Success);
521523
}
522524
catch(Exception ex) {
523-
Log.Error($"[{SolutionEventType.CommandEvent}] error: {ex.Message}");
525+
Log.Error($"[{SolutionEventType.CommandEvent}] error: {ex.Message}", new ExecLocator(item, SolutionEventType.CommandEvent));
524526
Log.Debug(ex.StackTrace);
525527
}
526528
Status._.add(SolutionEventType.CommandEvent, StatusType.Fail);
@@ -546,7 +548,7 @@ protected int bindSln(SBEEvent[] evt, SolutionEventType type)
546548
Status._.add(type, StatusType.Success);
547549
}
548550
catch(Exception ex) {
549-
Log.Error($"[{typeString}] error: {ex.Message}");
551+
Log.Error($"[{typeString}] error: {ex.Message}", new ExecLocator(item, SolutionEventType.SlnOpened));
550552
Log.Debug(ex.StackTrace);
551553
Status._.add(type, StatusType.Fail);
552554
}
@@ -567,7 +569,7 @@ protected int execPre(SBEEvent evt)
567569
return Codes.Success;
568570
}
569571
catch(Exception ex) {
570-
Log.Error($"[{SolutionEventType.Pre}] error: {ex.Message}");
572+
Log.Error($"[{SolutionEventType.Pre}] error: {ex.Message}", new ExecLocator(evt, SolutionEventType.Pre));
571573
Log.Debug(ex.StackTrace);
572574
}
573575
return Codes.Failed;
@@ -801,17 +803,23 @@ protected bool hasExecutionOrder(ISolutionEvent evt)
801803

802804
protected void attachLoggingEvent()
803805
{
804-
lock(sync) {
806+
semsync.Wait();
807+
try
808+
{
805809
detachLoggingEvent();
806810
Log._.Received += onLogging;
807811
}
812+
finally
813+
{
814+
semsync.Release();
815+
}
808816
}
809817

810818
protected void detachLoggingEvent()
811819
{
812820
Log._.Received -= onLogging;
813821
}
814-
822+
815823
/// <summary>
816824
/// Works with all processes of internal logging.
817825
/// </summary>
@@ -836,13 +844,15 @@ private void onLogging(object sender, MessageArgs e)
836844
return;
837845
}
838846

847+
//FIXME
839848
(new Task(() =>
840849
{
841850
if(Thread.CurrentThread.Name == null) {
842851
Thread.CurrentThread.Name = LoggingEvent.IDENT_TH;
843852
}
844853

845-
lock(sync)
854+
semsync.Wait();
855+
try
846856
{
847857
var ld = cLoader.GetComponent(typeof(OwpComponent)) as ILogInfo;
848858
ld?.UpdateLogInfo(e.Message, e.Level);
@@ -861,11 +871,12 @@ private void onLogging(object sender, MessageArgs e)
861871
}
862872
}
863873
catch(Exception ex) {
864-
Log.Error($"[{SolutionEventType.Logging}] error: {ex.Message}");
874+
Log.Error($"[{SolutionEventType.Logging}] error: {ex.Message}", new ExecLocator(evt, SolutionEventType.Logging));
865875
Log.Debug(ex.StackTrace);
866876
}
867877
}
868878
}
879+
finally { semsync.Release(); }
869880

870881
})).Start();
871882
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*!
2+
* Copyright (c) 2013 Denis Kuzmin <x-3F@outlook.com> github/3F
3+
* Copyright (c) vsSolutionBuildEvent contributors https://github.com/3F/vsSolutionBuildEvent/graphs/contributors
4+
* Licensed under the LGPLv3.
5+
* See accompanying LICENSE file or visit https://github.com/3F/vsSolutionBuildEvent
6+
*/
7+
8+
using net.r_eg.vsSBE.Events;
9+
10+
namespace net.r_eg.vsSBE.Actions
11+
{
12+
internal sealed class ExecLocator(ISolutionEvent evt, SolutionEventType type)
13+
{
14+
public ISolutionEvent Evt { get; } = evt;
15+
16+
public SolutionEventType EvtType { get; } = type;
17+
}
18+
}

vsSolutionBuildEvent/Log.cs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using System.Threading;
1313
using Microsoft.VisualStudio.Shell;
1414
using Microsoft.VisualStudio.Shell.Interop;
15+
using net.r_eg.vsSBE.Actions;
1516
using net.r_eg.vsSBE.Events;
1617
using net.r_eg.vsSBE.Logger;
1718
using net.r_eg.vsSBE.VSTools.OW;
@@ -244,7 +245,7 @@ public bool isWarn(string level)
244245
/// Entry point for NLog messages.
245246
/// https://github.com/nlog/nlog/wiki/MethodCall-target
246247
/// </summary>
247-
public static void nprint(string level, string message, string stamp)
248+
public static void nprint(string level, string message, string stamp, string src, string type)
248249
{
249250
if(!Settings._.DebugMode
250251
&& LogLevel.FromString(level) < LogLevel.Info)
@@ -253,7 +254,7 @@ public static void nprint(string level, string message, string stamp)
253254
}
254255

255256
Log log = _lazy.Value;
256-
log.write(log.format(level, message, stamp), level);
257+
log.write(new(log.format(level, message, stamp), level, src, type, message));
257258
}
258259

259260
/// <summary>
@@ -298,7 +299,17 @@ public static void Fatal(string message, params object[] args)
298299
internal static void Msg(LogLevel level, string message, params object[] args)
299300
{
300301
if(!Fallback(level, message))
301-
_.NLog.Log(level, message, args);
302+
{
303+
LogEventInfo msg = new(level, _.NLog.Name, message);
304+
305+
if(args.Length == 1 && args[0] is ExecLocator el)
306+
{
307+
msg.Properties.Add("src", el.Evt?.Name);
308+
msg.Properties.Add("type", el.EvtType);
309+
}
310+
311+
_.NLog.Log(msg);
312+
}
302313
}
303314

304315
/// <remarks>
@@ -356,19 +367,19 @@ protected bool ignoreLevel(string level)
356367
return false;
357368
}
358369

359-
/// <summary>
360-
/// Where to write.
361-
/// </summary>
362-
/// <param name="message"></param>
363-
/// <param name="level"></param>
364-
protected virtual void write(string message, string level = null)
370+
protected void write(MessageArgs args)
371+
=> write(args.Message, args.Level ?? string.Empty, args);
372+
373+
// TODO: combine MessageArgs and message
374+
protected virtual void write(string message, string level = null, MessageArgs args = null)
365375
{
366376
if(ignoreLevel(level)) { //TODO: extract ignoreLevel() from here due to Fallback use etc.
367377
return;
368378
}
369379

370-
if(Thread.CurrentThread.Name != LoggingEvent.IDENT_TH) {
371-
Received(this, new MessageArgs() { Message = message, Level = (level)?? String.Empty });
380+
if(Thread.CurrentThread.Name != LoggingEvent.IDENT_TH)
381+
{
382+
Received(this, args ?? new() { Message = message, Level = level ?? string.Empty });
372383
}
373384

374385
try

vsSolutionBuildEvent/Logger/Initializer.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public void configure()
5050
t.Parameters.Add(new MethodCallParameter("${level:uppercase=true}"));
5151
t.Parameters.Add(new MethodCallParameter("${message}"));
5252
t.Parameters.Add(new MethodCallParameter("${ticks}"));
53+
t.Parameters.Add(new MethodCallParameter("${event-properties:item=src}"));
54+
t.Parameters.Add(new MethodCallParameter("${event-properties:item=type}"));
5355

5456
configure(t);
5557
}
@@ -114,15 +116,9 @@ protected void fixLoggerCfg(LoggingConfiguration cfg, ConditionBasedFilter filte
114116
/// </summary>
115117
private void initLoggerCfg()
116118
{
117-
LoggingConfiguration config = LogManager.Configuration;
118-
if(config == null) {
119-
config = new LoggingConfiguration();
120-
}
119+
LoggingConfiguration config = LogManager.Configuration ?? new LoggingConfiguration();
121120

122-
NLog.Targets.Target t = config.FindTargetByName(GuidList.PACKAGE_LOGGER);
123-
if(t != null) {
124-
return; // the config is already contains our logger
125-
}
121+
if(config.FindTargetByName(GuidList.PACKAGE_LOGGER) != null) return;
126122

127123
// configure entry point
128124

vsSolutionBuildEvent/Logger/MessageArgs.cs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,49 @@ namespace net.r_eg.vsSBE.Logger
1313
public class MessageArgs: EventArgs
1414
{
1515
/// <summary>
16-
/// Received message.
16+
/// Formatted message.
1717
/// </summary>
18-
public string Message
19-
{
20-
get;
21-
set;
22-
}
18+
public string Message { get; set; }
19+
20+
/// <summary>
21+
/// Message level.
22+
/// </summary>
23+
public string Level { get; set; }
24+
25+
/// <summary>
26+
/// Source name.
27+
/// </summary>
28+
public string Src { get; set; }
2329

2430
/// <summary>
25-
/// Received level.
31+
/// Source type.
2632
/// </summary>
27-
public string Level
33+
public string SrcType { get; set; }
34+
35+
/// <summary>
36+
/// Raw message without level, stamp etc.
37+
/// </summary>
38+
public string Raw { get; set; }
39+
40+
public MessageArgs
41+
(
42+
string message,
43+
string level,
44+
string src = null,
45+
string type = null,
46+
string raw = null
47+
)
2848
{
29-
get;
30-
set;
49+
Message = message;
50+
Level = level;
51+
Src = src;
52+
SrcType = type;
53+
Raw = raw;
54+
}
55+
56+
public MessageArgs()
57+
{
58+
3159
}
3260
}
3361
}

vsSolutionBuildEvent/Pkg.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,10 +535,10 @@ private void onLateOpenedSolution(object sender, EventArgs e)
535535
private void onLogReceived(object sender, Logger.MessageArgs e)
536536
{
537537
if(Log._.isError(e.Level)) {
538-
errorList.error(e.Message);
538+
errorList.error(e.Raw, e.Src, e.SrcType);
539539
}
540540
else if(Log._.isWarn(e.Level)) {
541-
errorList.warn(e.Message);
541+
errorList.warn(e.Raw, e.Src, e.SrcType);
542542
}
543543
}
544544

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*!
2+
* Copyright (c) 2013 Denis Kuzmin <x-3F@outlook.com> github/3F
3+
* Copyright (c) vsSolutionBuildEvent contributors https://github.com/3F/vsSolutionBuildEvent/graphs/contributors
4+
* Licensed under the LGPLv3.
5+
* See accompanying LICENSE file or visit https://github.com/3F/vsSolutionBuildEvent
6+
*/
7+
8+
using net.r_eg.vsSBE.Events;
9+
10+
namespace net.r_eg.vsSBE.UI
11+
{
12+
public interface ICodeInspector
13+
{
14+
void activateAction(string name, SolutionEventType type);
15+
}
16+
}

vsSolutionBuildEvent/UI/Util.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,17 @@ public static void noticeAboutChanges(Type type, Form control, EventHandler call
121121
}
122122
}
123123

124+
public static int GetRowIndexByColumn(DataGridView dgv, DataGridViewColumn col, string name)
125+
{
126+
if(string.IsNullOrEmpty(name)) return -1;
127+
128+
for(int i = 0; i < dgv.Rows.Count; ++i)
129+
{
130+
if(dgv.Rows[i].Cells[col.Name].Value.ToString() == name) return i;
131+
}
132+
return -1;
133+
}
134+
124135
/// <summary>
125136
/// Open url in default web-browser
126137
/// </summary>

0 commit comments

Comments
 (0)