⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codedomoutputvisitor.cs

📁 根据cs源码解析为codedom
💻 CS
📖 第 1 页 / 共 5 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 1965 $</version>
// </file>

using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using ICSharpCode.NRefactory.Ast;

namespace ICSharpCode.NRefactory.Visitors
{
	public class CodeDomVisitor : AbstractAstVisitor
	{
		Stack<CodeNamespace>  namespaceDeclarations = new Stack<CodeNamespace>();
		Stack<CodeTypeDeclaration> typeDeclarations = new Stack<CodeTypeDeclaration>();
		Stack<CodeStatementCollection> codeStack    = new Stack<CodeStatementCollection>();
		List<CodeVariableDeclarationStatement> variables = new List<CodeVariableDeclarationStatement>();
        List<CodeParameterDeclarationExpression> parameters = new List<CodeParameterDeclarationExpression>();
        Stack<Breakable> breakableStack = new Stack<Breakable>();
		
		TypeDeclaration currentTypeDeclaration = null;
		
		IEnvironmentInformationProvider environmentInformationProvider = new DummyEnvironmentInformationProvider();

        // track break and continue statements
        class Breakable
        {
            public static int NextId = 0;

            public int Id = 0;
            public bool IsBreak = false;
            public bool IsContinue = false;
            public bool AllowContinue = true;

            public Breakable()
            {
                Id = ++NextId;
            }

            public Breakable(bool allowContinue)
                : this()
            {
                AllowContinue = allowContinue;
            }
        }

		public IEnvironmentInformationProvider EnvironmentInformationProvider {
			get {
				return environmentInformationProvider;
			}
			set {
				environmentInformationProvider = value;
			}
		}
		
		// dummy collection used to swallow statements
		CodeStatementCollection NullStmtCollection = new CodeStatementCollection();
		
		public CodeCompileUnit codeCompileUnit   = new CodeCompileUnit();

        // RG
        //
        // Initialise Scope Variables for Current Method
        void InitMethodScope()
        {
            usingId = 0;
            foreachId = 0;
            switchId = 0;
            doId = 0;
            Breakable.NextId = 0;
            variables.Clear();
            parameters.Clear();
        }

		CodeTypeReference ConvType(TypeReference type)
		{
			if (type == null) {
				throw new ArgumentNullException("type");
			}
			if (string.IsNullOrEmpty(type.SystemType)) {
				throw new InvalidOperationException("empty type");
			}
			
			CodeTypeReference t = new CodeTypeReference(type.SystemType);
			foreach (TypeReference gt in type.GenericTypes) {
				t.TypeArguments.Add(ConvType(gt));
			}
			if (type.IsArrayType) {
				t = new CodeTypeReference(t, type.RankSpecifier.Length);
			}
			
			return t;
		}
		
		void AddStmt(CodeStatement stmt)
		{
			if (codeStack.Count == 0)
				return;
			CodeStatementCollection stmtCollection = codeStack.Peek();
			if (stmtCollection != null) {
				stmtCollection.Add(stmt);
			}
		}
		
		// FIXME: map all modifiers correctly
		static MemberAttributes ConvMemberAttributes(Modifiers modifier)
		{
			MemberAttributes attr = (MemberAttributes)0;
			
			if ((modifier & Modifiers.Abstract) != 0)
				attr |=  MemberAttributes.Abstract;
			if ((modifier & Modifiers.Const) != 0)
				attr |=  MemberAttributes.Const;
			if ((modifier & Modifiers.Sealed) != 0)
				attr |=  MemberAttributes.Final;
			if ((modifier & Modifiers.New) != 0)
				attr |=  MemberAttributes.New;
			if ((modifier & Modifiers.Virtual) != 0)
				attr |=  MemberAttributes.Overloaded;
			if ((modifier & Modifiers.Override) != 0)
				attr |=  MemberAttributes.Override;
			if ((modifier & Modifiers.Static) != 0)
				attr |=  MemberAttributes.Static;
			
			if ((modifier & Modifiers.Public) != 0)
				attr |=  MemberAttributes.Public;
			else if ((modifier & Modifiers.Internal) != 0 && (modifier & Modifiers.Protected) != 0)
				attr |=  MemberAttributes.FamilyOrAssembly;
			else if ((modifier & Modifiers.Internal) != 0)
				attr |=  MemberAttributes.Assembly;
			else if ((modifier & Modifiers.Protected) != 0)
				attr |=  MemberAttributes.Family;
            else if ((modifier & Modifiers.Private) != 0)
                attr |= MemberAttributes.Private;
	
			return attr;
		}
		
		#region ICSharpCode.SharpRefactory.Parser.IASTVisitor interface implementation
		public override object VisitCompilationUnit(CompilationUnit compilationUnit, object data)
		{
			if (compilationUnit == null) {
				throw new ArgumentNullException("compilationUnit");
			}
            CodeNamespace globalNamespace = new CodeNamespace("Global");
            //namespaces.Add(globalNamespace);
			namespaceDeclarations.Push(globalNamespace);
			compilationUnit.AcceptChildren(this, data);
			codeCompileUnit.Namespaces.Add(globalNamespace);
			return globalNamespace;
		}
		
		public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
		{
			CodeNamespace currentNamespace = new CodeNamespace(namespaceDeclaration.Name);
			//namespaces.Add(currentNamespace);
			// add imports from mother namespace
			foreach (CodeNamespaceImport import in ((CodeNamespace)namespaceDeclarations.Peek()).Imports) {
				currentNamespace.Imports.Add(import);
			}
			namespaceDeclarations.Push(currentNamespace);
			namespaceDeclaration.AcceptChildren(this, data);
			namespaceDeclarations.Pop();
			codeCompileUnit.Namespaces.Add(currentNamespace);
			
			// TODO : Nested namespaces allowed in CodeDOM ? Doesn't seem so :(
			return null;
		}
		
