Beispiel #1
0
        /// <summary>
        /// Formats the <see cref="Diagnostic"/> message using the optional <see cref="IFormatProvider"/>.
        /// </summary>
        /// <param name="diagnostic">The diagnostic.</param>
        /// <param name="formatter">The formatter; or null to use the default formatter.</param>
        /// <returns>The formatted message.</returns>
        public virtual string Format(Diagnostic diagnostic, IFormatProvider formatter = null)
        {
            if (diagnostic == null)
            {
                throw new ArgumentNullException("diagnostic");
            }

            var culture = formatter as CultureInfo;

            switch (diagnostic.Location.Kind)
            {
                case LocationKind.SourceFile:
                case LocationKind.XmlFile:
                    var span = diagnostic.Location.GetLineSpan();
                    var mappedSpan = diagnostic.Location.GetMappedLineSpan();
                    if (!span.IsValid || !mappedSpan.IsValid)
                    {
                        goto default;
                    }

                    string path, basePath;
                    if (mappedSpan.HasMappedPath)
                    {
                        path = mappedSpan.Path;
                        basePath = span.Path;
                    }
                    else
                    {
                        path = span.Path;
                        basePath = null;
                    }

                    return string.Format(formatter, "{0}{1}: {2}: {3}",
                                         FormatSourcePath(path, basePath, formatter),
                                         FormatSourceSpan(mappedSpan.Span, formatter),
                                         GetMessagePrefix(diagnostic, culture),
                                         diagnostic.GetMessage(culture));

                case LocationKind.MetadataFile:
                    return string.Format(formatter, "{0}: {1}: {2}",
                                         diagnostic.Location.MetadataModule.Name,
                                         GetMessagePrefix(diagnostic, culture),
                                         diagnostic.GetMessage(culture));

                default:
                    return string.Format(formatter, "{0}: {1}",
                                         GetMessagePrefix(diagnostic, culture),
                                         diagnostic.GetMessage(culture));
            }
        }
Beispiel #2
0
        private static Uri GetHelpLink(Diagnostic diagnostic, out string helpLinkToolTipText)
        {
            var isBing = false;

            helpLinkToolTipText = string.Empty;

            Uri helpLink;

            if (!BrowserHelper.TryGetUri(diagnostic.Descriptor.HelpLinkUri, out helpLink))
            {
                // We use the ENU version of the message for bing search.
                helpLink = BrowserHelper.CreateBingQueryUri(diagnostic.Id, diagnostic.GetMessage(DiagnosticData.USCultureInfo));
                isBing   = true;
            }

            // We make sure not to use Uri.AbsoluteUri for the url displayed in the tooltip so that the url dislayed in the tooltip stays human readable.
            if (helpLink != null)
            {
                helpLinkToolTipText =
                    string.Format(ServicesVSResources.DiagnosticIdHyperlinkTooltipText, diagnostic.Id,
                                  isBing ? ServicesVSResources.FromBing : null, Environment.NewLine, helpLink);
            }

            return(helpLink);
        }
Beispiel #3
0
        object IPreviewPaneService.GetPreviewPane(Diagnostic diagnostic, object previewContent)
        {
            var title = diagnostic?.GetMessage();

            if (string.IsNullOrWhiteSpace(title))
            {
                if (previewContent == null)
                {
                    // Bail out in cases where there is nothing to put in the header section
                    // of the preview pane and no preview content (i.e. no diff view) either.
                    return(null);
                }

                return(new PreviewPane(
                           severityIcon: null, id: null, title: null, description: null, helpLink: null, helpLinkToolTipText: null,
                           previewContent: previewContent, logIdVerbatimInTelemetry: false, serviceProvider: _serviceProvider));
            }

            var helpLinkToolTipText = string.Empty;
            Uri helpLink            = GetHelpLink(diagnostic, out helpLinkToolTipText);

            return(new PreviewPane(
                       severityIcon: GetSeverityIconForDiagnostic(diagnostic),
                       id: diagnostic.Id, title: title,
                       description: diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                       helpLink: helpLink,
                       helpLinkToolTipText: helpLinkToolTipText,
                       previewContent: previewContent,
                       logIdVerbatimInTelemetry: diagnostic.Descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Telemetry),
                       serviceProvider: _serviceProvider));
        }
        public static DiagnosticData Create(Project project, Diagnostic diagnostic)
        {
            if (diagnostic.Location.IsInSource)
            {
                // Project diagnostic reported at a document location (e.g. compilation end action diagnostics).
                var document = project.GetDocument(diagnostic.Location.SourceTree);
                if (document != null)
                {
                    return(Create(document, diagnostic));
                }
            }

            return(new DiagnosticData(
                       diagnostic.Id,
                       diagnostic.Descriptor.Category,
                       diagnostic.GetMessage(CultureInfo.CurrentUICulture),
                       diagnostic.Descriptor.MessageFormat.ToString(USCultureInfo),
                       diagnostic.Severity,
                       diagnostic.DefaultSeverity,
                       diagnostic.Descriptor.IsEnabledByDefault,
                       diagnostic.WarningLevel,
                       diagnostic.Descriptor.CustomTags.AsImmutableOrEmpty(),
                       diagnostic.Properties,
                       project.Solution.Workspace,
                       project.Id,
                       title: diagnostic.Descriptor.Title.ToString(CultureInfo.CurrentUICulture),
                       description: diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                       helpLink: diagnostic.Descriptor.HelpLinkUri));
        }
 private static string GetNotExcpectedMessage
     (DiagnosticAnalyzer analyzer,
     Diagnostic actual,
     DiagnosticResult expected)
 {
     return($"Expected diagnostic message to be \"{expected.Message}\" was \"{actual.GetMessage()}\"{Environment.NewLine}{Environment.NewLine}Diagnostic:{Environment.NewLine}    {FormatDiagnostics(analyzer, new[] { actual })}{Environment.NewLine}");
 }
        object IPreviewPaneService.GetPreviewPane(Diagnostic diagnostic, object previewContent)
        {
            var title = diagnostic?.GetMessage();

            if (string.IsNullOrWhiteSpace(title))
            {
                if (previewContent == null)
                {
                    // Bail out in cases where there is nothing to put in the header section
                    // of the preview pane and no preview content (i.e. no diff view) either.
                    return(null);
                }

                return(new PreviewPane(
                           severityIcon: null, id: null, title: null, helpMessage: null,
                           description: null, helpLink: null, telemetry: false,
                           previewContent: previewContent, serviceProvider: _serviceProvider));
            }

            return(new PreviewPane(
                       GetSeverityIconForDiagnostic(diagnostic),
                       diagnostic.Id, title,
                       diagnostic.Descriptor.MessageFormat.ToString(DiagnosticData.USCultureInfo),
                       diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                       diagnostic.Descriptor.HelpLinkUri,
                       diagnostic.Descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Telemetry),
                       previewContent, _serviceProvider));
        }
