csharpoutputvisitor.cs

来自「SharpDevelop2.0.0 c#开发免费工具」· CS 代码 · 共 1,955 行 · 第 1/5 页

CS
1,955
字号
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 1434 $</version>
// </file>

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Diagnostics;

using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.CSharp;
using ICSharpCode.NRefactory.Parser.AST;

namespace ICSharpCode.NRefactory.PrettyPrinter
{
	public class CSharpOutputVisitor : IOutputASTVisitor
	{
		Errors                errors             = new Errors();
		CSharpOutputFormatter outputFormatter;
		PrettyPrintOptions    prettyPrintOptions = new PrettyPrintOptions();
		NodeTracker           nodeTracker;
//		Stack<WithStatement> withExpressionStack = new Stack<WithStatement>();
		Stack withExpressionStack = new Stack();
		
		public string Text {
			get {
				return outputFormatter.Text;
			}
		}
		
		public Errors Errors {
			get {
				return errors;
			}
		}
		
		public object Options {
			get {
				return prettyPrintOptions;
			}
			set {
				prettyPrintOptions = value as PrettyPrintOptions;
			}
		}
		
		public IOutputFormatter OutputFormatter {
			get {
				return outputFormatter;
			}
		}
		
		public NodeTracker NodeTracker {
			get {
				return nodeTracker;
			}
		}
		
		public CSharpOutputVisitor()
		{
			outputFormatter = new CSharpOutputFormatter(prettyPrintOptions);
			nodeTracker     = new NodeTracker(this);
		}
		
		#region ICSharpCode.NRefactory.Parser.IASTVisitor interface implementation
		public object Visit(INode node, object data)
		{
			errors.Error(-1, -1, String.Format("Visited INode (should NEVER HAPPEN), node is : {0}", node.ToString()));
			return node.AcceptChildren(this, data);
		}
		
		public object Visit(CompilationUnit compilationUnit, object data)
		{
			nodeTracker.TrackedVisitChildren(compilationUnit, data);
			outputFormatter.EndFile();
			return null;
		}
		
		string ConvertTypeString(string typeString)
		{
			switch (typeString) {
				case "System.Boolean":
					return "bool";
				case "System.String":
					return "string";
				case "System.Char":
					return "char";
				case "System.Double":
					return "double";
				case "System.Single":
					return "float";
				case "System.Decimal":
					return "decimal";
				case "System.Int64":
					return "long";
				case "System.Int32":
					return "int";
				case "System.Int16":
					return "short";
				case "System.Byte":
					return "byte";
				case "System.Void":
					return "void";
				case "System.Object":
					return "object";
					
				case "System.UInt64":
					return "ulong";
				case "System.UInt32":
					return "uint";
				case "System.UInt16":
					return "ushort";
				case "System.SByte":
					return "sbyte";
			}
			return typeString;
		}
		
		
		void PrintTemplates(List<TemplateDefinition> templates)
		{
			if (templates.Count == 0) return;
			outputFormatter.PrintToken(Tokens.LessThan);
			for (int i = 0; i < templates.Count; i++) {
				if (i > 0) PrintFormattedComma();
				outputFormatter.PrintIdentifier(templates[i].Name);
			}
			outputFormatter.PrintToken(Tokens.GreaterThan);
		}
		
		public object Visit(TypeReference typeReference, object data)
		{
			PrintTypeReferenceWithoutArray(typeReference);
			if (typeReference.IsArrayType) {
				PrintArrayRank(typeReference.RankSpecifier, 0);
			}
			return null;
		}
		
		void PrintArrayRank(int[] rankSpecifier, int startRankIndex)
		{
			for (int i = startRankIndex; i < rankSpecifier.Length; ++i) {
				outputFormatter.PrintToken(Tokens.OpenSquareBracket);
				if (this.prettyPrintOptions.SpacesWithinBrackets) {
					outputFormatter.Space();
				}
				for (int j = 0; j < rankSpecifier[i]; ++j) {
					outputFormatter.PrintToken(Tokens.Comma);
				}
				if (this.prettyPrintOptions.SpacesWithinBrackets) {
					outputFormatter.Space();
				}
				outputFormatter.PrintToken(Tokens.CloseSquareBracket);
			}
		}
		
