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

📄 vbnetvisitor.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 4 页
字号:
// VBNetVisitor.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;
using ICSharpCode.SharpRefactory.Parser.AST;

namespace ICSharpCode.SharpRefactory.PrettyPrinter
{
	public class VBNetVisitor : AbstractASTVisitor
	{
		readonly string newLineSep  = Environment.NewLine;
		StringBuilder   sourceText  = new StringBuilder();
		int             indentLevel = 0;
		Errors          errors      = new Errors();
		TypeDeclaration currentType = null;
		bool            generateAttributeUnderScore = false;

		public StringBuilder SourceText {
			get {
				return sourceText;
			}
		}
		
#region ICSharpCode.SharpRefactory.Parser.IASTVisitor interface implementation
		public override object Visit(INode node, object data)
		{
			errors.Error(-1, -1, String.Format("Visited INode (should NEVER HAPPEN)"));
			Console.WriteLine("Visitor was: " + this.GetType());
			Console.WriteLine("Node was : " + node.GetType());
			return node.AcceptChildren(this, data);
		}
		
		public void AppendIndentation()
		{
			for (int i = 0; i < indentLevel; ++i) {
				sourceText.Append("\t");
			}
		}
		
		public void AppendNewLine()
		{
			sourceText.Append(newLineSep);
		}
		
		void DebugOutput(object o)
		{
//			Console.WriteLine(o.ToString());
		}
		
		public override object Visit(CompilationUnit compilationUnit, object data)
		{
			DebugOutput(compilationUnit);
			new VBNetRefactory().Refactor(compilationUnit);
			compilationUnit.AcceptChildren(this, data);
			return null;
		}
		
		public override object Visit(NamespaceDeclaration namespaceDeclaration, object data)
		{
			DebugOutput(namespaceDeclaration);
			AppendIndentation();
			sourceText.Append("Namespace ");
			sourceText.Append(namespaceDeclaration.NameSpace);
			AppendNewLine();
			++indentLevel;
			namespaceDeclaration.AcceptChildren(this, data);
			--indentLevel;
			AppendIndentation();
			sourceText.Append("End Namespace");
			AppendNewLine();
			return null;
		}
		
		public override object Visit(UsingDeclaration usingDeclaration, object data)
		{
			DebugOutput(usingDeclaration);
			AppendIndentation();
			sourceText.Append("Imports ");
			sourceText.Append(usingDeclaration.Namespace);
			AppendNewLine();
			return null;
		}
		
		public override object Visit(UsingAliasDeclaration usingAliasDeclaration, object data)
		{
			DebugOutput(usingAliasDeclaration);
			AppendIndentation();
			sourceText.Append("Imports ");
			sourceText.Append(usingAliasDeclaration.Alias);
			sourceText.Append(" = ");
			sourceText.Append(usingAliasDeclaration.Namespace);
			AppendNewLine();
			return null;
		}
		
		public override object Visit(AttributeSection attributeSection, object data)
		{
			DebugOutput(attributeSection);
			AppendIndentation();
			sourceText.Append("<");
			if (attributeSection.AttributeTarget != null && attributeSection.AttributeTarget.Length > 0) {
				sourceText.Append(attributeSection.AttributeTarget);
				sourceText.Append(": ");
			}
			for (int j = 0; j < attributeSection.Attributes.Count; ++j) {
				ICSharpCode.SharpRefactory.Parser.AST.Attribute attr = (ICSharpCode.SharpRefactory.Parser.AST.Attribute)attributeSection.Attributes[j];
				
				sourceText.Append(attr.Name);
				sourceText.Append("(");
				for (int i = 0; i < attr.PositionalArguments.Count; ++i) {
					Expression expr = (Expression)attr.PositionalArguments[i];
					sourceText.Append(expr.AcceptVisitor(this, data).ToString());
					if (i + 1 < attr.PositionalArguments.Count) { 
						sourceText.Append(", ");
					}
				}
				
				for (int i = 0; i < attr.NamedArguments.Count; ++i) {
					NamedArgument named = (NamedArgument)attr.NamedArguments[i];
					sourceText.Append(named.Name);
					sourceText.Append("=");
					sourceText.Append(named.Expr.AcceptVisitor(this, data).ToString());
					if (i + 1 < attr.NamedArguments.Count) { 
						sourceText.Append(", ");
					}
				}
				sourceText.Append(")");
				if (j + 1 < attributeSection.Attributes.Count) {
					sourceText.Append(", ");
				}
			}
			sourceText.Append("> ");
			if (generateAttributeUnderScore) {
				sourceText.Append("_");
			}
			AppendNewLine();
			return null;
		}
		