Beispiel #7
0
        private ImmutableArray <Diagnostic> GetFunctionDiagnostics(Diagnostic diagnostic)
        {
            // If metadata file not found
            if (string.Compare(diagnostic.Id, "CS0006", StringComparison.OrdinalIgnoreCase) == 0)
            {
                string messagePattern = diagnostic.Descriptor.MessageFormat.ToString().Replace("{0}", "(?<arg>.*)");

                Match match = Regex.Match(diagnostic.GetMessage(), messagePattern);

                PackageReference package;

                // If we have the assembly name argument, and it is a package assembly, add a compilation warning
                if (match.Success && match.Groups["arg"] != null && _metadataResolver.TryGetPackageReference(match.Groups["arg"].Value, out package))
                {
                    string message = string.Format(
                        CultureInfo.InvariantCulture,
                        "The reference '{0}' is part of the referenced NuGet package '{1}'. Package assemblies are automatically referenced by your Function and do not require a '#r' directive.",
                        match.Groups["arg"].Value, package.Name);

                    var descriptor = new DiagnosticDescriptor(
                        DotNetConstants.RedundantPackageAssemblyReference,
                        "Redundant assembly reference", message, "AzureFunctions", DiagnosticSeverity.Warning, true);

                    return(ImmutableArray.Create(Diagnostic.Create(descriptor, diagnostic.Location)));
                }
            }

            return(ImmutableArray <Diagnostic> .Empty);
        }
Beispiel #8
0
        private static void VerifyDiagnostics(DiagnosticResult[] expectedDiagnostics, Diagnostic[] actualDiagnostics)
        {
            Assert.Equal(expectedDiagnostics.Length, actualDiagnostics.Length);
            for (var i = 0; i < expectedDiagnostics.Length; i++)
            {
                DiagnosticResult expected = expectedDiagnostics[i];
                Diagnostic       actual   = actualDiagnostics[i];

                Assert.Equal(expected.Id, actual.Id);
                Assert.Equal(expected.Severity, actual.Severity);
                if (expected.HasLocation)
                {
                    FileLinePositionSpan expectedSpan = expected.Spans[0].Span;
                    FileLinePositionSpan actualSpan   = actual.Location.GetLineSpan();
                    Assert.Equal(expectedSpan, actualSpan);
                }

                if (expected.MessageArguments is null)
                {
                    Assert.Equal(expected.MessageFormat, actual.Descriptor.MessageFormat);
                }
                else
                {
                    Assert.Equal(expected.Message, actual.GetMessage());
                }
            }
        }
        private static XElement SerializeDiagnostic(Diagnostic diagnostic, IFormatProvider formatProvider)
        {
            XElement filePathElement = null;
            XElement locationElement = null;

            FileLinePositionSpan span = diagnostic.Location.GetMappedLineSpan();

            if (span.IsValid)
            {
                filePathElement = new XElement("FilePath", span.Path);

                LinePosition linePosition = span.Span.Start;

                locationElement = new XElement("Location",
                                               new XAttribute("Line", linePosition.Line + 1),
                                               new XAttribute("Character", linePosition.Character + 1));
            }

            return(new XElement(
                       "Diagnostic",
                       new XAttribute("Id", diagnostic.Id),
                       new XElement("Severity", diagnostic.Severity),
                       new XElement("Message", diagnostic.GetMessage(formatProvider)),
                       filePathElement,
                       locationElement));
        }
        object IPreviewPaneService.GetPreviewPane(Diagnostic diagnostic, object previewContent)
        {
            var telemetry = diagnostic == null ? false : diagnostic.Descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Telemetry);

            if ((diagnostic == null) && (previewContent == null))
            {
                // Bail out in cases where there is no diagnostic (which means there is nothing to put in
                // the header section of the preview pane) as well as no preview content (i.e. no diff view).
                return(null);
            }

            if ((diagnostic == null) || (diagnostic.Descriptor is TriggerDiagnosticDescriptor))
            {
                return(new PreviewPane(
                           null, null, null, null, null, null, telemetry, previewContent, _serviceProvider));
            }
            else
            {
                return(new PreviewPane(
                           GetSeverityIconForDiagnostic(diagnostic),
                           diagnostic.Id, diagnostic.GetMessage(),
                           diagnostic.Descriptor.MessageFormat.ToString(DiagnosticData.USCultureInfo),
                           diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                           diagnostic.Descriptor.HelpLinkUri, telemetry, previewContent, _serviceProvider));
            }
        }
        internal static CompilationDiagnostic FromCSharpDiagnostic(Diagnostic diagnostic)
        {
            if (diagnostic == null)
            {
                return(null);
            }

            var mappedLineSpan = diagnostic.Location.GetMappedLineSpan();
            var file           = Path.GetFileName(mappedLineSpan.Path);
            var line           = mappedLineSpan.StartLinePosition.Line;

            if (file != CoreConstants.MainComponentFilePath)
            {
                // Make it 1-based. Skip the main component where we add @page directive line
                line++;
            }
            else
            {
                // Offset for MudProviders
                line -= 4;
            }

            return(new CompilationDiagnostic
            {
                Kind = CompilationDiagnosticKind.CSharp,
                Code = diagnostic.Descriptor.Id,
                Severity = diagnostic.Severity,
                Description = diagnostic.GetMessage(),
                File = file,
                Line = line,
            });
        }
Beispiel #12
0
        public void LogDiagnostic(Diagnostic diagnostic)
        {
            _writer.WriteObjectStart(); // result
            _writer.Write("ruleId", diagnostic.Id);

            string ruleKey = _descriptors.Add(diagnostic.Descriptor);
            if (ruleKey != diagnostic.Id)
            {
                _writer.Write("ruleKey", ruleKey);
            }

            _writer.Write("level", GetLevel(diagnostic.Severity));

            string message = diagnostic.GetMessage(_culture);
            if (!string.IsNullOrEmpty(message))
            {
                _writer.Write("message", message);
            }

            if (diagnostic.IsSuppressed)
            {
                _writer.WriteArrayStart("suppressionStates");
                _writer.Write("suppressedInSource");
                _writer.WriteArrayEnd();
            }

            WriteLocations(diagnostic.Location, diagnostic.AdditionalLocations);
            WriteProperties(diagnostic);

            _writer.WriteObjectEnd(); // result
        }
