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

📄 codedomvisitor.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 3 页
字号:
// CodeDOMVisitor.cs
// Copyright (C) 2003 Mike Krueger (mike@icsharpcode.net)
// 
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

using System;
using System.Reflection;
using System.CodeDom;
using System.Text;
using System.Collections;

using ICSharpCode.SharpRefactory.Parser.AST;

namespace ICSharpCode.SharpRefactory.Parser
{
	public class CodeDOMVisitor : AbstractASTVisitor
	{
		Stack namespaceDeclarations = new Stack();
		Stack typeDeclarations     = new Stack();
		Stack codeStack  = new Stack();
		TypeDeclaration currentTypeDeclaration;

		// dummy collection used to swallow statements
		System.CodeDom.CodeStatementCollection NullStmtCollection = new CodeStatementCollection();
		
		public CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
		public ArrayList namespaces = new ArrayList();
		
		static string[,] typeConversionList = new string[,] {
			{"System.Void",    "void"},
			{"System.Object",  "object"},
			{"System.Boolean", "bool"},
			{"System.Byte",    "byte"},
			{"System.SByte",   "sbyte"},
			{"System.Char",    "char"},
			{"System.Enum",    "enum"},
			{"System.Int16",   "short"},
			{"System.Int32",   "int"},
			{"System.Int64",   "long"},
			{"System.UInt16",  "ushort"},
			{"System.UInt32",  "uint"},
			{"System.UInt64",  "ulong"},
			{"System.Single",  "float"},
			{"System.Double",  "double"},
			{"System.Decimal", "decimal"},
			{"System.String",  "string"}
		};
		
		static Hashtable typeConversionTable = new Hashtable();
		
		static CodeDOMVisitor()
		{
			for (int i = 0; i < typeConversionList.GetLength(0); ++i) {
				typeConversionTable[typeConversionList[i, 1]] = typeConversionList[i, 0];
			}
		}

		string ConvType(string type) 
		{
			if (typeConversionTable[type] != null) {
				return typeConversionTable[type].ToString();
			}
			return type;
		}

		void AddStmt(System.CodeDom.CodeStatement stmt)
		{
			System.CodeDom.CodeStatementCollection stmtCollection = codeStack.Peek() as System.CodeDom.CodeStatementCollection;
			if (stmtCollection != null) {
				stmtCollection.Add(stmt);
			}
		}

		void AddStmt(System.CodeDom.CodeExpression expr)
		{
			System.CodeDom.CodeStatementCollection stmtCollection = codeStack.Peek() as System.CodeDom.CodeStatementCollection;
			if (stmtCollection != null) {
				stmtCollection.Add(expr);
			}
		}

		// FIXME: map all modifiers correctly
		MemberAttributes ConvMemberAttributes(Modifier modifier) 
		{
			MemberAttributes attr = (MemberAttributes)0;

			if ((modifier & Modifier.Abstract) != 0)
				attr |=  MemberAttributes.Abstract;
//			if ((modifier & Modifier.None) != 0)
//				attr |=  MemberAttributes.AccessMask;
			if ((modifier & Modifier.Internal) != 0)
				attr |=  MemberAttributes.Assembly;
			if ((modifier & Modifier.Const) != 0)
				attr |=  MemberAttributes.Const;
			if ((modifier & Modifier.Protected) != 0)
				attr |=  MemberAttributes.Family;
			if ((modifier & Modifier.Protected) != 0 && (modifier & Modifier.Internal) != 0)
				attr |=  MemberAttributes.FamilyAndAssembly;
//			if ((modifier & Modifier.None) != 0)
//				attr |=  MemberAttributes.FamilyOrAssembly;
			if ((modifier & Modifier.Sealed) != 0)
				attr |=  MemberAttributes.Final;
			if ((modifier & Modifier.New) != 0)
				attr |=  MemberAttributes.New;
			if ((modifier & Modifier.Virtual) != 0)
				attr |=  MemberAttributes.Overloaded;
			if ((modifier & Modifier.Override) != 0)
				attr |=  MemberAttributes.Override;
			if ((modifier & Modifier.Private) != 0)
				attr |=  MemberAttributes.Private;
			if ((modifier & Modifier.Public) != 0)
				attr |=  MemberAttributes.Public;
//			if ((modifier & Modifier.None) != 0)
//				attr |=  MemberAttributes.ScopeMask;
			if ((modifier & Modifier.Static) != 0)
				attr |=  MemberAttributes.Static;
//			if ((modifier & Modifier.None) != 0)
//				attr |=  MemberAttributes.VTableMask;

			return attr;
		}

