/mcs/class/System.ServiceModel/Mono.CodeGeneration/CodeClass.cs
C# | 348 lines | 271 code | 52 blank | 25 comment | 48 complexity | 0c19a864f1cd48b8eb5636f6d1cd8891 MD5 | raw file
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // Copyright (C) Lluis Sanchez Gual, 2004
- //
- using System;
- using System.IO;
- using System.Collections;
- using System.Reflection;
- using System.Reflection.Emit;
- namespace Mono.CodeGeneration
- {
- public class CodeClass
- {
- TypeBuilder typeBuilder;
- ArrayList customAttributes = new ArrayList ();
- ArrayList methods = new ArrayList ();
- ArrayList properties = new ArrayList ();
- ArrayList fields = new ArrayList ();
- Hashtable fieldAttributes = new Hashtable ();
- Type baseType;
- Type[] interfaces;
- CodeMethod ctor;
- CodeMethod cctor;
- CodeBuilder instanceInit;
- CodeBuilder classInit;
- int varId;
-
- public CodeClass (ModuleBuilder mb, string name)
- : this (mb, name, TypeAttributes.Public, typeof(object))
- {
- }
-
- public CodeClass (ModuleBuilder mb, string name, Type baseType, params Type[] interfaces)
- : this (mb, name, TypeAttributes.Public, baseType, interfaces)
- {
- }
-
- public CodeClass (ModuleBuilder mb, string name, TypeAttributes attr, Type baseType, params Type[] interfaces)
- {
- typeBuilder = mb.DefineType (name, attr, baseType, interfaces);
- this.baseType = baseType;
- this.interfaces = interfaces;
- }
- public CodeCustomAttribute CreateCustomAttribute (Type attributeType)
- {
- return CreateCustomAttribute (attributeType,
- Type.EmptyTypes, new object [0], new string [0], new object [0]);
- }
- public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs, string [] namedArgFieldNames, object [] namedArgValues)
- {
- CodeCustomAttribute cca = CodeCustomAttribute.Create (
- attributeType, ctorArgTypes, ctorArgs, namedArgFieldNames, namedArgValues);
- typeBuilder.SetCustomAttribute (cca.Builder);
- customAttributes.Add (cca);
- return cca;
- }
- public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, CodeLiteral [] ctorArgs, FieldInfo [] fields, CodeLiteral [] fieldValues)
- {
- CodeCustomAttribute cca = CodeCustomAttribute.Create (
- attributeType, ctorArgTypes, ctorArgs, fields, fieldValues);
- typeBuilder.SetCustomAttribute (cca.Builder);
- customAttributes.Add (cca);
- return cca;
- }
- public CodeProperty CreateProperty (string name, Type returnType, params Type [] parameterTypes)
- {
- return CreateProperty (name, returnType, MethodAttributes.Private, parameterTypes);
- }
- public CodeProperty CreateProperty (string name, Type returnType, MethodAttributes methodAttributes, params Type [] parameterTypes)
- {
- CodeProperty prop = new CodeProperty (this, GetPropertyName (name), PropertyAttributes.None, methodAttributes, returnType, parameterTypes);
- properties.Add (prop);
- return prop;
- }
- public CodeMethod CreateMethod (string name, Type returnType, params Type[] parameterTypes)
- {
- CodeMethod met = new CodeMethod (this, GetMethodName (name), MethodAttributes.Public, returnType, parameterTypes);
- methods.Add (met);
- return met;
- }
-
- public CodeMethod CreateVirtualMethod (string name, Type returnType, params Type[] parameterTypes)
- {
- CodeMethod met = new CodeMethod (this, GetMethodName (name), MethodAttributes.Public | MethodAttributes.Virtual, returnType, parameterTypes);
- methods.Add (met);
- return met;
- }
-
- public CodeMethod CreateStaticMethod (string name, Type returnType, params Type[] parameterTypes)
- {
- CodeMethod met = new CodeMethod (this, GetMethodName (name), MethodAttributes.Public | MethodAttributes.Static, returnType, parameterTypes);
- methods.Add (met);
- return met;
- }
-
- public CodeMethod CreateMethod (string name, MethodAttributes attributes, Type returnType, params Type[] parameterTypes)
- {
- CodeMethod met = new CodeMethod (this, GetMethodName (name), attributes, returnType, parameterTypes);
- methods.Add (met);
- return met;
- }
-
- public CodeMethod GetDefaultConstructor ()
- {
- if (ctor != null) return ctor;
- ctor = CreateConstructor (MethodAttributes.Public, Type.EmptyTypes);
- return ctor;
- }
-
- public CodeMethod CreateConstructor (params Type[] parameters)
- {
- return CreateConstructor (MethodAttributes.Private, parameters);
- }
- public CodeMethod CreateConstructor (MethodAttributes attributes, params Type[] parameters)
- {
- if (ctor != null) return ctor;
- ctor = CodeMethod.DefineConstructor (this, attributes, parameters);
- methods.Add (ctor);
- CodeBuilder cb = GetInstanceInitBuilder ();
- ctor.CodeBuilder.CurrentBlock.Add (cb.CurrentBlock);
- return ctor;
- }
-
- public CodeMethod GetStaticConstructor ()
- {
- if (cctor != null) return cctor;
- cctor = CodeMethod.DefineConstructor (this, MethodAttributes.Public | MethodAttributes.Static, Type.EmptyTypes);
- methods.Add (cctor);
- CodeBuilder cb = GetClassInitBuilder ();
- cctor.CodeBuilder.CurrentBlock.Add (cb.CurrentBlock);
- return cctor;
- }
-
- public CodeMethod ImplementMethod (Type baseType, string methodName)
- {
- MethodInfo basem = baseType.GetMethod (methodName);
- return ImplementMethod (baseType, basem);
- }
-
- public CodeMethod ImplementMethod (MethodInfo basem)
- {
- return ImplementMethod (basem.DeclaringType, basem);
- }
-
- public CodeMethod ImplementMethod (Type baseType, MethodInfo basem)
- {
- ParameterInfo[] pinfos = basem.GetParameters ();
- Type[] pars = new Type[pinfos.Length];
- for (int n=0; n<pinfos.Length; n++)
- pars[n] = pinfos[n].ParameterType;
- CodeMethod met = CodeMethod.DefineMethod (this, basem.Name, MethodAttributes.Public | MethodAttributes.Virtual, basem.ReturnType, pars);
- typeBuilder.DefineMethodOverride (met.MethodInfo, basem);
- methods.Add (met);
- return met;
- }
-
- public CodeFieldReference DefineField (string name, Type type, params CodeCustomAttribute [] customAttributes)
- {
- return DefineField (GetFieldName (name), type, FieldAttributes.Public, null, customAttributes);
- }
-
- public CodeFieldReference DefineStaticField (CodeExpression initialValue, params CodeCustomAttribute [] customAttributes)
- {
- return DefineField (GetFieldName (null), initialValue.GetResultType(), FieldAttributes.Public | FieldAttributes.Static, initialValue, customAttributes);
- }
-
- public CodeFieldReference DefineStaticField (string name, Type type, CodeExpression initialValue, params CodeCustomAttribute [] customAttributes)
- {
- return DefineField (GetFieldName (name), type, FieldAttributes.Public | FieldAttributes.Static, initialValue, customAttributes);
- }
-
- public CodeFieldReference DefineField (string name, Type type, FieldAttributes attrs, CodeExpression initialValue, params CodeCustomAttribute [] customAttributes)
- {
- FieldBuilder fb = typeBuilder.DefineField (GetFieldName (name), type, attrs);
- foreach (CodeCustomAttribute a in customAttributes)
- fb.SetCustomAttribute (a.Builder);
- fieldAttributes [fb] = new ArrayList (customAttributes);
- fields.Add (fb);
- CodeFieldReference fr;
- if ((attrs & FieldAttributes.Static) != 0)
- fr = new CodeFieldReference (fb);
- else
- fr = new CodeFieldReference (new CodeArgumentReference (TypeBuilder, 0, "this"), fb);
-
- if (null != (object) initialValue) {
- CodeBuilder cb = (attrs & FieldAttributes.Static) == 0 ? GetInstanceInitBuilder () : GetClassInitBuilder ();
- cb.Assign (fr, initialValue);
- }
- return fr;
- }
-
- public TypeBuilder TypeBuilder
- {
- get { return typeBuilder; }
- }
-
- private CodeBuilder GetInstanceInitBuilder ()
- {
- if (instanceInit != null) return instanceInit;
- instanceInit = new CodeBuilder (this);
- return instanceInit;
- }
-
- private CodeBuilder GetClassInitBuilder ()
- {
- if (classInit != null) return classInit;
- classInit = new CodeBuilder (this);
- return classInit;
- }
-
- private string GetFieldName (string name)
- {
- if (name == null) return "__field_" + (varId++);
- else return name;
- }
-
- private string GetMethodName (string name)
- {
- if (name == null) return "__Method_" + (varId++);
- else return name;
- }
-
- private string GetPropertyName (string name)
- {
- if (name == null) return "__Property_" + (varId++);
- else return name;
- }
-
- public string PrintCode ()
- {
- StringWriter sw = new StringWriter ();
- CodeWriter cw = new CodeWriter (sw);
- PrintCode (cw);
- return sw.ToString ();
- }
-
- public void PrintCode (CodeWriter cw)
- {
- for (int n=0; n<customAttributes.Count; n++) {
- CodeCustomAttribute cca = customAttributes [n] as CodeCustomAttribute;
- if (n > 0) cw.WriteLine ("");
- cca.PrintCode (cw);
- }
- /* if ((typeBuilder.Attributes & TypeAttributes.Abstract) != 0) cw.Write ("abstract ");
- if ((typeBuilder.Attributes & TypeAttributes.NestedAssembly) != 0) cw.Write ("internal ");
- if ((typeBuilder.Attributes & TypeAttributes.NestedPrivate) != 0) cw.Write ("private ");
- */ if ((typeBuilder.Attributes & TypeAttributes.Public) != 0) cw.Write ("public ");
- cw.Write ("class ").Write (typeBuilder.Name);
-
- bool dots = false;
- if (baseType != null && baseType != typeof(object)) {
- cw.Write (" : " + baseType);
- dots = true;
- }
-
- if (interfaces != null && interfaces.Length > 0) {
- if (!dots) cw.Write (" : ");
- else cw.Write (", ");
- for (int n=0; n<interfaces.Length; n++) {
- if (n > 0) cw.Write (", ");
- cw.Write (interfaces[n].ToString ());
- }
- }
-
- cw.EndLine ().WriteLineInd ("{");
-
- foreach (FieldInfo f in fields) {
- cw.BeginLine ();
- ArrayList atts = (ArrayList) fieldAttributes [f];
- foreach (CodeCustomAttribute a in atts)
- a.PrintCode (cw);
- if ((f.Attributes & FieldAttributes.Static) != 0)
- cw.Write ("static ");
- cw.Write (f.FieldType.Name + " ");
- cw.Write (f.Name + ";");
- cw.EndLine ();
- cw.WriteLine ("");
- }
-
- for (int n=0; n<properties.Count; n++) {
- CodeProperty prop = properties [n] as CodeProperty;
- if (n > 0) cw.WriteLine ("");
- prop.PrintCode (cw);
- }
- for (int n=0; n<methods.Count; n++) {
- CodeMethod met = methods[n] as CodeMethod;
- if (n > 0) cw.WriteLine ("");
- met.PrintCode (cw);
- }
- cw.WriteLineUnind ("}");
- }
-
- public Type CreateType ()
- {
- if (ctor == null)
- ctor = GetDefaultConstructor ();
-
- foreach (CodeProperty prop in properties)
- prop.Generate ();
- foreach (CodeMethod met in methods)
- met.Generate ();
-
- Type t = typeBuilder.CreateType ();
-
- foreach (CodeMethod met in methods)
- met.UpdateMethodBase (t);
-
- foreach (CodeProperty prop in properties)
- prop.UpdatePropertyInfo (t);
- return t;
- }
- }
- }