		public override object Visit(TypeDeclaration typeDeclaration, object data)
		{
			DebugOutput(typeDeclaration);
			AppendNewLine();
			generateAttributeUnderScore = true;
			AppendAttributes(typeDeclaration.Attributes);
			string modifier =  GetModifier(typeDeclaration.Modifier);
			string type = String.Empty;
			
			if ((typeDeclaration.Modifier & Modifier.Abstract) == Modifier.Abstract)
				modifier = modifier.Replace("MustOverride", "MustInherit");
			
			switch (typeDeclaration.Type) {
				case Types.Class:
					type = "Class ";
					break;
				case Types.Enum:
					type = "Enum ";
					break;
				case Types.Interface:
					type = "Interface ";
					break;
				case Types.Struct:
					// this should be better in VBNetRefactory class because it is an AST transformation, but currently I'm too lazy
					if (TypeHasOnlyStaticMembers(typeDeclaration)) {
						goto case Types.Class;
					}
					type = "Structure ";
					break;
			}
			AppendIndentation();
			sourceText.Append(modifier);
			sourceText.Append(type);
			sourceText.Append(typeDeclaration.Name);
			AppendNewLine();
			
			if (typeDeclaration.BaseTypes != null) {
				foreach (string baseType in typeDeclaration.BaseTypes) {
					AppendIndentation();
					
					bool baseTypeIsInterface = baseType.StartsWith("I") && (baseType.Length <= 1 || Char.IsUpper(baseType[1]));
					
					if (!baseTypeIsInterface || typeDeclaration.Type == Types.Interface) {
						sourceText.Append("Inherits "); 
					} else {
						sourceText.Append("Implements "); 
					}
					sourceText.Append(baseType); 
					AppendNewLine();
				}
			}
			
			++indentLevel;
			TypeDeclaration oldType = currentType;
			currentType = typeDeclaration;
			typeDeclaration.AcceptChildren(this, data);
			currentType = oldType;
			--indentLevel;
			AppendIndentation();
			sourceText.Append("End ");
			sourceText.Append(type);
			AppendNewLine();
			generateAttributeUnderScore = false;
			return null;
		}
		
		public override object Visit(DelegateDeclaration delegateDeclaration, object data)
		{
			DebugOutput(delegateDeclaration);
			AppendNewLine();
			AppendAttributes(delegateDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(delegateDeclaration.Modifier));
			sourceText.Append("Delegate ");
			bool isFunction = (delegateDeclaration.ReturnType.Type != "void");
			if (isFunction) {
				sourceText.Append("Function ");
			} else {
				sourceText.Append("Sub ");
			}
			
			sourceText.Append(delegateDeclaration.Name);
			sourceText.Append("(");
			AppendParameters(delegateDeclaration.Parameters);
			sourceText.Append(")");
			if (isFunction) {
				sourceText.Append(" As ");
				sourceText.Append(GetTypeString(delegateDeclaration.ReturnType));
			}
			AppendNewLine();
			return null;
		}
		
		public override 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 override object Visit(FieldDeclaration fieldDeclaration, object data)
		{
			DebugOutput(fieldDeclaration);
			foreach (VariableDeclaration field in fieldDeclaration.Fields) {
				AppendAttributes(fieldDeclaration.Attributes);
				AppendIndentation();
				if (fieldDeclaration.Modifier == Modifier.None) {
					sourceText.Append("Private ");
				} else {
					sourceText.Append(GetModifier(fieldDeclaration.Modifier));
				}
				sourceText.Append(field.Name);
				
				// the type can be null (enum members)
				if(fieldDeclaration.TypeReference != null) {
					sourceText.Append(" As ");
					sourceText.Append(GetTypeString(fieldDeclaration.TypeReference));
				}
				if (field.Initializer != null) {
					sourceText.Append(" = ");
					sourceText.Append(field.Initializer.AcceptVisitor(this, data).ToString());
				}
				AppendNewLine();
			}

			return null;
		}
		