		void PrintTypeReferenceWithoutArray(TypeReference typeReference)
		{
			if (typeReference.IsGlobal) {
				outputFormatter.PrintText("global::");
			}
			if (typeReference.Type == null || typeReference.Type.Length ==0) {
				outputFormatter.PrintText("void");
			} else if (typeReference.SystemType == "System.Nullable" && typeReference.GenericTypes != null
			           && typeReference.GenericTypes.Count == 1)
			{
				nodeTracker.TrackedVisit(typeReference.GenericTypes[0], null);
				outputFormatter.PrintText("?");
			} else {
				if (typeReference.SystemType.Length > 0) {
					outputFormatter.PrintText(ConvertTypeString(typeReference.SystemType));
				} else {
					outputFormatter.PrintText(typeReference.Type);
				}
				if (typeReference.GenericTypes != null && typeReference.GenericTypes.Count > 0) {
					outputFormatter.PrintToken(Tokens.LessThan);
					AppendCommaSeparatedList(typeReference.GenericTypes);
					outputFormatter.PrintToken(Tokens.GreaterThan);
				}
			}
			for (int i = 0; i < typeReference.PointerNestingLevel; ++i) {
				outputFormatter.PrintToken(Tokens.Times);
			}
		}
		
		public object Visit(InnerClassTypeReference typeReference, object data)
		{
			nodeTracker.TrackedVisit(typeReference.BaseType, data);
			outputFormatter.PrintToken(Tokens.Dot);
			return Visit((TypeReference)typeReference, data); // call Visit(TypeReference, object)
		}
		
		#region Global scope
		void VisitAttributes(ICollection attributes, object data)
		{
			if (attributes == null || attributes.Count <= 0) {
				return;
			}
			foreach (AttributeSection section in attributes) {
				nodeTracker.TrackedVisit(section, data);
			}
		}
		void PrintFormattedComma()
		{
			if (this.prettyPrintOptions.SpacesBeforeComma) {
				outputFormatter.Space();
			}
			outputFormatter.PrintToken(Tokens.Comma);
			if (this.prettyPrintOptions.SpacesAfterComma) {
				outputFormatter.Space();
			}
		}
		
		public object Visit(AttributeSection attributeSection, object data)
		{
			outputFormatter.Indent();
			outputFormatter.PrintToken(Tokens.OpenSquareBracket);
			if (this.prettyPrintOptions.SpacesWithinBrackets) {
				outputFormatter.Space();
			}
			if (attributeSection.AttributeTarget != null && attributeSection.AttributeTarget != String.Empty) {
				outputFormatter.PrintText(attributeSection.AttributeTarget);
				outputFormatter.PrintToken(Tokens.Colon);
				outputFormatter.Space();
			}
			Debug.Assert(attributeSection.Attributes != null);
			for (int j = 0; j < attributeSection.Attributes.Count; ++j) {
				nodeTracker.TrackedVisit((INode)attributeSection.Attributes[j], data);
				if (j + 1 < attributeSection.Attributes.Count) {
					PrintFormattedComma();
				}
			}
			if (this.prettyPrintOptions.SpacesWithinBrackets) {
				outputFormatter.Space();
			}
			outputFormatter.PrintToken(Tokens.CloseSquareBracket);
			outputFormatter.NewLine();
			return null;
		}
		
		public object Visit(ICSharpCode.NRefactory.Parser.AST.Attribute attribute, object data)
		{
			outputFormatter.PrintIdentifier(attribute.Name);
			outputFormatter.PrintToken(Tokens.OpenParenthesis);
			this.AppendCommaSeparatedList(attribute.PositionalArguments);
			
			if (attribute.NamedArguments != null && attribute.NamedArguments.Count > 0) {
				if (attribute.PositionalArguments.Count > 0) {
					PrintFormattedComma();
				}
				for (int i = 0; i < attribute.NamedArguments.Count; ++i) {
					nodeTracker.TrackedVisit((INode)attribute.NamedArguments[i], data);
					if (i + 1 < attribute.NamedArguments.Count) {
						PrintFormattedComma();
					}
				}
			}
			outputFormatter.PrintToken(Tokens.CloseParenthesis);
			return null;
		}
		
		public object Visit(NamedArgumentExpression namedArgumentExpression, object data)
		{
			outputFormatter.PrintIdentifier(namedArgumentExpression.Name);
			outputFormatter.Space();
			outputFormatter.PrintToken(Tokens.Assign);
			outputFormatter.Space();
			nodeTracker.TrackedVisit(namedArgumentExpression.Expression, data);
			return null;
		}
		
