示例#1
0
    public override void ValidateCode(object target, Assembly assembly)
    {
        MemberInfo targetMember = target as MemberInfo;

        if (targetMember != null)
        {
            Type targetType = target as Type;

            if (targetType != null)
            {
                // validate derived types
                foreach (TypeInheritanceCodeReference reference in ReflectionSearch.GetDerivedTypes(targetType, ReflectionSearchOptions.IncludeTypeElement))
                {
                    Validate(reference);
                }
                // validate member references
                foreach (MemberTypeCodeReference reference in ReflectionSearch.GetMembersOfType(targetType, ReflectionSearchOptions.IncludeTypeElement))
                {
                    Validate(reference);
                }
            }
            // validate references in methods
            foreach (MethodUsageCodeReference methodUsageCodeReference in ReflectionSearch.GetMethodsUsingDeclaration(targetMember))
            {
                Validate(methodUsageCodeReference);
            }
        }
    }
        internal static Type GetStateMachineType(MethodInfo method)
        {
            CustomAttributeInstance customAttribute = ReflectionSearch.GetCustomAttributesOnTarget(method).SingleOrDefault(
                attribute => attribute.Construction.TypeName.StartsWith("System.Runtime.CompilerServices.AsyncStateMachineAttribute"));

            return(customAttribute == null ? null : (Type)customAttribute.Construction.ConstructorArguments[0]);
        }
示例#3
0
        public override void ValidateCode(object target, Assembly assembly)
        {
            var reflectionService = PostSharpEnvironment.CurrentProject.GetService <ISyntaxReflectionService>();

            // Iterate through all instances of WeakEventAttribute custom attribute.
            var customAttributes = ReflectionSearch.GetCustomAttributesOfType(typeof(WeakEventAttribute));

            foreach (var customAttribute in customAttributes)
            {
                // If the aspect allows for strong references, we don't need to validate anything.
                if (((WeakEventAttribute)customAttribute.Attribute).AllowStrongReferences)
                {
                    continue;
                }


                // Iterate through all methods that add an event handler to the event.
                var targetEvent = (EventInfo)customAttribute.Target;

                foreach (var usage in ReflectionSearch.GetMethodsUsingDeclaration(targetEvent.AddMethod))
                {
                    // Decompile the method body into an expression tree and visit it.
                    var methodBody = reflectionService.GetMethodBody(usage.UsingMethod, SyntaxAbstractionLevel.ExpressionTree);
                    var visitor    = new Visitor(targetEvent);
                    visitor.VisitMethodBody(methodBody);
                }
            }
        }
示例#4
0
        protected HashSet <string> GetFieldsWithAttribute(Type type, Type attributeType, string error)
        {
            HashSet <string> fieldSet = new HashSet <string>();

            foreach (var propertyInfo in type.GetProperties(BindingFlagsSet.AllInstance).Where(f => f.IsDefined(attributeType, true)))
            {
                var propertyInfoClosure = propertyInfo;

                var fields =
                    ReflectionSearch.GetDeclarationsUsedByMethod(propertyInfo.GetGetMethod(true))
                    .Select(r => r.UsedDeclaration as FieldInfo)
                    .Where(f => f != null)
                    .Where(f => propertyInfoClosure.PropertyType.IsAssignableFrom(f.FieldType))
                    .Where(f => f.DeclaringType.IsAssignableFrom(type))
                    .ToList();

                if (fields.Count() != 1)
                {
                    DomainMessageSource.Instance.Write(propertyInfo, SeverityType.Error, error, propertyInfo.FullName());
                }
                else
                {
                    fieldSet.Add(fields.First().FullName());
                }
            }

            foreach (FieldInfo fieldInfo in type.GetFields(BindingFlagsSet.AllInstanceDeclared).Where(f => f.IsDefined(attributeType, true)))
            {
                fieldSet.Add(fieldInfo.FullName());
            }

            return(fieldSet);
        }
        public override bool CompileTimeValidate(Type type)
        {
            bool result = base.CompileTimeValidate(type);

            // All fields should be private or protected unless marked as [ThreadSafe]. [Error]
            foreach (FieldInfo publicField in
                     type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).Where(
                         f => f.GetCustomAttributes(typeof(ThreadSafeAttribute), false).Length == 0))
            {
                ThreadingMessageSource.Instance.Write(type, SeverityType.Error, "THR007", type.Name, publicField.Name);
                result = false;
            }

            // Fields cannot be accessed from a static method unless the method or the field is marked as [ThreadSafe]. [Warning]

            IEnumerable <FieldInfo> nonPublicFields =
                type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                .Where(m => m.GetCustomAttributes(typeof(ThreadSafeAttribute), false).Length == 0);

            foreach (FieldInfo nonPublicField in nonPublicFields)
            {
                foreach (MethodUsageCodeReference codeReference in ReflectionSearch.GetMethodsUsingDeclaration(nonPublicField))
                {
                    if (codeReference.UsingMethod.IsStatic &&
                        codeReference.UsingMethod.GetCustomAttributes(typeof(ThreadSafeAttribute), false).Length == 0)
                    {
                        ThreadingMessageSource.Instance.Write(codeReference.UsingMethod, SeverityType.Warning, "THR012", nonPublicField.Name, codeReference.UsingMethod.Name);
                    }
                }
            }

            return(result);
        }
