Can I move the Declaration or Triva syntax at a certain position?
-
Donnerstag, 26. April 2012 10:14
Dear everyone,
I'm trying to create some small program to play with Roslyn, I just want to add [OperationContract] for every methods in interface, and it works fine. And you can see the result's like this:
using System; using System.ServiceModel; namespace Solution { public class IInterface { [OperationContract] /* * We have comments here */ string Method1(string value); } }But I wonder that if we can change the [OperationContract] attribute is right above the "Method1" or not?, and MultilineComments trivia is above the attribute.
Thanks in advance.
Bui Duc Nha.
- Bearbeitet Bui Duc Nha Donnerstag, 26. April 2012 10:22
Alle Antworten
-
Donnerstag, 26. April 2012 22:48Besitzer
Hi - You should be able to do this by removing the leading trivia from the MethodDeclarationSyntax and attaching it to your new Attribute. The below example demonstrates a couple of ways to do this.
using System; using System.Collections.Generic; using System.Linq; using Roslyn.Compilers.CSharp; class Program { static void Main() { var code = @" using System; using System.ServiceModel; namespace Solution { public interface IInterface { /* * We have comments here */ string Method1(string value); string Method2(string value); } }"; SyntaxTree tree = SyntaxTree.ParseCompilationUnit(code); var rewriter = new AttributeInserter(tree); var newRoot = (CompilationUnitSyntax)rewriter.Visit(tree.Root); // newRoot = newRoot.Format(); // This is required in case of Option2 below. Console.WriteLine(newRoot.GetFullText()); var newTree = SyntaxTree.Create("MyFile.cs", newRoot); } class AttributeInserter : SyntaxRewriter { SyntaxTree tree; public AttributeInserter(SyntaxTree tree) { this.tree = tree; } private IEnumerable<SyntaxTrivia> GetAllLeadingWhitespaceThatIsOnSameLineAsNode(SyntaxNode node) { var line = tree.GetLineSpan(node.Span, false).StartLinePosition.Line; return node.GetLeadingTrivia() .Where(t => t.Kind == SyntaxKind.WhitespaceTrivia && tree.GetLineSpan(t.Span, false).StartLinePosition.Line == line); } protected override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax methodDeclaration) { if (methodDeclaration.Parent.Kind == SyntaxKind.InterfaceDeclaration) { // Create new attribute. var attribute = Syntax.AttributeDeclaration(attributes: Syntax.SeparatedList<AttributeSyntax>( Syntax.Attribute(Syntax.ParseName("OperationContract")))); // Copy all leading trivia from method declaration (including comments) onto the attribute. attribute = attribute .WithLeadingTrivia(methodDeclaration.GetLeadingTrivia()) .WithTrailingTrivia(Syntax.EndOfLine("\r\n")); // Remove leading trivia from the method declaration since we // have now copied those over to the attribute. // Option1: // We can preserve just the leading whitespace trivia that exists on the // same line as the method declaration to preserve formatting. methodDeclaration = methodDeclaration.WithLeadingTrivia( GetAllLeadingWhitespaceThatIsOnSameLineAsNode(methodDeclaration)); // Option2: If you don't want to worry about formatting now, you could // remove 'all' leading trivia from the method declaration // and just call .Format() to normalize whitespace on 'newRoot' above. // node = node.WithLeadingTrivia(); // Update the method declaration with the new attribute. methodDeclaration = methodDeclaration.Update( attributes: Syntax.List<AttributeDeclarationSyntax>(attribute), modifiers: methodDeclaration.Modifiers, returnType: methodDeclaration.ReturnType, explicitInterfaceSpecifierOpt: methodDeclaration.ExplicitInterfaceSpecifierOpt, identifier: methodDeclaration.Identifier, typeParameterListOpt: methodDeclaration.TypeParameterListOpt, parameterList: methodDeclaration.ParameterList, constraintClauses: methodDeclaration.ConstraintClauses, bodyOpt: methodDeclaration.BodyOpt, semicolonTokenOpt: methodDeclaration.SemicolonTokenOpt); } return methodDeclaration; } } }
Hope this helps!
Shyam Namboodiripad | Software Development Engineer in Test | Roslyn Compilers Team
- Als Antwort markiert Bui Duc Nha Freitag, 27. April 2012 01:57
-
Freitag, 27. April 2012 01:59That's exactly What I need, thanks a lot!

