/// <summary> /// Creates new error with given text and associates it with current project reference. /// Old error is removed /// </summary> /// <param name="text"></param> private void SetError(string text) { UIThread.DoOnUIThread(() => { // delete existing error if exists CleanProjectReferenceErrorState(); projectRefError = new Shell.ErrorTask { ErrorCategory = Shell.TaskErrorCategory.Warning, HierarchyItem = ProjectMgr.InteropSafeIVsHierarchy, Text = text }; ProjectMgr.ProjectErrorsTaskListProvider.Tasks.Add(projectRefError); } ); }
public static void RunSync(Action a) { if (isUnitTestingMode) { a(); return; } Exception exn = null; Debug.Assert(ctxt != null, "The SynchronizationContext must be captured before calling this method"); // Send on UI thread will execute immediately. #pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs ctxt.Send(ignore => #pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs { try { UIThread.MustBeCalledFromUIThread(); a(); } catch (Exception e) { exn = e; } }, null ); if (exn != null) { // throw exception on calling thread, preserve stacktrace if (!exn.Data.Contains(WrappedStacktraceKey)) { exn.Data[WrappedStacktraceKey] = exn.StackTrace; } throw exn; } }
/// <summary> /// Add the error/warning to the error list and potentially to the output window. /// </summary> private void AddToErrorList( BuildEventArgs errorEvent, string subcategory, string errorCode, string file, int startLine, int startColumn, int endLine, int endColumn) { if (file == null) { file = String.Empty; } bool isWarning = errorEvent is BuildWarningEventArgs; Shell.TaskPriority priority = isWarning ? Shell.TaskPriority.Normal : Shell.TaskPriority.High; TextSpan span; span.iStartLine = startLine; span.iStartIndex = startColumn; span.iEndLine = endLine < startLine ? span.iStartLine : endLine; span.iEndIndex = (endColumn < startColumn) && (span.iStartLine == span.iEndLine) ? span.iStartIndex : endColumn; if (OutputWindowPane != null && (this.Verbosity != LoggerVerbosity.Quiet || errorEvent is BuildErrorEventArgs)) { // Format error and output it to the output window string message = this.FormatMessage(errorEvent.Message); DefaultCompilerError e = new DefaultCompilerError(file, span.iStartLine, span.iStartIndex, span.iEndLine, span.iEndIndex, errorCode, message); e.IsWarning = isWarning; Output(GetFormattedErrorMessage(e)); } UIThread.Run(delegate() { IVsUIShellOpenDocument openDoc = serviceProvider.GetService(typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument; if (openDoc == null) { return; } IVsWindowFrame frame; IOleServiceProvider sp; IVsUIHierarchy hier; uint itemid; Guid logicalView = VSConstants.LOGVIEWID_Code; IVsTextLines buffer = null; // JAF // Notes about acquiring the buffer: // If the file physically exists then this will open the document in the current project. It doesn't matter if the file is a member of the project. // Also, it doesn't matter if this is an F# file. For example, an error in Microsoft.Common.targets will cause a file to be opened here. // However, opening the document does not mean it will be shown in VS. if (!Microsoft.VisualStudio.ErrorHandler.Failed(openDoc.OpenDocumentViaProject(file, ref logicalView, out sp, out hier, out itemid, out frame)) && frame != null) { object docData; frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out docData); // Get the text lines buffer = docData as IVsTextLines; if (buffer == null) { IVsTextBufferProvider bufferProvider = docData as IVsTextBufferProvider; if (bufferProvider != null) { bufferProvider.GetTextBuffer(out buffer); } } } // Need to adjust line and column indexing for the task window, which assumes zero-based values if (span.iStartLine > 0 && span.iStartIndex > 0) { span.iStartLine -= 1; span.iEndLine -= 1; span.iStartIndex -= 1; span.iEndIndex -= 1; } // Add error to task list var taskText = global::FSharp.Compiler.ErrorLogger.NewlineifyErrorString(errorEvent.Message); if (errorReporter != null) { errorReporter.ReportError2(taskText, errorCode, (VSTASKPRIORITY)priority, span.iStartLine, span.iStartIndex, span.iEndLine, span.iEndIndex, file); } }); }
/// <summary> /// Add the error/warning to the error list and potentially to the output window. /// </summary> private void AddToErrorList( BuildEventArgs errorEvent, string subcategory, string errorCode, string file, int startLine, int startColumn, int endLine, int endColumn) { if (file == null) { file = String.Empty; } bool isWarning = errorEvent is BuildWarningEventArgs; TaskPriority priority = isWarning ? TaskPriority.Normal : TaskPriority.High; TextSpan span; span.iStartLine = startLine; span.iStartIndex = startColumn; span.iEndLine = endLine < startLine ? span.iStartLine : endLine; span.iEndIndex = (endColumn < startColumn) && (span.iStartLine == span.iEndLine) ? span.iStartIndex : endColumn; if (OutputWindowPane != null && (this.Verbosity != LoggerVerbosity.Quiet || errorEvent is BuildErrorEventArgs)) { // Format error and output it to the output window string message = this.FormatMessage(errorEvent.Message); DefaultCompilerError e = new DefaultCompilerError(file, span.iStartLine, span.iStartIndex, span.iEndLine, span.iEndIndex, errorCode, message); e.IsWarning = isWarning; Output(GetFormattedErrorMessage(e)); } UIThread.Run(delegate() { IVsUIShellOpenDocument openDoc = serviceProvider.GetService(typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument; if (openDoc == null) { return; } IVsWindowFrame frame; IOleServiceProvider sp; IVsUIHierarchy hier; uint itemid; Guid logicalView = VSConstants.LOGVIEWID_Code; IVsTextLines buffer = null; // JAF // Notes about acquiring the buffer: // If the file physically exists then this will open the document in the current project. It doesn't matter if the file is a member of the project. // Also, it doesn't matter if this is an F# file. For example, an error in Microsoft.Common.targets will cause a file to be opened here. // However, opening the document does not mean it will be shown in VS. if (!Microsoft.VisualStudio.ErrorHandler.Failed(openDoc.OpenDocumentViaProject(file, ref logicalView, out sp, out hier, out itemid, out frame)) && frame != null) { object docData; frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out docData); // Get the text lines buffer = docData as IVsTextLines; if (buffer == null) { IVsTextBufferProvider bufferProvider = docData as IVsTextBufferProvider; if (bufferProvider != null) { bufferProvider.GetTextBuffer(out buffer); } } } // Need to adjust line and column indexing for the task window, which assumes zero-based values if (span.iStartLine > 0 && span.iStartIndex > 0) { span.iStartLine -= 1; span.iEndLine -= 1; span.iStartIndex -= 1; span.iEndIndex -= 1; } // Add new document task to task list DocumentTask task = new DocumentTask(serviceProvider, buffer, // May be null // This seems weird. Why would warning status make this a 'compile error'? // The “code sense” errors produce red squiggles, whereas the “compile” errors produce blue squiggles. (This is in line with C#’s pre-VS2008-SP1 behavior.) Swapping these two gives us a look consistent with that of the language service. isWarning ? MARKERTYPE.MARKER_COMPILE_ERROR : MARKERTYPE.MARKER_CODESENSE_ERROR, span, file, subcategory); // Add error to task list task.Text = Microsoft.FSharp.Compiler.ErrorLogger.NewlineifyErrorString(errorEvent.Message); task.Priority = priority; task.ErrorCategory = isWarning ? TaskErrorCategory.Warning : TaskErrorCategory.Error; task.Category = TaskCategory.BuildCompile; task.HierarchyItem = hierarchy; task.Navigate += new EventHandler(NavigateTo); if (null != this.TaskReporter) { this.taskReporter.AddTask(task); } else { this.taskProvider.Tasks.Add(task); } }); }