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

📄 csharpvisitor.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 4 页
字号:
// CSharpVisitor.cs
// Copyright (C) 2004 Markus Palme (markuspalme@gmx.de)
// 
// 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.VB;
using ICSharpCode.SharpRefactory.Parser.AST.VB;

namespace ICSharpCode.SharpRefactory.PrettyPrinter.VB
{
	public class CSharpVisitor : IASTVisitor
	{
		readonly string newLineSep  = Environment.NewLine;
		StringBuilder   sourceText  = new StringBuilder();
		int             indentLevel = 0;
		Errors          errors      = new Errors();
		TypeDeclaration currentType = null;		
		Stack   withExpressionStack = new Stack();
		
		public StringBuilder SourceText {
			get {
				return sourceText;
			}
		}
		
		public void AppendIndentation()
		{
			for (int i = 0; i < indentLevel; ++i) {
				sourceText.Append("\t");
			}
		}
		
		public void AppendNewLine()
		{
			sourceText.Append(newLineSep);
		}
		
		public void AppendStatementEnd()
		{
			sourceText.Append(";");
			AppendNewLine();
		}
		
		void DebugOutput(object o)
		{
//			Console.WriteLine(o.ToString());
		}
		
		#region ICSharpCode.SharpRefactory.Parser.VB.IASTVisitor interface implementation
		public object Visit(INode node, object data)
		{
			AppendIndentation();
			sourceText.Append("// warning visited unknown node :");
			sourceText.Append(node);
			AppendNewLine();
			return String.Empty;
		}
		
		public object Visit(CompilationUnit compilationUnit, object data)
		{
			DebugOutput(compilationUnit);
			compilationUnit.AcceptChildren(this, data);
			return null;
		}
		
#region GlobalScope
		public object Visit(NamespaceDeclaration namespaceDeclaration, object data)
		{
			DebugOutput(namespaceDeclaration);
			AppendIndentation();
			sourceText.Append("namespace ");
			sourceText.Append(namespaceDeclaration.NameSpace);
			AppendNewLine();
			sourceText.Append("{");
			AppendNewLine();
			++indentLevel;
			namespaceDeclaration.AcceptChildren(this, data);
			--indentLevel;
			AppendIndentation();
			sourceText.Append("}");
			AppendNewLine();
			return null;
		}
		
		public object Visit(ImportsStatement importsStatement, object data)
		{
			foreach (INode node in importsStatement.ImportClauses) {
				node.AcceptVisitor(this, data);
			}
			return null;
		}
		
		
		public object Visit(ImportsDeclaration importsDeclaration, object data)
		{
			DebugOutput(importsDeclaration);
			AppendIndentation();
			sourceText.Append("using ");
			sourceText.Append(importsDeclaration.Namespace);
			sourceText.Append(";");
			AppendNewLine();
			return null;
		}
		
		public object Visit(ImportsAliasDeclaration importsAliasDeclaration, object data)
		{
			DebugOutput(importsAliasDeclaration);
			AppendIndentation();
			sourceText.Append("using ");
			sourceText.Append(importsAliasDeclaration.Alias);
			sourceText.Append(" = ");
			sourceText.Append(importsAliasDeclaration.Namespace);
			sourceText.Append(";");
			AppendNewLine();
			return null;
		}
		
		
		public object Visit(TypeDeclaration typeDeclaration, object data)
		{
			DebugOutput(typeDeclaration);
			AppendAttributes(typeDeclaration.Attributes);
			string modifier =  GetModifier(typeDeclaration.Modifier);
			string type = String.Empty;
			
			switch (typeDeclaration.Type) {
				case Types.Class:
					type = "class ";
					break;
				case Types.Enum:
					type = "enum ";
					break;
				case Types.Interface:
					type = "interface ";
					break;
				case Types.Module:
				case Types.Structure:
					type = "struct ";
					break;
			}
			AppendIndentation();
			sourceText.Append(modifier);
			sourceText.Append(type);
			sourceText.Append(typeDeclaration.Name);
			
			bool hasBaseType = typeDeclaration.BaseType != null;
			if (hasBaseType) {
				sourceText.Append(" : "); 
				sourceText.Append(ConvertTypeString(typeDeclaration.BaseType)); 
			}
			
			if (typeDeclaration.BaseInterfaces != null && typeDeclaration.BaseInterfaces.Count > 0) {
				if (!hasBaseType) {
					sourceText.Append(" : "); 
				} else {
					sourceText.Append(", "); 
				}
				for (int i = 0; i < typeDeclaration.BaseInterfaces.Count; ++i) {
					if (typeDeclaration.BaseInterfaces[i] is TypeReference) {
						sourceText.Append((typeDeclaration.BaseInterfaces[i] as TypeReference).Type);
					} else {
						sourceText.Append(typeDeclaration.BaseInterfaces[i].ToString());
					}
					if (i + 1 < typeDeclaration.BaseInterfaces.Count) {
						sourceText.Append(", "); 
					}
				}
			}
			AppendNewLine();
			AppendIndentation();
			sourceText.Append("{");
			AppendNewLine();
			++indentLevel;
			TypeDeclaration oldType = currentType;
			currentType = typeDeclaration;
			typeDeclaration.AcceptChildren(this, data);
			currentType = oldType;
			--indentLevel;
			AppendIndentation();
			sourceText.Append("}");
			AppendNewLine();
			return null;
		}
		
