Ejemplo n.º 1
0
        private void AddCustomLogicCall(TypeDefDeclaration enhancedType, InstructionWriter writer,
                                        MethodDefDeclaration customMethod)
        {
            var parameters = customMethod.Parameters;

            if (parameters.Count != 0)
            {
                Message.Write(enhancedType, SeverityType.Error, "EQU1", "The signature of a method annotated with ["
                              + nameof(AdditionalGetHashCodeMethodAttribute) +
                              "] must be 'int MethodName()'. It can't have parameters.");
                writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                return;
            }

            if (!customMethod.ReturnParameter.ParameterType.IsIntrinsic(IntrinsicType.Int32))
            {
                Message.Write(enhancedType, SeverityType.Error, "EQU2", "The signature of a method annotated with ["
                              + nameof(AdditionalGetHashCodeMethodAttribute) +
                              "] must be 'int MethodName()'. Its return type must be 'int'.");
                writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                return;
            }

            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
            writer.EmitInstructionMethod(
                enhancedType.IsValueTypeSafe() == true ? OpCodeNumber.Call : OpCodeNumber.Callvirt,
                customMethod.GetCanonicalGenericInstance());
        }
        private static void InjectCustomMethods(TypeDefDeclaration enhancedType, InstructionWriter writer,
                                                CreatedEmptyMethod methodBody)
        {
            // Custom equality methods.
            foreach (var customEqualsMethod in enhancedType.Methods)
            {
                if (customEqualsMethod.CustomAttributes.GetOneByType(
                        "PostSharp.Community.StructuralEquality.AdditionalEqualsMethodAttribute") != null)
                {
                    if (customEqualsMethod.IsStatic ||
                        !customEqualsMethod.ReturnParameter.ParameterType.IsIntrinsic(IntrinsicType.Boolean) ||
                        customEqualsMethod.Parameters.Count != 1 ||
                        !customEqualsMethod.Parameters[0].ParameterType.GetTypeDefinition().Equals(enhancedType)
                        )
                    {
                        CustomMethodSignatureError(enhancedType, customEqualsMethod);
                    }

                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, customEqualsMethod.GetCanonicalGenericInstance());
                    writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, methodBody.ReturnSequence);
                }
            }
        }
Ejemplo n.º 3
0
 public TypeTreeNode(TypeDefDeclaration type, string name) : base(
         type, GetImage(type), type.Visibility)
 {
     this.type = type;
     this.Text = name;
     this.EnableLatePopulate();
 }
 public InterfaceImplementationCollectionTreeNode(TypeDefDeclaration type) :
     base(TreeViewImage.Folder, null)
 {
     this.type = type;
     this.Text = "Interfaces";
     this.EnableLatePopulate();
 }
 public InterfaceImplementationCollectionTreeNode( TypeDefDeclaration type ) :
     base( TreeViewImage.Folder, null )
 {
     this.type = type;
     this.Text = "Interfaces";
     this.EnableLatePopulate();
 }
        private static void CustomMethodSignatureError(TypeDefDeclaration enhancedType, MethodDefDeclaration method)
        {
            string message =
                $"Method {method.Name} marked with [CustomEqualsInternal] must be public, instance, must return bool and accept 1 parameter of the same type as the declaring type {enhancedType.Name}";

            throw new InjectionException("EQU3", message);
        }
Ejemplo n.º 7
0
 public NestedTypeFolderTreeNode(TypeDefDeclaration parentType)
     : base(TreeViewImage.Folder, null)
 {
     this.Text       = "Nested Types";
     this.parentType = parentType;
     this.EnableLatePopulate();
 }
 private void MakeSerializable(TypeDefDeclaration type)
 {
     if (!IsSerializable(type))
     {
         type.Attributes |= TypeAttributes.Serializable;
     }
 }