		void ProcessSpecials(Hashtable specials)
		{
			if (specials == null) {
				return;
			}
			
			foreach (object special in specials) {
				if (special is BlankLine) {
					AddStmt(new CodeSnippetStatement());
				} else if (special is PreProcessingDirective) {
					// TODO
				} else if (special is Comment) {
					Comment comment = (Comment)special;
					switch (comment.CommentType) {
						case CommentType.SingleLine:
							AddStmt(new CodeCommentStatement(comment.CommentText, false));
							break;
						case CommentType.Documentation:
							AddStmt(new CodeCommentStatement(comment.CommentText, true));
							break;
						case CommentType.Block:
							AddStmt(new CodeCommentStatement(comment.CommentText, false));
							break;
					}
				}
			}
		}

#region ICSharpCode.SharpRefactory.Parser.IASTVisitor interface implementation
		public override object Visit(CompilationUnit compilationUnit, object data)
		{
			CodeNamespace globalNamespace = new CodeNamespace("Global");
			namespaces.Add(globalNamespace);
			namespaceDeclarations.Push(globalNamespace);
			compilationUnit.AcceptChildren(this, data);
			codeCompileUnit.Namespaces.Add(globalNamespace);
			return globalNamespace;
		}
		
		public override object Visit(NamespaceDeclaration namespaceDeclaration, object data)
		{
			ProcessSpecials(namespaceDeclaration.Specials);

			CodeNamespace currentNamespace = new CodeNamespace(namespaceDeclaration.NameSpace);
			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 Visit(UsingDeclaration usingDeclaration, object data)
		{
			ProcessSpecials(usingDeclaration.Specials);

			((CodeNamespace)namespaceDeclarations.Peek()).Imports.Add(new CodeNamespaceImport(usingDeclaration.Namespace));
			return null;
		}
		
		public override object Visit(UsingAliasDeclaration usingAliasDeclaration, object data)
		{
			return null;
		}
		
		public override object Visit(AttributeSection attributeSection, object data)
		{
			return null;
		}
		
		public override object Visit(TypeDeclaration typeDeclaration, object data)
		{
			ProcessSpecials(typeDeclaration.Specials);

			this.currentTypeDeclaration = typeDeclaration;
			CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration(typeDeclaration.Name);
			codeTypeDeclaration.IsClass     = typeDeclaration.Type == Types.Class;
			codeTypeDeclaration.IsEnum      = typeDeclaration.Type == Types.Enum;
			codeTypeDeclaration.IsInterface = typeDeclaration.Type == Types.Interface;
			codeTypeDeclaration.IsStruct    = typeDeclaration.Type == Types.Struct;
			
			if (typeDeclaration.BaseTypes != null) {
				foreach (object o in typeDeclaration.BaseTypes) {
					codeTypeDeclaration.BaseTypes.Add(new CodeTypeReference(o.ToString()));
				}
			}
			
			typeDeclarations.Push(codeTypeDeclaration);
			typeDeclaration.AcceptChildren(this,data);
//			((INode)typeDeclaration.Children[0]).(this, data);
			
			typeDeclarations.Pop();
			
			((CodeNamespace)namespaceDeclarations.Peek()).Types.Add(codeTypeDeclaration);
			
			return null;
		}
		
		public override object Visit(DelegateDeclaration delegateDeclaration, object data)
		{
//			CodeTypeDelegate codeTypeDelegate = new CodeTypeDelegate(delegateDeclaration.Name);
//			codeTypeDelegate.Parameters
//			
//			((CodeNamespace)namespaceDeclarations.Peek()).Types.Add(codeTypeDelegate);
			return null;
		}
		
		public override object Visit(VariableDeclaration variableDeclaration, object data)
		{
			return null;
		}
		
		public override object Visit(FieldDeclaration fieldDeclaration, object data)
		{
			ProcessSpecials(fieldDeclaration.Specials);

			for (int i = 0; i < fieldDeclaration.Fields.Count; ++i) 
			{
				VariableDeclaration field = (VariableDeclaration)fieldDeclaration.Fields[i];
				
				CodeMemberField memberField = new CodeMemberField(new CodeTypeReference(ConvType(fieldDeclaration.TypeReference.Type)), field.Name);
				memberField.Attributes = ConvMemberAttributes(fieldDeclaration.Modifier);
				if (field.Initializer != null) {
					memberField.InitExpression =  (CodeExpression)((INode)field.Initializer).AcceptVisitor(this, data);
				}
				
				((CodeTypeDeclaration)typeDeclarations.Peek()).Members.Add(memberField);
			}
			
			return null;
		}
		
		public override object Visit(MethodDeclaration methodDeclaration, object data)
		{
			ProcessSpecials(methodDeclaration.Specials);

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

			((CodeTypeDeclaration)typeDeclarations.Peek()).Members.Add(memberMethod);

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

			methodDeclaration.Body.AcceptChildren(this, data);

			codeStack.Pop();

			return null;
		}
		
		public override object Visit(PropertyDeclaration propertyDeclaration, object data)
		{
			return null;
		}
		
		public override object Visit(PropertyGetRegion propertyGetRegion, object data)
		{
			return null;
		}
		
		public override object Visit(PropertySetRegion PropertySetRegion, object data)
		{
			return null;
		}
		
		public override object Visit(EventDeclaration eventDeclaration, object data)
		{
			return null;
		}
		
		public override object Visit(EventAddRegion eventAddRegion, object data)
		{
			return null;
		}
		
		public override object Visit(EventRemoveRegion eventRemoveRegion, object data)
		{
			return null;
		}
		
		public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
		{
			ProcessSpecials(constructorDeclaration.Specials);

			CodeMemberMethod memberMethod = new CodeConstructor();

			codeStack.Push(memberMethod.Statements);
			((CodeTypeDeclaration)typeDeclarations.Peek()).Members.Add(memberMethod);
//			constructorDeclaration.AcceptChildren(this, data);
			codeStack.Pop();

			return null;
		}
		
		public override object Visit(DestructorDeclaration destructorDeclaration, object data)
		{
			return null;
		}

		public override object Visit(OperatorDeclaration operatorDeclaration, object data)
		{
			return null;
		}
		
		public override object Visit(IndexerDeclaration indexerDeclaration, object data)
		{
			return null;
		}
		
		public override object Visit(BlockStatement blockStatement, object data)
		{
			ProcessSpecials(blockStatement.Specials);

			blockStatement.AcceptChildren(this, data);
			return null;
		}
		
		public override object Visit(StatementExpression statementExpression, object data)
		{
			object exp = statementExpression.Expression.AcceptVisitor(this, data);
			if (exp is CodeExpression) {
				AddStmt(new CodeExpressionStatement((CodeExpression)exp));
			}
			return exp;
		}
		
		public string Convert(TypeReference typeRef)
		{
			StringBuilder builder = new StringBuilder();
			builder.Append(ConvType(typeRef.Type));
			
			for (int i = 0; i < typeRef.PointerNestingLevel; ++i) {
				builder.Append('*');
			}
			
			
			for (int i = 0; i < typeRef.RankSpecifier.Length; ++i) {
				builder.Append('[');

⌨️ 快捷键说明

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