		public override object VisitUsingDeclaration(UsingDeclaration usingDeclaration, object data)
		{
			foreach (Using u in usingDeclaration.Usings) {
				namespaceDeclarations.Peek().Imports.Add(new CodeNamespaceImport(u.Name));
			}
			return null;
		}

        // RG
        public override object VisitEventDeclaration(EventDeclaration eventDeclaration, object data)
        {
            CodeMemberEvent evt = new CodeMemberEvent();
            evt.Type = ConvType(eventDeclaration.TypeReference);
            evt.Name = eventDeclaration.Name;

            evt.Attributes = ConvMemberAttributes(eventDeclaration.Modifier);

            typeDeclarations.Peek().Members.Add(evt);

            return null;
        }
		
		public override object VisitAttributeSection(AttributeSection attributeSection, object data)
		{
			return null;
		}

        // RG: CodeTypeReferenceExpression
        public override object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data)
        {
            return new CodeTypeReferenceExpression(ConvType(typeReferenceExpression.TypeReference));
        }

		public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
		{
			TypeDeclaration oldTypeDeclaration = currentTypeDeclaration;
			this.currentTypeDeclaration = typeDeclaration;
			CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration(typeDeclaration.Name);
			codeTypeDeclaration.IsClass     = typeDeclaration.Type == ClassType.Class;
			codeTypeDeclaration.IsEnum      = typeDeclaration.Type == ClassType.Enum;
			codeTypeDeclaration.IsInterface = typeDeclaration.Type == ClassType.Interface;
			codeTypeDeclaration.IsStruct    = typeDeclaration.Type == ClassType.Struct;
			
			if (typeDeclaration.BaseTypes != null) {
				foreach (TypeReference typeRef in typeDeclaration.BaseTypes) {
					codeTypeDeclaration.BaseTypes.Add(ConvType(typeRef));
				}
			}
			
			typeDeclarations.Push(codeTypeDeclaration);
			typeDeclaration.AcceptChildren(this, data);
			typeDeclarations.Pop();
			
			if (typeDeclarations.Count > 0) {
				typeDeclarations.Peek().Members.Add(codeTypeDeclaration);
			} else {
				namespaceDeclarations.Peek().Types.Add(codeTypeDeclaration);
			}
			currentTypeDeclaration = oldTypeDeclaration;
			
			return null;
		}
		
		public override object VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, object data)
		{
			CodeTypeDelegate codeTypeDelegate = new CodeTypeDelegate(delegateDeclaration.Name);
            codeTypeDelegate.Attributes = ConvMemberAttributes(delegateDeclaration.Modifier);
            codeTypeDelegate.ReturnType = ConvType(delegateDeclaration.ReturnType);

            foreach (ParameterDeclarationExpression parameter in delegateDeclaration.Parameters)
            {
                codeTypeDelegate.Parameters.Add((CodeParameterDeclarationExpression)VisitParameterDeclarationExpression(parameter, data));
            }

            if (typeDeclarations.Count > 0)
            {
                typeDeclarations.Peek().Members.Add(codeTypeDelegate);
            }
            else
            {
                namespaceDeclarations.Peek().Types.Add(codeTypeDelegate);
            }

			return null;
		}
		
		public override object VisitVariableDeclaration(VariableDeclaration variableDeclaration, object data)
		{
			return null;
		}
		
		public override object VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data)
		{
			for (int i = 0; i < fieldDeclaration.Fields.Count; ++i) {
				VariableDeclaration field = (VariableDeclaration)fieldDeclaration.Fields[i];
				
				if ((fieldDeclaration.Modifier & Modifiers.WithEvents) != 0) {
					//this.withEventsFields.Add(field);
				}
				TypeReference fieldType = fieldDeclaration.GetTypeForField(i);
				
				if (fieldType.IsNull) {
					fieldType = new TypeReference(typeDeclarations.Peek().Name);
				}
				
				CodeMemberField memberField = new CodeMemberField(ConvType(fieldType), field.Name);
				memberField.Attributes = ConvMemberAttributes(fieldDeclaration.Modifier);
				if (!field.Initializer.IsNull) {
					memberField.InitExpression = (CodeExpression)field.Initializer.AcceptVisitor(this, data);
				}
				
				typeDeclarations.Peek().Members.Add(memberField);
			}
			
			return null;
		}
		
		public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
		{
            InitMethodScope();

			CodeMemberMethod memberMethod = new CodeMemberMethod();
			memberMethod.Name = methodDeclaration.Name;
			memberMethod.Attributes = ConvMemberAttributes(methodDeclaration.Modifier);

            // RG: Private Interface Decl
            if ((memberMethod.Attributes & MemberAttributes.Public) != MemberAttributes.Public &&
                methodDeclaration.InterfaceImplementations.Count > 0) 
            {
                memberMethod.PrivateImplementationType = ConvType(methodDeclaration.InterfaceImplementations[0].InterfaceType);
            }

			codeStack.Push(memberMethod.Statements);
			
			typeDeclarations.Peek().Members.Add(memberMethod);
			
			// Add Method Parameters
            parameters.Clear();

			foreach (ParameterDeclarationExpression parameter in methodDeclaration.Parameters)
			{
				memberMethod.Parameters.Add((CodeParameterDeclarationExpression)VisitParameterDeclarationExpression(parameter, data));
			}

            usingId = 0; // RG
            foreachId = 0;
            switchId = 0;
            doId = 0;
            Breakable.NextId = 0;
			variables.Clear();
			methodDeclaration.Body.AcceptChildren(this, data);
			
			codeStack.Pop();
			
			return null;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -