public void GetAdjustedDiagnosticSpan( DocumentId documentId, Location location, out TextSpan sourceSpan, out FileLinePositionSpan originalLineInfo, out FileLinePositionSpan mappedLineInfo) { sourceSpan = location.SourceSpan; originalLineInfo = location.GetLineSpan(); mappedLineInfo = location.GetMappedLineSpan(); // Update the original source span, if required. LinePositionSpan originalSpan; LinePositionSpan mappedSpan; if (!TryAdjustSpanIfNeededForVenus(documentId, originalLineInfo, mappedLineInfo, out originalSpan, out mappedSpan)) { return; } if (originalSpan.Start != originalLineInfo.StartLinePosition || originalSpan.End != originalLineInfo.EndLinePosition) { originalLineInfo = new FileLinePositionSpan(originalLineInfo.Path, originalSpan.Start, originalSpan.End); var textLines = location.SourceTree.GetText().Lines; var startPos = textLines.GetPosition(originalSpan.Start); var endPos = textLines.GetPosition(originalSpan.End); sourceSpan = new TextSpan(startPos, endPos - startPos); } if (mappedSpan.Start != mappedLineInfo.StartLinePosition || mappedSpan.End != mappedLineInfo.EndLinePosition) { mappedLineInfo = new FileLinePositionSpan(mappedLineInfo.Path, mappedSpan.Start, mappedSpan.End); } }
private QuickFix ConvertSymbol(ISymbol symbol, Location location) { var lineSpan = location.GetLineSpan(); var path = lineSpan.Path; var documents = _workspace.GetDocuments(path); var format = SymbolDisplayFormat.MinimallyQualifiedFormat; format = format.WithMemberOptions(format.MemberOptions ^ SymbolDisplayMemberOptions.IncludeContainingType ^ SymbolDisplayMemberOptions.IncludeType); format = format.WithKindOptions(SymbolDisplayKindOptions.None); return new SymbolLocation { Text = symbol.ToDisplayString(format), Kind = symbol.GetKind(), FileName = path, Line = lineSpan.StartLinePosition.Line + 1, Column = lineSpan.StartLinePosition.Character + 1, EndLine = lineSpan.EndLinePosition.Line + 1, EndColumn = lineSpan.EndLinePosition.Character + 1, Projects = documents.Select(document => document.Project.Name).ToArray() }; }
public void GetAdjustedDiagnosticSpan( DocumentId documentId, Location location, out TextSpan sourceSpan, out FileLinePositionSpan originalLineInfo, out FileLinePositionSpan mappedLineInfo) { sourceSpan = location.SourceSpan; originalLineInfo = location.GetLineSpan(); mappedLineInfo = location.GetMappedLineSpan(); // check quick bail out case. if (location == Location.None) { return; } // Update the original source span, if required. if (!TryAdjustSpanIfNeededForVenus(documentId, originalLineInfo, mappedLineInfo, out var originalSpan, out var mappedSpan)) { return; } if (originalSpan.Start != originalLineInfo.StartLinePosition || originalSpan.End != originalLineInfo.EndLinePosition) { originalLineInfo = new FileLinePositionSpan(originalLineInfo.Path, originalSpan.Start, originalSpan.End); var textLines = location.SourceTree.GetText().Lines; var startPos = textLines.GetPosition(originalSpan.Start); var endPos = textLines.GetPosition(originalSpan.End); sourceSpan = TextSpan.FromBounds(startPos, Math.Max(startPos, endPos)); } if (mappedSpan.Start != mappedLineInfo.StartLinePosition || mappedSpan.End != mappedLineInfo.EndLinePosition) { mappedLineInfo = new FileLinePositionSpan(mappedLineInfo.Path, mappedSpan.Start, mappedSpan.End); } }
internal static void GetObjectData(Location location, SerializationInfo info) { var fileSpan = location.GetLineSpan(); var mappedFileSpan = location.GetMappedLineSpan(); info.AddValue("sourceSpan", location.SourceSpan, typeof(TextSpan)); info.AddValue("fileSpan", fileSpan, typeof(FileLinePositionSpan)); info.AddValue("mappedFileSpan", mappedFileSpan, typeof(FileLinePositionSpan)); info.AddValue("kind", (byte)location.Kind); }
protected override void WritePhysicalLocation(Location location) { Debug.Assert(HasPath(location)); FileLinePositionSpan span = location.GetLineSpan(); _writer.WriteObjectStart(); _writer.Write("uri", GetUri(span.Path)); WriteRegion(span); _writer.WriteObjectEnd(); }
public static DomRegion ToDomRegion(this Microsoft.CodeAnalysis.Location location, int injectedHeaderLines = 0) { //DomRegion is 1-based Editor friendly struct var linePosition = location.GetLineSpan().StartLinePosition; return(new DomRegion { FileName = location.SourceTree.FilePath, BeginLine = linePosition.Line + 1 - injectedHeaderLines, EndLine = linePosition.Line + 1 - injectedHeaderLines, BeginColumn = linePosition.Character + 1, }); }
private FileMemberElement AsNode(SyntaxNode node, string text, Location location) { var ret = new FileMemberElement(); var lineSpan = location.GetLineSpan(); ret.Projects = new List<string>(); ret.ChildNodes = new List<FileMemberElement>(); ret.Kind = node.Kind().ToString(); ret.Location = new QuickFix(); ret.Location.Text = text; ret.Location.Line = 1 + lineSpan.StartLinePosition.Line; ret.Location.Column = 1 + lineSpan.StartLinePosition.Character; ret.Location.EndLine = 1 + lineSpan.EndLinePosition.Line; ret.Location.EndColumn = 1 + lineSpan.EndLinePosition.Character; return ret; }
protected override void WritePhysicalLocation(Location diagnosticLocation) { Debug.Assert(HasPath(diagnosticLocation)); FileLinePositionSpan span = diagnosticLocation.GetLineSpan(); _writer.WriteObjectStart(); // physicalLocation _writer.WriteObjectStart("artifactLocation"); _writer.Write("uri", GetUri(span.Path)); _writer.WriteObjectEnd(); // artifactLocation WriteRegion(span); _writer.WriteObjectEnd(); }
private void WritePhysicalLocation(Location location) { Debug.Assert(HasPath(location)); FileLinePositionSpan span = location.GetLineSpan(); _writer.WriteObjectStart(); _writer.Write("uri", GetUri(span.Path)); // Note that SARIF lines and columns are 1-based, but FileLinePositionSpan is 0-based _writer.WriteObjectStart("region"); _writer.Write("startLine", span.StartLinePosition.Line + 1); _writer.Write("startColumn", span.StartLinePosition.Character + 1); _writer.Write("endLine", span.EndLinePosition.Line + 1); _writer.Write("endColumn", span.EndLinePosition.Character + 1); _writer.WriteObjectEnd(); // region _writer.WriteObjectEnd(); }
internal GraphNode GetLocationNode(ISymbol symbol, Location location, IGraphContext context, ProjectId projectId, CancellationToken cancellationToken) { var span = location.GetLineSpan(); var lineText = location.SourceTree.GetText(cancellationToken).Lines[span.StartLinePosition.Line].ToString(); var filePath = location.SourceTree.FilePath; var sourceLocation = new SourceLocation(filePath, new Position(span.StartLinePosition.Line, span.StartLinePosition.Character), new Position(span.EndLinePosition.Line, span.EndLinePosition.Character)); var label = string.Format("{0} ({1}, {2}): {3}", System.IO.Path.GetFileName(filePath), span.StartLinePosition.Line + 1, span.StartLinePosition.Character + 1, lineText.TrimStart()); var locationNode = context.Graph.Nodes.GetOrCreate(sourceLocation.CreateGraphNodeId(), label, CodeNodeCategories.SourceLocation); locationNode[CodeNodeProperties.SourceLocation] = sourceLocation; locationNode[RoslynGraphProperties.ContextProjectId] = projectId; locationNode[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Reference", Accessibility.NotApplicable); return locationNode; }
private Value GetLocationValue(Location location) { var builder = ArrayBuilder <KeyValuePair <string, Value> > .GetInstance(); var path = location.IsInSource ? location.SourceTree.FilePath : WellKnownStrings.None; builder.Add(CreateSimpleKeyValuePair(WellKnownStrings.LocationSyntaxTreePath, path)); var spanInfoValue = GetSpanInfoValue(location.GetLineSpan()); builder.Add(KeyValuePair.Create(WellKnownStrings.LocationSpanInfo, spanInfoValue)); var coreLocationValue = Value.Create(builder.ToImmutableAndFree(), this); // Our log format requires this to be wrapped. var wrapperList = Value.Create(ImmutableArray.Create(coreLocationValue), this); var wrapperKvp = KeyValuePair.Create(WellKnownStrings.Location, wrapperList); return(Value.Create(ImmutableArray.Create(wrapperKvp), this)); }
private async Task<QuickFix> GetQuickFix(Location location) { if (!location.IsInSource) throw new Exception("Location is not in the source tree"); var lineSpan = location.GetLineSpan(); var path = lineSpan.Path; var documents = _workspace.GetDocuments(path); var line = lineSpan.StartLinePosition.Line; var syntaxTree = await documents.First().GetSyntaxTreeAsync(); var text = syntaxTree.GetText().Lines[line].ToString(); return new QuickFix { Text = text.Trim(), FileName = path, Line = line + 1, Column = lineSpan.StartLinePosition.Character + 1, EndLine = lineSpan.EndLinePosition.Line + 1, EndColumn = lineSpan.EndLinePosition.Character + 1, Projects = documents.Select(document => document.Project.Name).ToArray() }; }
private static bool HasPath(Location location) { return(!string.IsNullOrEmpty(location.GetLineSpan().Path)); }
/// <summary> /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location in the expected DiagnosticResult. /// </summary> /// <param name="analyzer">The analyzer that was being run on the sources.</param> /// <param name="diagnostic">The diagnostic that was found in the code.</param> /// <param name="actual">The Location of the Diagnostic found in the code.</param> /// <param name="expected">The DiagnosticResultLocation that should have been found.</param> private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) { var actualSpan = actual.GetLineSpan(); var message = FormattableString.Invariant( $@"Expected diagnostic to be in file ""{expected.Path}"" was actually in file ""{actualSpan.Path}"" Diagnostic: {FormatDiagnostics(analyzer, diagnostic)} "); (actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test."))) .Should().BeTrue(message); var actualLinePosition = actualSpan.StartLinePosition; // Only check line position if there is an actual line in the real diagnostic if (actualLinePosition.Line > 0) { if (actualLinePosition.Line + 1 != expected.Line) { message = FormattableString.Invariant( $@"Expected diagnostic to be on line ""{expected.Line}"" was actually on line ""{actualLinePosition.Line + 1}"" Diagnostic: {FormatDiagnostics(analyzer, diagnostic)} "); Execute.Assertion.FailWith(message); } } // Only check column position if there is an actual column position in the real diagnostic if (actualLinePosition.Character > 0) { if (actualLinePosition.Character + 1 != expected.Column) { message = FormattableString.Invariant( $@"Expected diagnostic to start at column ""{expected.Column}"" was actually at column ""{actualLinePosition.Character + 1}"" Diagnostic: {FormatDiagnostics(analyzer, diagnostic)} "); Execute.Assertion.FailWith(message); } } }
private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location acturalLocation, DiagnosticResultLocation expectedLocation) { var actualSpan = acturalLocation.GetLineSpan(); Assert.IsTrue(actualSpan.Path == expectedLocation.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expectedLocation.Path.Contains("Test.")), $"Expected diagnostic to be in file \"{expectedLocation.Path}\" was actually in file \"{actualSpan.Path}\"{NewLine}{NewLine}Diagnostic:{NewLine} {FormatDiagnostics(analyzer, diagnostic)}{NewLine}"); var actualLinePosition = actualSpan.StartLinePosition; if (actualLinePosition.Line > 0 && actualLinePosition.Line + 1 != expectedLocation.Line) { Assert.Fail($"Expected diagnostic to be on line \"{expectedLocation.Line}\" was actually on line \"{actualLinePosition.Line + 1}\"{NewLine}{NewLine}Diagnostic:{NewLine} {FormatDiagnostics(analyzer, diagnostic)}{NewLine}"); } if (actualLinePosition.Character > 0 && actualLinePosition.Character + 1 != expectedLocation.Column) { Assert.Fail($"Expected diagnostic to start at column \"{expectedLocation.Column}\" was actually at column \"{actualLinePosition.Character + 1}\"{NewLine}{NewLine}Diagnostic:{NewLine} {FormatDiagnostics(analyzer, diagnostic)}{NewLine}"); } }
/// <summary> /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location in the expected DiagnosticResult. /// </summary> /// <param name="analyzer">The analyzer that was being run on the sources</param> /// <param name="diagnostic">The diagnostic that was found in the code</param> /// <param name="actual">The Location of the Diagnostic found in the code</param> /// <param name="expected">The DiagnosticResultLocation that should have been found</param> private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) { var actualSpan = actual.GetLineSpan(); Assert.IsTrue(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")), $"Expected diagnostic to be in file \"{expected.Path}\" was actually in file \"{actualSpan.Path}\"\r\n\r\nDiagnostic:\r\n {FormatDiagnostics(analyzer, diagnostic)}\r\n"); var actualLinePosition = actualSpan.StartLinePosition; if (actual.GetLineSpan().Span != expected.Span) { Assert.Fail($"Expected diagnostic to have span {expected.Span}; actually had span {actualSpan.Span}.\r\n\r\nDiagnostic:\r\n {FormatDiagnostics(analyzer, diagnostic)}\r\n"); } }
/// <summary> /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location in the expected DiagnosticResult. /// </summary> /// <param name="analyzer">The analyzer that was being run on the sources</param> /// <param name="diagnostic">The diagnostic that was found in the code</param> /// <param name="actual">The Location of the Diagnostic found in the code</param> /// <param name="expected">The DiagnosticResultLocation that should have been found</param> private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) { var actualSpan = actual.GetLineSpan(); Assert.IsTrue(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")), string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic))); var actualLinePosition = actualSpan.StartLinePosition; // Only check line position if there is an actual line in the real diagnostic if (actualLinePosition.Line > 0) { if (actualLinePosition.Line + 1 != expected.Line) { Assert.IsTrue(false, string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic))); } } // Only check column position if there is an actual column position in the real diagnostic if (actualLinePosition.Character > 0) { if (actualLinePosition.Character + 1 != expected.Column) { Assert.IsTrue(false, string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic))); } } }
/// <summary> /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location /// in the expected DiagnosticResult. /// </summary> /// <param name="analyzer">The analyzer that was being run on the sources</param> /// <param name="diagnostic">The diagnostic that was found in the code</param> /// <param name="actual">The Location of the Diagnostic found in the code</param> /// <param name="expected">The DiagnosticResultLocation that should have been found</param> private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) { if (expected.Line == null || expected.Column == null) { if (actual != Location.None) { Assert.Fail($"Expected:\nA project diagnostic with No location\nActual:\n{FormatDiagnostics(analyzer, diagnostic)}"); } } var actualSpan = actual.GetLineSpan(); Assert.AreEqual(actualSpan.Path, expected.FilePath, $"Expected diagnostic to be in file \"{expected.FilePath}\" was actually in file \"{actualSpan.Path}\"\r\n\r\nDiagnostic:\r\n{FormatDiagnostics(analyzer, diagnostic)}\r\n"); var actualLinePosition = actualSpan.StartLinePosition; if (actualLinePosition.Line + 1 != expected.Line) { Assert.Fail( $"Expected diagnostic to be on line \"{expected.Line}\" was actually on line \"{actualLinePosition.Line + 1}\"\r\n\r\nDiagnostic:\r\n{FormatDiagnostics(analyzer, diagnostic)}\r\n"); } if (actualLinePosition.Character + 1 != expected.Column) { Assert.Fail( $"Expected diagnostic to start at column \"{expected.Column}\" was actually at column \"{actualLinePosition.Character + 1}\"\r\n\r\nDiagnostic:\r\n{FormatDiagnostics(analyzer, diagnostic)}\r\n"); } }
/// <summary> /// Helper method to <see cref="VerifyDiagnosticResults"/> that checks the location of a /// <see cref="Diagnostic"/> and compares it with the location described by a /// <see cref="FileLinePositionSpan"/>. /// </summary> /// <param name="analyzers">The analyzer that have been run on the sources.</param> /// <param name="diagnostic">The diagnostic that was found in the code.</param> /// <param name="actual">The location of the diagnostic found in the code.</param> /// <param name="expected">The <see cref="FileLinePositionSpan"/> describing the expected location of the /// diagnostic.</param> private static void VerifyDiagnosticLocation(ImmutableArray<DiagnosticAnalyzer> analyzers, Diagnostic diagnostic, Location actual, FileLinePositionSpan expected) { var actualSpan = actual.GetLineSpan(); string message = string.Format( "Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", expected.Path, actualSpan.Path, FormatDiagnostics(analyzers, diagnostic)); Assert.True( actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")), message); var actualStartLinePosition = actualSpan.StartLinePosition; var actualEndLinePosition = actualSpan.EndLinePosition; VerifyLinePosition(analyzers, diagnostic, actualSpan.StartLinePosition, expected.StartLinePosition, "start"); if (expected.StartLinePosition < expected.EndLinePosition) { VerifyLinePosition(analyzers, diagnostic, actualSpan.EndLinePosition, expected.EndLinePosition, "end"); } }
internal static TextSpan GetTextSpan(Location location) { if (location != null && location.IsInSource) { var csLineSpan = location.GetLineSpan(); if (csLineSpan.IsValid) { var csTextSpan = location.SourceSpan; return new TextSpan(csLineSpan.Path, csTextSpan.Start, csTextSpan.Length, ToTextPosition(csLineSpan.StartLinePosition), ToTextPosition(csLineSpan.EndLinePosition)); } } return default(TextSpan); }
private Value GetLocationValue(Location location) { if (location.SourceTree == null) { return null; } var builder = ArrayBuilder<KeyValuePair<string, Value>>.GetInstance(); builder.Add(CreateSimpleKeyValuePair(WellKnownStrings.LocationSyntaxTreePath, location.SourceTree.FilePath)); var spanInfoValue = GetSpanInfoValue(location.GetLineSpan()); builder.Add(KeyValuePair.Create(WellKnownStrings.LocationSpanInfo, spanInfoValue)); var coreLocationValue = Value.Create(builder.ToImmutableAndFree(), this); // Our log format requires this to be wrapped. var wrapperList = Value.Create(ImmutableArray.Create(coreLocationValue), this); var wrapperKvp = KeyValuePair.Create(WellKnownStrings.Location, wrapperList); return Value.Create(ImmutableArray.Create(wrapperKvp), this); }
private void WriteLocation(Location location) { if (location.SourceTree == null) { return; } _writer.WriteObjectStart(); // location _writer.WriteArrayStart("analysisTarget"); _writer.WriteObjectStart(); // physical location component _writer.Write("uri", GetUri(location.SourceTree)); // Note that SARIF lines and columns are 1-based, but FileLinePositionSpan is 0-based FileLinePositionSpan span = location.GetLineSpan(); _writer.WriteKey("region"); _writer.WriteObjectStart(); _writer.Write("startLine", span.StartLinePosition.Line + 1); _writer.Write("startColumn", span.StartLinePosition.Character + 1); _writer.Write("endLine", span.EndLinePosition.Line + 1); _writer.Write("endColumn", span.EndLinePosition.Character + 1); _writer.WriteObjectEnd(); // region _writer.WriteObjectEnd(); // physical location component _writer.WriteArrayEnd(); // analysisTarget _writer.WriteObjectEnd(); // location }
/// <summary> /// 診断結果のソースコードの位置を検証する内部メソッドです。 /// </summary> private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) { var actualSpan = actual.GetLineSpan(); const string MESSAGE_FORMAT = "Expected diagnostic to be {0} '{1}' was actually {0} '{2}'\r\n\r\nDiagnostic:\r\n {3}"; Assert.IsTrue(string.IsNullOrEmpty(expected.Path) || actualSpan.Path == expected.Path, string.Format(MESSAGE_FORMAT, "in file", expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic))); var actualLinePosition = actualSpan.StartLinePosition; if (actualLinePosition.Line > 0) { Assert.AreEqual(expected.Line, actualLinePosition.Line + 1, string.Format(MESSAGE_FORMAT, "on line", expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic))); } if (actualLinePosition.Character > 0) { Assert.AreEqual(expected.Column, actualLinePosition.Character + 1, string.Format(MESSAGE_FORMAT, "at column", expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic))); } }
public Location(Microsoft.CodeAnalysis.Location location) { this.location = location; this.fileLinePositionSpan = location.GetLineSpan(); }
private static bool HasPath(Location location) { return !string.IsNullOrEmpty(location.GetLineSpan().Path); }
protected NonGeneratedSourceLocation(Context cx, Microsoft.CodeAnalysis.Location init) : base(cx, init) { Position = init.GetLineSpan(); FileEntity = File.Create(Context, Position.Path); }
SourceCodeLocation ConvertToSourceCodeLocation (Location loc) { var lineSpan = loc.GetLineSpan (); return new SourceCodeLocation (loc.SourceTree.FilePath, lineSpan.StartLinePosition.Line, lineSpan.StartLinePosition.Character); }
/// <summary> /// Helper method to <see cref="VerifyDiagnosticResults"/> that checks the location of a /// <see cref="Diagnostic"/> and compares it with the location described by a /// <see cref="DiagnosticResultLocation"/>. /// </summary> /// <param name="analyzers">The analyzer that have been run on the sources.</param> /// <param name="diagnostic">The diagnostic that was found in the code.</param> /// <param name="actual">The location of the diagnostic found in the code.</param> /// <param name="expected">The <see cref="DiagnosticResultLocation"/> describing the expected location of the /// diagnostic.</param> private static void VerifyDiagnosticLocation(ImmutableArray<DiagnosticAnalyzer> analyzers, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) { var actualSpan = actual.GetLineSpan(); string message = string.Format( "Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", expected.Path, actualSpan.Path, FormatDiagnostics(analyzers, diagnostic)); Assert.True( actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")), message); var actualLinePosition = actualSpan.StartLinePosition; // Only check line position if it matters if (expected.Line > 0) { if (actualLinePosition.Line + 1 != expected.Line) { string message2 = string.Format( "Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzers, diagnostic)); Assert.True(false, message2); } } // Only check column position if it matters if (expected.Column > 0) { if (actualLinePosition.Character + 1 != expected.Column) { string message2 = string.Format( "Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzers, diagnostic)); Assert.True(false, message2); } } }
public static Protocol.Range AsRange(this Microsoft.CodeAnalysis.Location location) => AsRange(location.GetLineSpan());