示例#6
0
 public static IEnumerable <MethodInfo> SelectUsesOf(this HashSet <MethodInfo> @this, MemberInfo member)
 {
     return(from usingDeclaration in ReflectionSearch.GetMethodsUsingDeclaration(member)
            let usingMethod = usingDeclaration.UsingMethod as MethodInfo
                              where @this.Contains(usingMethod)
                              select usingMethod);
 }
示例#7
0
        public override void CompileTimeInitialize(Type type, AspectInfo aspectInfo)
        {
            //TODO: What about overloads?!?
            this.MethodAttributes = new Dictionary <string, MethodSnapshotStrategy>();

            foreach (MethodInfo method in type.GetMethods(BindingFlagsSet.PublicInstanceDeclared))
            {
                if (method.GetCustomAttributes(typeof(NoAutomaticChangeTrackingOperationAttribute), true).Any())
                {
                    this.MethodAttributes.Add(method.Name, MethodSnapshotStrategy.Never);
                }
                else if (method.GetCustomAttributes(typeof(ForceChangeTrackingOperationAttribute), true).Any())
                {
                    this.MethodAttributes.Add(method.Name, MethodSnapshotStrategy.Always);
                }
                else
                {
                    this.MethodAttributes.Add(method.Name, MethodSnapshotStrategy.Auto);
                }
            }

            this.TrackedFields = new HashSet <string>();

            foreach (var propertyInfo in type.GetProperties(BindingFlagsSet.AllInstanceDeclared).Where(f => f.IsDefined(typeof(ChangeTrackedAttribute), false)))
            {
                var propertyInfoClosure = propertyInfo;

                var fields = ReflectionSearch.GetDeclarationsUsedByMethod(propertyInfo.GetGetMethod(true))
                             .Select(r => r.UsedDeclaration as FieldInfo)
                             .Where(f => f != null)
                             .Where(f => propertyInfoClosure.PropertyType.IsAssignableFrom(f.FieldType))
                             .Where(f => f.DeclaringType.IsAssignableFrom(type))
                             .ToList();

                if (fields.Count() != 1)
                {
                    DomainMessageSource.Instance.Write(propertyInfo, SeverityType.Error, "INPC013", propertyInfo.Name);
                }
                else
                {
                    this.TrackedFields.Add(fields.First().Name);
                }
            }

            foreach (FieldInfo fieldInfo in type
                     .GetFields(BindingFlagsSet.AllInstanceDeclared)
                     .Where(f => f.IsDefined(typeof(ChangeTrackedAttribute), false)))
            {
                this.TrackedFields.Add(fieldInfo.Name);
            }

            base.CompileTimeInitialize(type, aspectInfo);
        }
    public IEnumerable <AspectInstance> ProvideAspects(object targetElement)
    {
        MethodBase targetMethod = (MethodBase)targetElement;

        foreach (var codeReference in ReflectionSearch.GetDeclarationsUsedByMethod(targetMethod))
        {
            if (codeReference.UsedDeclaration.MemberType == MemberTypes.Method)
            {
                yield return(new AspectInstance(codeReference.UsedDeclaration, new ProfileAttribute()));
            }
        }
    }
        /// <summary>
        /// Uses ReflectionSearch so can be used only in Compile Time !!!
        /// </summary>
        public static bool IsToBeImplementedMethod(this MethodBase method)
        {
            var usedDeclarations = ReflectionSearch.GetDeclarationsUsedByMethod(method);

            if (usedDeclarations.Count() != 1)
            {
                return(false);
            }

            var usedDeclaration = usedDeclarations.Single();

            return(usedDeclaration.UsedType == typeof(ToBeIntroducedException) && usedDeclaration.UsedDeclaration is ConstructorInfo);
        }
