提交 723dea47 编写于 作者: M Matt Warren

Merge pull request #2760 from mattwar/Bug293

add base list before trailing trivia
......@@ -53,8 +53,7 @@ public NoDisposeClass()
using System.IO;
// This class violates the rule.
public class NoDisposeClass
: IDisposable
public class NoDisposeClass : IDisposable
{
FileStream newFile;
......@@ -132,8 +131,7 @@ public class NoDisposeClass
using System.IO;
// This class violates the rule.
public class NoDisposeClass
: IDisposable
public class NoDisposeClass : IDisposable
{
FileStream newFile;
......@@ -166,8 +164,7 @@ public partial class NoDisposeClass
using System.IO;
// This class violates the rule.
public partial class NoDisposeClass
: IDisposable
public partial class NoDisposeClass : IDisposable
{
FileStream newFile;
......
......@@ -2907,22 +2907,36 @@ public override SyntaxNode AddBaseType(SyntaxNode declaration, SyntaxNode baseTy
{
var baseList = this.GetBaseList(declaration);
var newBaseList = (baseList != null)
? baseList.WithTypes(baseList.Types.Insert(0, SyntaxFactory.SimpleBaseType((TypeSyntax)baseType)))
: SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(SyntaxFactory.SimpleBaseType((TypeSyntax)baseType)));
return this.WithBaseList(declaration, newBaseList);
if (baseList != null)
{
return this.WithBaseList(declaration, baseList.WithTypes(baseList.Types.Insert(0, SyntaxFactory.SimpleBaseType((TypeSyntax)baseType))));
}
else
{
return this.AddBaseList(declaration, SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(SyntaxFactory.SimpleBaseType((TypeSyntax)baseType))));
}
}
public override SyntaxNode AddInterfaceType(SyntaxNode declaration, SyntaxNode interfaceType)
{
var baseList = this.GetBaseList(declaration);
var newBaseList = (baseList != null)
? baseList.WithTypes(baseList.Types.Insert(baseList.Types.Count, SyntaxFactory.SimpleBaseType((TypeSyntax)interfaceType)))
: SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(SyntaxFactory.SimpleBaseType((TypeSyntax)interfaceType)));
if (baseList != null)
{
return this.WithBaseList(declaration, baseList.WithTypes(baseList.Types.Insert(baseList.Types.Count, SyntaxFactory.SimpleBaseType((TypeSyntax)interfaceType))));
}
else
{
return this.AddBaseList(declaration, SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(SyntaxFactory.SimpleBaseType((TypeSyntax)interfaceType))));
}
}
private SyntaxNode AddBaseList(SyntaxNode declaration, BaseListSyntax baseList)
{
var newDecl = this.WithBaseList(declaration, baseList);
return this.WithBaseList(declaration, newBaseList);
// move trivia from type identifier to after base list
return this.ShiftTrivia(newDecl, this.GetBaseList(newDecl));
}
private BaseListSyntax GetBaseList(SyntaxNode declaration)
......@@ -3237,6 +3251,26 @@ private SyntaxNode RemoveNodeInternal(SyntaxNode root, SyntaxNode declaration)
return base.RemoveNode(root, declaration);
}
/// <summary>
/// Moves the trailing trivia from the node's previous token to the end of the node
/// </summary>
private SyntaxNode ShiftTrivia(SyntaxNode root, SyntaxNode node)
{
var firstToken = node.GetFirstToken();
var previousToken = firstToken.GetPreviousToken();
if (previousToken != default(SyntaxToken) && root.Contains(previousToken.Parent))
{
var newNode = node.WithTrailingTrivia(node.GetTrailingTrivia().AddRange(previousToken.TrailingTrivia));
var newPreviousToken = previousToken.WithTrailingTrivia(default(SyntaxTriviaList));
return root.ReplaceSyntax(
nodes: new[] { node }, computeReplacementNode: (o, r) => newNode,
tokens: new[] { previousToken }, computeReplacementToken: (o, r) => newPreviousToken,
trivia: null, computeReplacementTrivia: null);
}
return root;
}
#endregion
#region Statements and Expressions
......
......@@ -816,8 +816,7 @@ class A
}";
var expected =
@"class C
: A
@"class C : A
{
}
......
......@@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
......@@ -14,7 +15,8 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Editting
{
public class SyntaxGeneratorTests
{
private readonly SyntaxGenerator _g = SyntaxGenerator.GetGenerator(new AdhocWorkspace(), LanguageNames.CSharp);
private readonly Workspace _ws;
private readonly SyntaxGenerator _g;
private readonly CSharpCompilation _emptyCompilation = CSharpCompilation.Create("empty",
references: new[] { TestReferences.NetFx.v4_0_30319.mscorlib, TestReferences.NetFx.v4_0_30319.System });
......@@ -23,6 +25,8 @@ public class SyntaxGeneratorTests
public SyntaxGeneratorTests()
{
_ws = new AdhocWorkspace();
_g = SyntaxGenerator.GetGenerator(_ws, LanguageNames.CSharp);
_ienumerableInt = _emptyCompilation.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T).Construct(_emptyCompilation.GetSpecialType(SpecialType.System_Int32));
}
......@@ -2867,6 +2871,32 @@ public void M()
{
}");
}
#endregion
[WorkItem(293, "https://github.com/dotnet/roslyn/issues/293")]
[Fact]
[Trait(Traits.Feature, Traits.Features.Formatting)]
public void IntroduceBaseList()
{
var text = @"
public class C
{
}
";
var expected = @"
public class C : IDisposable
{
}
";
var root = SyntaxFactory.ParseCompilationUnit(text);
var decl = root.DescendantNodes().OfType<ClassDeclarationSyntax>().First();
var newDecl = _g.AddInterfaceType(decl, _g.IdentifierName("IDisposable"));
var newRoot = root.ReplaceNode(decl, newDecl);
var elasticOnlyFormatted = Formatter.Format(newRoot, SyntaxAnnotation.ElasticAnnotation, _ws).ToFullString();
Assert.Equal(expected, elasticOnlyFormatted);
}
#endregion
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册