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

📄 codedomvisitor.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 1323 $</version>
// </file>

using System;
using System.Collections;
using System.CodeDom;
using System.Text;
using Boo.Lang.Compiler;
using Boo.Lang.Compiler.Ast;
using Boo.Lang.Compiler.Ast.Visitors;
using Boo.Lang.Parser;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using Grunwald.BooBinding.CodeCompletion;

namespace Grunwald.BooBinding.Designer
{
	/// <summary>
	/// The CodeDomVisitor is able to convert from the Boo AST to System.CodeDom
	/// It makes use of the SharpDevelop parser service to get necessary additional
	/// information about the types.
	/// </summary>
	public class CodeDomVisitor : DepthFirstVisitor
	{
		CodeCompileUnit _compileUnit = new CodeCompileUnit();
		
		public CodeCompileUnit OutputCompileUnit {
			get {
				return _compileUnit;
			}
		}
		
		IProjectContent pc;
		
		public CodeDomVisitor(IProjectContent pc)
		{
			this.pc = pc;
		}
		
		CodeNamespace _namespace;
		CodeTypeDeclaration _class;
		CodeStatementCollection _statements;
		CodeExpression _expression;
		
		MemberAttributes ConvModifiers(TypeMember member)
		{
			if (member is Field)
				return ConvModifiers(member.Modifiers, MemberAttributes.Family);
			else
				return ConvModifiers(member.Modifiers, MemberAttributes.Public);
		}
		
		MemberAttributes ConvModifiers(TypeMemberModifiers modifier, MemberAttributes defaultAttr)
		{
			MemberAttributes attr = 0;
			if ((modifier & TypeMemberModifiers.Abstract) == TypeMemberModifiers.Abstract)
				attr |= MemberAttributes.Abstract;
			if ((modifier & TypeMemberModifiers.Final) == TypeMemberModifiers.Final)
				attr |= MemberAttributes.Const;
			if ((modifier & TypeMemberModifiers.Internal) == TypeMemberModifiers.Internal)
				attr |= MemberAttributes.Assembly;
			if ((modifier & TypeMemberModifiers.Override) == TypeMemberModifiers.Override)
				attr |= MemberAttributes.Override;
			if ((modifier & TypeMemberModifiers.Private) == TypeMemberModifiers.Private)
				attr |= MemberAttributes.Private;
			if ((modifier & TypeMemberModifiers.Protected) == TypeMemberModifiers.Protected)
				attr |= MemberAttributes.Family;
			if ((modifier & TypeMemberModifiers.Public) == TypeMemberModifiers.Public)
				attr |= MemberAttributes.Public;
			if ((modifier & TypeMemberModifiers.Static) == TypeMemberModifiers.Static)
				attr |= MemberAttributes.Static;
			if ((modifier & TypeMemberModifiers.Virtual) != TypeMemberModifiers.Virtual)
				attr |= MemberAttributes.Final;
			if (attr == 0)
				return defaultAttr;
			else
				return attr;
		}
		