Beispiel #13
0
        internal void LogDiagnostic(Diagnostic diagnostic, CultureInfo culture)
        {
            _writer.WriteObjectStart(); // result
            _writer.Write("ruleId", diagnostic.Id);
            _writer.Write("kind", GetKind(diagnostic.Severity));

            WriteLocations(diagnostic.Location, diagnostic.AdditionalLocations);

            string message = diagnostic.GetMessage(culture);
            if (string.IsNullOrEmpty(message))
            {
                message = "<None>";
            }

            string description = diagnostic.Descriptor.Description.ToString(culture);
            if (string.IsNullOrEmpty(description))
            {
                _writer.Write("fullMessage", message);
            }
            else
            {
                _writer.Write("shortMessage", message);
                _writer.Write("fullMessage", description);
            }

            _writer.Write("isSuppressedInSource", diagnostic.IsSuppressed);

            WriteTags(diagnostic);

            WriteProperties(diagnostic, culture);

            _writer.WriteObjectEnd(); // result
        }
Beispiel #14
0
        /// <summary>
        /// Create DiagnosticHelper instance based on Microsoft.CodeAnalysis.<see cref="Diagnostic"/> class.
        /// </summary>
        /// <param name="diagnostic">Diagnostic info, which is use to create helper object</param>
        /// <returns>Helper object based on <see cref="diagnostic"/></returns>
        public static DiagnosticHelper Create(Diagnostic diagnostic)
        {
            // Set proper severity type
            SeverityType severity = SeverityType.None;

            if (diagnostic.Severity == DiagnosticSeverity.Error)
            {
                severity = SeverityType.Error;
            }
            else if (diagnostic.Severity == DiagnosticSeverity.Warning)
            {
                severity = SeverityType.Warning;
            }
            else if (diagnostic.Severity == DiagnosticSeverity.Info)
            {
                severity = SeverityType.Info;
            }

            // Create helper object
            return(new DiagnosticHelper {
                Severity = severity,
                Location = new CodeLocation(diagnostic.Location),
                Information = diagnostic.GetMessage(),
                SyntaxNode = diagnostic.Location
                             .SourceTree
                             ?.GetRoot()
                             .FindNode(diagnostic.Location.SourceSpan),
            });
        }
Beispiel #15
0
        public static string GetBingHelpMessage(this Diagnostic diagnostic, Workspace workspace = null)
        {
            var option = GetCustomTypeInBingSearchOption(workspace);

            // We use the ENU version of the message for bing search.
            return(option ? diagnostic.GetMessage(USCultureInfo) : diagnostic.Descriptor.GetBingHelpMessage());
        }
Beispiel #16
0
        /// <summary>
        /// Checks the actual Diagnostic found and compares it to the corresponding DiagnosticResult.
        /// Diagnostics are considered equal only if the DiagnosticResultLocation, Id, Severity, and Message of the DiagnosticResult match the actual diagnostic.
        /// </summary>
        /// <param name="analyzer">The analyzer that was being run on the sources</param>
        /// <param name="expected">Diagnostic Result that should have appeared in the code</param>
        /// <param name="actual">The Diagnostic found by the compiler after running the analyzer on the source code</param>
        private static void VerifyDiagnosticResult(DiagnosticAnalyzer analyzer, DiagnosticResult expected, Diagnostic actual)
        {
            if (expected.Line == -1 && expected.Column == -1)
            {
                Assert.AreEqual(Location.None, actual.Location,
                                $"Expected:\nA project diagnostic with No location\nActual:\n{FormatDiagnostics(analyzer, actual)}");
            }
            else
            {
                VerifyDiagnosticLocation(analyzer, actual, actual.Location, expected.Locations.First());
                var additionalLocations = actual.AdditionalLocations.ToArray();

                Assert.AreEqual(expected.Locations.Length - 1, additionalLocations.Length,
                                $"Expected {expected.Locations.Length - 1} additional locations but got {additionalLocations.Length} for Diagnostic:\r\n    {FormatDiagnostics(analyzer, actual)}\r\n");

                for (int j = 0; j < additionalLocations.Length; ++j)
                {
                    VerifyDiagnosticLocation(analyzer, actual, additionalLocations[j], expected.Locations[j + 1]);
                }
            }

            Assert.AreEqual(expected.Id, actual.Id,
                            $"Expected diagnostic id to be \"{expected.Id}\" was \"{actual.Id}\"\r\n\r\nDiagnostic:\r\n    {FormatDiagnostics(analyzer, actual)}\r\n");

            Assert.AreEqual(expected.Severity, actual.Severity,
                            $"Expected diagnostic severity to be \"{expected.Severity}\" was \"{actual.Severity}\"\r\n\r\nDiagnostic:\r\n    {FormatDiagnostics(analyzer, actual)}\r\n");

            Assert.AreEqual(expected.Message, actual.GetMessage(),
                            $"Expected diagnostic message to be \"{expected.Message}\" was \"{actual.GetMessage()}\"\r\n\r\nDiagnostic:\r\n    {FormatDiagnostics(analyzer, actual)}\r\n");
        }
Beispiel #17
0
        public void GetErrorsAndWarnings()
        {
            string            text        = @"class Program
{
    static int Main(string[] args)
    {
    }
}";
            SyntaxTree        tree        = SyntaxFactory.ParseSyntaxTree(text);
            CSharpCompilation compilation = CSharpCompilation
                                            .Create("program.exe")
                                            .AddSyntaxTrees(tree)
                                            .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
            IEnumerable <Diagnostic> errorsAndWarnings = compilation.GetDiagnostics();

            Assert.Single(errorsAndWarnings);
            Diagnostic error = errorsAndWarnings.First();

            Assert.Equal(
                "'Program.Main(string[])': not all code paths return a value",
                error.GetMessage(CultureInfo.InvariantCulture));
            Location errorLocation = error.Location;

            Assert.Equal(4, error.Location.SourceSpan.Length);
            SourceText programText = errorLocation.SourceTree.GetText();

            Assert.Equal("Main", programText.ToString(errorLocation.SourceSpan));
            FileLinePositionSpan span = error.Location.GetLineSpan();

            Assert.Equal(15, span.StartLinePosition.Character);
            Assert.Equal(2, span.StartLinePosition.Line);
        }