Ejemplo n.º 9
0
 public TypeTreeNode( TypeDefDeclaration type, string name ) : base(
     type, GetImage( type ), type.Visibility )
 {
     this.type = type;
     this.Text = name;
     this.EnableLatePopulate();
 }
            public override void ProvideAspectTransformations(AspectWeaverTransformationAdder adder)
            {
                // Find the MoveNext method.
                TypeDefDeclaration   targetType     = (TypeDefDeclaration)this.aspectInstanceInfo.TargetElement;
                MethodDefDeclaration moveNextMethod = targetType.Methods.Single <MethodDefDeclaration>(m => m.Name.EndsWith("MoveNext"));

                adder.Add(moveNextMethod, this.parent.moveNextTransformation.CreateInstance(this));
            }
        private void AddEquatable(TypeDefDeclaration enhancedType)
        {
            var genericInstance = this.equatableInterface.GetTypeDefinition().GetGenericInstance(new GenericMap(
                                                                                                     enhancedType.Module,
                                                                                                     new ITypeSignature[] { enhancedType.GetCanonicalGenericInstance() }));
            ITypeSignature interfaceRef = genericInstance.TranslateType(enhancedType.Module);

            enhancedType.InterfaceImplementations.Add(interfaceRef);
        }
        public void AddEqualsTo(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config,
                                ISet <FieldDefDeclaration> ignoredFields)
        {
            var typedEqualsMethod = this.InjectEqualsType(enhancedType, config, ignoredFields);

            this.InjectEqualsObject(enhancedType, config, typedEqualsMethod);

            this.AddEquatable(enhancedType);
        }
        private void InjectEqualsObject(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config,
                                        MethodDefDeclaration typedEqualsMethod)
        {
            var existingMethod = enhancedType.Methods.FirstOrDefault <IMethod>(declaration =>
            {
                return(declaration.Name == "Equals" &&
                       declaration.IsPublic() &&
                       !declaration.IsStatic &&
                       declaration.ParameterCount == 1 &&
                       declaration.GetParameterType(0).Equals(this.objectType));
            });

            if (existingMethod != null)
            {
                return;
            }

            // public virtual bool Equals( object other )
            var equalsDeclaration = new MethodDefDeclaration
            {
                Name              = "Equals",
                Attributes        = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                CallingConvention = CallingConvention.HasThis
            };

            enhancedType.Methods.Add(equalsDeclaration);
            equalsDeclaration.Parameters.Add(new ParameterDeclaration(0, "other", this.objectType));
            equalsDeclaration.ReturnParameter = ParameterDeclaration.CreateReturnParameter(this.booleanType);
            CompilerGeneratedAttributeHelper.AddCompilerGeneratedAttribute(equalsDeclaration);

            using (var writer = InstructionWriter.GetInstance())
            {
                var methodBody = MethodBodyCreator.CreateModifiableMethodBody(writer, equalsDeclaration);

                writer.AttachInstructionSequence(methodBody.PrincipalBlock.AddInstructionSequence());

                writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, methodBody.ReturnVariable);

                this.InjectReferenceEquals(writer, methodBody, enhancedType);

                var genericTypeInstance = enhancedType.GetCanonicalGenericInstance();

                this.EmitTypeCheck(enhancedType, config, writer, genericTypeInstance, methodBody);
                if (enhancedType.IsValueTypeSafe() == true)
                {
                    this.EmitEqualsObjectOfValueType(writer, genericTypeInstance, typedEqualsMethod, methodBody);
                }
                else
                {
                    this.EmitEqualsObjectOfReferenceType(writer, genericTypeInstance, typedEqualsMethod, methodBody);
                }

                writer.DetachInstructionSequence();
            }
        }
Ejemplo n.º 14
0
        public void ProcessEqualityOperators(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config)
        {
            if (config.DoNotAddEqualityOperators)
            {
                return;
            }

            ProcessOperator(enhancedType, "op_Equality", "==", false);
            ProcessOperator(enhancedType, "op_Inequality", "!=", true);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Adds a method to a class
        /// </summary>
        /// <param name="decl">Class to add the method to</param>
        /// <param name="method">Method to add</param>
        public static void AddMethod([NotNull] TypeDefDeclaration decl, [NotNull] MethodDefDeclaration method)
        {
            MethodDefDeclaration previous = FindSameMethod(decl, method);

            if (previous != null)
            {
                previous.Remove();
            }

            decl.Methods.Add(method);
        }
        private void VerifySerializable(TypeDefDeclaration type, MessageLocation location)
        {
            if (!IsSerializable(type))
            {
                // This does not work properly on .NET Core.
                // PostSharp has difficulty understanding that some classes in .NET Core are serializable.

                // In addition, some fields are not meant to be serialized so it's better not to emit a warning for those
                // as well.

                // Message.Write(location, SeverityType.Warning, "DSER001",
                //     "A type (" + type.Name +
                //     ") is not serializable, but it's not in the same assembly so I cannot modify it.");
            }
        }
Ejemplo n.º 17
0
        private static MethodDefDeclaration FindOnPropertyChangedMethod(TypeDefDeclaration currentType)
        {
            foreach (MethodDefDeclaration declaration in currentType.Methods)
            {
                foreach (CustomAttributeDeclaration attributeType in declaration.CustomAttributes)
                {
                    if (attributeType.ConstructRuntimeObject().GetType().UnderlyingSystemType == typeof(OnPropertyChangedAttribute))
                    {
                        return declaration;
                    }
                }
            }

            return null;
        }
Ejemplo n.º 18
0
        private void AddCollectionCodeInternal(FieldDefDeclaration field, LocalVariableSymbol resultVariable,
                                               MethodDefDeclaration method, TypeDefDeclaration enhancedType, InstructionWriter writer)
        {
            LoadVariable(field, writer);

            var enumeratorVariable =
                method.MethodBody.RootInstructionBlock.DefineLocalVariable(IEnumeratorType, "enumeratorVariable");
            var currentVariable =
                method.MethodBody.RootInstructionBlock.DefineLocalVariable(
                    method.Module.Cache.GetIntrinsic(IntrinsicType.Object), "enumeratorObject");

            AddGetEnumerator(writer, enumeratorVariable, field);

            AddCollectionLoop(resultVariable, writer, enumeratorVariable, currentVariable);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Finds a method with the same signature in the class
        /// </summary>
        /// <param name="decl">Class to inspect</param>
        /// <param name="method">Method with a name and signature</param>
        /// <returns>Found method or null</returns>
        public static MethodDefDeclaration FindSameMethod([NotNull] TypeDefDeclaration decl, [NotNull] MethodDefDeclaration method)
        {
            IMethod found =
                decl.Methods.GetMethod(
                    method.Name,
                    method,
                    BindingOptions.OnlyExisting);

            if (found == null)
            {
                return(null);
            }

            return(found.GetMethodDefinition(BindingOptions.OnlyExisting));
        }
        private void IdentifyAndMakeSerializableRecursively(ITypeSignature type, MessageLocation location)
        {
            switch (type.TypeSignatureElementKind)
            {
            case TypeSignatureElementKind.Intrinsic:
                // This works automatically for most, but:
                // Consider an error for object, IntPtr, but also consider that those fields may be marked as [NonSerialized].
                // In the future, we might want to exclude such fields.
                break;

            case TypeSignatureElementKind.TypeDef:
                TypeDefDeclaration typeDef = (TypeDefDeclaration)type;
                if (typeDef.DeclaringAssembly == this.Project.Module.DeclaringAssembly)
                {
                    MakeSerializableRecursively(typeDef);
                }
                else
                {
                    VerifySerializable(typeDef, location);
                }
                break;

            case TypeSignatureElementKind.TypeRef:
                IdentifyAndMakeSerializableRecursively(type.GetTypeDefinition(), location);
                break;

            case TypeSignatureElementKind.GenericInstance:
                GenericTypeInstanceTypeSignature
                    genericInstanceSignature = type as GenericTypeInstanceTypeSignature;
                IdentifyAndMakeSerializableRecursively(genericInstanceSignature.ElementType, location);
                foreach (ITypeSignature argument in genericInstanceSignature.GenericArguments)
                {
                    IdentifyAndMakeSerializableRecursively(argument, location);
                }
                break;

            case TypeSignatureElementKind.Array:
                ArrayTypeSignature arraySignature = type as ArrayTypeSignature;
                IdentifyAndMakeSerializableRecursively(arraySignature.ElementType, location);
                break;

            default:
                // Other possible signature types can be ignored:
                //  Pointers: they cannot be serialized
                //  Custom modifiers: they should not be used on fields.
                break;
            }
        }
        public LoggingImplementationTypeBuilder(ModuleDeclaration module)
        {
            this.module         = module;
            this.categoryFields = new Dictionary <string, FieldDefDeclaration>();
            this.wrapperMethods = new Dictionary <IMethod, MethodDefDeclaration>();

            this.stringFormatArrayMethod = module.FindMethod(module.Cache.GetIntrinsic(IntrinsicType.String), "Format",
                                                             method => method.Parameters.Count == 2 &&
                                                             IntrinsicTypeSignature.Is(method.Parameters[0].ParameterType, IntrinsicType.String) &&
                                                             method.Parameters[1].ParameterType.BelongsToClassification(TypeClassifications.Array));

            this.traceWriteLineMethod = module.FindMethod(module.Cache.GetType(typeof(System.Diagnostics.Trace)), "WriteLine",
                                                          method => method.Parameters.Count == 1 &&
                                                          IntrinsicTypeSignature.Is(method.Parameters[0].ParameterType, IntrinsicType.String));

            this.weavingHelper      = new WeavingHelper(module);
            this.implementationType = this.CreateContainingType();
            this.isLoggingField     = this.CreateIsLoggingField();
        }
Ejemplo n.º 22
0
        private void ReplaceOperator(TypeDefDeclaration enhancedType, MethodDefDeclaration equalityMethodDef,
                                     bool negate)
        {
            InstructionBlock originalCode = equalityMethodDef.MethodBody.RootInstructionBlock;

            originalCode.Detach();

            InstructionBlock root = equalityMethodDef.MethodBody.CreateInstructionBlock();

            equalityMethodDef.MethodBody.RootInstructionBlock = root;
            var newSequence = root.AddInstructionSequence();

            using (var writer = InstructionWriter.GetInstance())
            {
                writer.AttachInstructionSequence(newSequence);

                if (enhancedType.IsValueType())
                {
                    var canonicalType = enhancedType.GetCanonicalGenericInstance();
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                }
                else
                {
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                }

                writer.EmitInstructionMethod(OpCodeNumber.Call, this.staticEqualsMethod);

                if (negate)
                {
                    writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                    writer.EmitInstruction(OpCodeNumber.Ceq);
                }

                writer.EmitInstruction(OpCodeNumber.Ret);

                writer.DetachInstructionSequence();
            }
        }
Ejemplo n.º 23
0
        private void ProcessOperator(TypeDefDeclaration enhancedType, string operatorName, string operatorSourceName, bool negate)
        {
            var operatorMethod = GetOperatorMethod(enhancedType, operatorName);

            string operatorExample = $"public static bool operator {operatorSourceName}({enhancedType.ShortName} left, {enhancedType.ShortName} right) => Operator.Weave(left, right);";

            if (operatorMethod == null)
            {
                throw new InjectionException("EQU10", $"The equality operator was not found on type {enhancedType.Name}, implement it like this: {operatorExample}");
            }

            var operatorMethodDef = operatorMethod.GetMethodDefinition();

            this.CheckOperator(operatorMethodDef, operatorExample);

            CompilerGeneratedAttributeHelper.AddCompilerGeneratedAttribute(operatorMethodDef);

            this.ReplaceOperator(enhancedType, operatorMethodDef, negate);
        }
        public LoggingImplementationTypeBuilder( ModuleDeclaration module )
        {
            this.module = module;
            this.categoryFields = new Dictionary<string, FieldDefDeclaration>();
            this.wrapperMethods = new Dictionary<IMethod, MethodDefDeclaration>();

            this.stringFormatArrayMethod = module.FindMethod( module.Cache.GetIntrinsic( IntrinsicType.String ), "Format",
                                                              method => method.Parameters.Count == 2 &&
                                                                        IntrinsicTypeSignature.Is( method.Parameters[0].ParameterType, IntrinsicType.String ) &&
                                                                        method.Parameters[1].ParameterType.BelongsToClassification( TypeClassifications.Array ) );

            this.traceWriteLineMethod = module.FindMethod( module.Cache.GetType( typeof(System.Diagnostics.Trace) ), "WriteLine",
                                                           method => method.Parameters.Count == 1 &&
                                                                     IntrinsicTypeSignature.Is( method.Parameters[0].ParameterType, IntrinsicType.String ) );

            this.weavingHelper = new WeavingHelper( module );
            this.implementationType = this.CreateContainingType();
            this.isLoggingField = this.CreateIsLoggingField();
        }
        private void MakeSerializableRecursively(TypeDefDeclaration type)
        {
            if (examinedTypes.Contains(type))
            {
                // We've already analyzed this type.
                return;
            }

            examinedTypes.Add(type);

            MakeSerializable(type);

            foreach (FieldDefDeclaration field in type.Fields)
            {
                IdentifyAndMakeSerializableRecursively(field.FieldType, field);
            }

            IdentifyAndMakeSerializableRecursively(type.BaseType, type);
        }
Ejemplo n.º 26
0
        public bool Match(PostSharp.CodeModel.IType type)
        {
            try
            {
                TypeDefDeclaration definition = type.GetTypeDefinition();
                if (definition == null)
                {
                    return(false);
                }
            }
            catch (Exception exc)
            {
                // bind error, or type does not have a definition
                // in either case, not a type we want to process
                return(false);
            }

            return(true);
        }
        private TypeDefDeclaration CreateContainingType()
        {
            string uniqueName = this.module.Types.GetUniqueName(
                DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}"));

            TypeDefDeclaration logCategoriesType = new TypeDefDeclaration
            {
                Name       = uniqueName,
                Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract,
                BaseType   = ((IType)this.module.Cache.GetType("System.Object, mscorlib"))
            };

            this.module.Types.Add(logCategoriesType);

            // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type
            this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes);
            this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes);

            MethodDefDeclaration staticConstructor = new MethodDefDeclaration
            {
                Name       = ".cctor",
                Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName |
                             MethodAttributes.SpecialName | MethodAttributes.HideBySig,
            };

            logCategoriesType.Methods.Add(staticConstructor);

            staticConstructor.ReturnParameter = new ParameterDeclaration
            {
                Attributes    = ParameterAttributes.Retval,
                ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void)
            };

            this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
            this.returnSequence   = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(this.returnSequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            return(logCategoriesType);
        }
Ejemplo n.º 28
0
        public static bool InheritsBase(this TypeDefDeclaration?declaration,
                                        TypeDefDeclaration baseType)
        {
            if (!baseType.IsClass())
            {
                return(false);
            }

            if (declaration?.BaseType == null)
            {
                return(false);
            }

            if (declaration.BaseType.Name == baseType.Name)
            {
                return(true);
            }

            return(declaration.BaseTypeDef.InheritsBase(baseType));
        }
Ejemplo n.º 29
0
        public static bool ImplementsInterface(this TypeDefDeclaration?declaration,
                                               TypeDefDeclaration interfaceType)
        {
            if (!interfaceType.IsInterface())
            {
                return(false);
            }

            if (declaration?.BaseType == null)
            {
                return(false);
            }

            if (declaration.InterfaceImplementations.Any(i =>
                                                         i.ImplementedInterface.Name == interfaceType.Name))
            {
                return(true);
            }

            return(declaration.BaseTypeDef.ImplementsInterface(interfaceType));
        }
        private TypeDefDeclaration CreateContainingType()
        {
            string uniqueName = this.module.Types.GetUniqueName(
                DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}"));

            TypeDefDeclaration logCategoriesType = new TypeDefDeclaration
            {
                Name = uniqueName,
                Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract,
                BaseType = ((IType)this.module.Cache.GetType("System.Object, mscorlib"))
            };
            this.module.Types.Add(logCategoriesType);

            // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type
            this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes);
            this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes);

            MethodDefDeclaration staticConstructor = new MethodDefDeclaration
            {
                Name = ".cctor",
                Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName |
                             MethodAttributes.SpecialName | MethodAttributes.HideBySig,
            };
            logCategoriesType.Methods.Add(staticConstructor);

            staticConstructor.ReturnParameter = new ParameterDeclaration
            {
                Attributes = ParameterAttributes.Retval,
                ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void)
            };

            this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
            this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(this.returnSequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            return logCategoriesType;
        }
        public override bool Execute()
        {
            this.wrapperType = this.GetWrapperType(this.Project.Module.Assembly, new HashSet <string>());
            if (this.wrapperType == null)
            {
                Message.Write(this.Project.Module.Assembly.GetSystemAssembly(), SeverityType.Error, "CUMA001", "You must create a CheckMemoryAccess class with the appropriate source code in your project.");
                return(false);
            }

            this.methods.Add(OpCodeNumber.Stind_I, this.wrapperType.Methods.GetOneByName("StoreIntPtr").Translate(this.Project.Module));
            this.methods.Add(OpCodeNumber.Stind_I1, this.wrapperType.Methods.GetOneByName("StoreByte").Translate(this.Project.Module));
            this.methods.Add(OpCodeNumber.Stind_I2, this.wrapperType.Methods.GetOneByName("StoreInt16").Translate(this.Project.Module));
            this.methods.Add(OpCodeNumber.Stind_I4, this.wrapperType.Methods.GetOneByName("StoreInt32").Translate(this.Project.Module));
            this.methods.Add(OpCodeNumber.Stind_I8, this.wrapperType.Methods.GetOneByName("StoreInt64").Translate(this.Project.Module));
            this.methods.Add(OpCodeNumber.Stind_R4, this.wrapperType.Methods.GetOneByName("StoreSingle").Translate(this.Project.Module));
            this.methods.Add(OpCodeNumber.Stind_R8, this.wrapperType.Methods.GetOneByName("StoreDouble").Translate(this.Project.Module));

            Sdk.CodeWeaver.Weaver weaver = new Sdk.CodeWeaver.Weaver(this.Project);
            weaver.AddMethodLevelAdvice(this, null, JoinPointKinds.InsteadOfStoreIndirect, null);
            weaver.Weave();
            return(base.Execute());
        }
        public TypeDefDeclaration GetWrapperType(AssemblyEnvelope assembly, HashSet <string> visitedAssemblies)
        {
            visitedAssemblies.Add(assembly.Name);

            TypeDefDeclaration result = assembly.GetTypeDefinition(wrapperTypeName, BindingOptions.DontThrowException);

            if (result != null)
            {
                return(result);
            }

            foreach (ModuleDeclaration module in assembly.Modules)
            {
                foreach (AssemblyRefDeclaration assemblyRef in module.AssemblyRefs)
                {
                    if (visitedAssemblies.Contains(assemblyRef.Name))
                    {
                        continue;
                    }

                    AssemblyEnvelope assemblyRefEnvelope = assemblyRef.GetAssemblyEnvelope(BindingOptions.DontThrowException);

                    if (assemblyRefEnvelope == null)
                    {
                        continue;
                    }

                    result = this.GetWrapperType(assemblyRefEnvelope, visitedAssemblies);

                    if (result != null)
                    {
                        return(result);
                    }
                }
            }

            return(null);
        }
        public EqualsInjection(Project project)
        {
            this.objectType  = project.Module.Cache.GetIntrinsic(IntrinsicType.Object);
            this.booleanType = project.Module.Cache.GetIntrinsic(IntrinsicType.Boolean);

            this.objectTypeDef = this.objectType.GetTypeDefinition();

            this.referenceEqualsMethod = project.Module.FindMethod(objectTypeDef, "ReferenceEquals");
            this.instanceEqualsMethod  = project.Module.FindMethod(objectTypeDef, "Equals", 1);
            this.staticEqualsMethod    = project.Module.FindMethod(objectTypeDef, "Equals", 2);
            this.getTypeMethod         = project.Module.FindMethod(objectTypeDef, "GetType");

            var collectionHelperTypeDef = project.Module.Cache.GetType(typeof(CollectionHelper)).GetTypeDefinition();

            this.collectionEqualsMethod = project.Module.FindMethod(collectionHelperTypeDef, "Equals",
                                                                    declaration => declaration.IsStatic);

            var typeTypeDef = project.Module.Cache.GetType(typeof(Type)).GetTypeDefinition();

            this.getTypeFromHandleMethod = project.Module.FindMethod(typeTypeDef, "GetTypeFromHandle");

            this.equatableInterface = project.Module.Cache.GetType(typeof(IEquatable <>));
        }
Ejemplo n.º 34
0
 private static TreeViewImage GetImage( TypeDefDeclaration type )
 {
     if ( type.BelongsToClassification( TypeClassifications.Class ) )
     {
         return TreeViewImage.Class;
     }
     else if ( type.BelongsToClassification( TypeClassifications.Interface ) )
     {
         return TreeViewImage.Interface;
     }
     else if ( type.BelongsToClassification( TypeClassifications.Struct ) )
     {
         return TreeViewImage.Struct;
     }
     else if ( type.BelongsToClassification( TypeClassifications.Enum ) )
     {
         return TreeViewImage.Enum;
     }
     else
     {
         return TreeViewImage.Class;
     }
 }
 protected void IntroduceEvent(TransformationContext context, TypeDefDeclaration type, EventDeclaration theEvent)
 {
     var fieldRef = type.FindField(theEvent.Name);
     FieldDefDeclaration field;
     if(fieldRef == null) {
         field = new FieldDefDeclaration {
             Attributes = FieldAttributes.Private,
             Name = theEvent.Name,
             FieldType = theEvent.EventType,
         };
         type.Fields.Add(field);
     } else {
         field = fieldRef.Field;
     }
     var addOn = theEvent.GetAccessor(MethodSemantics.AddOn);
     if (addOn == null) {
         theEvent.ImplementAddOn(type, field, AspectInfrastructureTask.WeavingHelper);
     }
     var removeOn = theEvent.GetAccessor(MethodSemantics.RemoveOn);
     if (removeOn == null) {
         theEvent.ImplementRemoveOn(type, field, AspectInfrastructureTask.WeavingHelper);
     }
 }
