未验证 提交 c6bf2eab 编写于 作者: A Andy Gocke 提交者: GitHub

Fix namespace incremental parsing bug (#37770)

There was a previous parsing change (#32999) which modified namespace
parsing to allow modifiers and attributes on namespaces, to improve
error recovery.

This PR contained a bug because it didn't move the incremental parsing
check to before parsing attributes and modifiers, which should now
be included in incremental parsing to prevent changes from being dropped

Fixes #37665, #37664, #37663
上级 a02d689f
......@@ -378,11 +378,6 @@ internal CompilationUnitSyntax ParseCompilationUnitCore()
SyntaxListBuilder<AttributeListSyntax> attributeLists,
SyntaxListBuilder modifiers)
{
if (this.IsIncrementalAndFactoryContextMatches && this.CurrentNodeKind == SyntaxKind.NamespaceDeclaration)
{
return (NamespaceDeclarationSyntax)this.EatNode();
}
Debug.Assert(this.CurrentToken.Kind == SyntaxKind.NamespaceKeyword);
var namespaceToken = this.EatToken(SyntaxKind.NamespaceKeyword);
......@@ -2005,10 +2000,9 @@ private bool IsTypeDeclarationStart()
}
}
private static bool CanReuseMemberDeclaration(
CSharp.Syntax.MemberDeclarationSyntax member)
private static bool CanReuseMemberDeclaration(SyntaxKind kind)
{
switch (member?.Kind())
switch (kind)
{
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
......@@ -2025,6 +2019,7 @@ private bool IsTypeDeclarationStart()
case SyntaxKind.DestructorDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.ConstructorDeclaration:
case SyntaxKind.NamespaceDeclaration:
return true;
default:
return false;
......@@ -2075,8 +2070,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatementCore(SyntaxKind
// don't reuse members if they were previously declared under a different type keyword kind
if (this.IsIncrementalAndFactoryContextMatches)
{
var member = this.CurrentNode as CSharp.Syntax.MemberDeclarationSyntax;
if (CanReuseMemberDeclaration(member))
if (CanReuseMemberDeclaration(CurrentNodeKind))
{
return (MemberDeclarationSyntax)this.EatNode();
}
......
......@@ -3,10 +3,7 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -2774,6 +2771,112 @@ class B
WalkTreeAndVerify(tree.GetCompilationUnitRoot(), fullTree.GetCompilationUnitRoot());
}
[Fact]
[WorkItem(37663, "https://github.com/dotnet/roslyn/issues/37663")]
public void AssemblyAttributeBeforeNamespace()
{
var src = @"
using System;
using System.Linq;
[assembly:]
namespace N
{ }";
var tree = SyntaxFactory.ParseSyntaxTree(src);
var text = tree.GetText();
var span = new TextSpan(src.IndexOf(":"), 1);
var change = new TextChange(span, "");
text = text.WithChanges(change);
tree = tree.WithChangedText(text);
var fullTree = SyntaxFactory.ParseSyntaxTree(text.ToString());
WalkTreeAndVerify(tree.GetCompilationUnitRoot(), fullTree.GetCompilationUnitRoot());
}
[WorkItem(37665, "https://github.com/dotnet/roslyn/issues/37665")]
[Fact]
public void AddBracketInUsingDirective()
{
var source =
@"using System;
namespace NS
{
class A { }
}
";
var tree = SyntaxFactory.ParseSyntaxTree(source);
var text = tree.GetText();
var span = new TextSpan(source.IndexOf(";"), 0);
var change = new TextChange(span, "[");
text = text.WithChanges(change);
tree = tree.WithChangedText(text);
var fullTree = SyntaxFactory.ParseSyntaxTree(text.ToString());
WalkTreeAndVerify(tree.GetCompilationUnitRoot(), fullTree.GetCompilationUnitRoot());
}
[WorkItem(37665, "https://github.com/dotnet/roslyn/issues/37665")]
[Fact]
public void AddAttributeAfterUsingDirective()
{
var source =
@"using System;
namespace NS
{
class A { }
}
";
var tree = SyntaxFactory.ParseSyntaxTree(source);
var text = tree.GetText();
var span = new TextSpan(source.IndexOf(";") + 1, 0);
var change = new TextChange(span, "[Obsolete]");
text = text.WithChanges(change);
tree = tree.WithChangedText(text);
var fullTree = SyntaxFactory.ParseSyntaxTree(text.ToString());
WalkTreeAndVerify(tree.GetCompilationUnitRoot(), fullTree.GetCompilationUnitRoot());
}
[WorkItem(37665, "https://github.com/dotnet/roslyn/issues/37665")]
[Fact]
public void AddTrailingModifierInUsingDirective()
{
var source =
@"using System;
namespace NS
{
class A { }
}
";
var tree = SyntaxFactory.ParseSyntaxTree(source);
var text = tree.GetText();
var span = new TextSpan(source.IndexOf(";") + 1, 0);
var change = new TextChange(span, "public");
text = text.WithChanges(change);
tree = tree.WithChangedText(text);
var fullTree = SyntaxFactory.ParseSyntaxTree(text.ToString());
WalkTreeAndVerify(tree.GetCompilationUnitRoot(), fullTree.GetCompilationUnitRoot());
}
[WorkItem(37665, "https://github.com/dotnet/roslyn/issues/37665")]
[Fact]
public void AddTrailingModifierInUsingDirective_2()
{
var source =
@"using System;publi
namespace NS
{
class A { }
}
";
var tree = SyntaxFactory.ParseSyntaxTree(source);
var text = tree.GetText();
var substring = "publi";
var span = new TextSpan(source.IndexOf(substring) + substring.Length, 0);
var change = new TextChange(span, "c");
text = text.WithChanges(change);
tree = tree.WithChangedText(text);
var fullTree = SyntaxFactory.ParseSyntaxTree(text.ToString());
WalkTreeAndVerify(tree.GetCompilationUnitRoot(), fullTree.GetCompilationUnitRoot());
}
#endregion
#region Helper functions
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册