示例#10
0
    public IEnumerable <AspectInstance> ProvideAspects(object targetElement)
    {
        MethodBase targetMethod = (MethodBase)targetElement;
        IAspectRepositoryService aspectRepositoryService = PostSharpEnvironment.CurrentProject.GetService <IAspectRepositoryService>();
        TimingAspect             aspect = new TimingAspect();

        MethodUsageCodeReference[] usages = ReflectionSearch.GetDeclarationsUsedByMethod(targetMethod);
        foreach (MethodUsageCodeReference codeReference in usages.Where(u => u.UsedDeclaration.MemberType == MemberTypes.Method))
        {
            if (!aspectRepositoryService.HasAspect(codeReference.UsedDeclaration, typeof(TimingAspect)))
            {
                yield return(new AspectInstance(codeReference.UsedDeclaration, aspect));
            }
        }
    }
        /// <summary>
        ///    Validates an <see cref="Assembly" /> against the current constraint.
        /// </summary>
        /// <param name="target">Parameter to which the current constraint has been applied.</param>
        /// <param name="assembly">Assembly being validated.</param>
        public override void ValidateCode(object target, Assembly assembly)
        {
            var parameter       = (ParameterInfo)target;
            var resourceManager = new ResourceManager(_resourceBaseName, assembly);

            // Get the list of methods referencing the parent method of the parameter.
            var reflectionService =
                PostSharpEnvironment.CurrentProject.GetService <ISyntaxReflectionService>();
            var usages = ReflectionSearch.GetMethodsUsingDeclaration(parameter.Member);

            foreach (MethodUsageCodeReference usage in usages)
            {
                // Decompiles the method into expression trees.
                ISyntaxMethodBody methodBody = reflectionService.GetMethodBody(usage.UsingMethod,
                                                                               SyntaxAbstractionLevel.ExpressionTree);

                // Visit the method body.
                var visitor = new Visitor(parameter, resourceManager);
                visitor.VisitMethodBody(methodBody);
            }
        }