Ejemplo n.º 36
0
 private static TreeViewImage GetImage(TypeDefDeclaration type)
 {
     if (type.BelongsToClassification(TypeClassifications.Class))
     {
         return(TreeViewImage.Class);
     }
     else if (type.BelongsToClassification(TypeClassifications.Interface))
     {
         return(TreeViewImage.Interface);
     }
     else if (type.BelongsToClassification(TypeClassifications.Struct))
     {
         return(TreeViewImage.Struct);
     }
     else if (type.BelongsToClassification(TypeClassifications.Enum))
     {
         return(TreeViewImage.Enum);
     }
     else
     {
         return(TreeViewImage.Class);
     }
 }
        private void EmitTypeCheck(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config,
                                   InstructionWriter writer, IType genericTypeInstance, CreatedEmptyMethod methodBody)
        {
            switch (config.TypeCheck)
            {
            case TypeCheck.ExactlyTheSameTypeAsThis:
                this.InjectExactlyTheSameTypeAsThis(writer, enhancedType, genericTypeInstance);
                break;

            case TypeCheck.ExactlyOfType:
                this.InjectExactlyOfType(writer, genericTypeInstance);
                break;

            case TypeCheck.SameTypeOrSubtype:
                this.InjectSameTypeOrSubtype(writer, genericTypeInstance);
                break;

            default:
                throw new InjectionException("EQU4", $"Unknown TypeCheck value: {config.TypeCheck}");
            }

            // Types are different, return false.
            writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, methodBody.ReturnSequence);
        }
 public LoggingImplementationTypeBuilder(ModuleDeclaration module)
 {
     this.module = module;
     this.weavingHelper = new WeavingHelper(module);
     this.containingType = this.CreateContainingType();
 }
Ejemplo n.º 39
0
        private static TypeDefDeclaration GetTypeDeclarationOfBase(TypeDefDeclaration type)
        {
            if(type.BaseType == null)
                return null;

            TypeDefDeclaration baseTypeDefDeclaration = type.BaseType as TypeDefDeclaration;

            if (baseTypeDefDeclaration == null)
            {
                TypeRefDeclaration baseAsTypeRefDeclaration = type.BaseType as TypeRefDeclaration;

                if (baseAsTypeRefDeclaration != null)
                {
                    baseTypeDefDeclaration = baseAsTypeRefDeclaration.GetTypeDefinition();
                }
                else
                {
                    TypeSpecDeclaration baseAsTypeSpecDeclaration = type.BaseType as TypeSpecDeclaration;
                    baseTypeDefDeclaration = baseAsTypeSpecDeclaration.GetTypeDefinition();
                }
            }

            return baseTypeDefDeclaration;
        }
 internal PerTypeLoggingData GetPerTypeLoggingData(TypeDefDeclaration type)
 {
     return this.perTypeLoggingDatas[type];
 }
