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]); }
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); } } }
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); }
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); }
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); }
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); } }
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); }
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); }