파스 트리 변경 및 변경 사항을 다시 파일에 기록하는 작은 Roslyn 프로젝트에서 작업하고 있습니다. 필자는 독립형 코드 분석기로 시작하여 명령 줄 응용 프로그램으로 빌드하려고합니다. 그래도 난 어려움을 겪었습니다. 작업 : Find classes which derive from a specific base class with Roslyn 부분적으로, 주로로 : https://github.com/dotnet/roslyn/wiki/Getting-Started-C%23-Syntax-Analysis 내가이 작은 프로젝트를 만든 : 코드 상태에서 주석으로Roslyn에서 C# 클래스를 상속하지 않고 기본 객체에서 상속하는 것으로 변경 (java와 비슷한)
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length < 1)
throw new ArgumentException();
SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0]));
var root = (CompilationUnitSyntax) tree.GetRoot();
var classes = from ClassDeclarationSyntax in root.DescendantNodesAndSelf() select ClassDeclarationSyntax;
foreach (var c in classes)
{
if (/*Not inheriting*/)
{
/*Add inherition*/
}
}
/*Write changes to file*/
}
catch (Exception e)
{
Console.WriteLine("Fatal error ocured.");
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}
을, 나는 수업 뭔가에서 상속 여부 확인 (선택 필요 두 번째 옵션) 다음 구문 분석 트리를 변경하고 마지막으로 파일에 쓰기, 지금은 2 단계와 3 단계에 대한 모든 지침도 환영하지만 "상속을"확인하는 방법을 알고 기쁠 것입니다. 구문 분석 및 변경이 여기에 프로그램의 매개 변수로 경로가 제공하는 파일 : 나는 응용 프로그램을 작동 함께 왔어요 받았다 답변의 지원을
if (args.Length < 1)
throw new ArgumentException();
SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0]));
솔루션
합니다. 다음은 어쩌면 완벽한하지만
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length < 1)
throw new ArgumentException();
SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0]));
var root = (CompilationUnitSyntax) tree.GetRoot();
IdentifierNameSyntax iname = SyntaxFactory.IdentifierName("Object");
BaseTypeSyntax bts = SyntaxFactory.SimpleBaseType(iname);
SeparatedSyntaxList<BaseTypeSyntax> ssl = new SeparatedSyntaxList<BaseTypeSyntax>();
ssl = ssl.Add(bts);
BaseListSyntax bls = SyntaxFactory.BaseList(ssl);
bool x = true;
while(x) //Way to handle all nodes due to impossibility to handle more than one in foreach
{
foreach (var c in root.DescendantNodesAndSelf())
{
x = false;
var classDeclaration = c as ClassDeclarationSyntax;
if (classDeclaration == null)
continue;
if (classDeclaration.BaseList != null) //Inherits
continue;
else //Not inherits
{
root = root.ReplaceNode(classDeclaration, classDeclaration.WithBaseList(bls));
x = true;
break;
}
}
}
if (args.Length > 1) //Write to given file
using (var sw = new StreamWriter(File.Open(args[1], FileMode.Open)))
{
root.WriteTo(sw);
}
else //Overwrite source
using (var sw = new StreamWriter(File.Open(args[0], FileMode.Open)))
{
root.WriteTo(sw);
}
}
catch (Exception e)
{
Console.WriteLine("Fatal error ocured.");
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}
을 사용하고 계십니까? 실험 한 것에서도 효과가 있습니다. –
@RobertGrzesiak 글쎄,'BaseList'와'null'의 비교가 안되면 예제를 모른다. 클래스가 기본 클래스를 가질 때'BaseList'가 null이 될 수 없다고 설명하는 문서를 찾지 못했다. 인터페이스를 구현합니다. 그래서 나는이 비교가 모든 경우에 효과가 있는지 없는지 확신하지 못합니다. –
클래스가 상속하거나 구현하는 경우에만'BaseList'가 존재합니다. 그래서'BaseList! = null'은 내가 이해하는 것으로부터 잘 작동 할 것입니다. –