Example #1
0
        void InjectRaiseMethodCall(PropertyDefinition property, MethodDefinition raiseMethod)
        {
            var setter     = property.SetMethod;
            var body       = setter.Body;
            var firstInstr = body.Instructions.First();
            var retInstr   = body.Instructions.Last();
            var il         = body.GetILProcessor();

            var info = CheckSetter(body, raiseMethod);

            switch (info)
            {
            case NpcInjectionPropertyInfo.Ok:
            {
                var fieldRef     = (FieldReference)body.Instructions[2].Operand;
                var propertyType = setter.Parameters[0].ParameterType;

                if (propertyType.IsPrimitive)
                {
                    EmitPrimitiveEqualityCheck(il, firstInstr, fieldRef, retInstr);
                }
                else if (propertyType.IsValueType)
                {
                    EmitValueTypeEqualityCheck(il, firstInstr, fieldRef, retInstr, propertyType);
                }
                else
                {
                    EmitReferenceTypeEqualityCheck(il, firstInstr, fieldRef, retInstr);
                }

                goto case NpcInjectionPropertyInfo.NoEqualityCheckInjected;
            }

            case NpcInjectionPropertyInfo.NoEqualityCheckInjected:
                il.InsertBefore(retInstr, Instruction.Create(OpCodes.Ldarg_0));
                il.InsertBefore(retInstr, Instruction.Create(OpCodes.Ldstr, property.Name));
                il.InsertBefore(retInstr, Instruction.Create(OpCodes.Callvirt, this.module.Import(raiseMethod)));
                break;
            }

            this.callback.NotifyProperty(property.GetQualifiedName(), info);
        }
Example #2
0
        ///////////////////////////////////////////////////////////////////////

        void ProcessProperty(PropertyDefinition property, MethodDefinition raiseMethod, bool isDependencyAware)
        {
            if (HasIgnoreNpcAttribute(property))
            {
                this.callback.NotifyProperty(property.GetQualifiedName(),
                                             NpcInjectionPropertyInfo.Ignored);

                return;
            }

            if (property.SetMethod != null)
            {
                InjectRaiseMethodCall(property, raiseMethod);
            }

            if (property.GetMethod != null && isDependencyAware)
            {
                InjectDependsUponAttributes(property);
            }
        }
Example #3
0
        void InjectDependsUponAttributes(PropertyDefinition property)
        {
            var getter       = property.GetMethod;
            var body         = getter.Body;
            var instructions = body.Instructions;

            // look for a call to a property getter on this instance ("this.Property"):
            // Ldarg_0
            // Call get_Property
            var calledProperties = (from instr in instructions.Skip(1)
                                    where instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt
                                    let methodRef = instr.Operand as MethodReference
                                                    where methodRef != null && methodRef.Name.StartsWith("get_", StringComparison.Ordinal)
                                                    let method = methodRef.Resolve()
                                                                 where method.IsGetter && method.IsStatic == false
                                                                 let prev = instr.Previous
                                                                            where prev.OpCode == OpCodes.Ldarg_0 ||
                                                                            prev.OpCode == OpCodes.Ldarg && Object.Equals(prev.Operand, 0)
                                                                            select method.Name.Substring(4))
                                   .ToList();

            if (calledProperties.Count > 0)
            {
                foreach (var calledProperty in calledProperties)
                {
                    var customAttr = new CustomAttribute(
                        this.module.ImportCtor <DependsUponAttribute>(typeof(string)));

                    customAttr.ConstructorArguments.Add(
                        new CustomAttributeArgument(this.module.TypeSystem.String, calledProperty));

                    property.CustomAttributes.Add(customAttr);
                }

                this.callback.NotifyPropertyDependencies(property.GetQualifiedName(), calledProperties);
            }
        }