Beispiel #18
0
        // emit the compilation result into a byte array.
        // throw an exception with corresponding message
        // if there are errors
        private static byte[] EmitToArray
        (
            this Compilation compilation
        )
        {
            using (var stream = new MemoryStream())
            {
                // emit result into a stream
                var emitResult = compilation.Emit(stream);

                if (!emitResult.Success)
                {
                    // if not successful, throw an exception
                    Diagnostic firstError =
                        emitResult
                        .Diagnostics
                        .FirstOrDefault
                        (
                            diagnostic =>
                            diagnostic.Severity == DiagnosticSeverity.Error
                        );

                    throw new Exception(firstError?.GetMessage());
                }

                // get the byte array from a stream
                return(stream.ToArray());
            }
        }
Beispiel #19
0
        public static List <Regex> Handler(Diagnostic diagnostic)
        {
            string formart = diagnostic.Descriptor.MessageFormat.ToString();
            string text    = diagnostic.GetMessage();

            lock (UsingCache)
            {
                if (!RegCache.ContainsKey(formart))
                {
                    var   deal  = RegexHelper.GetRealRegexString(formart).Replace("\\{0\\}", "(?<result0>.*)");
                    Regex regex = new Regex(deal, RegexOptions.Singleline | RegexOptions.Compiled);
                    RegCache[formart]   = regex;
                    UsingCache[formart] = new List <Regex>();
                }


                var matches = RegCache[formart].Matches(text);
                for (int i = 0; i < matches.Count; i++)
                {
                    var tempReg = $"using (?<result0>{matches[i].Groups["result0"].Value}.*?);";
                    UsingCache[formart].Add(new Regex(tempReg, RegexOptions.Singleline | RegexOptions.Compiled));
                }
                return(UsingCache[formart]);
            }
        }
Beispiel #20
0
        public static DiagnosticData Create(Document document, Diagnostic diagnostic)
        {
            var location = CreateLocation(document, diagnostic.Location);

            var additionalLocations = diagnostic.AdditionalLocations.Count == 0
                ? (IReadOnlyCollection <DiagnosticDataLocation>)Array.Empty <DiagnosticDataLocation>()
                : diagnostic.AdditionalLocations.Where(loc => loc.IsInSource)
                                      .Select(loc => CreateLocation(document.Project.GetDocument(loc.SourceTree), loc))
                                      .WhereNotNull()
                                      .ToReadOnlyCollection();

            return(new DiagnosticData(
                       diagnostic.Id,
                       diagnostic.Descriptor.Category,
                       diagnostic.GetMessage(CultureInfo.CurrentUICulture),
                       diagnostic.GetBingHelpMessage(),
                       diagnostic.Severity,
                       diagnostic.DefaultSeverity,
                       diagnostic.Descriptor.IsEnabledByDefault,
                       diagnostic.WarningLevel,
                       diagnostic.Descriptor.CustomTags.AsImmutableOrEmpty(),
                       diagnostic.Properties,
                       document.Project.Solution.Workspace,
                       document.Project.Id,
                       location,
                       additionalLocations,
                       title: diagnostic.Descriptor.Title.ToString(CultureInfo.CurrentUICulture),
                       description: diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                       helpLink: diagnostic.Descriptor.HelpLinkUri,
                       isSuppressed: diagnostic.IsSuppressed));
        }
Beispiel #21
0
        private static void ThrowExceptionFromDiagnostic(string path, string code, Diagnostic diagnostic)
        {
            var message  = diagnostic.GetMessage();
            var position = diagnostic.Location.GetLineSpan().StartLinePosition.Line + 1;

            throw new CompilerException(message, path, code, position);
        }
		public DiagnosticResult (Diagnostic diagnostic) : base (GetSpan (diagnostic), diagnostic.GetMessage ())
		{
			if (diagnostic == null)
				throw new ArgumentNullException ("diagnostic");
			this.diagnostic = diagnostic;

			SetSeverity (diagnostic.Severity, GetIssueMarker ()); 
		}
        protected override Task <ImmutableArray <CodeAction> > ComputeCodeActionsAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var codeAction = new MyCodeAction(
                diagnostic.GetMessage(),
                c => FixWithSyntaxEditorAsync(document, diagnostic, c));

            return(Task.FromResult(ImmutableArray.Create <CodeAction>(codeAction)));
        }
        private void AddMessage(Diagnostic diagnostic)
        {
            var messageType = RoslynConvert.ConvertMessageType(diagnostic.Severity);
            var textSpan    = RoslynConvert.ConvertTextSpan(diagnostic.Location.SourceSpan);

            var message = new CompilationMessage(messageType, textSpan, diagnostic.GetMessage());

            _messages.Add(message);
        }
Beispiel #25
0
        /// <summary>
        /// Writes the diagnostic and the offending code.
        /// </summary>
        /// <returns>A string for use in assert exception</returns>
        internal static string ToString(this Diagnostic diagnostic, IReadOnlyList <string> sources)
        {
            var idAndPosition = diagnostic.Location.GetMappedLineSpan();
            var match         = sources.SingleOrDefault(x => CodeReader.FileName(x) == idAndPosition.Path);
            var line          = match != null?CodeReader.GetLineWithErrorIndicated(match, idAndPosition.StartLinePosition) : string.Empty;

            return($"{diagnostic.Id} {diagnostic.GetMessage(CultureInfo.InvariantCulture)}\r\n" +
                   $"  at line {idAndPosition.StartLinePosition.Line} and character {idAndPosition.StartLinePosition.Character} in file {idAndPosition.Path} | {line.TrimStart(' ')}");
        }
Beispiel #26
0
        private static void ThrowExceptionFromDiagnostic(IDictionary <string, string> files, Diagnostic diagnostic)
        {
            var message  = diagnostic.GetMessage();
            var position = diagnostic.Location.GetLineSpan().StartLinePosition.Line + 1;
            var path     = diagnostic.Location.SourceTree.FilePath;
            var code     = files.ContainsKey(path) ? files[path] : string.Empty;

            throw new CompilerException(message, path, code, position);
        }
Beispiel #27
0
        public void RemoveFromHash(Diagnostic dc)
        {
            int hash = dc.GetMessage().GetHashCode();

            if (hcd.ContainsKey(hash))
            {
                hcd.Remove(hash);
            }
        }
