a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
247 lines
7.0 KiB
C#
247 lines
7.0 KiB
C#
//
|
|
// 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
|
|
//
|
|
|
|
#if !FULL_AOT_RUNTIME
|
|
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
|
|
namespace Mono.CodeGeneration
|
|
{
|
|
public class CodeProperty
|
|
{
|
|
PropertyInfo propertyInfo;
|
|
CodeBuilder get_builder;
|
|
CodeBuilder set_builder;
|
|
string name;
|
|
PropertyAttributes attributes;
|
|
MethodAttributes methodAttributes;
|
|
Type returnType;
|
|
TypeBuilder typeBuilder;
|
|
Type[] parameterTypes;
|
|
ArrayList customAttributes = new ArrayList ();
|
|
CodeClass cls;
|
|
|
|
internal static CodeProperty DefineProperty (CodeClass cls, string name, PropertyAttributes attributes, MethodAttributes methodAttributes, Type returnType, Type[] parameterTypes)
|
|
{
|
|
return new CodeProperty (cls, name, attributes, methodAttributes, returnType, parameterTypes);
|
|
}
|
|
|
|
internal CodeProperty (CodeClass cls, string name, PropertyAttributes attributes, MethodAttributes methodAttributes, Type returnType, Type[] parameterTypes)
|
|
{
|
|
this.cls = cls;
|
|
this.typeBuilder = cls.TypeBuilder;
|
|
this.name = name;
|
|
this.attributes = attributes;
|
|
this.methodAttributes = methodAttributes;
|
|
this.returnType = returnType;
|
|
this.parameterTypes = parameterTypes;
|
|
|
|
PropertyBuilder pb = typeBuilder.DefineProperty (name, attributes, returnType, parameterTypes);
|
|
pb.SetGetMethod (typeBuilder.DefineMethod ("get_" + name, methodAttributes, CallingConventions.Standard, returnType, Type.EmptyTypes));
|
|
pb.SetSetMethod (typeBuilder.DefineMethod ("set_" + name, methodAttributes, CallingConventions.Standard, typeof (void), new Type [] {returnType}));
|
|
get_builder = new CodeBuilder (cls);
|
|
set_builder = new CodeBuilder (cls);
|
|
propertyInfo = pb;
|
|
}
|
|
|
|
public TypeBuilder DeclaringType
|
|
{
|
|
get { return typeBuilder; }
|
|
}
|
|
|
|
public PropertyBuilder PropertyBuilder
|
|
{
|
|
get { return propertyInfo as PropertyBuilder; }
|
|
}
|
|
|
|
public string Name
|
|
{
|
|
get { return name; }
|
|
}
|
|
|
|
public PropertyAttributes Attributes
|
|
{
|
|
get { return attributes; }
|
|
}
|
|
|
|
public Type ReturnType
|
|
{
|
|
get { return returnType; }
|
|
}
|
|
|
|
public Type[] ParameterTypes
|
|
{
|
|
get { return parameterTypes; }
|
|
}
|
|
|
|
public CodeBuilder CodeBuilderGet
|
|
{
|
|
get { return get_builder; }
|
|
}
|
|
|
|
public CodeBuilder CodeBuilderSet
|
|
{
|
|
get { return set_builder; }
|
|
}
|
|
|
|
public bool IsStatic
|
|
{
|
|
get { return (methodAttributes & MethodAttributes.Static) != 0; }
|
|
}
|
|
|
|
public bool IsPublic
|
|
{
|
|
get { return (methodAttributes & MethodAttributes.Public) != 0; }
|
|
}
|
|
|
|
public CodeCustomAttribute CreateCustomAttribute (Type attributeType)
|
|
{
|
|
return CreateCustomAttribute (attributeType,
|
|
Type.EmptyTypes, new object [0]);
|
|
}
|
|
|
|
public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs)
|
|
{
|
|
return CreateCustomAttribute (attributeType,
|
|
ctorArgTypes, ctorArgs, 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);
|
|
SetCustomAttribute (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);
|
|
SetCustomAttribute (cca);
|
|
return cca;
|
|
}
|
|
|
|
void SetCustomAttribute (CodeCustomAttribute cca)
|
|
{
|
|
PropertyBuilder.SetCustomAttribute (cca.Builder);
|
|
customAttributes.Add (cca);
|
|
}
|
|
|
|
public string PrintCode ()
|
|
{
|
|
StringWriter sw = new StringWriter ();
|
|
CodeWriter cw = new CodeWriter (sw);
|
|
PrintCode (cw);
|
|
return sw.ToString ();
|
|
}
|
|
|
|
public void PrintCode (CodeWriter cp)
|
|
{
|
|
cp.BeginLine ();
|
|
foreach (CodeCustomAttribute a in customAttributes)
|
|
a.PrintCode (cp);
|
|
cp.BeginLine ();
|
|
if (IsStatic)
|
|
cp.Write ("static ");
|
|
if (IsPublic)
|
|
cp.Write ("public ");
|
|
if (returnType != null) cp.Write (returnType + " ");
|
|
cp.Write (name);
|
|
if (parameterTypes.Length > 0) {
|
|
cp.Write (name + " [");
|
|
for (int n=0; n<parameterTypes.Length; n++) {
|
|
if (n > 0) cp.Write (", ");
|
|
cp.Write (parameterTypes[n] + " arg" + n);
|
|
}
|
|
cp.Write ("]");
|
|
}
|
|
cp.Write (" {");
|
|
cp.EndLine ();
|
|
cp.Indent ();
|
|
cp.WriteLineInd ("get {");
|
|
get_builder.PrintCode (cp);
|
|
cp.WriteLineUnind ("}");
|
|
cp.WriteLine ("set {");
|
|
set_builder.PrintCode (cp);
|
|
cp.WriteLine ("}");
|
|
cp.WriteLineUnind ("}");
|
|
}
|
|
|
|
public CodeArgumentReference GetArg (int n)
|
|
{
|
|
if (n < 0 || n >= parameterTypes.Length)
|
|
throw new InvalidOperationException ("Invalid argument number");
|
|
|
|
int narg = IsStatic ? n : n + 1;
|
|
return new CodeArgumentReference (parameterTypes[n], narg, "arg" + n);
|
|
}
|
|
|
|
public CodeArgumentReference GetThis ()
|
|
{
|
|
if (IsStatic)
|
|
throw new InvalidOperationException ("'this' not available in static methods");
|
|
|
|
return new CodeArgumentReference (DeclaringType, 0, "this");
|
|
}
|
|
|
|
public void Generate ()
|
|
{
|
|
ILGenerator gen;
|
|
Label returnLabel;
|
|
MethodBuilder mb;
|
|
|
|
// getter
|
|
mb = (MethodBuilder) propertyInfo.GetGetMethod ();
|
|
if (mb != null) {
|
|
gen = mb.GetILGenerator();
|
|
returnLabel = gen.DefineLabel ();
|
|
get_builder.ReturnLabel = returnLabel;
|
|
get_builder.Generate (gen);
|
|
gen.MarkLabel (returnLabel);
|
|
gen.Emit (OpCodes.Ret);
|
|
}
|
|
|
|
// setter
|
|
mb = (MethodBuilder) propertyInfo.GetSetMethod ();
|
|
if (mb != null) {
|
|
gen = mb.GetILGenerator();
|
|
returnLabel = gen.DefineLabel ();
|
|
set_builder.ReturnLabel = returnLabel;
|
|
set_builder.Generate (gen);
|
|
gen.MarkLabel (returnLabel);
|
|
gen.Emit (OpCodes.Ret);
|
|
}
|
|
}
|
|
|
|
public void UpdatePropertyInfo (Type type)
|
|
{
|
|
propertyInfo = type.GetProperty (propertyInfo.Name, parameterTypes);
|
|
}
|
|
}
|
|
}
|
|
#endif
|