main.cs

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

CS
495
字号
					}
					
					for (int i = 0; i < assertions.Count; i++) {
						m.Statements.Insert(i, assertions[i]);
					}
				}
			}
			return td;
		}
		
		static void AddFieldVisitCode(CodeMemberMethod m, Type type, CodeVariableReferenceExpression var, List<CodeStatement> assertions, bool transformer)
		{
			if (type != null) {
				if (type.BaseType != typeof(StatementWithEmbeddedStatement)) {
					AddFieldVisitCode(m, type.BaseType, var, assertions, transformer);
				}
				foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) {
					AddVisitCode(m, field, var, assertions, transformer);
				}
				if (type.BaseType == typeof(StatementWithEmbeddedStatement)) {
					AddFieldVisitCode(m, type.BaseType, var, assertions, transformer);
				}
			}
		}
		
		static CodeStatement AssertIsNotNull(CodeExpression expr)
		{
			CodeExpression bop = new CodeBinaryOperatorExpression(expr,
			                                                      CodeBinaryOperatorType.IdentityInequality,
			                                                      new CodePrimitiveExpression(null)
			                                                     );
			return new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("Debug"),
			                                                                  "Assert",
			                                                                  bop));
		}
		
		static string GetCode(CodeExpression ex)
		{
			using (StringWriter writer = new StringWriter()) {
				new Microsoft.CSharp.CSharpCodeProvider().GenerateCodeFromExpression(ex, writer, null);
				return writer.ToString();
			}
		}
		
		static string CreateTransformerLoop(string collection, string typeName)
		{
			return
				"\t\t\tfor (int i = 0; i < " + collection + ".Count; i++) {\n" +
				"\t\t\t\t" + typeName + " o = " + collection + "[i];\n" +
				"\t\t\t\tDebug.Assert(o != null);\n" +
				"\t\t\t\tnodeStack.Push(o);\n" +
				"\t\t\t\to.AcceptVisitor(this, data);\n" +
				(typeName == "INode"
				 ? "\t\t\t\to = nodeStack.Pop();\n"
				 : "\t\t\t\to = (" + typeName + ")nodeStack.Pop();\n") +
				"\t\t\t\tif (o == null)\n" +
				"\t\t\t\t\t" + collection + ".RemoveAt(i--);\n" +
				"\t\t\t\telse\n" +
				"\t\t\t\t\t" + collection + "[i] = o;\n" +
				"\t\t\t}";
		}
		
		static bool AddVisitCode(CodeMemberMethod m, FieldInfo field, CodeVariableReferenceExpression var, List<CodeStatement> assertions, bool transformer)
		{
			CodeExpression prop = new CodePropertyReferenceExpression(var, GetPropertyName(field.Name));
			CodeExpression nodeStack = new CodeVariableReferenceExpression("nodeStack");
			if (field.FieldType.FullName.StartsWith("System.Collections.Generic.List")) {
				Type elType = field.FieldType.GetGenericArguments()[0];
				if (!typeof(INode).IsAssignableFrom(elType))
					return false;
				assertions.Add(AssertIsNotNull(prop));
				string code;
				if (transformer) {
					code = CreateTransformerLoop(GetCode(prop), ConvertType(elType).BaseType);
				} else {
					code =
						"\t\t\tforeach (" + ConvertType(elType).BaseType + " o in " + GetCode(prop) + ") {\n" +
						"\t\t\t\tDebug.Assert(o != null);\n" +
						"\t\t\t\to.AcceptVisitor(this, data);\n" +
						"\t\t\t}";
				}
				m.Statements.Add(new CodeSnippetStatement(code));
				return true;
			}
			if (!typeof(INode).IsAssignableFrom(field.FieldType))
				return false;
			assertions.Add(AssertIsNotNull(prop));
			if (transformer) {
				m.Statements.Add(new CodeMethodInvokeExpression(nodeStack, "Push",
				                                                prop));
			}
			m.Statements.Add(new CodeMethodInvokeExpression(prop,
			                                                "AcceptVisitor",
			                                                new CodeThisReferenceExpression(),
			                                                new CodeVariableReferenceExpression("data")));
			if (transformer) {
				CodeExpression ex = new CodeMethodInvokeExpression(nodeStack, "Pop");
				ex = new CodeCastExpression(ConvertType(field.FieldType), ex);
				m.Statements.Add(new CodeAssignStatement(prop, ex));
			}
			return true;
		}
		
		static CodeExpression CreateToString(Type type)
		{
			CodeMethodInvokeExpression ie = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(string)),
			                                                               "Format");
			CodePrimitiveExpression prim = new CodePrimitiveExpression();
			ie.Parameters.Add(prim);
			string text = "[" + type.Name;
			int index = 0;
			do {
				foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) {
					text += " " + GetPropertyName(field.Name) + "={" + index.ToString() + "}";
					index++;
					if (typeof(System.Collections.ICollection).IsAssignableFrom(field.FieldType)) {
						ie.Parameters.Add(new CodeSnippetExpression("GetCollectionString(" + GetPropertyName(field.Name) + ")"));
					} else {
						ie.Parameters.Add(new CodeVariableReferenceExpression(GetPropertyName(field.Name)));
					}
				}
				type = type.BaseType;
			} while (type != null);
			prim.Value = text + "]";
			if (ie.Parameters.Count == 1)
				return prim;
			else
				return ie;
			//	return String.Format("[AnonymousMethodExpression: Parameters={0} Body={1}]",
			//	                     GetCollectionString(Parameters),
			//	                     Body);
		}
		
		static void ProcessType(Type type, CodeTypeDeclaration ctd)
		{
			foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic)) {
				CodeMemberField f = new CodeMemberField(ConvertType(field.FieldType), field.Name);
				f.Attributes = 0;
				ctd.Members.Add(f);
			}
			foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic)) {
				CodeMemberProperty p = new CodeMemberProperty();
				p.Name = GetPropertyName(field.Name);
				p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				p.Type = ConvertType(field.FieldType);
				p.GetStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression(field.Name)));
				CodeExpression ex;
				if (field.FieldType.IsValueType)
					ex = new CodePropertySetValueReferenceExpression();
				else
					ex = GetDefaultValue("value", field);
				p.SetStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(field.Name), ex));
				ctd.Members.Add(p);
			}
			foreach (ConstructorInfo ctor in type.GetConstructors()) {
				CodeConstructor c = new CodeConstructor();
				c.Attributes = MemberAttributes.Public;
				ctd.Members.Add(c);
				ConstructorInfo baseCtor = GetBaseCtor(type);
				foreach(ParameterInfo param in ctor.GetParameters()) {
					c.Parameters.Add(new CodeParameterDeclarationExpression(ConvertType(param.ParameterType),
					                                                        param.Name));
					if (baseCtor != null && Array.Exists(baseCtor.GetParameters(), delegate(ParameterInfo p) { return param.Name == p.Name; }))
						continue;
					c.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(GetPropertyName(param.Name)),
					                                         new CodeVariableReferenceExpression(param.Name)));
				}
				if (baseCtor != null) {
					foreach(ParameterInfo param in baseCtor.GetParameters()) {
						c.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(param.Name));
					}
				}
				// initialize fields that were not initialized by parameter
				foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic)) {
					if (field.FieldType.IsValueType && field.FieldType != typeof(Point))
						continue;
					if (Array.Exists(ctor.GetParameters(), delegate(ParameterInfo p) { return field.Name == p.Name; }))
						continue;
					c.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(field.Name),
					                                         GetDefaultValue(null, field)));
				}
			}
		}
		
		internal static ConstructorInfo GetBaseCtor(Type type)
		{
			ConstructorInfo[] list = type.BaseType.GetConstructors();
			if (list.Length == 0)
				return null;
			else
				return list[0];
		}
		
		internal static CodeExpression GetDefaultValue(string inputVariable, FieldInfo field)
		{
			string code;
			// get default value:
			if (field.FieldType == typeof(string)) {
				code = "\"\"";
				if (field.GetCustomAttributes(typeof(QuestionMarkDefaultAttribute), false).Length > 0) {
					if (inputVariable == null)
						return new CodePrimitiveExpression("?");
					else
						return new CodeSnippetExpression("string.IsNullOrEmpty(" + inputVariable + ") ? \"?\" : " + inputVariable);
				}
			} else if (field.FieldType.FullName.StartsWith("System.Collections.Generic.List")) {
				code = "new List<" + field.FieldType.GetGenericArguments()[0].Name + ">()";
			} else if (field.FieldType == typeof(Point)) {
				code = "new Point(-1, -1)";
			} else {
				code = field.FieldType.Name + ".Null";
			}
			if (inputVariable != null) {
				code = inputVariable + " ?? " + code;
			}
			return new CodeSnippetExpression(code);
		}
		
		internal static string GetFieldName(string typeName)
		{
			return char.ToLower(typeName[0]) + typeName.Substring(1);
		}
		
		internal static string GetPropertyName(string fieldName)
		{
			return char.ToUpper(fieldName[0]) + fieldName.Substring(1);
		}
		
		internal static CodeTypeReference ConvertType(Type type)
		{
			if (type.IsGenericType && !type.IsGenericTypeDefinition) {
				CodeTypeReference tr = ConvertType(type.GetGenericTypeDefinition());
				foreach (Type subType in type.GetGenericArguments()) {
					tr.TypeArguments.Add(ConvertType(subType));
				}
				return tr;
			} else if (type.FullName.StartsWith("NRefactory") || type.FullName.StartsWith("System.Collections")) {
				if (type.Name == "Attribute")
					return new CodeTypeReference("ICSharpCode.NRefactory.Parser.AST.Attribute");
				return new CodeTypeReference(type.Name);
			} else {
				return new CodeTypeReference(type);
			}
		}
	}
}

⌨️ 快捷键说明

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