Beispiel #28
0
        /// <summary>
        /// Writes the diagnostic and the offending code.
        /// </summary>
        /// <returns>A string for use in assert exception.</returns>
        internal static string ToErrorString(this Diagnostic diagnostic, string padding = "")
        {
            var idAndPosition = diagnostic.Location.GetMappedLineSpan();
            var code          = diagnostic.Location.SourceTree?.GetText(CancellationToken.None).ToString() ?? string.Empty;
            var line          = CodeReader.GetLineWithErrorIndicated(code, idAndPosition.StartLinePosition);

            return($"{padding}{diagnostic.Id} {diagnostic.GetMessage(CultureInfo.InvariantCulture)}\r\n" +
                   $"{padding}  at line {idAndPosition.StartLinePosition.Line} and character {idAndPosition.StartLinePosition.Character} in file {idAndPosition.Path} | {line.TrimStart(' ')}");
        }
        private static CompilationErrorResultObject GetCompilationErrorResultObject(Diagnostic diagnostic)
        {
            var lineSpan = diagnostic.Location.GetLineSpan();
            var result   = CompilationErrorResultObject.Create(diagnostic.Severity.ToString(),
                                                               diagnostic.Id, diagnostic.GetMessage(), lineSpan.Path,
                                                               lineSpan.StartLinePosition.Line, lineSpan.StartLinePosition.Character);

            return(result);
        }
Beispiel #30
0
 public CompilationError(Diagnostic d)
 {
     this.Column      = d.Location.GetLineSpan().StartLinePosition.Character;
     this.Line        = d.Location.GetLineSpan().StartLinePosition.Line + 1;
     this.FileContent = d.Location.SourceTree !.ToString();
     this.FileName    = d.Location.SourceTree.FilePath;
     this.ErrorNumber = d.Descriptor.Id;
     this.ErrorText   = d.GetMessage(null);
 }
Beispiel #31
0
 private static string DescriptionIfObsolete(Diagnostic warning)
 {
     if (warning.Id == "CS0612") // Grouping obsolete warnings by description.
     {
         return(warning.GetMessage());
     }
     else if (warning.Id == "CS0618") // Grouping obsolete warnings with custom message by custom message, to avoid spamming the log for each generated class.
     {
         const string obsoleteInfoTag   = "is obsolete: ";
         var          warningMessage    = warning.GetMessage();
         int          obsoleteInfoStart = warningMessage.IndexOf(obsoleteInfoTag);
         if (obsoleteInfoStart != -1)
         {
             return(" " + warningMessage.Substring(obsoleteInfoStart + obsoleteInfoTag.Length));
         }
     }
     return("");
 }
        /// <inheritdoc />
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
            {
                return(null);
            }
            Diagnostic d = (Diagnostic)value;

            return(d.GetMessage());
        }
        public ProcessingResultDiagnostic(Diagnostic diagnostic)
        {
            Id = diagnostic.Id;
            Severity = diagnostic.Severity;
            Message = diagnostic.GetMessage();

            var lineSpan = diagnostic.Location.GetMappedLineSpan();
            Start = new ProcessingResultDiagnosticLocation(lineSpan.StartLinePosition);
            End = new ProcessingResultDiagnosticLocation(lineSpan.EndLinePosition);
        }
Beispiel #34
0
        private static string GetDiagnosticError(Diagnostic diagnostic)
        {
            var lineSpan = diagnostic.Location.GetMappedLineSpan();

            return
                (lineSpan.Path + "[Line " +
                 (lineSpan.StartLinePosition.Line + 1) + " Pos " +
                 (lineSpan.StartLinePosition.Character + 1) + "]: " +
                 diagnostic.GetMessage());
        }
        private static bool IsINotifyPropertyChangedMissing(Diagnostic diagnostic)
        {
            if (diagnostic.Id == "CS0246")
            {
                return(diagnostic.GetMessage(CultureInfo.InvariantCulture) ==
                       "The type or namespace name 'INotifyPropertyChanged' could not be found (are you missing a using directive or an assembly reference?)");
            }

            return(false);
        }
        public static string Format(Diagnostic diagnostic, FrameworkName targetFramework, IFormatProvider formatter = null)
        {
            if (diagnostic == null)
            {
                throw new ArgumentNullException(nameof(diagnostic));
            }

            var culture = formatter as CultureInfo;

            switch (diagnostic.Location.Kind)
            {
                case LocationKind.SourceFile:
                case LocationKind.XmlFile:
                case LocationKind.ExternalFile:
                    var span = diagnostic.Location.GetLineSpan();
                    var mappedSpan = diagnostic.Location.GetMappedLineSpan();
                    if (!span.IsValid || !mappedSpan.IsValid)
                    {
                        goto default;
                    }

                    string path, basePath;
                    if (mappedSpan.HasMappedPath)
                    {
                        path = mappedSpan.Path;
                        basePath = span.Path;
                    }
                    else
                    {
                        path = span.Path;
                        basePath = null;
                    }

                    var start = mappedSpan.Span.Start;
                    var framework = targetFramework == null ? string.Empty : $" {targetFramework.FullName}";
                    return $"{path}({start.Line + 1},{start.Character + 1}):{framework} {GetMessagePrefix(diagnostic)}: {diagnostic.GetMessage(culture)}";
                default:
                    return $"{GetMessagePrefix(diagnostic)}: {diagnostic.GetMessage(culture)}";
            }
        }
        public override string Format(Diagnostic diagnostic, IFormatProvider formatter = null)
        {
            if (diagnostic == null)
            {
                throw new ArgumentNullException(nameof(diagnostic));
            }

            var culture = formatter as CultureInfo;

            return string.Format(formatter, "{0}: {1}",
                                         GetMessagePrefix(diagnostic),
                                         diagnostic.GetMessage(culture));
        }
        private static QuickFix MakeQuickFix(Diagnostic diagnostic)
        {
            var span = diagnostic.Location.GetMappedLineSpan();
            var quickFix = new QuickFix();
            quickFix.FileName = span.Path;
            quickFix.Line = span.StartLinePosition.Line + 1;
            quickFix.Column = span.StartLinePosition.Character + 1;
            quickFix.EndLine = span.EndLinePosition.Line + 1;
            quickFix.EndColumn = span.EndLinePosition.Character + 1;
            quickFix.Text = diagnostic.GetMessage();
            quickFix.LogLevel = diagnostic.Severity.ToString();

            return quickFix;
        }
 private static QuickFix MakeQuickFix(Diagnostic diagnostic)
 {
     var span = diagnostic.Location.GetMappedLineSpan();
     return new DiagnosticLocation
     {
         FileName = span.Path,
         Line = span.StartLinePosition.Line + 1,
         Column = span.StartLinePosition.Character + 1,
         EndLine = span.EndLinePosition.Line + 1,
         EndColumn = span.EndLinePosition.Character + 1,
         Text = diagnostic.GetMessage(),
         LogLevel = diagnostic.Severity.ToString()
     };
 }
        internal static void LogDiagnostic(Diagnostic diagnostic, CultureInfo culture, ErrorLogger errorLogger)
        {
            if (errorLogger != null)
            {
#pragma warning disable RS0013 // We need to invoke Diagnostic.Descriptor here to log all the metadata properties of the diagnostic.
                var issue = new Issue(diagnostic.Id, diagnostic.GetMessage(culture),
                    diagnostic.Descriptor.Description.ToString(culture), diagnostic.Descriptor.Title.ToString(culture),
                    diagnostic.Category, diagnostic.Descriptor.HelpLinkUri, diagnostic.IsEnabledByDefault, diagnostic.IsSuppressed,
                    diagnostic.DefaultSeverity, diagnostic.Severity, diagnostic.WarningLevel, diagnostic.Location,
                    diagnostic.AdditionalLocations, diagnostic.CustomTags, diagnostic.Properties);
#pragma warning restore RS0013

                errorLogger.LogIssue(issue);
            }
        }
