diff --git a/src/.nuget/packages.config b/src/.nuget/packages.config index 79c9ceb367b3f43092dfea526cb692a91919e5cb..74f1c396ca3ccc13742e00dfd843d9c86b718d89 100644 --- a/src/.nuget/packages.config +++ b/src/.nuget/packages.config @@ -1,8 +1,8 @@  - - + + diff --git a/src/Diagnostics/FxCop/System.Runtime.Analyzers/Test/Design/TypesThatOwnDisposableFieldsShouldBeDisposableTests.Fixer.cs b/src/Diagnostics/FxCop/System.Runtime.Analyzers/Test/Design/TypesThatOwnDisposableFieldsShouldBeDisposableTests.Fixer.cs index c735e3cc50d03bd1f4f7fd8d225e40d4e2b88989..1186ee13e436eb2244e5dfc049096e8b134c96a2 100644 --- a/src/Diagnostics/FxCop/System.Runtime.Analyzers/Test/Design/TypesThatOwnDisposableFieldsShouldBeDisposableTests.Fixer.cs +++ b/src/Diagnostics/FxCop/System.Runtime.Analyzers/Test/Design/TypesThatOwnDisposableFieldsShouldBeDisposableTests.Fixer.cs @@ -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; diff --git a/src/Tools/Microsoft.CodeAnalysis.Toolset.Open/Targets/VSL.Settings.targets b/src/Tools/Microsoft.CodeAnalysis.Toolset.Open/Targets/VSL.Settings.targets index 9126255c4e01a8bd365c2924eb47692917a64045..bf33ab2016a71d5a587476aedc41520f1f281a49 100644 --- a/src/Tools/Microsoft.CodeAnalysis.Toolset.Open/Targets/VSL.Settings.targets +++ b/src/Tools/Microsoft.CodeAnalysis.Toolset.Open/Targets/VSL.Settings.targets @@ -62,8 +62,8 @@ Microsoft.Net.ToolsetCompilers - $(NuGetPackagesPath)\Microsoft.Net.ToolsetCompilers.1.0.0-rc2-20150415-05\build\Microsoft.Net.ToolsetCompilers.props - $(NuGetPackagesPath)\Microsoft.Net.RoslynDiagnostics.1.0.0-rc2-20150415-05\build\Microsoft.Net.RoslynDiagnostics.props + $(NuGetPackagesPath)\Microsoft.Net.ToolsetCompilers.1.0.0-rc3-20150510-01\build\Microsoft.Net.ToolsetCompilers.props + $(NuGetPackagesPath)\Microsoft.Net.RoslynDiagnostics.1.0.0-rc3-20150510-01\build\Microsoft.Net.RoslynDiagnostics.props $(AdditionalFileItemNames);PublicAPI diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs index 33e11b37f4b10536a39225ede3f3849dfaf0c797..54e6f1392b189f9b395221beef316f09da3dfaa0 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs @@ -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(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(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(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(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); } + + /// + /// Moves the trailing trivia from the node's previous token to the end of the node + /// + 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 diff --git a/src/Workspaces/CSharpTest/CodeGeneration/SymbolEditorTests.cs b/src/Workspaces/CSharpTest/CodeGeneration/SymbolEditorTests.cs index 58d262b129375c1f8d4a40329c53d422cadf7d4a..29adea0b13c0221f5cbd019b9c6d4ad688ecfe06 100644 --- a/src/Workspaces/CSharpTest/CodeGeneration/SymbolEditorTests.cs +++ b/src/Workspaces/CSharpTest/CodeGeneration/SymbolEditorTests.cs @@ -816,8 +816,7 @@ class A }"; var expected = -@"class C -: A +@"class C : A { } diff --git a/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs b/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs index 37680dc3ff6a4a654a434501e0cb722d025f5f2c..839a3d5b7195e8f296d54af3c8b171599eff2f9f 100644 --- a/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs +++ b/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs @@ -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().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 } }