示例#12
0
        public override void ValidateCode(object target, Assembly assembly)
        {
            var type = target as Type;

            if (type == null)
            {
                return;
            }

            var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);

            var virtuals = properties.Where(IsVirtual).Select(p => p.Name).ToList();

            var derrivedTypes = ReflectionSearch.GetDerivedTypes(type, ReflectionSearchOptions.IncludeDerivedTypes);

            foreach (var derrivedType in derrivedTypes)
            {
                var propertyInfos = derrivedType.DerivedType
                                    .GetProperties(BindingFlags.Instance
                                                   | BindingFlags.Public
                                                   | BindingFlags.DeclaredOnly);

                var names = propertyInfos.Select(p => p.Name).Intersect(virtuals).Select(n => n).ToList();

                if (names.Any())
                {
                    var violations = propertyInfos.Where(p => names.Contains(p.Name)).Select(p => p).ToList();
                    foreach (var vp in violations)
                    {
                        Message.Write(vp // location of violation in code
                                      , SeverityType.Error
                                      , "vir001"
                                      , $"Property {vp.Name} declared in {vp.DeclaringType} should override base property.");
                    }
                }
            }
        }
        public override bool CompileTimeValidate(Type type)
        {
            bool result = base.CompileTimeValidate(type);

            // [ThreadUnsafeMethod] cannot be used on static methods. [Error]
            IEnumerable <MethodInfo> staticThreadUnsafeMethods =
                type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where(
                    m => m.GetCustomAttributes(typeof(ThreadUnsafeMethodAttribute), false).Length != 0);

            foreach (MethodInfo staticThreadUnsafeMethod in staticThreadUnsafeMethods)
            {
                ThreadingMessageSource.Instance.Write(staticThreadUnsafeMethod, SeverityType.Error, "THR002", staticThreadUnsafeMethod.DeclaringType.Name,
                                                      staticThreadUnsafeMethod.Name);

                result = false;
            }

            // [ThreadUnsafeMethod] should not be used if policy is "Static". [Warning]
            if (this.Policy == ThreadUnsafePolicy.Static)
            {
                IEnumerable <MethodInfo> threadUnsafeMethods = type
                                                               .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                                                               .Where(m => m.GetCustomAttributes(typeof(ThreadUnsafeMethodAttribute), false).Length != 0);
                foreach (MethodInfo threadUnsafeMethod in threadUnsafeMethods)
                {
                    ThreadingMessageSource.Instance.Write(threadUnsafeMethod, SeverityType.Warning, "THR003", threadUnsafeMethod.DeclaringType.Name,
                                                          threadUnsafeMethod.Name);
                }
            }

            // All instance fields should be private or protected unless marked as [ThreadSafe]. [Error]
            foreach (
                FieldInfo publicField in
                type.GetFields(BindingFlags.Public | BindingFlags.Instance).Where(
                    f => f.GetCustomAttributes(typeof(ThreadSafeAttribute), false).Length == 0))
            {
                ThreadingMessageSource.Instance.Write(type, SeverityType.Error, "THR008", type.Name, publicField.Name);
                result = false;
            }

            // If policy is "Instance", fields cannot be accessed from a static method unless method or field marked as [ThreadSafe]. [Warning]

            if (this.policy == ThreadUnsafePolicy.Instance)
            {
                IEnumerable <FieldInfo> nonPublicFields =
                    type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                    .Where(m => m.GetCustomAttributes(typeof(ThreadSafeAttribute), false).Length == 0);

                foreach (FieldInfo nonPublicField in nonPublicFields)
                {
                    foreach (MethodUsageCodeReference codeReference in ReflectionSearch.GetMethodsUsingDeclaration(nonPublicField))
                    {
                        if (codeReference.UsingMethod.IsStatic &&
                            codeReference.UsingMethod.GetCustomAttributes(typeof(ThreadSafeAttribute), false).Length == 0)
                        {
                            ThreadingMessageSource.Instance.Write(codeReference.UsingMethod, SeverityType.Warning, "THR012", nonPublicField.Name, codeReference.UsingMethod.Name);
                        }
                    }
                }

                // If policy is "Instance", static methods cannot access instance methods that are not public or internal or [ThreadUnsafeMethod]. [Warning]

                IEnumerable <MethodInfo> nonPublicMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                                            .Where(m => !ReflectionHelper.IsInternalOrPublic(m, false))
                                                            .Where(m => m.GetCustomAttributes(typeof(ThreadUnsafeMethodAttribute), false).Length == 0);

                foreach (MethodInfo nonPublicMethod in nonPublicMethods)
                {
                    foreach (MethodUsageCodeReference codeReference in ReflectionSearch.GetMethodsUsingDeclaration(nonPublicMethod))
                    {
                        if (codeReference.UsingMethod.IsStatic &&
                            codeReference.UsingMethod.GetCustomAttributes(typeof(ThreadSafeAttribute), false).Length == 0)
                        {
                            ThreadingMessageSource.Instance.Write(codeReference.UsingMethod, SeverityType.Warning, "THR013", nonPublicMethod.Name, codeReference.UsingMethod.Name);
                        }
                    }
                }
            }


            // TODO: If policy is "Instance", fields of instance A cannot be accessed from an instance method of instance B (A!=B) unless method or field marked as [ThreadSafe]. [Warning]

            return(result);
        }
示例#14
0
 public static IEnumerable <MethodInfo> SelectUsesOf(this IEnumerable <MethodInfo> @this, MemberInfo member)
 {
     return(from usingDeclaration in ReflectionSearch.GetMethodsUsingDeclaration(member)
            join method in @this on usingDeclaration.UsingMethod equals method
            select method);
 }