public static Location ConvertLocation( this DiagnosticDataLocation dataLocation, SyntacticDocument?document = null) { if (dataLocation?.DocumentId == null) { return(Location.None); } if (document == null) { if (dataLocation.OriginalFilePath == null || dataLocation.SourceSpan == null) { return(Location.None); } var span = dataLocation.SourceSpan.Value; return(Location.Create(dataLocation.OriginalFilePath, span, new LinePositionSpan( new LinePosition(dataLocation.OriginalStartLine, dataLocation.OriginalStartColumn), new LinePosition(dataLocation.OriginalEndLine, dataLocation.OriginalEndColumn)))); } Contract.ThrowIfFalse(dataLocation.DocumentId == document.Document.Id); var syntaxTree = document.SyntaxTree; return(syntaxTree.GetLocation(dataLocation.SourceSpan ?? DiagnosticData.GetTextSpan(dataLocation, document.Text))); }
public DiagnosticData( string id, string category, string message, string enuMessageForBingSearch, DiagnosticSeverity severity, bool isEnabledByDefault, int warningLevel, Workspace workspace, ProjectId projectId, DiagnosticDataLocation location = null, IReadOnlyCollection <DiagnosticDataLocation> additionalLocations = null, string title = null, string description = null, string helpLink = null, bool isSuppressed = false, IReadOnlyList <string> customTags = null, ImmutableDictionary <string, string> properties = null) : this( id, category, message, enuMessageForBingSearch, severity, severity, isEnabledByDefault, warningLevel, customTags ?? ImmutableArray <string> .Empty, properties ?? ImmutableDictionary <string, string> .Empty, workspace, projectId, location, additionalLocations, title, description, helpLink, isSuppressed) { }
public static TextSpan GetTextSpan(DiagnosticDataLocation dataLocation, SourceText text) { var lines = text.Lines; if (lines.Count == 0) { return(default);
private static void AdjustBoundaries(DiagnosticDataLocation dataLocation, TextLineCollection lines, out int startLine, out int startColumn, out int endLine, out int endColumn) { startLine = dataLocation?.OriginalStartLine ?? 0; var originalStartColumn = dataLocation?.OriginalStartColumn ?? 0; startColumn = Math.Max(originalStartColumn, 0); if (startLine < 0) { startLine = 0; startColumn = 0; } endLine = dataLocation?.OriginalEndLine ?? 0; var originalEndColumn = dataLocation?.OriginalEndColumn ?? 0; endColumn = Math.Max(originalEndColumn, 0); if (endLine < 0) { endLine = startLine; endColumn = startColumn; } else if (endLine >= lines.Count) { endLine = lines.Count - 1; endColumn = lines[endLine].EndIncludingLineBreak; } }
public static async Task <Location> ConvertLocationAsync( this DiagnosticDataLocation dataLocation, Project project, CancellationToken cancellationToken) { if (dataLocation?.DocumentId == null) { return(Location.None); } var document = project.GetDocument(dataLocation?.DocumentId); if (document == null) { return(Location.None); } if (document.SupportsSyntaxTree) { var syntacticDocument = await SyntacticDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); return(dataLocation.ConvertLocation(syntacticDocument)); } return(dataLocation.ConvertLocation()); }
private static async Task <Location> ConvertLocationAsync( Project project, DiagnosticDataLocation dataLocation, ImmutableDictionary <DocumentId, SyntaxTree> documentIdToTree, CancellationToken cancellationToken) { if (dataLocation?.DocumentId != null) { var document = project.GetDocument(dataLocation?.DocumentId); if (document != null) { if (document.SupportsSyntaxTree) { var syntaxTree = documentIdToTree != null ? documentIdToTree[document.Id] : await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var span = dataLocation.SourceSpan ?? GetTextSpan(dataLocation, syntaxTree.GetText()); return(syntaxTree.GetLocation(span)); } else if (dataLocation?.OriginalFilePath != null && dataLocation.SourceSpan != null) { var span = dataLocation.SourceSpan.Value; return(Location.Create(dataLocation?.OriginalFilePath, span, new LinePositionSpan( new LinePosition(dataLocation.OriginalStartLine, dataLocation.OriginalStartColumn), new LinePosition(dataLocation.OriginalEndLine, dataLocation.OriginalEndColumn)))); } } } return(Location.None); }
public static TextSpan GetTextSpan(DiagnosticDataLocation dataLocation, SourceText text) { var lines = text.Lines; if (lines.Count == 0) { return(default(TextSpan)); } var originalStartLine = dataLocation?.OriginalStartLine ?? 0; if (originalStartLine >= lines.Count) { return(new TextSpan(text.Length, 0)); } int startLine, startColumn, endLine, endColumn; AdjustBoundaries(dataLocation, lines, out startLine, out startColumn, out endLine, out endColumn); var startLinePosition = new LinePosition(startLine, startColumn); var endLinePosition = new LinePosition(endLine, endColumn); SwapIfNeeded(ref startLinePosition, ref endLinePosition); var span = text.Lines.GetTextSpan(new LinePositionSpan(startLinePosition, endLinePosition)); return(TextSpan.FromBounds(Math.Min(Math.Max(span.Start, 0), text.Length), Math.Min(Math.Max(span.End, 0), text.Length))); }
public DiagnosticData( string id, string category, string message, string enuMessageForBingSearch, DiagnosticSeverity severity, DiagnosticSeverity defaultSeverity, bool isEnabledByDefault, int warningLevel, IReadOnlyList <string> customTags, ImmutableDictionary <string, string> properties, Workspace workspace, ProjectId projectId, DiagnosticDataLocation location = null, IReadOnlyCollection <DiagnosticDataLocation> additionalLocations = null, string title = null, string description = null, string helpLink = null, bool isSuppressed = false) { this.Id = id; this.Category = category; this.Message = message; this.ENUMessageForBingSearch = enuMessageForBingSearch; this.Severity = severity; this.DefaultSeverity = defaultSeverity; this.IsEnabledByDefault = isEnabledByDefault; this.WarningLevel = warningLevel; this.CustomTags = customTags; this.Properties = properties; this.Workspace = workspace; this.ProjectId = projectId; this.DataLocation = location; this.AdditionalLocations = additionalLocations; this.Title = title; this.Description = description; this.HelpLink = helpLink; this.IsSuppressed = isSuppressed; }
public DiagnosticData( string id, string category, string message, string enuMessageForBingSearch, DiagnosticSeverity severity, DiagnosticSeverity defaultSeverity, bool isEnabledByDefault, int warningLevel, IReadOnlyList <string> customTags, ImmutableDictionary <string, string> properties, ProjectId projectId, DiagnosticDataLocation location = null, IReadOnlyCollection <DiagnosticDataLocation> additionalLocations = null, string language = null, string title = null, string description = null, string helpLink = null, bool isSuppressed = false) { Id = id; Category = category; Message = message; ENUMessageForBingSearch = enuMessageForBingSearch; Severity = severity; DefaultSeverity = defaultSeverity; IsEnabledByDefault = isEnabledByDefault; WarningLevel = warningLevel; CustomTags = customTags; Properties = properties; ProjectId = projectId; DataLocation = location; AdditionalLocations = additionalLocations; Language = language; Title = title; Description = description; HelpLink = helpLink; IsSuppressed = isSuppressed; }
/// <summary> /// Gets <see cref="DiagnosticData"/> objects for selected error list entries. /// For remove suppression, the method also returns selected external source diagnostics. /// </summary> public async Task<ImmutableArray<DiagnosticData>> GetSelectedItemsAsync(bool isAddSuppression, CancellationToken cancellationToken) { var builder = ImmutableArray.CreateBuilder<DiagnosticData>(); Dictionary<string, Project> projectNameToProjectMapOpt = null; Dictionary<Project, ImmutableDictionary<string, Document>> filePathToDocumentMapOpt = null; foreach (var entryHandle in _tableControl.SelectedEntries) { cancellationToken.ThrowIfCancellationRequested(); DiagnosticData diagnosticData = null; int index; var roslynSnapshot = GetEntriesSnapshot(entryHandle, out index); if (roslynSnapshot != null) { diagnosticData = roslynSnapshot.GetItem(index)?.Primary; } else if (!isAddSuppression) { // For suppression removal, we also need to handle FxCop entries. bool isSuppressedEntry; if (!IsNonRoslynEntrySupportingSuppressionState(entryHandle, out isSuppressedEntry) || !isSuppressedEntry) { continue; } string errorCode = null, category = null, message = null, filePath = null, projectName = null; int line = -1; // FxCop only supports line, not column. DiagnosticDataLocation location = null; if (entryHandle.TryGetValue(StandardTableColumnDefinitions.ErrorCode, out errorCode) && !string.IsNullOrEmpty(errorCode) && entryHandle.TryGetValue(StandardTableColumnDefinitions.ErrorCategory, out category) && !string.IsNullOrEmpty(category) && entryHandle.TryGetValue(StandardTableColumnDefinitions.Text, out message) && !string.IsNullOrEmpty(message) && entryHandle.TryGetValue(StandardTableColumnDefinitions.ProjectName, out projectName) && !string.IsNullOrEmpty(projectName)) { if (projectNameToProjectMapOpt == null) { projectNameToProjectMapOpt = new Dictionary<string, Project>(); foreach (var p in _workspace.CurrentSolution.Projects) { projectNameToProjectMapOpt[p.Name] = p; } } cancellationToken.ThrowIfCancellationRequested(); Project project; if (!projectNameToProjectMapOpt.TryGetValue(projectName, out project)) { // bail out continue; } Document document = null; var hasLocation = (entryHandle.TryGetValue(StandardTableColumnDefinitions.DocumentName, out filePath) && !string.IsNullOrEmpty(filePath)) && (entryHandle.TryGetValue(StandardTableColumnDefinitions.Line, out line) && line >= 0); if (hasLocation) { if (string.IsNullOrEmpty(filePath) || line < 0) { // bail out continue; } ImmutableDictionary<string, Document> filePathMap; filePathToDocumentMapOpt = filePathToDocumentMapOpt ?? new Dictionary<Project, ImmutableDictionary<string, Document>>(); if (!filePathToDocumentMapOpt.TryGetValue(project, out filePathMap)) { filePathMap = await GetFilePathToDocumentMapAsync(project, cancellationToken).ConfigureAwait(false); filePathToDocumentMapOpt[project] = filePathMap; } if (!filePathMap.TryGetValue(filePath, out document)) { // bail out continue; } var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var linePosition = new LinePosition(line, 0); var linePositionSpan = new LinePositionSpan(start: linePosition, end: linePosition); var textSpan = (await tree.GetTextAsync(cancellationToken).ConfigureAwait(false)).Lines.GetTextSpan(linePositionSpan); location = new DiagnosticDataLocation(document.Id, textSpan, filePath, originalStartLine: linePosition.Line, originalStartColumn: linePosition.Character, originalEndLine: linePosition.Line, originalEndColumn: linePosition.Character); } Contract.ThrowIfNull(project); Contract.ThrowIfFalse((document != null) == (location != null)); // Create a diagnostic with correct values for fields we care about: id, category, message, isSuppressed, location // and default values for the rest of the fields (not used by suppression fixer). diagnosticData = new DiagnosticData( id: errorCode, category: category, message: message, enuMessageForBingSearch: message, severity: DiagnosticSeverity.Warning, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 1, isSuppressed: isSuppressedEntry, title: message, location: location, customTags: SuppressionHelpers.SynthesizedExternalSourceDiagnosticCustomTags, properties: ImmutableDictionary<string, string>.Empty, workspace: _workspace, projectId: project.Id); } } if (IsEntryWithConfigurableSuppressionState(diagnosticData)) { builder.Add(diagnosticData); } } return builder.ToImmutable(); }
public static TextSpan GetTextSpan(DiagnosticDataLocation dataLocation, SourceText text) { var lines = text.Lines; if (lines.Count == 0) { return default(TextSpan); } var originalStartLine = dataLocation?.OriginalStartLine ?? 0; if (originalStartLine >= lines.Count) { return new TextSpan(text.Length, 0); } int startLine, startColumn, endLine, endColumn; AdjustBoundaries(dataLocation, lines, out startLine, out startColumn, out endLine, out endColumn); var startLinePosition = new LinePosition(startLine, startColumn); var endLinePosition = new LinePosition(endLine, endColumn); SwapIfNeeded(ref startLinePosition, ref endLinePosition); var span = text.Lines.GetTextSpan(new LinePositionSpan(startLinePosition, endLinePosition)); return TextSpan.FromBounds(Math.Min(Math.Max(span.Start, 0), text.Length), Math.Min(Math.Max(span.End, 0), text.Length)); }
public DiagnosticData( string id, string category, string message, string enuMessageForBingSearch, DiagnosticSeverity severity, DiagnosticSeverity defaultSeverity, bool isEnabledByDefault, int warningLevel, IReadOnlyList<string> customTags, ImmutableDictionary<string, string> properties, Workspace workspace, ProjectId projectId, DiagnosticDataLocation location = null, IReadOnlyCollection<DiagnosticDataLocation> additionalLocations = null, string title = null, string description = null, string helpLink = null, bool isSuppressed = false) { this.Id = id; this.Category = category; this.Message = message; this.ENUMessageForBingSearch = enuMessageForBingSearch; this.Severity = severity; this.DefaultSeverity = defaultSeverity; this.IsEnabledByDefault = isEnabledByDefault; this.WarningLevel = warningLevel; this.CustomTags = customTags; this.Properties = properties; this.Workspace = workspace; this.ProjectId = projectId; this.DataLocation = location; this.AdditionalLocations = additionalLocations; this.Title = title; this.Description = description; this.HelpLink = helpLink; this.IsSuppressed = isSuppressed; }
public DiagnosticData( string id, string category, string message, string enuMessageForBingSearch, DiagnosticSeverity severity, bool isEnabledByDefault, int warningLevel, Workspace workspace, ProjectId projectId, DiagnosticDataLocation location = null, IReadOnlyCollection<DiagnosticDataLocation> additionalLocations = null, string title = null, string description = null, string helpLink = null, bool isSuppressed = false) : this( id, category, message, enuMessageForBingSearch, severity, severity, isEnabledByDefault, warningLevel, ImmutableArray<string>.Empty, ImmutableDictionary<string, string>.Empty, workspace, projectId, location, additionalLocations, title, description, helpLink, isSuppressed) { }
private static void WriteTo(ObjectWriter writer, DiagnosticDataLocation item, CancellationToken cancellationToken) { if (item == null) { writer.WriteBoolean(false); return; } else { writer.WriteBoolean(true); } if (item.SourceSpan.HasValue) { writer.WriteBoolean(true); writer.WriteInt32(item.SourceSpan.Value.Start); writer.WriteInt32(item.SourceSpan.Value.Length); } else { writer.WriteBoolean(false); } writer.WriteString(item.OriginalFilePath); writer.WriteInt32(item.OriginalStartLine); writer.WriteInt32(item.OriginalStartColumn); writer.WriteInt32(item.OriginalEndLine); writer.WriteInt32(item.OriginalEndColumn); writer.WriteString(item.MappedFilePath); writer.WriteInt32(item.MappedStartLine); writer.WriteInt32(item.MappedStartColumn); writer.WriteInt32(item.MappedEndLine); writer.WriteInt32(item.MappedEndColumn); }
private static async Task<Location> ConvertLocationAsync( Project project, DiagnosticDataLocation dataLocation, ImmutableDictionary<DocumentId, SyntaxTree> documentIdToTree, CancellationToken cancellationToken) { if (dataLocation?.DocumentId != null) { var document = project.GetDocument(dataLocation?.DocumentId); if (document != null) { if (document.SupportsSyntaxTree) { var syntaxTree = documentIdToTree != null ? documentIdToTree[document.Id] : await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var span = dataLocation.SourceSpan ?? GetTextSpan(dataLocation, syntaxTree.GetText()); return syntaxTree.GetLocation(span); } else if (dataLocation?.OriginalFilePath != null && dataLocation.SourceSpan != null) { var span = dataLocation.SourceSpan.Value; return Location.Create(dataLocation?.OriginalFilePath, span, new LinePositionSpan( new LinePosition(dataLocation.OriginalStartLine, dataLocation.OriginalStartColumn), new LinePosition(dataLocation.OriginalEndLine, dataLocation.OriginalEndColumn))); } } } return Location.None; }