提交 6f189c4f 编写于 作者: O Omar Tawfik 提交者: GitHub

Getting diagnostics and location of a token without a syntax tree should not crash (#17899)

* Getting diagnostics and location of a token without a syntax tree should not crash

* Address PR Comments

* Cleanup

* PR Comments
上级 3353af7c
......@@ -2,17 +2,18 @@
using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
using InternalSyntax = Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class SyntaxFactoryTests
public class SyntaxFactoryTests : CSharpTestBase
{
[Fact]
public void SyntaxTree()
......@@ -377,5 +378,75 @@ private static string ToXmlEntities(string str)
return builder.ToString();
}
[Fact]
[WorkItem(17067, "https://github.com/dotnet/roslyn/issues/17067")]
public void GetTokenDiagnosticsWithoutSyntaxTree_WithDiagnostics()
{
var tokens = SyntaxFactory.ParseTokens("1l").ToList();
Assert.Equal(2, tokens.Count); // { "1l", "EOF" }
var literal = tokens.First();
Assert.Equal("1l", literal.Text);
Assert.Equal(Location.None, literal.GetLocation());
literal.GetDiagnostics().Verify(
// warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
Diagnostic(ErrorCode.WRN_LowercaseEllSuffix));
}
[Fact]
[WorkItem(17067, "https://github.com/dotnet/roslyn/issues/17067")]
public void GetTokenDiagnosticsWithoutSyntaxTree_WithoutDiagnostics()
{
var tokens = SyntaxFactory.ParseTokens("1L").ToList();
Assert.Equal(2, tokens.Count); // { "1L", "EOF" }
var literal = tokens.First();
Assert.Equal("1L", literal.Text);
Assert.Equal(Location.None, literal.GetLocation());
literal.GetDiagnostics().Verify();
}
[Fact]
[WorkItem(17067, "https://github.com/dotnet/roslyn/issues/17067")]
public void GetTokenDiagnosticsWithSyntaxTree_WithDiagnostics()
{
var expression = (LiteralExpressionSyntax)SyntaxFactory.ParseExpression("1l");
Assert.Equal("1l", expression.Token.Text);
Assert.NotNull(expression.Token.SyntaxTree);
var expectedLocation = Location.Create(expression.Token.SyntaxTree, TextSpan.FromBounds(0, 2));
Assert.Equal(expectedLocation, expression.Token.GetLocation());
expression.Token.GetDiagnostics().Verify(
// (1,2): warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
// 1l
Diagnostic(ErrorCode.WRN_LowercaseEllSuffix, "l").WithLocation(1, 2));
}
[Fact]
[WorkItem(17067, "https://github.com/dotnet/roslyn/issues/17067")]
public void GetTokenDiagnosticsWithSyntaxTree_WithoutDiagnostics()
{
var expression = (LiteralExpressionSyntax)SyntaxFactory.ParseExpression("1L");
Assert.Equal("1L", expression.Token.Text);
Assert.NotNull(expression.Token.SyntaxTree);
var expectedLocation = Location.Create(expression.Token.SyntaxTree, TextSpan.FromBounds(0, 2));
Assert.Equal(expectedLocation, expression.Token.GetLocation());
expression.Token.GetDiagnostics().Verify();
}
[Fact]
[WorkItem(17067, "https://github.com/dotnet/roslyn/issues/17067")]
public void GetDiagnosticsFromNullToken()
{
var token = new SyntaxToken(null);
Assert.Equal(Location.None, token.GetLocation());
token.GetDiagnostics().Verify();
}
}
}
......@@ -20,6 +20,8 @@ namespace Microsoft.CodeAnalysis
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
public struct SyntaxToken : IEquatable<SyntaxToken>
{
private static readonly Func<DiagnosticInfo, Diagnostic> s_createDiagnosticWithoutLocation = Diagnostic.Create;
internal static readonly Func<SyntaxToken, bool> NonZeroWidth = t => t.Width > 0;
internal static readonly Func<SyntaxToken, bool> Any = t => true;
......@@ -634,9 +636,11 @@ internal SyntaxToken GetPreviousToken(Func<SyntaxToken, bool> predicate, Func<Sy
/// </summary>
public Location GetLocation()
{
return Node != null
? this.SyntaxTree.GetLocation(this.Span)
: Location.None;
var tree = SyntaxTree;
return tree == null
? Location.None
: tree.GetLocation(Span);
}
/// <summary>
......@@ -646,9 +650,23 @@ public Location GetLocation()
/// </summary>
public IEnumerable<Diagnostic> GetDiagnostics()
{
return Node != null
? this.SyntaxTree.GetDiagnostics(this)
: SpecializedCollections.EmptyEnumerable<Diagnostic>();
if (Node == null)
{
return SpecializedCollections.EmptyEnumerable<Diagnostic>();
}
var tree = SyntaxTree;
if (tree == null)
{
var diagnostics = Node.GetDiagnostics();
return diagnostics.Length == 0
? SpecializedCollections.EmptyEnumerable<Diagnostic>()
: diagnostics.Select(s_createDiagnosticWithoutLocation);
}
return tree.GetDiagnostics(this);
}
/// <summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册