private void AddOwnDefaultCaseDiscriminatorSetter() { // discr val paramter ParameterSpec discrArg = new ParameterSpec("discrVal", DiscriminatorType, ParameterSpec.ParameterDirection.s_in); ParameterSpec[] parameters = new ParameterSpec[] { discrArg }; MethodBuilder modifier = m_ilEmitHelper.AddMethod(m_builder, "SetDefault", parameters, new TypeContainer(ReflectionHelper.VoidType), MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator gen = modifier.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stfld, m_initalizedField); // store initalizedfield gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Stfld, m_discrField); // store discriminator field // check, if discrvalue assigned is ok Label endMethodLabel = gen.DefineLabel(); SwitchCase ownDefault = new SwitchCase(null, null, new object[] { s_defaultCaseDiscriminator }, null); GenerateDiscrValueOkTest(gen, ownDefault, endMethodLabel, s_BadParamConstr, 34); gen.MarkLabel(endMethodLabel); gen.Emit(OpCodes.Ret); }
private void GenerateModifierMethod(SwitchCase switchCase) { ParameterSpec[] parameters; ParameterSpec valArg = new ParameterSpec("val", switchCase.ElemType, ParameterSpec.ParameterDirection.s_in); if (switchCase.HasMoreThanOneDiscrValue()) { // need an additional parameter ParameterSpec discrArg = new ParameterSpec("discrVal", DiscriminatorType, ParameterSpec.ParameterDirection.s_in); parameters = new ParameterSpec[] { valArg, discrArg }; } else { // don't need an additional parameter parameters = new ParameterSpec[] { valArg }; } MethodBuilder modifier = m_ilEmitHelper.AddMethod(m_builder, "Set" + switchCase.ElemName, parameters, new TypeContainer(ReflectionHelper.VoidType), MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator gen = modifier.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stfld, m_initalizedField); // store initalizedfield gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Stfld, switchCase.ElemField); // store value field gen.Emit(OpCodes.Ldarg_0); if (switchCase.HasMoreThanOneDiscrValue()) { gen.Emit(OpCodes.Ldarg_2); } else { PushDiscriminatorValueToStack(gen, switchCase.DiscriminatorValues[0]); } gen.Emit(OpCodes.Stfld, m_discrField); // store discriminator field if (switchCase.HasMoreThanOneDiscrValue()) { // check, if discrvalue assigned is ok Label endMethodLabel = gen.DefineLabel(); GenerateDiscrValueOkTest(gen, switchCase, endMethodLabel, s_BadParamConstr, 34); gen.MarkLabel(endMethodLabel); } gen.Emit(OpCodes.Ret); }
/// <summary> /// reefines a prameter; not possible for return parameter, ...? TODO: refact ... /// </summary> /// <param name="methodBuild"></param> /// <param name="spec"></param> /// <param name="paramNr"></param> private void DefineParameter(MethodBuilder methodBuild, ParameterSpec spec, int paramNr) { ParameterAttributes paramAttr = ParameterAttributes.None; if (spec.IsOut()) { paramAttr = paramAttr | ParameterAttributes.Out; } ParameterBuilder paramBuild = methodBuild.DefineParameter(paramNr, paramAttr, spec.GetPramName()); // custom attribute spec TypeContainer specType = spec.GetParamType(); for (int i = 0; i < specType.GetSeparatedAttrs().Length; i++) { paramBuild.SetCustomAttribute(specType.GetSeparatedAttrs()[i]); } }
private void GenerateGetObjectDataMethod() { ParameterSpec[] getObjDataParams = new ParameterSpec[] { new ParameterSpec("info", typeof(System.Runtime.Serialization.SerializationInfo)), new ParameterSpec("context", typeof(System.Runtime.Serialization.StreamingContext)) }; MethodBuilder getObjectDataMethod = m_ilEmitHelper.AddMethod(m_builder, "GetObjectData", getObjDataParams, new TypeContainer(typeof(void)), MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator body = getObjectDataMethod.GetILGenerator(); MethodInfo addValueMethod = typeof(System.Runtime.Serialization.SerializationInfo).GetMethod("AddValue", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { ReflectionHelper.StringType, ReflectionHelper.ObjectType, ReflectionHelper.TypeType }, new ParameterModifier[0]); MethodInfo getTypeFromH = ReflectionHelper.TypeType.GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static); Label beforeReturn = body.DefineLabel(); // serialize initalized field GenerateAddFieldToObjectData(m_initalizedField, body, addValueMethod, getTypeFromH); // nothing more to do, if not initalized, therefore check here body.Emit(OpCodes.Ldarg_0); body.Emit(OpCodes.Ldfld, m_initalizedField); // fieldvalue body.Emit(OpCodes.Brfalse, beforeReturn); // initalized -> serialise discriminator and corresponding value GenerateAddFieldToObjectData(m_discrField, body, addValueMethod, getTypeFromH); // now serialize field corresponding to discriminator value // do this by using a switch structure GenerateInsertIntoInfoForDiscAction action = new GenerateInsertIntoInfoForDiscAction(this, addValueMethod, getTypeFromH); GenerateSwitchForDiscriminator(body, action, beforeReturn); body.MarkLabel(beforeReturn); body.Emit(OpCodes.Ret); }
private void GenerateISerializableDeserializationConstructor() { // deserialisation constructor ParameterSpec[] constrParams = new ParameterSpec[] { new ParameterSpec("info", typeof(System.Runtime.Serialization.SerializationInfo)), new ParameterSpec("context", typeof(System.Runtime.Serialization.StreamingContext)) }; ConstructorBuilder constrBuilder = m_ilEmitHelper.AddConstructor(m_builder, constrParams, MethodAttributes.Family | MethodAttributes.HideBySig); ILGenerator body = constrBuilder.GetILGenerator(); // value type constructors don't call base class constructors // directly start with deserialisation MethodInfo getValueMethod = typeof(System.Runtime.Serialization.SerializationInfo).GetMethod("GetValue", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(string), typeof(Type) }, new ParameterModifier[0]); MethodInfo getTypeFromH = ReflectionHelper.TypeType.GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static); Label beforeReturn = body.DefineLabel(); // get the value of the init field GenerateGetFieldFromObjectData(m_initalizedField, body, getValueMethod, getTypeFromH); // nothing more to do, if not initalized, therefore check here body.Emit(OpCodes.Ldarg_0); body.Emit(OpCodes.Ldfld, m_initalizedField); // fieldvalue body.Emit(OpCodes.Brfalse, beforeReturn); // initalized -> deserialise discriminator and corresponding value GenerateGetFieldFromObjectData(m_discrField, body, getValueMethod, getTypeFromH); // now deserialize field corresponding to discriminator value GenerateAssignFromInfoForDiscAction action = new GenerateAssignFromInfoForDiscAction(this, getValueMethod, getTypeFromH); GenerateSwitchForDiscriminator(body, action, beforeReturn); body.MarkLabel(beforeReturn); body.Emit(OpCodes.Ret); }
private void AddStructConstructor(TypeBuilder structToCreate, IList /* members */ members) { ParameterSpec[] constrParams = new ParameterSpec[members.Count]; for (int i = 0; i < members.Count; i++) { FieldBuilder member = (FieldBuilder)members[i]; constrParams[i] = new ParameterSpec(member.Name, member.FieldType); } ConstructorBuilder constrBuilder = m_ilEmitHelper.AddConstructor(structToCreate, constrParams, MethodAttributes.Public); ILGenerator body = constrBuilder.GetILGenerator(); // don't need to call parent constructor for a struct; only assign the fields for (int i = 0; i < members.Count; i++) { FieldBuilder member = (FieldBuilder)members[i]; body.Emit(OpCodes.Ldarg_0); // this body.Emit(OpCodes.Ldarg, i+1); // param value body.Emit(OpCodes.Stfld, member); } body.Emit(OpCodes.Ret); }
/// <summary>adds a method to a type, setting the attributes on the parameters</summary> /// <remarks>forgeign method: should be better on TypeBuilder, but not possible</remarks> /// <returns>the MethodBuilder for the method created</returns> public MethodBuilder AddMethod(TypeBuilder builder, string methodName, ParameterSpec[] parameters, TypeContainer returnType, MethodAttributes attrs) { Type[] paramTypes = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { paramTypes[i] = parameters[i].GetParamTypeMergedDirection(); } MethodBuilder methodBuild = builder.DefineMethod(methodName, attrs, returnType.GetSeparatedClsType(), paramTypes); // define the paramter-names / attributes for (int i = 0; i < parameters.Length; i++) { DefineParameter(methodBuild, parameters[i], i+1); } // add custom attributes for the return type ParameterBuilder paramBuild = CreateParamBuilderForRetParam(methodBuild); for (int i = 0; i < returnType.GetSeparatedAttrs().Length; i++) { paramBuild.SetCustomAttribute(returnType.GetSeparatedAttrs()[i]); } return methodBuild; }
/// <summary> /// Like <see cref="Ch.Elca.Iiop.Idl.IlEmitHelper.AddMethod(TypeBuilder, string, ParameterSpec[], TypeContainer, MethodAttributes)"/>, /// but adds additionally a FromIdlName attribute to the method /// </summary> public MethodBuilder AddMethod(TypeBuilder builder, string clsMethodName, string forIdlMethodName, ParameterSpec[] parameters, TypeContainer returnType, MethodAttributes attrs) { MethodBuilder methodBuild = AddMethod(builder, clsMethodName, parameters, returnType, attrs); AddFromIdlNameAttribute(methodBuild, forIdlMethodName); return methodBuild; }
/** * @see parser.IDLParserVisitor#visit(ASTparam_dcl, Object) * @param data the active buildinfo for the current scope * @return an instance of ParameterSpec, containing the relevant information */ public Object visit(ASTparam_dcl node, Object data) { // determine direction ... ParameterSpec.ParameterDirection direction = ((ASTparam_attribute) node.jjtGetChild(0)).getParamDir(); // determine name and type TypeContainer paramType = (TypeContainer)node.jjtGetChild(1).jjtAccept(this, data); if (paramType == null) { throw new InvalidIdlException(String.Format("parameter type {0} not (yet) defined for {1}", ((SimpleNode)node.jjtGetChild(1)).GetIdentification(), node.GetIdentification())); } paramType = ReplaceByCustomMappedIfNeeded(paramType); String paramName = IdlNaming.MapIdlNameToClsName(((ASTsimple_declarator)node.jjtGetChild(2)).getIdent()); ParameterSpec result = new ParameterSpec(paramName, paramType, direction); return result; }
///<summary>add abstract methods for all implemented interfaces to the abstract class, ///add properties for all implemented interfaces to the abstrct class</summary> private void AddInheritedMembersAbstractDeclToClassForIf(TypeBuilder classBuilder, System.Type[] interfaces) { if (!(classBuilder.IsClass)) { return; } // only needed for classes // make sure to include interfaces inherited by the direct implemented interfaces are also considered here interfaces = FlattenInterfaceHierarchy(interfaces); for (int i = 0; i < interfaces.Length; i++) { Type ifType = interfaces[i]; // methods MethodInfo[] methods = ifType.GetMethods(BindingFlags.Instance | BindingFlags.Public); for (int j = 0; j < methods.Length; j++) { if (methods[j].IsSpecialName) { continue; // do not add methods with special name, e.g. property accessor methods } if (ReflectionHelper.IsMethodDefinedOnType(methods[j], classBuilder.BaseType, BindingFlags.Instance | BindingFlags.Public)) { continue; // method is already defined on a baseclass -> do not re-add } // normal parameters ParameterInfo[] parameters = methods[j].GetParameters(); ParameterSpec[] paramSpecs = new ParameterSpec[parameters.Length]; for (int k = 0; k < parameters.Length; k++) { paramSpecs[k] = new ParameterSpec(parameters[k]); } m_ilEmitHelper.AddMethod(classBuilder, methods[j].Name, paramSpecs, new TypeContainer(methods[j].ReturnType, AttributeExtCollection.ConvertToAttributeCollection( methods[j].ReturnTypeCustomAttributes.GetCustomAttributes(false)), true), MethodAttributes.Abstract | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.HideBySig); } // properties PropertyInfo[] properties = ifType.GetProperties(BindingFlags.Instance | BindingFlags.Public); for (int j = 0; j < properties.Length; j++) { if (ReflectionHelper.IsPropertyDefinedOnType(properties[j], classBuilder.BaseType, BindingFlags.Instance | BindingFlags.Public)) { continue; // property is already defined on a baseclass -> do not re-add } TypeContainer propType = new TypeContainer(properties[j].PropertyType, AttributeExtCollection.ConvertToAttributeCollection( properties[j].GetCustomAttributes(true)), true); MethodBuilder getAccessor = m_ilEmitHelper.AddPropertyGetter(classBuilder, properties[j].Name, propType, MethodAttributes.Virtual | MethodAttributes.Abstract | MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot); MethodBuilder setAccessor = null; if (properties[j].CanWrite) { setAccessor = m_ilEmitHelper.AddPropertySetter(classBuilder, properties[j].Name, propType, MethodAttributes.Virtual | MethodAttributes.Abstract | MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot); } m_ilEmitHelper.AddProperty(classBuilder, properties[j].Name, propType, getAccessor, setAccessor); } } }
/** * @see parser.IDLParserVisitor#visit(ASTparameter_dcls, Object) * @param data the active buildinfo for the current scope * @return an array of ParameterSpec instances, describing the paramters */ public Object visit(ASTparameter_dcls node, Object data) { ParameterSpec[] parameters = new ParameterSpec[node.jjtGetNumChildren()]; for (int i = 0; i < node.jjtGetNumChildren(); i++) { parameters[i] = (ParameterSpec) node.jjtGetChild(i).jjtAccept(this, data); } return parameters; }
/// <summary> /// adds the constructors for deserialization. /// </summary> private void AddExceptionDeserializationConstructors(TypeBuilder exceptToCreate, IList members) { // for ISerializable ParameterSpec[] constrParams = new ParameterSpec[] { new ParameterSpec("info", typeof(System.Runtime.Serialization.SerializationInfo)), new ParameterSpec("context", typeof(System.Runtime.Serialization.StreamingContext)) }; ConstructorBuilder constrBuilder = m_ilEmitHelper.AddConstructor(exceptToCreate, constrParams, MethodAttributes.Family | MethodAttributes.HideBySig); ILGenerator body = constrBuilder.GetILGenerator(); body.Emit(OpCodes.Ldarg_0); body.Emit(OpCodes.Ldarg_1); body.Emit(OpCodes.Ldarg_2); body.Emit(OpCodes.Call, typeof(AbstractUserException).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(System.Runtime.Serialization.SerializationInfo), typeof(System.Runtime.Serialization.StreamingContext) }, new ParameterModifier[0])); MethodInfo getValueMethod = typeof(System.Runtime.Serialization.SerializationInfo).GetMethod("GetValue", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(string), typeof(Type) }, new ParameterModifier[0]); MethodInfo getTypeFromH = ReflectionHelper.TypeType.GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static); for (int i = 0; i < members.Count; i++) { FieldBuilder member = (FieldBuilder)members[i]; body.Emit(OpCodes.Ldarg_0); // this for calling store field after GetValue body.Emit(OpCodes.Ldarg_1); // info body.Emit(OpCodes.Ldstr, member.Name); // ld the first arg of GetValue body.Emit(OpCodes.Ldtoken, member.FieldType); body.Emit(OpCodes.Call, getTypeFromH); // ld the 2nd arg of GetValue body.Emit(OpCodes.Callvirt, getValueMethod); // call info.GetValue // now store result in the corresponding field m_ilEmitHelper.GenerateCastObjectToType(body, member.FieldType); body.Emit(OpCodes.Stfld, member); } body.Emit(OpCodes.Ret); // default constructor m_ilEmitHelper.AddDefaultConstructor(exceptToCreate, MethodAttributes.Public); }
/// <summary> /// adds a GetObjectData override to the exception to create. /// </summary> private void AddExceptionGetObjectDataOverride(TypeBuilder exceptToCreate, IList members) { ParameterSpec[] getObjDataParams = new ParameterSpec[] { new ParameterSpec("info", typeof(System.Runtime.Serialization.SerializationInfo)), new ParameterSpec("context", typeof(System.Runtime.Serialization.StreamingContext)) }; MethodBuilder getObjectDataMethod = m_ilEmitHelper.AddMethod(exceptToCreate, "GetObjectData", getObjDataParams, new TypeContainer(typeof(void)), MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator body = getObjectDataMethod.GetILGenerator(); body.Emit(OpCodes.Ldarg_0); body.Emit(OpCodes.Ldarg_1); body.Emit(OpCodes.Ldarg_2); body.Emit(OpCodes.Call, typeof(Exception).GetMethod("GetObjectData", BindingFlags.Public | BindingFlags.Instance)); MethodInfo addValueMethod = typeof(System.Runtime.Serialization.SerializationInfo).GetMethod("AddValue", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { ReflectionHelper.StringType, ReflectionHelper.ObjectType, ReflectionHelper.TypeType }, new ParameterModifier[0]); MethodInfo getTypeFromH = ReflectionHelper.TypeType.GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static); for (int i = 0; i < members.Count; i++) { FieldInfo member = (FieldInfo)members[i]; body.Emit(OpCodes.Ldarg_1); // info body.Emit(OpCodes.Ldstr, member.Name); // memberName body.Emit(OpCodes.Ldarg_0); // this body.Emit(OpCodes.Ldfld, member); // load the member if (member.FieldType.IsValueType) { // need to box a valuetype, because formal parameter is object body.Emit(OpCodes.Box, member.FieldType); } body.Emit(OpCodes.Ldtoken, member.FieldType); body.Emit(OpCodes.Call, getTypeFromH); // load the type, the third argument of AddValue body.Emit(OpCodes.Callvirt, addValueMethod); } body.Emit(OpCodes.Ret); }
private void GenerateModifierMethod(SwitchCase switchCase) { ParameterSpec[] parameters; ParameterSpec valArg = new ParameterSpec("val", switchCase.ElemType, ParameterSpec.ParameterDirection.s_in); if (switchCase.HasMoreThanOneDiscrValue()) { // need an additional parameter ParameterSpec discrArg = new ParameterSpec("discrVal", DiscriminatorType, ParameterSpec.ParameterDirection.s_in); parameters = new ParameterSpec[] { valArg, discrArg}; } else { // don't need an additional parameter parameters = new ParameterSpec[] { valArg }; } MethodBuilder modifier = m_ilEmitHelper.AddMethod(m_builder, "Set" + switchCase.ElemName, parameters, new TypeContainer(ReflectionHelper.VoidType), MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator gen = modifier.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stfld, m_initalizedField); // store initalizedfield gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Stfld, switchCase.ElemField); // store value field gen.Emit(OpCodes.Ldarg_0); if (switchCase.HasMoreThanOneDiscrValue()) { gen.Emit(OpCodes.Ldarg_2); } else { PushDiscriminatorValueToStack(gen, switchCase.DiscriminatorValues[0]); } gen.Emit(OpCodes.Stfld, m_discrField); // store discriminator field if (switchCase.HasMoreThanOneDiscrValue()) { // check, if discrvalue assigned is ok Label endMethodLabel = gen.DefineLabel(); GenerateDiscrValueOkTest(gen, switchCase, endMethodLabel, s_BadParamConstr, 34); gen.MarkLabel(endMethodLabel); } gen.Emit(OpCodes.Ret); }
/// <summary>adds a constructor to a type, setting the attributes on the parameters</summary> /// <remarks>forgeign method: should be better on TypeBuilder, but not possible</remarks> /// <returns>the ConstructorBuilder for the method created</returns> public ConstructorBuilder AddConstructor(TypeBuilder builder, ParameterSpec[] parameters, MethodAttributes attrs) { Type[] paramTypes = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { paramTypes[i] = parameters[i].GetParamTypeMergedDirection(); } ConstructorBuilder constrBuild = builder.DefineConstructor(attrs, CallingConventions.Standard, paramTypes); // define the paramter-names / attributes for (int i = 0; i < parameters.Length; i++) { ParameterAttributes paramAttr = ParameterAttributes.None; ParameterBuilder paramBuild = constrBuild.DefineParameter(i + 1, paramAttr, parameters[i].GetPramName()); // custom attribute spec TypeContainer specType = parameters[i].GetParamType(); for (int j = 0; j < specType.GetSeparatedAttrs().Length; j++) { paramBuild.SetCustomAttribute(specType.GetSeparatedAttrs()[j]); } } return constrBuild; }
/** * @see parser.IDLParserVisitor#visit(ASTinit_param_delcs, Object) */ public Object visit(ASTinit_param_delcs node, Object data) { // visit all init parameters ParameterSpec[] parameters = new ParameterSpec[node.jjtGetNumChildren()]; for (int i = 0; i < node.jjtGetNumChildren(); i++) { parameters[i] = (ParameterSpec) node.jjtGetChild(i).jjtAccept(this, data); } return parameters; }