		public object Visit(DelegateDeclaration delegateDeclaration, object data)
		{
			DebugOutput(delegateDeclaration);
			AppendAttributes(delegateDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(delegateDeclaration.Modifier));
			sourceText.Append("delegate ");
			sourceText.Append(GetTypeString(delegateDeclaration.ReturnType));
			sourceText.Append(" ");
			sourceText.Append(delegateDeclaration.Name);
			sourceText.Append("(");
			AppendParameters(delegateDeclaration.Parameters);
			sourceText.Append(");");
			AppendNewLine();
			return null;
		}
		
		public object Visit(EventDeclaration eventDeclaration, object data)
		{
			DebugOutput(eventDeclaration);
			AppendAttributes(eventDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(eventDeclaration.Modifier));
			sourceText.Append("event ");
			
			if (eventDeclaration.TypeReference == null) {
				sourceText.Append(eventDeclaration.Name);
				sourceText.Append("EventHandler");
			} else {
				sourceText.Append(GetTypeString(eventDeclaration.TypeReference));
			}
			sourceText.Append(" ");
			sourceText.Append(eventDeclaration.Name);
			sourceText.Append(";");
			AppendNewLine();
			return null;
		}
#endregion

#region TypeLevel
		public object Visit(VariableDeclaration variableDeclaration, object data)
		{
			// called inside ENUMS
//			AppendAttributes(field.Attributes);
			AppendIndentation();
			sourceText.Append(variableDeclaration.Name);
			if (variableDeclaration.Initializer != null) {
				sourceText.Append(" = ");
				sourceText.Append(variableDeclaration.Initializer.AcceptVisitor(this, data));
			}
			AppendNewLine();
			return null;
		}
		
		public object Visit(FieldDeclaration fieldDeclaration, object data)
		{
			DebugOutput(fieldDeclaration);
			
			foreach (VariableDeclaration field in fieldDeclaration.Fields) {
				AppendAttributes(fieldDeclaration.Attributes);
				AppendIndentation();
				if (currentType.Type == Types.Enum) {
					if (fieldDeclaration.Fields.IndexOf(field) > 0) {
						sourceText.Append(", ");
					}
					sourceText.Append(field.Name);
					if (field.Initializer != null) {
						sourceText.Append(" = ");
						sourceText.Append(field.Initializer.AcceptVisitor(this, data).ToString());
					}
				} else {
					if (fieldDeclaration.Modifier == Modifier.None) {
						sourceText.Append(" private ");
					} else {
						sourceText.Append(GetModifier(fieldDeclaration.Modifier));
					}
					if (field.Type == null)
						sourceText.Append("object");
					else	
						sourceText.Append(GetTypeString(field.Type));
					sourceText.Append(" ");
					sourceText.Append(field.Name);
					if (field.Initializer != null) {
						sourceText.Append(" = ");
						sourceText.Append(field.Initializer.AcceptVisitor(this, data).ToString());
					} else {
						if (field.Type != null && field.Type.Dimension != null) {
							sourceText.Append(" = new ");
							sourceText.Append(ConvertTypeString(field.Type.Type));
							sourceText.Append("[");
							sourceText.Append(GetExpressionList(field.Type.Dimension));
							sourceText.Append("]");
						}
					}
					sourceText.Append(";");
					AppendNewLine();
				}
			}
			
			// if that's not the last enum member, add a comma
			if (currentType.Type == Types.Enum) {
				int pos = currentType.Children.IndexOf(fieldDeclaration);
				if (pos >= 0) {
					for (int i = pos+1; i < currentType.Children.Count; i++) {
						if (currentType.Children[i] is FieldDeclaration) {
							sourceText.Append(",");
							break;
						}
					}
				}
				AppendNewLine();
			}
			return null;
		}
		
		public object Visit(MethodDeclaration methodDeclaration, object data)
		{
			DebugOutput(methodDeclaration);
			exitConstructStack.Push(new DictionaryEntry(typeof(MethodDeclaration), null));
			
			AppendNewLine();
			AppendAttributes(methodDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(methodDeclaration.Modifier));
			sourceText.Append(GetTypeString(methodDeclaration.TypeReference));
			sourceText.Append(" ");
			sourceText.Append(methodDeclaration.Name);
			sourceText.Append("(");
			AppendParameters(methodDeclaration.Parameters);
			sourceText.Append(")");
			