		public object Visit(Using u, object data)
		{
			outputFormatter.Indent();
			outputFormatter.PrintToken(Tokens.Using);
			outputFormatter.Space();
			
			outputFormatter.PrintIdentifier(u.Name);
			
			if (u.IsAlias) {
				outputFormatter.Space();
				outputFormatter.PrintToken(Tokens.Assign);
				outputFormatter.Space();
				nodeTracker.TrackedVisit(u.Alias, data);
			}
			
			outputFormatter.PrintToken(Tokens.Semicolon);
			outputFormatter.NewLine();
			return null;
		}
		
		public object Visit(UsingDeclaration usingDeclaration, object data)
		{
			foreach (Using u in usingDeclaration.Usings) {
				nodeTracker.TrackedVisit(u, data);
			}
			return null;
		}
		
		public object Visit(NamespaceDeclaration namespaceDeclaration, object data)
		{
			outputFormatter.Indent();
			outputFormatter.PrintToken(Tokens.Namespace);
			outputFormatter.Space();
			outputFormatter.PrintIdentifier(namespaceDeclaration.Name);
			
			outputFormatter.BeginBrace(this.prettyPrintOptions.NameSpaceBraceStyle);
			
			nodeTracker.TrackedVisitChildren(namespaceDeclaration, data);
			
			outputFormatter.EndBrace();
			
			return null;
		}
		
		
		void OutputEnumMembers(TypeDeclaration typeDeclaration, object data)
		{
			for (int i = 0; i < typeDeclaration.Children.Count; i++) {
				FieldDeclaration fieldDeclaration = (FieldDeclaration)typeDeclaration.Children[i];
				nodeTracker.BeginNode(fieldDeclaration);
				VariableDeclaration f = (VariableDeclaration)fieldDeclaration.Fields[0];
				VisitAttributes(fieldDeclaration.Attributes, data);
				outputFormatter.Indent();
				outputFormatter.PrintIdentifier(f.Name);
				if (f.Initializer != null && !f.Initializer.IsNull) {
					outputFormatter.Space();
					outputFormatter.PrintToken(Tokens.Assign);
					outputFormatter.Space();
					nodeTracker.TrackedVisit(f.Initializer, data);
				}
				if (i < typeDeclaration.Children.Count - 1) {
					outputFormatter.PrintToken(Tokens.Comma);
				}
				outputFormatter.NewLine();
				nodeTracker.EndNode(fieldDeclaration);
			}
		}
		
		TypeDeclaration currentType = null;
		
		public object Visit(TypeDeclaration typeDeclaration, object data)
		{
			VisitAttributes(typeDeclaration.Attributes, data);
			outputFormatter.Indent();
			OutputModifier(typeDeclaration.Modifier);
			switch (typeDeclaration.Type) {
				case ClassType.Enum:
					outputFormatter.PrintToken(Tokens.Enum);
					break;
				case ClassType.Interface:
					outputFormatter.PrintToken(Tokens.Interface);
					break;
				case ClassType.Struct:
					outputFormatter.PrintToken(Tokens.Struct);
					break;
				default:
					outputFormatter.PrintToken(Tokens.Class);
					break;
			}
			outputFormatter.Space();
			outputFormatter.PrintIdentifier(typeDeclaration.Name);
			
			PrintTemplates(typeDeclaration.Templates);
			
			if (typeDeclaration.BaseTypes != null && typeDeclaration.BaseTypes.Count > 0) {
				outputFormatter.Space();
				outputFormatter.PrintToken(Tokens.Colon);
				outputFormatter.Space();
				for (int i = 0; i < typeDeclaration.BaseTypes.Count; ++i) {
					if (i > 0) {
						PrintFormattedComma();
					}
					nodeTracker.TrackedVisit(typeDeclaration.BaseTypes[i], data);
				}
			}
			
			foreach (TemplateDefinition templateDefinition in typeDeclaration.Templates) {
				nodeTracker.TrackedVisit(templateDefinition, data);
			}
			
			switch (typeDeclaration.Type) {
				case ClassType.Enum:
					outputFormatter.BeginBrace(this.prettyPrintOptions.EnumBraceStyle);
					break;
				case ClassType.Interface:
					outputFormatter.BeginBrace(this.prettyPrintOptions.InterfaceBraceStyle);

⌨️ 快捷键说明

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