Beispiel #41
0
        object IPreviewPaneService.GetPreviewPane(Diagnostic diagnostic, object previewContent)
        {
            var telemetry = diagnostic == null ? false : diagnostic.Descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Telemetry);

            if ((diagnostic == null) || (diagnostic.Descriptor is TriggerDiagnosticDescriptor))
            {
                return new PreviewPane(
                    null, null, null, null, null, null, telemetry, previewContent, _serviceProvider);
            }
            else
            {
                return new PreviewPane(
                    GetSeverityIconForDiagnostic(diagnostic),
                    diagnostic.Id, diagnostic.GetMessage(),
                    diagnostic.Descriptor.MessageFormat.ToString(DiagnosticData.USCultureInfo),
                    diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                    diagnostic.Descriptor.HelpLinkUri, telemetry, previewContent, _serviceProvider);
            }
        }
        private static Uri GetHelpLink(Diagnostic diagnostic, out string helpLinkToolTipText)
        {
            var isBing = false;
            helpLinkToolTipText = string.Empty;

            Uri helpLink;
            if (!BrowserHelper.TryGetUri(diagnostic.Descriptor.HelpLinkUri, out helpLink))
            {
                // We use the ENU version of the message for bing search.
                helpLink = BrowserHelper.CreateBingQueryUri(diagnostic.Id, diagnostic.GetMessage(DiagnosticData.USCultureInfo));
                isBing = true;
            }

            if (helpLink != null)
            {
                helpLinkToolTipText =
                    string.Format(ServicesVSResources.DiagnosticIdHyperlinkTooltipText, diagnostic.Id,
                        isBing ? ServicesVSResources.FromBing : null, Environment.NewLine, helpLink);
            }

            return helpLink;
        }
Beispiel #43
0
        private static Uri GetHelpLink(Diagnostic diagnostic, string language, string projectType, out string helpLinkToolTipText)
        {
            var isBing = false;
            helpLinkToolTipText = string.Empty;

            Uri helpLink;
            if (!BrowserHelper.TryGetUri(diagnostic.Descriptor.HelpLinkUri, out helpLink))
            {
                // We use the ENU version of the message for bing search.
                helpLink = BrowserHelper.CreateBingQueryUri(diagnostic.Id, diagnostic.GetMessage(DiagnosticData.USCultureInfo), language, projectType);
                isBing = true;
            }

            // We make sure not to use Uri.AbsoluteUri for the url displayed in the tooltip so that the url displayed in the tooltip stays human readable.
            if (helpLink != null)
            {
                helpLinkToolTipText =
                    string.Format(ServicesVSResources.DiagnosticIdHyperlinkTooltipText, diagnostic.Id,
                        isBing ? ServicesVSResources.FromBing : null, Environment.NewLine, helpLink);
            }

            return helpLink;
        }
        public bool IsDiagnosticSuppressed(Diagnostic diagnostic, ISymbol symbolOpt = null)
        {
            // Suppress duplicate analyzer exception diagnostics from the analyzer driver.
            if (diagnostic.CustomTags.Contains(WellKnownDiagnosticTags.AnalyzerException))
            {
                if (_faultedAnalyzerMessages == null)
                {
                    Interlocked.CompareExchange(ref _faultedAnalyzerMessages, new ConcurrentSet<string>(), null);
                }

                var message = diagnostic.GetMessage();
                if (!_faultedAnalyzerMessages.Add(message))
                {
                    return true;
                }
            }

            if (symbolOpt != null && IsDiagnosticSuppressed(diagnostic.Id, symbolOpt))
            {
                return true;
            }

            return IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location);
        }
        public static DiagnosticData Create(Workspace workspace, Diagnostic diagnostic)
        {
            Contract.Requires(diagnostic.Location == null || !diagnostic.Location.IsInSource);

            return new DiagnosticData(
                diagnostic.Id,
                diagnostic.Descriptor.Category,
                diagnostic.GetMessage(CultureInfo.CurrentUICulture),
                diagnostic.GetMessage(USCultureInfo), // We use the ENU version of the message for bing search.
                diagnostic.Severity,
                diagnostic.DefaultSeverity,
                diagnostic.Descriptor.IsEnabledByDefault,
                diagnostic.WarningLevel,
                diagnostic.Descriptor.CustomTags.AsImmutableOrEmpty(),
                diagnostic.Properties,
                workspace,
                projectId: null,
                title: diagnostic.Descriptor.Title.ToString(CultureInfo.CurrentUICulture),
                description: diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                helpLink: diagnostic.Descriptor.HelpLinkUri);
        }
