main.cs
来自「SharpDevelop2.0.0 c#开发免费工具」· CS 代码 · 共 495 行 · 第 1/2 页
CS
495 行
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 1080 $</version>
// </file>
using System;
using System.Collections.Generic;
using System.CodeDom;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using NRefactoryASTGenerator.AST;
namespace NRefactoryASTGenerator
{
class MainClass
{
public static void Main(string[] args)
{
string directory = "../../../Project/Src/Parser/AST/";
string visitorsDir = "../../../Project/Src/Parser/Visitors/";
Debug.WriteLine("AST Generator running...");
if (!File.Exists(directory + "INode.cs")) {
Debug.WriteLine("did not find output directory");
return;
}
if (!File.Exists(visitorsDir + "IASTVisitor.cs")) {
Debug.WriteLine("did not find visitor output directory");
return;
}
List<Type> nodeTypes = new List<Type>();
foreach (Type type in typeof(MainClass).Assembly.GetTypes()) {
if (type.IsClass && typeof(INode).IsAssignableFrom(type)) {
nodeTypes.Add(type);
}
}
nodeTypes.Sort(delegate(Type a, Type b) { return a.Name.CompareTo(b.Name); });
CodeCompileUnit ccu = new CodeCompileUnit();
CodeNamespace cns = new CodeNamespace("ICSharpCode.NRefactory.Parser.AST");
ccu.Namespaces.Add(cns);
cns.Imports.Add(new CodeNamespaceImport("System"));
cns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
cns.Imports.Add(new CodeNamespaceImport("System.Diagnostics"));
cns.Imports.Add(new CodeNamespaceImport("System.Drawing"));
foreach (Type type in nodeTypes) {
if (type.GetCustomAttributes(typeof(CustomImplementationAttribute), false).Length == 0) {
CodeTypeDeclaration ctd = new CodeTypeDeclaration(type.Name);
if (type.IsAbstract) {
ctd.TypeAttributes |= TypeAttributes.Abstract;
}
ctd.BaseTypes.Add(new CodeTypeReference(type.BaseType.Name));
cns.Types.Add(ctd);
ProcessType(type, ctd);
foreach (object o in type.GetCustomAttributes(false)) {
if (o is TypeImplementationModifierAttribute) {
(o as TypeImplementationModifierAttribute).ModifyImplementation(cns, ctd, type);
}
}
if (!type.IsAbstract) {
CodeMemberMethod method = new CodeMemberMethod();
method.Name = "AcceptVisitor";
method.Attributes = MemberAttributes.Public | MemberAttributes.Override;
method.Parameters.Add(new CodeParameterDeclarationExpression("IAstVisitor", "visitor"));
method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "data"));
method.ReturnType = new CodeTypeReference(typeof(object));
CodeExpression ex = new CodeVariableReferenceExpression("visitor");
ex = new CodeMethodInvokeExpression(ex, "Visit",
new CodeThisReferenceExpression(),
new CodeVariableReferenceExpression("data"));
method.Statements.Add(new CodeMethodReturnStatement(ex));
ctd.Members.Add(method);
method = new CodeMemberMethod();
method.Name = "ToString";
method.Attributes = MemberAttributes.Public | MemberAttributes.Override;
method.ReturnType = new CodeTypeReference(typeof(string));
method.Statements.Add(new CodeMethodReturnStatement(CreateToString(type)));
ctd.Members.Add(method);
}
}
}
System.CodeDom.Compiler.CodeGeneratorOptions settings = new System.CodeDom.Compiler.CodeGeneratorOptions();
settings.IndentString = "\t";
settings.VerbatimOrder = true;
using (StringWriter writer = new StringWriter()) {
new Microsoft.CSharp.CSharpCodeProvider().GenerateCodeFromCompileUnit(ccu, writer, settings);
File.WriteAllText(directory + "Generated.cs", writer.ToString());
}
ccu = new CodeCompileUnit();
cns = new CodeNamespace("ICSharpCode.NRefactory.Parser");
ccu.Namespaces.Add(cns);
cns.Imports.Add(new CodeNamespaceImport("System"));
cns.Imports.Add(new CodeNamespaceImport("ICSharpCode.NRefactory.Parser.AST"));
cns.Types.Add(CreateAstVisitorInterface(nodeTypes));
using (StringWriter writer = new StringWriter()) {
new Microsoft.CSharp.CSharpCodeProvider().GenerateCodeFromCompileUnit(ccu, writer, settings);
File.WriteAllText(visitorsDir + "IAstVisitor.cs", writer.ToString());
}
ccu = new CodeCompileUnit();
cns = new CodeNamespace("ICSharpCode.NRefactory.Parser");
ccu.Namespaces.Add(cns);
cns.Imports.Add(new CodeNamespaceImport("System"));
cns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
cns.Imports.Add(new CodeNamespaceImport("System.Diagnostics"));
cns.Imports.Add(new CodeNamespaceImport("ICSharpCode.NRefactory.Parser.AST"));
cns.Types.Add(CreateAstVisitorClass(nodeTypes, false));
using (StringWriter writer = new StringWriter()) {
new Microsoft.CSharp.CSharpCodeProvider().GenerateCodeFromCompileUnit(ccu, writer, settings);
File.WriteAllText(visitorsDir + "AbstractAstVisitor.cs", writer.ToString());
}
ccu = new CodeCompileUnit();
cns = new CodeNamespace("ICSharpCode.NRefactory.Parser");
ccu.Namespaces.Add(cns);
cns.Imports.Add(new CodeNamespaceImport("System"));
cns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
cns.Imports.Add(new CodeNamespaceImport("System.Diagnostics"));
cns.Imports.Add(new CodeNamespaceImport("ICSharpCode.NRefactory.Parser.AST"));
cns.Types.Add(CreateAstVisitorClass(nodeTypes, true));
using (StringWriter writer = new StringWriter()) {
new Microsoft.CSharp.CSharpCodeProvider().GenerateCodeFromCompileUnit(ccu, writer, settings);
File.WriteAllText(visitorsDir + "AbstractAstTransformer.cs", writer.ToString());
}
}
static CodeTypeDeclaration CreateAstVisitorInterface(List<Type> nodeTypes)
{
CodeTypeDeclaration td = new CodeTypeDeclaration("IAstVisitor");
td.IsInterface = true;
foreach (Type t in nodeTypes) {
if (!t.IsAbstract) {
CodeMemberMethod m = new CodeMemberMethod();
m.Name = "Visit";
m.ReturnType = new CodeTypeReference(typeof(object));
m.Parameters.Add(new CodeParameterDeclarationExpression(ConvertType(t), GetFieldName(t.Name)));
m.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "data"));
td.Members.Add(m);
}
}
return td;
}
static CodeTypeDeclaration CreateAstVisitorClass(List<Type> nodeTypes, bool transformer)
{
CodeTypeDeclaration td = new CodeTypeDeclaration(transformer ? "AbstractAstTransformer" : "AbstractAstVisitor");
td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract;
td.BaseTypes.Add(new CodeTypeReference("IAstVisitor"));
if (transformer) {
string comment = "<summary>\n " +
"The AbstractAstTransformer will iterate through the whole AST,\n " +
"just like the AbstractAstVisitor. However, the AbstractAstTransformer allows\n " +
"you to modify the AST at the same time: It does not use 'foreach' internally,\n " +
"so you can add members to collections of parents of the current node (but\n " +
"you cannot insert or delete items as that will make the index used invalid).\n " +
"You can use the methods ReplaceCurrentNode and RemoveCurrentNode to replace\n " +
"or remove the current node, totally independent from the type of the parent node.\n " +
"</summary>";
td.Comments.Add(new CodeCommentStatement(comment, true));
CodeMemberField field = new CodeMemberField("Stack", "nodeStack");
field.Type.TypeArguments.Add("INode");
field.InitExpression = new CodeObjectCreateExpression(field.Type);
td.Members.Add(field);
CodeExpression nodeStack = new CodeVariableReferenceExpression("nodeStack");
/*
CodeMemberProperty p = new CodeMemberProperty();
p.Name = "CurrentNode";
p.Type = new CodeTypeReference("INode");
p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
p.GetStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("currentNode")));
p.SetStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("currentNode"),
new CodePropertySetValueReferenceExpression()));
td.Members.Add(p);
*/
CodeMemberMethod m = new CodeMemberMethod();
m.Name = "ReplaceCurrentNode";
m.Attributes = MemberAttributes.Public | MemberAttributes.Final;
m.Parameters.Add(new CodeParameterDeclarationExpression("INode", "newNode"));
m.Statements.Add(new CodeMethodInvokeExpression(nodeStack, "Pop"));
m.Statements.Add(new CodeMethodInvokeExpression(nodeStack, "Push",
new CodeVariableReferenceExpression("newNode")));
td.Members.Add(m);
m = new CodeMemberMethod();
m.Name = "RemoveCurrentNode";
m.Attributes = MemberAttributes.Public | MemberAttributes.Final;
m.Statements.Add(new CodeMethodInvokeExpression(nodeStack, "Pop"));
m.Statements.Add(new CodeMethodInvokeExpression(nodeStack, "Push",
new CodePrimitiveExpression(null)));
td.Members.Add(m);
}
foreach (Type type in nodeTypes) {
if (!type.IsAbstract) {
CodeMemberMethod m = new CodeMemberMethod();
m.Name = "Visit";
m.Attributes = MemberAttributes.Public;
m.ReturnType = new CodeTypeReference(typeof(object));
m.Parameters.Add(new CodeParameterDeclarationExpression(ConvertType(type), GetFieldName(type.Name)));
m.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "data"));
td.Members.Add(m);
List<CodeStatement> assertions = new List<CodeStatement>();
CodeVariableReferenceExpression var = new CodeVariableReferenceExpression(GetFieldName(type.Name));
assertions.Add(AssertIsNotNull(var));
AddFieldVisitCode(m, type, var, assertions, transformer);
if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0) {
if (transformer) {
m.Statements.Add(new CodeSnippetStatement(CreateTransformerLoop(var.VariableName + ".Children", "INode")));
m.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
} else {
CodeExpression ex = new CodeMethodInvokeExpression(var, "AcceptChildren",
new CodeThisReferenceExpression(),
new CodeVariableReferenceExpression("data"));
m.Statements.Add(new CodeMethodReturnStatement(ex));
}
} else {
CodeExpressionStatement lastStatement = null;
if (m.Statements.Count > 0) {
lastStatement = m.Statements[m.Statements.Count - 1] as CodeExpressionStatement;
}
if (lastStatement != null) {
m.Statements.RemoveAt(m.Statements.Count - 1);
m.Statements.Add(new CodeMethodReturnStatement(lastStatement.Expression));
} else {
m.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?