		public override object Visit(MethodDeclaration methodDeclaration, object data)
		{
			DebugOutput(methodDeclaration);
			AppendNewLine();
			AppendAttributes(methodDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(methodDeclaration.Modifier));
			bool isFunction = methodDeclaration.TypeReference.Type != "void";
			string defStr   = isFunction ? "Function" : "Sub";
			sourceText.Append(defStr);
			sourceText.Append(" ");
			sourceText.Append(methodDeclaration.Name);
			sourceText.Append("(");
			AppendParameters(methodDeclaration.Parameters);
			sourceText.Append(")");
			if (isFunction) {
				sourceText.Append(" As ");
				sourceText.Append(GetTypeString(methodDeclaration.TypeReference));
			}
			AppendNewLine();
			
			if (currentType.Type != Types.Interface) {
				if (methodDeclaration.Body != null) {
					++indentLevel;
					methodDeclaration.Body.AcceptVisitor(this, data);
					--indentLevel;
				}
				
				if ((methodDeclaration.Modifier & Modifier.Abstract) != Modifier.Abstract) {
					AppendIndentation();
					sourceText.Append("End ");
					sourceText.Append(defStr);
					AppendNewLine();
				}
			}
			return null;
		}
		
		public override object Visit(PropertyDeclaration propertyDeclaration, object data)
		{
			DebugOutput(propertyDeclaration);
			AppendNewLine();
			AppendAttributes(propertyDeclaration.Attributes);
			AppendIndentation();
			sourceText.Append(GetModifier(propertyDeclaration.Modifier));
			if (propertyDeclaration.IsReadOnly) {
				sourceText.Append("ReadOnly ");
			} else if (propertyDeclaration.IsWriteOnly) {
				sourceText.Append("WriteOnly ");
			}
			sourceText.Append("Property ");
			sourceText.Append(propertyDeclaration.Name);
			sourceText.Append("() As ");
			sourceText.Append(GetTypeString(propertyDeclaration.TypeReference));
			AppendNewLine();
			
			bool isAbstract = (propertyDeclaration.Modifier & Modifier.Abstract) == Modifier.Abstract;
			
			if (currentType.Type != Types.Interface && !isAbstract) {
				if (propertyDeclaration.GetRegion != null) {
					++indentLevel;
					propertyDeclaration.GetRegion.AcceptVisitor(this, data);
					--indentLevel;
				}
				
				if (propertyDeclaration.SetRegion != null) {
					++indentLevel;
					propertyDeclaration.SetRegion.AcceptVisitor(this, data);
					--indentLevel;
				}
				
				AppendIndentation();
				sourceText.Append("End Property");
				AppendNewLine();
			}
			return null;
		}
		
		public override object Visit(PropertyGetRegion propertyGetRegion, object data)
		{
			DebugOutput(propertyGetRegion);
			AppendAttributes(propertyGetRegion.Attributes);
			AppendIndentation();
			sourceText.Append("Get");
			AppendNewLine();
			
			if (propertyGetRegion.Block != null) {
				++indentLevel;
				propertyGetRegion.Block.AcceptVisitor(this, data);
				--indentLevel;
			} 
			AppendIndentation();
			sourceText.Append("End Get");
			AppendNewLine();
			return null;
		}
		
		public override object Visit(PropertySetRegion propertySetRegion, object data)
		{
			DebugOutput(propertySetRegion);
			AppendAttributes(propertySetRegion.Attributes);
			AppendIndentation();
			sourceText.Append("Set");
			AppendNewLine();
			
			if (propertySetRegion.Block != null) {
				++indentLevel;
				propertySetRegion.Block.AcceptVisitor(this, data);
				--indentLevel;
			}
			
			AppendIndentation();
			sourceText.Append("End Set");
			AppendNewLine();
			return null;
		}
		
		public override object Visit(EventDeclaration eventDeclaration, object data)
		{
			DebugOutput(eventDeclaration);
			AppendNewLine();
			if (eventDeclaration.Name == null) { 
				foreach (VariableDeclaration field in eventDeclaration.VariableDeclarators) {
					AppendAttributes(eventDeclaration.Attributes);
					AppendIndentation();
					sourceText.Append(GetModifier(eventDeclaration.Modifier));
					sourceText.Append("Event ");
					sourceText.Append(field.Name);
					sourceText.Append(" As ");
					sourceText.Append(GetTypeString(eventDeclaration.TypeReference));
				}
			} else {
				AppendAttributes(eventDeclaration.Attributes);
				AppendIndentation();
				sourceText.Append(GetModifier(eventDeclaration.Modifier));
				sourceText.Append("Event ");
				sourceText.Append(eventDeclaration.Name);
				sourceText.Append(" As ");
				sourceText.Append(GetTypeString(eventDeclaration.TypeReference));
				if (eventDeclaration.HasAddRegion) {
					errors.Error(-1, -1, String.Format("Event add region can't be converted"));
				}
				if (eventDeclaration.HasRemoveRegion) {
					errors.Error(-1, -1, String.Format("Event remove region can't be converted"));
				}
			}
			
			AppendNewLine();

⌨️ 快捷键说明

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