Example #1
0
        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)));
        }
Example #2
0
 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)
 {
 }
Example #3
0
        public static TextSpan GetTextSpan(DiagnosticDataLocation dataLocation, SourceText text)
        {
            var lines = text.Lines;

            if (lines.Count == 0)
            {
                return(default);
Example #4
0
        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;
            }
        }
Example #5
0
        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());
        }
Example #6
0
        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);
        }
Example #7
0
        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)));
        }
Example #8
0
        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;
        }
Example #9
0
        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();
        }
        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 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);
        }
Example #16
0
        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;
        }