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

📄 codegenerator.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: 1317 $</version>
// </file>

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.NRefactory.Parser.AST;

namespace ICSharpCode.SharpDevelop.Refactoring
{
	/// <summary>
	/// Provides code generation facilities.
	/// </summary>
	public abstract class CodeGenerator
	{
		#region DOM -> NRefactory conversion (static)
		public static TypeReference ConvertType(IReturnType returnType, ClassFinder context)
		{
			if (returnType == null)           return TypeReference.Null;
			if (returnType is NullReturnType) return TypeReference.Null;
			
			TypeReference typeRef;
			if (context != null && CanUseShortTypeName(returnType, context))
				typeRef = new TypeReference(returnType.Name);
			else
				typeRef = new TypeReference(returnType.FullyQualifiedName);
			while (returnType.ArrayDimensions > 0) {
				int[] rank = typeRef.RankSpecifier ?? new int[0];
				Array.Resize(ref rank, rank.Length + 1);
				rank[rank.Length - 1] = returnType.ArrayDimensions - 1;
				typeRef.RankSpecifier = rank;
				returnType = returnType.ArrayElementType;
			}
			if (returnType.TypeArguments != null) {
				foreach (IReturnType typeArgument in returnType.TypeArguments) {
					typeRef.GenericTypes.Add(ConvertType(typeArgument, context));
				}
			}
			return typeRef;
		}
		
		/// <summary>
		/// Returns true if the short name of a type is valid in the given context.
		/// Returns false for primitive types because they should be passed around using their
		/// fully qualified names to allow the ambience or output visitor to use the intrinsic
		/// type name.
		/// </summary>
		public static bool CanUseShortTypeName(IReturnType returnType, ClassFinder context)
		{
			switch (returnType.FullyQualifiedName) {
				case "System.Void":
				case "System.String":
				case "System.Char":
				case "System.Boolean":
				case "System.Single":
				case "System.Double":
				case "System.Decimal":
				case "System.Byte":
				case "System.SByte":
				case "System.Int16":
				case "System.Int32":
				case "System.Int64":
				case "System.UInt16":
				case "System.UInt32":
				case "System.UInt64":
					return false;
			}
			int typeArgumentCount = (returnType.TypeArguments != null) ? returnType.TypeArguments.Count : 0;
			IReturnType typeInTargetContext = context.SearchType(returnType.Name, typeArgumentCount);
			return typeInTargetContext != null && typeInTargetContext.FullyQualifiedName == returnType.FullyQualifiedName;
		}
		
		public static Modifier ConvertModifier(ModifierEnum m)
		{
			return (Modifier)m;
		}
		
		public static ParamModifier ConvertModifier(ParameterModifiers m)
		{
			return (ParamModifier)m;
		}
		
		public static List<ParameterDeclarationExpression> ConvertParameters(IList<IParameter> parameters, ClassFinder targetContext)
		{
			List<ParameterDeclarationExpression> l = new List<ParameterDeclarationExpression>(parameters.Count);
			foreach (IParameter p in parameters) {
				ParameterDeclarationExpression pd = new ParameterDeclarationExpression(ConvertType(p.ReturnType, targetContext),
				                                                                       p.Name,
				                                                                       ConvertModifier(p.Modifiers));
				pd.Attributes = ConvertAttributes(p.Attributes, targetContext);
				l.Add(pd);
			}
			return l;
		}
		
		public static List<AttributeSection> ConvertAttributes(IList<IAttribute> attributes, ClassFinder targetContext)
		{
			AttributeSection sec = new AttributeSection(null, null);
			foreach (IAttribute att in attributes) {
				sec.Attributes.Add(new ICSharpCode.NRefactory.Parser.AST.Attribute(att.Name, null, null));
			}
			List<AttributeSection> resultList = new List<AttributeSection>(1);
			if (sec.Attributes.Count > 0)
				resultList.Add(sec);
			return resultList;
		}
		
		public static List<TemplateDefinition> ConvertTemplates(IList<ITypeParameter> l, ClassFinder targetContext)
		{
			List<TemplateDefinition> o = new List<TemplateDefinition>(l.Count);
			foreach (ITypeParameter p in l) {
				TemplateDefinition td = new TemplateDefinition(p.Name, ConvertAttributes(p.Attributes, targetContext));
				foreach (IReturnType rt in p.Constraints) {
					td.Bases.Add(ConvertType(rt, targetContext));
				}
				o.Add(td);
			}
			return o;
		}
		
		public static BlockStatement CreateNotImplementedBlock()
		{
			BlockStatement b = new BlockStatement();
			b.AddChild(new ThrowStatement(new ObjectCreateExpression(new TypeReference("NotImplementedException"), null)));
			return b;
		}
		