Beispiel #46
0
 private static void WriteCompileError(Diagnostic diag)
 {
     // var info = diag.;
     switch (diag.Severity)
     {
         case DiagnosticSeverity.Warning:
             Console.ForegroundColor = ConsoleColor.DarkYellow;
             Console.Write("Warning");
             break;
         case DiagnosticSeverity.Error:
             Console.ForegroundColor = ConsoleColor.DarkRed;
             Console.Write("Error");
             break;
         default:
             return;
     }
     Console.ResetColor();
     Console.WriteLine(": " + diag.GetMessage());
 }
 private static string ExtractParameterTypeFromDiagnosticMessage(Diagnostic diagnostic) =>
     Regex.Match(diagnostic.GetMessage(CultureInfo.InvariantCulture), "Inconsistent accessibility: parameter type '(.*)' is less accessible than method '(.*)'").Groups[1].Value;
Beispiel #48
0
		/// <summary>
		///   Reports <paramref name="diagnostic" /> depending on its severity. If <paramref name="errorsOnly" /> is <c>true</c>, only
		///   error diagnostics are reported.
		/// </summary>
		/// <param name="diagnostic">The diagnostic that should be reported.</param>
		/// <param name="errorsOnly">Indicates whether error diagnostics should be reported exclusively.</param>
		internal override void Report(Diagnostic diagnostic, bool errorsOnly)
		{
			var location = diagnostic.Location.GetMappedLineSpan();
			var message = diagnostic.GetMessage();

			if (message == null)
				return;

			switch (diagnostic.Severity)
			{
				case DiagnosticSeverity.Error:
					_logger.LogError(
						null,
						diagnostic.Id,
						diagnostic.Descriptor.HelpLinkUri,
						location.Path,
						location.StartLinePosition.Line + 1,
						location.StartLinePosition.Character + 1,
						location.EndLinePosition.Line + 1,
						location.EndLinePosition.Character + 1,
						"{0}",
						message);
					break;
				case DiagnosticSeverity.Warning:
					if (errorsOnly)
						break;

					_logger.LogWarning(
						null,
						diagnostic.Id,
						diagnostic.Descriptor.HelpLinkUri,
						location.Path,
						location.StartLinePosition.Line + 1,
						location.StartLinePosition.Character + 1,
						location.EndLinePosition.Line + 1,
						location.EndLinePosition.Character + 1,
						"{0}",
						message);
					break;
				case DiagnosticSeverity.Info:
				case DiagnosticSeverity.Hidden:
					if (errorsOnly)
						break;

					_logger.LogMessage(
						null,
						diagnostic.Id,
						diagnostic.Descriptor.HelpLinkUri,
						location.Path,
						location.StartLinePosition.Line + 1,
						location.StartLinePosition.Character + 1,
						location.EndLinePosition.Line + 1,
						location.EndLinePosition.Character + 1,
						MessageImportance.Low,
						"{0}",
						message);
					break;
				default:
					Assert.NotReached("Unknown diagnostic severity.");
					break;
			}
		}
Beispiel #49
0
 private static ErrorListItem CreateErrorListItem(Diagnostic diagnostic)
 {
     var mappedSpan = diagnostic.Location.GetMappedLineSpan();
     ErrorSeverity errorSeverity;
     if (diagnostic.Severity == DiagnosticSeverity.Error)
     {
         errorSeverity = ErrorSeverity.Error;
     }
     else if (diagnostic.Severity == DiagnosticSeverity.Warning)
     {
         errorSeverity = ErrorSeverity.Warning;
     }
     else
     {
         errorSeverity = ErrorSeverity.Info;
     }
     return new ErrorListItem(errorSeverity, diagnostic.GetMessage(), mappedSpan.Span.Start.Line, mappedSpan.Span.Start.Character,
         mappedSpan.Span.End.Line, mappedSpan.Span.End.Character);
 }
 private static void ThrowExceptionFromDiagnostic(string path, string code, Diagnostic diagnostic)
 {
     var message = diagnostic.GetMessage();
     var position = diagnostic.Location.GetLineSpan().StartLinePosition.Line + 1;
     throw new HttpParseException(message, null, path, code, position);
 }
Beispiel #51
0
 /// <summary>
 /// SemanticAnalysisに関する診断を格納します
 /// </summary>
 public void AppendSemanticDiagnostic(Diagnostic item)
 {
     this.semanticDiagnosticsBuilder.AppendLine(String.Format(DIAGNOSTIC_ITEM_TEMPLATE,
         item.Severity.ToString(),
         item.GetMessage(),
         item.Id,
         item.Location.SourceSpan.ToString()));
 }
 private static DiagnosticMessage GetDiagnosticMessage(Diagnostic diagnostic)
 {
     var mappedLineSpan = diagnostic.Location.GetMappedLineSpan();
     return new DiagnosticMessage(
         diagnostic.GetMessage(),
         CSharpDiagnosticFormatter.Instance.Format(diagnostic),
         mappedLineSpan.Path,
         mappedLineSpan.StartLinePosition.Line + 1,
         mappedLineSpan.StartLinePosition.Character + 1,
         mappedLineSpan.EndLinePosition.Line + 1,
         mappedLineSpan.EndLinePosition.Character + 1);
 }
        private ImmutableArray<Diagnostic> GetFunctionDiagnostics(Diagnostic diagnostic)
        {
            // If metadata file not found
            if (string.Compare(diagnostic.Id, "CS0006", StringComparison.OrdinalIgnoreCase) == 0)
            {
                string messagePattern = diagnostic.Descriptor.MessageFormat.ToString().Replace("{0}", "(?<arg>.*)");

                Match match = Regex.Match(diagnostic.GetMessage(), messagePattern);

                PackageReference package;
                // If we have the assembly name argument, and it is a package assembly, add a compilation warning
                if (match.Success && match.Groups["arg"] != null && _metadataResolver.TryGetPackageReference(match.Groups["arg"].Value, out package))
                {
                    string message = string.Format(CultureInfo.InvariantCulture,
                        "The reference '{0}' is part of the referenced NuGet package '{1}'. Package assemblies are automatically referenced by your Function and do not require a '#r' directive.",
                        match.Groups["arg"].Value, package.Name);

                    var descriptor = new DiagnosticDescriptor(CSharpConstants.RedundantPackageAssemblyReference,
                       "Redundant assembly reference", message, "AzureFunctions", DiagnosticSeverity.Warning, true);

                    return ImmutableArray.Create(Diagnostic.Create(descriptor, diagnostic.Location));
                }
            }

            return ImmutableArray<Diagnostic>.Empty;
        }