		CodeTypeReference ConvTypeRef(TypeReference tr)
		{
			if (tr == null) return null;
			string name = tr.ToString();
			if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name))
				name = BooAmbience.ReverseTypeConversionTable[name];
			return new CodeTypeReference(name);
		}
		
		public override void OnCompileUnit(CompileUnit node)
		{
			foreach (Module m in node.Modules)
				m.Accept(this);
		}
		
		public override void OnModule(Module node)
		{
			if (node.Namespace == null) {
				_namespace = new CodeNamespace("Global");
				_compileUnit.Namespaces.Add(_namespace);
			} else {
				node.Namespace.Accept(this);
			}
			foreach (Import i in node.Imports)
				i.Accept(this);
			foreach (TypeMember m in node.Members)
				m.Accept(this);
		}
		
		public override void OnNamespaceDeclaration(NamespaceDeclaration node)
		{
			_namespace = new CodeNamespace(node.Name);
			_compileUnit.Namespaces.Add(_namespace);
		}
		
		public override void OnImport(Import node)
		{
			_namespace.Imports.Add(new CodeNamespaceImport(node.Namespace));
		}
		
		CodeTypeDeclaration ConvertTypeDefinition(TypeDefinition node)
		{
			CodeTypeDeclaration oldClass = _class;
			CodeTypeDeclaration newClass = new CodeTypeDeclaration(node.Name);
			_class = newClass;
			
			foreach (TypeReference b in node.BaseTypes)
				newClass.BaseTypes.Add(ConvTypeRef(b));
			
			foreach (TypeMember member in node.Members)
				member.Accept(this);
			
			if (oldClass == null)
				_namespace.Types.Add(newClass);
			else
				oldClass.Members.Add(newClass);
			_class = oldClass;
			return newClass;
		}
		
		public override void OnClassDefinition(ClassDefinition node)
		{
			ConvertTypeDefinition(node).IsClass = true;
		}
		
		public override void OnStructDefinition(StructDefinition node)
		{
			ConvertTypeDefinition(node).IsStruct = true;
		}
		public override void OnInterfaceDefinition(InterfaceDefinition node)
		{
			ConvertTypeDefinition(node).IsInterface = true;
		}
		
		public override void OnField(Field node)
		{
			CodeMemberField field = new CodeMemberField(ConvTypeRef(node.Type), node.Name);
			field.Attributes = ConvModifiers(node);
			if (node.Initializer != null) {
				_expression = null;
				//Visit(node.Initializer);
				field.InitExpression = _expression;
			}
			_class.Members.Add(field);
		}
		
		public override void OnConstructor(Boo.Lang.Compiler.Ast.Constructor node)
		{
			ConvertMethod(node, new CodeConstructor());
		}
		public override void OnMethod(Method node)
		{
			CodeMemberMethod cmm = new CodeMemberMethod();
			cmm.Name = node.Name;
			cmm.ReturnType = ConvTypeRef(node.ReturnType);
			ConvertMethod(node, cmm);
		}
		public override void OnDestructor(Boo.Lang.Compiler.Ast.Destructor node)
		{
			CodeMemberMethod cmm = new CodeMemberMethod();
			cmm.Name = "Finalize";
			ConvertMethod(node, cmm);
		}
		void ConvertMethod(Method node, CodeMemberMethod method)
		{
			method.Attributes = ConvModifiers(node);
			if (node.Parameters != null) {
				foreach (ParameterDeclaration p in node.Parameters)
					method.Parameters.Add(new CodeParameterDeclarationExpression(ConvTypeRef(p.Type), p.Name));
			}
			_statements = method.Statements;
			
			if (node.Body != null)
				node.Body.Accept(this);
			
			_class.Members.Add(method);
		}
		
		static CodeBinaryOperatorType GetOperatorType(BinaryOperatorType op)
		{
			switch (op) {
				case BinaryOperatorType.Addition:
					return CodeBinaryOperatorType.Add;
				case BinaryOperatorType.And:
					return CodeBinaryOperatorType.BooleanAnd;
				case BinaryOperatorType.BitwiseAnd:
					return CodeBinaryOperatorType.BitwiseAnd;
				case BinaryOperatorType.BitwiseOr:
					return CodeBinaryOperatorType.BitwiseOr;
				case BinaryOperatorType.Division:
					return CodeBinaryOperatorType.Divide;
				case BinaryOperatorType.Equality:
					return CodeBinaryOperatorType.ValueEquality;
				case BinaryOperatorType.GreaterThan:
					return CodeBinaryOperatorType.GreaterThan;
				case BinaryOperatorType.GreaterThanOrEqual:
					return CodeBinaryOperatorType.GreaterThanOrEqual;
				case BinaryOperatorType.LessThan:
					return CodeBinaryOperatorType.LessThan;
				case BinaryOperatorType.LessThanOrEqual:
					return CodeBinaryOperatorType.LessThanOrEqual;
				case BinaryOperatorType.Modulus:
					return CodeBinaryOperatorType.Modulus;
				case BinaryOperatorType.Multiply:
					return CodeBinaryOperatorType.Multiply;
				case BinaryOperatorType.Or:
					return CodeBinaryOperatorType.BooleanOr;
				case BinaryOperatorType.Subtraction:
					return CodeBinaryOperatorType.Subtract;
				default:
					return CodeBinaryOperatorType.Assign;
			}
		}
		
		public override void OnBinaryExpression(BinaryExpression node)
		{
			_expression = null;
			CodeBinaryOperatorType op = GetOperatorType(node.Operator);
			if (op == CodeBinaryOperatorType.Assign) {
				// non-standard op
				if (node.Operator == BinaryOperatorType.Assign) {
					node.Left.Accept(this);
					CodeExpression left = _expression;
					_expression = null;
					node.Right.Accept(this);
					if (left != null && _expression != null)
						_statements.Add(new CodeAssignStatement(left, _expression));
					_expression = null;
				} else if (node.Operator == BinaryOperatorType.InPlaceAddition) {
					node.Left.Accept(this);
					CodeEventReferenceExpression left = _expression as CodeEventReferenceExpression;
					_expression = null;
					node.Right.Accept(this);
					if (left != null && _expression != null)
						_statements.Add(new CodeAttachEventStatement(left, _expression));
					_expression = null;
				} else {
					LoggingService.Warn("CodeDomVisitor: ignoring unknown Binary Operator" + node.Operator);
				}
			} else {
				node.Left.Accept(this);
				CodeExpression left = _expression;
				_expression = null;
				node.Right.Accept(this);
				_expression = new CodeBinaryOperatorExpression(left, op, _expression);
			}
		}
		
		public override void OnTryCastExpression(TryCastExpression node)
		{
			_expression = null;
			node.Target.Accept(this);
			if (_expression == null)
				return;
			if (_expression is CodeMethodReferenceExpression) {
				_expression = new CodeObjectCreateExpression(ConvTypeRef(node.Type), _expression);
			} else {
				_expression = new CodeCastExpression(ConvTypeRef(node.Type), _expression);
			}
		}
		
		public override void OnCastExpression(CastExpression node)

⌨️ 快捷键说明

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