Ejemplo n.º 41
0
        private static void ImplementSetter(
            PropertyDeclaration property,
            TypeDefDeclaration type,
            IField field,
            MethodAttributes methodAttributes,
            CustomAttributeDeclaration compilerGenerated)
        {
            // Implement setter
            var setter = new MethodDefDeclaration
            {
                Attributes = methodAttributes,
                Name = "set_" + property.Name,
                CallingConvention = CallingConvention.HasThis,
            };
            type.Methods.Add(setter);

            MarkCompilerGenerated(setter, compilerGenerated);
            setter.ReturnParameter = new ParameterDeclaration
            {
                ParameterType = type.Module.Cache.GetIntrinsic(IntrinsicType.Void),
                Attributes = ParameterAttributes.Retval
            };
            setter.Parameters.Add(new ParameterDeclaration(0, "value", property.PropertyType));

            var methodBody = new MethodBodyDeclaration();
            var sequence = methodBody.CreateInstructionSequence();
            var instructionBlock = methodBody.CreateInstructionBlock();
            instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null);
            methodBody.RootInstructionBlock = instructionBlock;
            setter.MethodBody = methodBody;

            var writer = new InstructionWriter();
            writer.AttachInstructionSequence(sequence);
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            writer.EmitInstructionField(OpCodeNumber.Stfld, field);
            writer.EmitInstruction(OpCodeNumber.Ret);
            writer.DetachInstructionSequence();

            property.Members.Add(new MethodSemanticDeclaration(MethodSemantics.Setter, setter));
        }
Ejemplo n.º 42
0
 private static PropertyDeclaration CreateProperty(TypeDefDeclaration type, string name, ITypeSignature propertyType, IEnumerable<CustomAttributeDeclaration> attributesList)
 {
     var property = new PropertyDeclaration
     {
         Name = name,
         PropertyType = propertyType,
         CallingConvention = CallingConvention.HasThis,
     };
     type.Properties.Add(property);
     ImplementAttributes(property, attributesList);
     return property;
 }