Beispiel #54
0
 private static string GetCompilationErrorMessage(Diagnostic diagnostic)
 {
     string line = diagnostic.Location.IsInSource ? "Line " + (diagnostic.Location.GetMappedLineSpan().Span.Start.Line + 1) : "Metadata";
     return $"{line}: {diagnostic.Id}: {diagnostic.GetMessage()}";
 }
 private static string GetDiagnosticString(Diagnostic diagnostic, string type)
 {
     var line = diagnostic.Location.GetLineSpan();
     return $"{line.Path}({line.StartLinePosition.Line + 1},{line.StartLinePosition.Character + 1}): " + $"{type} {diagnostic.Id}: {diagnostic.GetMessage()}";
 }
 private static DiagnosticMessage GetDiagnosticMessage(Diagnostic diagnostic, FrameworkName targetFramework)
 {
     var mappedLineSpan = diagnostic.Location.GetMappedLineSpan();
     return new DiagnosticMessage(
         diagnostic.GetMessage(),
         RoslynDiagnosticFormatter.Format(diagnostic, targetFramework),
         mappedLineSpan.Path,
         mappedLineSpan.StartLinePosition.Line + 1,
         mappedLineSpan.StartLinePosition.Character + 1,
         mappedLineSpan.EndLinePosition.Line + 1,
         mappedLineSpan.EndLinePosition.Character + 1);
 }
        public static DiagnosticData Create(Document document, Diagnostic diagnostic)
        {
            var location = diagnostic.Location;

            TextSpan sourceSpan;
            FileLinePositionSpan mappedLineInfo;
            FileLinePositionSpan originalLineInfo;
            GetLocationInfo(document, location, out sourceSpan, out originalLineInfo, out mappedLineInfo);

            var mappedStartLine = mappedLineInfo.StartLinePosition.Line;
            var mappedStartColumn = mappedLineInfo.StartLinePosition.Character;
            var mappedEndLine = mappedLineInfo.EndLinePosition.Line;
            var mappedEndColumn = mappedLineInfo.EndLinePosition.Character;

            var originalStartLine = originalLineInfo.StartLinePosition.Line;
            var originalStartColumn = originalLineInfo.StartLinePosition.Character;
            var originalEndLine = originalLineInfo.EndLinePosition.Line;
            var originalEndColumn = originalLineInfo.EndLinePosition.Character;

            return new DiagnosticData(
                diagnostic.Id,
                diagnostic.Descriptor.Category,
                diagnostic.GetMessage(CultureInfo.CurrentUICulture),
                diagnostic.GetMessage(USCultureInfo), // We use the ENU version of the message for bing search.
                diagnostic.Severity,
                diagnostic.DefaultSeverity,
                diagnostic.Descriptor.IsEnabledByDefault,
                diagnostic.WarningLevel,
                diagnostic.Descriptor.CustomTags.AsImmutableOrEmpty(),
                diagnostic.Properties,
                document.Project.Solution.Workspace,
                document.Project.Id,
                document.Id,
                sourceSpan,
                mappedLineInfo.GetMappedFilePathIfExist(),
                mappedStartLine,
                mappedStartColumn,
                mappedEndLine,
                mappedEndColumn,
                originalLineInfo.Path,
                originalStartLine,
                originalStartColumn,
                originalEndLine,
                originalEndColumn,
                title: diagnostic.Descriptor.Title.ToString(CultureInfo.CurrentUICulture),
                description: diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                helpLink: diagnostic.Descriptor.HelpLinkUri);
        }
        public static DiagnosticData Create(Document document, Diagnostic diagnostic)
        {
            var location = CreateLocation(document, diagnostic.Location);

            var additionalLocations = diagnostic.AdditionalLocations.Count == 0
                ? (IReadOnlyCollection<DiagnosticDataLocation>)SpecializedCollections.EmptyArray<DiagnosticDataLocation>()
                : diagnostic.AdditionalLocations.Where(loc => loc.IsInSource)
                                                .Select(loc => CreateLocation(document.Project.GetDocument(loc.SourceTree), loc))
                                                .WhereNotNull()
                                                .ToReadOnlyCollection();

            return new DiagnosticData(
                diagnostic.Id,
                diagnostic.Descriptor.Category,
                diagnostic.GetMessage(CultureInfo.CurrentUICulture),
                diagnostic.GetBingHelpMessage(),
                diagnostic.Severity,
                diagnostic.DefaultSeverity,
                diagnostic.Descriptor.IsEnabledByDefault,
                diagnostic.WarningLevel,
                diagnostic.Descriptor.CustomTags.AsImmutableOrEmpty(),
                diagnostic.Properties,
                document.Project.Solution.Workspace,
                document.Project.Id,
                location,
                additionalLocations,
                title: diagnostic.Descriptor.Title.ToString(CultureInfo.CurrentUICulture),
                description: diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                helpLink: diagnostic.Descriptor.HelpLinkUri,
                isSuppressed: diagnostic.IsSuppressed);
        }
        public static DiagnosticData Create(Project project, Diagnostic diagnostic)
        {
            Contract.Requires(diagnostic.Location == null || !diagnostic.Location.IsInSource);

            return new DiagnosticData(
                diagnostic.Id,
                diagnostic.Descriptor.Category,
                diagnostic.GetMessage(CultureInfo.CurrentUICulture),
                diagnostic.GetBingHelpMessage(),
                diagnostic.Severity,
                diagnostic.DefaultSeverity,
                diagnostic.Descriptor.IsEnabledByDefault,
                diagnostic.WarningLevel,
                diagnostic.Descriptor.CustomTags.AsImmutableOrEmpty(),
                diagnostic.Properties,
                project.Solution.Workspace,
                project.Id,
                title: diagnostic.Descriptor.Title.ToString(CultureInfo.CurrentUICulture),
                description: diagnostic.Descriptor.Description.ToString(CultureInfo.CurrentUICulture),
                helpLink: diagnostic.Descriptor.HelpLinkUri,
                isSuppressed: diagnostic.IsSuppressed);
        }
        private string GetDiagnosticString(Diagnostic diagnostic, string type)
        {
            var line = diagnostic.Location.GetLineSpan();

            // Unity3d must have a relative path starting with "Assets/".
            var path = (line.Path.StartsWith(_options.WorkDirectory + "/") || line.Path.StartsWith(_options.WorkDirectory + "\\"))
                ? line.Path.Substring(_options.WorkDirectory.Length + 1)
                : line.Path;

            return $"{path}({line.StartLinePosition.Line + 1},{line.StartLinePosition.Character + 1}): " + $"{type} {diagnostic.Id}: {diagnostic.GetMessage()}";
        }