		public static ParametrizedNode ConvertMember(IMethod m, ClassFinder targetContext)
		{
			if (m.IsConstructor) {
				return new ConstructorDeclaration(m.Name,
				                                  ConvertModifier(m.Modifiers),
				                                  ConvertParameters(m.Parameters, targetContext),
				                                  ConvertAttributes(m.Attributes, targetContext));
			} else {
				MethodDeclaration md;
				md = new MethodDeclaration(m.Name,
				                           ConvertModifier(m.Modifiers),
				                           ConvertType(m.ReturnType, targetContext),
				                           ConvertParameters(m.Parameters, targetContext),
				                           ConvertAttributes(m.Attributes, targetContext));
				md.Templates = ConvertTemplates(m.TypeParameters, targetContext);
				md.Body = CreateNotImplementedBlock();
				return md;
			}
		}
		
		public static AttributedNode ConvertMember(IMember m, ClassFinder targetContext)
		{
			if (m == null)
				throw new ArgumentNullException("m");
			if (m is IProperty)
				return ConvertMember((IProperty)m, targetContext);
			else if (m is IMethod)
				return ConvertMember((IMethod)m, targetContext);
			else if (m is IEvent)
				return ConvertMember((IEvent)m, targetContext);
			else if (m is IField)
				return ConvertMember((IField)m, targetContext);
			else
				throw new ArgumentException("Unknown member: " + m.GetType().FullName);
		}
		
		public static AttributedNode ConvertMember(IProperty p, ClassFinder targetContext)
		{
			if (p.IsIndexer) {
				IndexerDeclaration md;
				md = new IndexerDeclaration(ConvertType(p.ReturnType, targetContext),
				                            ConvertParameters(p.Parameters, targetContext),
				                            ConvertModifier(p.Modifiers),
				                            ConvertAttributes(p.Attributes, targetContext));
				md.Parameters = ConvertParameters(p.Parameters, targetContext);
				if (p.CanGet) md.GetRegion = new PropertyGetRegion(CreateNotImplementedBlock(), null);
				if (p.CanSet) md.SetRegion = new PropertySetRegion(CreateNotImplementedBlock(), null);
				return md;
			} else {
				PropertyDeclaration md;
				md = new PropertyDeclaration(p.Name,
				                             ConvertType(p.ReturnType, targetContext),
				                             ConvertModifier(p.Modifiers),
				                             ConvertAttributes(p.Attributes, targetContext));
				md.Parameters = ConvertParameters(p.Parameters, targetContext);
				if (p.CanGet) md.GetRegion = new PropertyGetRegion(CreateNotImplementedBlock(), null);
				if (p.CanSet) md.SetRegion = new PropertySetRegion(CreateNotImplementedBlock(), null);
				return md;
			}
		}
		
		public static FieldDeclaration ConvertMember(IField f, ClassFinder targetContext)
		{
			TypeReference type = ConvertType(f.ReturnType, targetContext);
			FieldDeclaration fd = new FieldDeclaration(ConvertAttributes(f.Attributes, targetContext),
			                                           type, ConvertModifier(f.Modifiers));
			fd.Fields.Add(new VariableDeclaration(f.Name, null, type));
			return fd;
		}
		
		public static EventDeclaration ConvertMember(IEvent e, ClassFinder targetContext)
		{
			return new EventDeclaration(ConvertType(e.ReturnType, targetContext),
			                            e.Name,
			                            ConvertModifier(e.Modifiers),
			                            ConvertAttributes(e.Attributes, targetContext),
			                            null);
		}
		#endregion
		
		#region Code generation / insertion
		public virtual void InsertCodeAfter(IMember member, IDocument document, params AbstractNode[] nodes)
		{
			if (member is IMethodOrProperty) {
				InsertCodeAfter(((IMethodOrProperty)member).BodyRegion.EndLine, document,
				                GetIndentation(document, member.Region.BeginLine), nodes);
			} else {
				InsertCodeAfter(member.Region.EndLine, document,
				                GetIndentation(document, member.Region.BeginLine), nodes);
			}
		}
		
		public virtual void InsertCodeAtEnd(DomRegion region, IDocument document, params AbstractNode[] nodes)
		{
			InsertCodeAfter(region.EndLine - 1, document,
			                GetIndentation(document, region.BeginLine) + '\t', nodes);
		}
		
		public virtual void InsertCodeInClass(IClass c, IDocument document, int targetLine, params AbstractNode[] nodes)
		{
			InsertCodeAfter(targetLine, document,
			                GetIndentation(document, c.Region.BeginLine) + '\t', false, nodes);
		}
		
		protected string GetIndentation(IDocument document, int line)
		{
			LineSegment lineSegment = document.GetLineSegment(line - 1);
			string lineText = document.GetText(lineSegment.Offset, lineSegment.Length);
			return lineText.Substring(0, lineText.Length - lineText.TrimStart().Length);
		}
		
		/// <summary>
		/// Generates code for <paramref name="nodes"/> and inserts it into <paramref name="document"/>
		/// after the line <paramref name="insertLine"/>.
		/// </summary>
		protected void InsertCodeAfter(int insertLine, IDocument document, string indentation, params AbstractNode[] nodes)
		{
			InsertCodeAfter(insertLine, document, indentation, true, nodes);
		}
		
		/// <summary>
		/// Generates code for <paramref name="nodes"/> and inserts it into <paramref name="document"/>
		/// after the line <paramref name="insertLine"/>.
		/// </summary>

⌨️ 快捷键说明

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