Ejemplo n.º 43
0
        public static void ImplementRemoveOn(
            this EventDeclaration theEvent,
            TypeDefDeclaration type,
            IField field,
            WeavingHelper weavingHelper = null,
            MethodAttributes methodAttributes =
                MethodAttributes.Public | MethodAttributes.HideBySig
                | MethodAttributes.Virtual | MethodAttributes.Final 
                | MethodAttributes.NewSlot | MethodAttributes.SpecialName)
        {
            var module = type.Module;
            weavingHelper = weavingHelper ?? new WeavingHelper(module);
            var pEWeavingHelper = module.Cache.GetItem(() => new PostEdgeWeaverAssets(module));

            var method = new MethodDefDeclaration {
                Attributes = methodAttributes,
                Name = "remove_" + theEvent.Name,
                CallingConvention = CallingConvention.HasThis
            };
            type.Methods.Add(method);
            weavingHelper.AddCompilerGeneratedAttribute(method.CustomAttributes);
            var parameter = new ParameterDeclaration {
                Name = "value",
                ParameterType = theEvent.EventType,
            };
            method.Parameters.Add(parameter);

            var methodBody = new MethodBodyDeclaration();
            methodBody.EnsureWritableLocalVariables();
            var instructionBlock = methodBody.CreateInstructionBlock();
            var initSequence = methodBody.CreateInstructionSequence();
            var loopSequence = methodBody.CreateInstructionSequence();
            var endSequence = methodBody.CreateInstructionSequence();
            instructionBlock.AddInstructionSequence(initSequence, NodePosition.After, null);
            instructionBlock.AddInstructionSequence(loopSequence, NodePosition.After, initSequence);
            instructionBlock.AddInstructionSequence(endSequence, NodePosition.After, loopSequence);
            methodBody.RootInstructionBlock = instructionBlock;
            method.MethodBody = methodBody;
            methodBody.CreateLocalVariable(theEvent.EventType);
            methodBody.CreateLocalVariable(theEvent.EventType);
            methodBody.CreateLocalVariable(theEvent.EventType);
            methodBody.CreateLocalVariable(module.Cache.GetIntrinsic(typeof(bool)));

            var writer = new InstructionWriter();
            //Initialize
            writer.AttachInstructionSequence(initSequence);

            //PropertyChangedHandler handler = this.PropertyChanged
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);           //Get the this pointer
            writer.EmitInstructionField(OpCodeNumber.Ldfld, field); //Get the event's field
            writer.EmitInstruction(OpCodeNumber.Stloc_0);           //store into the first local variable
            writer.DetachInstructionSequence();

            //Loop
            //do {
            writer.AttachInstructionSequence(loopSequence);

            //PropertyChangedHandler handler2 = handler;
            writer.EmitInstruction(OpCodeNumber.Ldloc_0);
            writer.EmitInstruction(OpCodeNumber.Stloc_1);

            //PropertyChangedHandler handler3 = System.Delegate.Remove(handler2, value)
            writer.EmitInstruction(OpCodeNumber.Ldloc_1);
            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            writer.EmitInstructionMethod(OpCodeNumber.Call, pEWeavingHelper.DelegateRemoveMethod);
            writer.EmitInstructionType(OpCodeNumber.Castclass, theEvent.EventType);
            writer.EmitInstruction(OpCodeNumber.Stloc_2);

            //handler = System.Threading.Interlocked.CompareExchnage<PropertyChangedEventHandler>(ref this.PropertyChtyChanged, handler3, handler2);
            var compareExchangeMethodT = pEWeavingHelper.CompareExchangeMethod;
            var compareExchangeMethod = compareExchangeMethodT.GetGenericInstance(module, theEvent.EventType);
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);           //Load this
            writer.EmitInstructionField(OpCodeNumber.Ldflda, field);
            writer.EmitInstruction(OpCodeNumber.Ldloc_2);
            writer.EmitInstruction(OpCodeNumber.Ldloc_1);
            writer.EmitInstructionMethod(OpCodeNumber.Call, compareExchangeMethod);
            writer.EmitInstruction(OpCodeNumber.Stloc_0);

            //flag = handler != handler2;
            writer.EmitInstruction(OpCodeNumber.Ldloc_0);
            writer.EmitInstruction(OpCodeNumber.Ldloc_1);
            writer.EmitInstruction(OpCodeNumber.Ceq);
            writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
            writer.EmitInstruction(OpCodeNumber.Ceq);
            writer.EmitInstruction(OpCodeNumber.Stloc_3);

            //} while (flag);
            writer.EmitInstruction(OpCodeNumber.Ldloc_3);
            writer.EmitBranchingInstruction(OpCodeNumber.Brtrue_S, loopSequence);

            writer.DetachInstructionSequence();

            //End
            writer.AttachInstructionSequence(endSequence);
            writer.EmitInstruction(OpCodeNumber.Ret);               //Exit the method
            writer.DetachInstructionSequence();

            theEvent.Members.Add(new MethodSemanticDeclaration(MethodSemantics.RemoveOn, method));
        }
        private void AddTypeLogginData(TypeDefDeclaration wovenType)
        {
            this.perTypeLoggingDatas.Add(wovenType, new PerTypeLoggingData());

              // Logging data for the woven type.
              PerTypeLoggingData perTypeLoggingData = this.perTypeLoggingDatas[wovenType];

              // Field where ILog instance is stored.
              FieldDefDeclaration logField = CreateField("~log4PostSharp~log", this.ilogType);
              wovenType.Fields.Add(logField);
              perTypeLoggingData.Log = logField;
        }
        /// <summary>
        /// Determines whether a type is annotated with the <b>DataContract</b>
        /// custom attribute.
        /// </summary>
        /// <param name="typeDef">Type.</param>
        /// <returns><b>true</b> if <paramref name="typeDef"/> is annotated with the <b>DataContract</b>
        /// custom attribute, otherwise <b>false</b>.</returns>
        private static bool ContainsDataContractAttribute( TypeDefDeclaration typeDef )
        {
            foreach ( CustomAttributeDeclaration customAttribute in typeDef.CustomAttributes )
            {
                if ( ((INamedType) customAttribute.Constructor.DeclaringType).Name == dataContractTypeName )
                    return true;
            }

            return false;
        }
Ejemplo n.º 46
0
 public NestedTypeFolderTreeNode( TypeDefDeclaration parentType )
     : base( TreeViewImage.Folder, null )
 {
     this.Text = "Nested Types";
     this.parentType = parentType;
     this.EnableLatePopulate();
 }
 public SingletonAccessorAdvice(TypeDefDeclaration typeDef)
 {
     m_type = typeDef;
 }
Ejemplo n.º 48
0
        private static IField CreateBackingField(
            TypeDefDeclaration type,
            string name,
            ITypeSignature fieldType,
            CustomAttributeDeclaration compilerGenerated)
        {
            var field = new FieldDefDeclaration
            {
                Attributes = FieldAttributes.Private,
                Name = string.Format("<{0}>k__BackingField", name),
                FieldType = fieldType
            };

            // Create a backing field
            type.Fields.Add(field);
            MarkCompilerGenerated(field, compilerGenerated);
            return GenericHelper.GetCanonicalGenericInstance(field);
        }