Sortieren und entfernen (nicht verwendet) mit Anweisungen Roslyn Skript/Code? Ich suche nach einem .NET/Roslyn-Code (Compiler als Service), der ein Projekt ausführen und nicht verwendete Anweisungen sortieren und entfernen kann. Ich glaube, das ist mit Roslyn möglich? Kann mir jemand auf Code hinweisen, der das umschreiben könnte? Sortieren und Entfernen (nicht verwendet) mit Anweisungen Roslyn Skript/Code?
Antwort
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();
Ü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.
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;
}
}
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;
}
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))
Sie können ".OfType()" anstelle von“.Where (Knoten ist UsingDirectiveSyntax) " –