			if (currentType.Type != Types.Interface &&
				(methodDeclaration.Modifier & Modifier.MustOverride) != Modifier.MustOverride)
			{
				AppendNewLine();
				AppendIndentation();
				sourceText.Append("{");
				AppendNewLine();
				if (methodDeclaration.Body != null) {
					++indentLevel;
					methodDeclaration.Body.AcceptVisitor(this, data);
					GenerateExitConstructLabel();
					--indentLevel;
				}
				AppendIndentation();
				sourceText.Append("}");
			} else {
				sourceText.Append(";");
			}
			AppendNewLine();
			return null;
		}
		
		public object Visit(ConstructorDeclaration constructorDeclaration, object data)
		{
			DebugOutput(constructorDeclaration);
			exitConstructStack.Push(new DictionaryEntry(typeof(MethodDeclaration), null));
			AppendNewLine();
			AppendAttributes(constructorDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(constructorDeclaration.Modifier));
			sourceText.Append(this.currentType.Name);
			sourceText.Append("(");
			AppendParameters(constructorDeclaration.Parameters);
			sourceText.Append(")");
			
			AppendNewLine();
			AppendIndentation();
			sourceText.Append("{");
			AppendNewLine();
			if (constructorDeclaration.Body != null) {
				++indentLevel;
				constructorDeclaration.Body.AcceptVisitor(this, data);
				GenerateExitConstructLabel();
				--indentLevel;
			}
			AppendIndentation();
			sourceText.Append("}");
			AppendNewLine();
			return null;
		}
		
		public object Visit(DeclareDeclaration declareDeclaration, object data)
		{
			DebugOutput(declareDeclaration);
			AppendAttributes(declareDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(String.Format("[System.Runtime.InteropServices.DllImport({0}", declareDeclaration.Library));
			if (declareDeclaration.Alias != null) {
				sourceText.Append(String.Format(", EntryPoint={0}", declareDeclaration.Alias));
			}
			
			switch (declareDeclaration.Charset) {
				case CharsetModifier.ANSI:
					sourceText.Append(", CharSet=System.Runtime.InteropServices.CharSet.Ansi");
					break;
				case CharsetModifier.Unicode:
					sourceText.Append(", CharSet=System.Runtime.InteropServices.CharSet.Unicode");
					break;
				case CharsetModifier.Auto:
					sourceText.Append(", CharSet=System.Runtime.InteropServices.CharSet.Auto");
					break;
			}
			
			sourceText.Append(")]");
			AppendNewLine();
			AppendIndentation();
			sourceText.Append(GetModifier(declareDeclaration.Modifier));
			sourceText.Append("static extern ");
			sourceText.Append(GetTypeString(declareDeclaration.ReturnType));
			sourceText.Append(" ");
			sourceText.Append(declareDeclaration.Name);
			sourceText.Append("(");
			AppendParameters(declareDeclaration.Parameters);
			sourceText.Append(");");
			AppendNewLine();
			return null;
		}
		
		public object Visit(PropertyDeclaration propertyDeclaration, object data)
		{
			DebugOutput(propertyDeclaration);
			AppendNewLine();
			AppendAttributes(propertyDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(propertyDeclaration.Modifier & ~Modifier.ReadOnly));
			
			sourceText.Append(GetTypeString(propertyDeclaration.TypeReference));
			sourceText.Append(" ");
			sourceText.Append(propertyDeclaration.Name);
			sourceText.Append(" {");
			AppendNewLine();
			
			if (currentType.Type != Types.Interface) {
				if (propertyDeclaration.GetRegion != null) {
					++indentLevel;
					propertyDeclaration.GetRegion.AcceptVisitor(this, data);
					--indentLevel;
				}
				
				if (propertyDeclaration.SetRegion != null) {
					++indentLevel;
					propertyDeclaration.SetRegion.AcceptVisitor(this, data);
					--indentLevel;
				}
				
			}
			// if abstract, add default get/set
			if ((propertyDeclaration.Modifier & Modifier.MustOverride) == Modifier.MustOverride &&
			    propertyDeclaration.GetRegion == null &&
			    propertyDeclaration.SetRegion == null) {
				AppendIndentation();
				sourceText.Append("get;");
				AppendNewLine();
				AppendIndentation();
				sourceText.Append("set;");
				AppendNewLine();
			}			
			AppendIndentation();
			sourceText.Append("}");
			AppendNewLine();
			return null;
		}
		
		public object Visit(PropertyGetRegion propertyGetRegion, object data)
		{
			DebugOutput(propertyGetRegion);
			exitConstructStack.Push(new DictionaryEntry(typeof(PropertyDeclaration), null));
			AppendAttributes(propertyGetRegion.Attributes);
			AppendIndentation();
			sourceText.Append("get {");
			AppendNewLine();
			if (propertyGetRegion.Block != null) {
				++indentLevel;

⌨️ 快捷键说明

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