2012-03-28 6 views

Antwort

5

Dies ist ein Feature in Visual Studio, aber akademisch ich glaube, Sie würden mit Aussagen von Ihrem SyntaxTree wie folgt sammeln:

var usings = syntaxTree.Root.DescendentNodes().Where(node is UsingDirectiveSyntax); 

... und vergleichen Sie das mit den von der Symboltabelle aufgelöst Namespaces wie folgt:

private static IEnumerable<INamespaceSymbol> GetNamespaceSymbol(ISymbol symbol) 
{ 
    if (symbol != null && symbol.ContainingNamespace != null) 
     yield return symbol.ContainingNamespace; 
} 

var ns = semanticModel.SyntaxTree.Root.DescendentNodes().SelectMany(node => 
    GetNamespaceSymbol(semanticModel.GetSemanticInfo(node).Symbol)).Distinct(); 
+1

Sie können ".OfType ()" anstelle von“.Where (Knoten ist UsingDirectiveSyntax) " –

1

Überprüfen Sie das Beispielprojekt OrganizeSolution, das mit Roslyn geliefert wurde. Es macht etwas ähnlich wie du willst. Es macht den sortierenden Teil. Sie müssen auch das SemanticModel wie Jeff Shows verwenden, um festzustellen, ob in der Quelle keine Verweise auf einen bestimmten Namespace vorhanden sind.

0

Zum Entfernen von Anweisungen lesen Sie den FAQ-Eintrag 30 in der Lösung im folgenden Verzeichnis in der Datei FAQ.cs: (Beachten Sie, dass dies für die CTP-Version von Roslyn im Juni 2012 gilt).

% userprofile% \ Documents \ Microsoft Roslyn CTP - Juni 2012 \ CSharp \ APISampleUnitTestsCS

Es gibt auch eine FAQ, die zu diesem Projekt bezieht:

http://www.codeplex.com/Download?ProjectName=dlr&DownloadId=386858

ist die Probe rewriter aus der Beispielcode, der Zuweisungsanweisungen entfernt

// Below SyntaxRewriter removes multiple assignement statements from under the 
// SyntaxNode being visited. 
public class AssignmentStatementRemover : SyntaxRewriter 
{ 
    public override SyntaxNode VisitExpressionStatement(ExpressionStatementSyntax node) 
    { 
     SyntaxNode updatedNode = base.VisitExpressionStatement(node); 

     if (node.Expression.Kind == SyntaxKind.AssignExpression) 
     { 
      if (node.Parent.Kind == SyntaxKind.Block) 
      { 
       // There is a parent block so it is ok to remove the statement completely. 
       updatedNode = null; 
      } 
      else 
      { 
       // The parent context is some statement like an if statement without a block. 
       // Return an empty statement. 
       updatedNode = Syntax.EmptyStatement() 
        .WithLeadingTrivia(updatedNode.GetLeadingTrivia()) 
        .WithTrailingTrivia(updatedNode.GetTrailingTrivia()); 
      } 
     } 
    return updatedNode; 
    } 
} 
1

Roslyn CTP September 2012 stellt eine GetUnusedImportDirectives() Methode, die hier von großem Nutzen ist.

Durch das Projekt OrganizeSolution Probe Modifizieren Matt referenzierten Sie sowohl das Sortieren und Entfernen von (nicht verwendet) mit Richtlinien erreichen können. Eine (veraltete) Version dieses Projekts finden Sie hier: http://go.microsoft.com/fwlink/?LinkId=263977. Es ist veraltet, weil document.GetUpdatedDocument() nicht mehr existiert,

var document = newSolution.GetDocument(documentId); 
var transformation = document.OrganizeImports(); 
var newDocument = transformation.GetUpdatedDocument(); 

kann

var document = newSolution.GetDocument(documentId); 
var newDocument = document.OrganizeImports(); 

newDocument = RemoveUnusedImportDirectives(newDocument); und die folgende Methode, den Trick tun Bereitstellung Hinzufügen vereinfacht werden.

private static IDocument RemoveUnusedImportDirectives(IDocument document) 
{ 
    var root = document.GetSyntaxRoot(); 
    var semanticModel = document.GetSemanticModel(); 

    // An IDocument can refer to both a CSharp as well as a VisualBasic source file. 
    // Therefore we need to distinguish those cases and provide appropriate casts. 
    // Since the question was tagged c# only the CSharp way is provided. 
    switch (document.LanguageServices.Language) 
    { 
     case LanguageNames.CSharp: 
      var oldUsings = ((CompilationUnitSyntax)root).Usings; 
      var unusedUsings = ((SemanticModel)semanticModel).GetUnusedImportDirectives(); 
      var newUsings = Syntax.List(oldUsings.Where(item => !unusedUsings.Contains(item))); 
      root = ((CompilationUnitSyntax)root).WithUsings(newUsings); 
      document = document.UpdateSyntaxRoot(root); 
      break; 

     case LanguageNames.VisualBasic: 
      // TODO 
      break; 
    } 
    return document; 
} 
1

Ich benutze dies die folgende Erweiterung Methode usings zu sortieren

internal static SyntaxList<UsingDirectiveSyntax> Sort(this SyntaxList<UsingDirectiveSyntax> usingDirectives, bool placeSystemNamespaceFirst = false) => 
    SyntaxFactory.List(
     usingDirectives 
     .OrderBy(x => x.StaticKeyword.IsKind(SyntaxKind.StaticKeyword) ? 1 : x.Alias == null ? 0 : 2) 
     .ThenBy(x => x.Alias?.ToString()) 
     .ThenByDescending(x => placeSystemNamespaceFirst && x.Name.ToString().StartsWith(nameof(System) + ".")) 
     .ThenBy(x => x.Name.ToString())); 

und

compilationUnit = compilationUnit.WithUsings(SortUsings(compilationUnit.Usings))