public override ConventionResult IsSatisfiedBy(Type type) { var toInspect = type.GetMethods().Where(m => m.ReturnType == typeof(void)); var failures = toInspect.Where(HasAttribute <AsyncStateMachineAttribute>); if (failures.Any()) { var details = failures.Aggregate(string.Empty, (s, info) => s + "\t- " + info.Name + Environment.NewLine); var failureMessage = BuildFailureMessage(details); return(ConventionResult.NotSatisfied(type.FullName, failureMessage)); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var failures = GetMethods(type).Where(method => !IsSatisfiedBy(method)).ToList(); if (failures.Any()) { var details = failures.Aggregate(string.Empty, (s, method) => $"{s}\t- {FullMethodName(method)}{Environment.NewLine}"); var failureMessage = BuildFailureMessage(details); return(ConventionResult.NotSatisfied(type.FullName, failureMessage)); } return(ConventionResult.Satisfied(type.FullName)); }
public ConventionResult IsSatisfiedBy(DatabaseSpecimen databaseSpecimen) { var resourceName = GetType().FullName + ".sql"; var assembly = GetType().Assembly.GetManifestResourceNames().Contains(resourceName) ? GetType().Assembly : typeof(DatabaseConventionSpecification).Assembly; string script; using (var stream = assembly.GetManifestResourceStream(resourceName)) using (var reader = new StreamReader(stream)) { script = reader.ReadToEnd(); } if (string.IsNullOrWhiteSpace(script)) { throw new InvalidOperationException("Resource identified did not contain any SQL script."); } var failures = new List <string>(); using (IDbConnection dbConnection = new SqlConnection(databaseSpecimen.ConnectionString)) { dbConnection.Open(); var command = dbConnection.CreateCommand(); command.CommandText = script; using (var reader = command.ExecuteReader()) { while (reader.Read()) { failures.Add(reader.GetString(0)); } } } if (failures.Any()) { return(ConventionResult.NotSatisfied(DatabaseConventionResultIdentifier, FailureMessage + Environment.NewLine + failures.Aggregate((x, y) => x + Environment.NewLine + y))); } return(ConventionResult.Satisfied(DatabaseConventionResultIdentifier)); }
public override ConventionResult IsSatisfiedBy(Type type) { var failures = type.ToTypeDefinition() .Methods .Where(HasAttribute <AsyncStateMachineAttribute>) .Where(AwaitingTasksWithoutConfigureAwait); if (failures.Any()) { var details = failures.Aggregate(string.Empty, (s, info) => s + "\t- " + type.Name + "." + info.Name + Environment.NewLine); var failureMessage = BuildFailureMessage(details); return(ConventionResult.NotSatisfied(type.FullName, failureMessage)); } return(ConventionResult.Satisfied(type.FullName)); }
protected override ConventionResult IsSatisfiedByInternal(string assemblyName, XDocument projectDocument) { var files = AllMatchingFilesInFolder(ConventionTargetFolder); var failures = files.Where(file => !ItemGroupItem.FromProjectDocument(projectDocument).Any(igi => igi.MatchesAbsolutePath(file.Replace(this.ProjectFolder, "").TrimStart('\\')))) .ToArray(); if (failures.Any()) { var failureText = FailureMessage.FormatWith(_pattern, ConventionTargetFolder) + Environment.NewLine + string.Join(Environment.NewLine, failures.Select(igi => "- " + igi.ToString())); return(ConventionResult.NotSatisfied(assemblyName, failureText)); } return(ConventionResult.Satisfied(assemblyName)); }
protected override ConventionResult IsSatisfiedByInternal(string assemblyName, XDocument projectDocument) { var failures = ItemGroupItem.FromProjectDocument(projectDocument) .Where(itemGroupItem => itemGroupItem.MatchesPatternAndIsNotAnEmbeddedResourceOrReference(_fileMatchRegex)) .ToArray(); if (failures.Any()) { var failureText = FailureMessage.FormatWith(_friendlyDescription, assemblyName) + Environment.NewLine + string.Join(Environment.NewLine, failures.Select(itemGroupItem => "- " + itemGroupItem.ToString())); return(ConventionResult.NotSatisfied(assemblyName, failureText)); } return(ConventionResult.Satisfied(assemblyName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var toInspect = type.GetProperties().Where(p => p.CanWrite); var failures = toInspect.Where(subject => subject.GetGetMethod() == null || subject.GetGetMethod().IsPublic == false).ToArray(); if (failures.Any()) { var failureMessage = BuildFailureMessage(failures.Aggregate(string.Empty, (s, info) => s + "\t- " + info.Name + Environment.NewLine)); return(ConventionResult.NotSatisfied(type.FullName, failureMessage)); } return(ConventionResult.Satisfied(type.FullName)); }
protected override ConventionResult IsSatisfiedBy(string assemblyName, XDocument projectDocument) { // NOTE: File inclusion rules for 2017 Csproj // NOTE: Element | Include glob | Exclude glob | Remove glob // NOTE: Compile | **/*.cs (or other language extensions) | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | N/A // NOTE: EmbeddedResource | **/*.resx | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | N/A // NOTE: None **/* | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | - **/*.cs; **/*.resx // TODO: Less Naive implementation for 2017 Csproj users var nonDefaultIncludeRulesInUse = projectDocument.Elements().Where(x => x.Name.LocalName == "PropertyGroup") .Any(x => x.Elements(XName.Get("EnableDefaultCompileItems")) != null); return(nonDefaultIncludeRulesInUse ? IsSatisfiedByLegacyCsprojFormat(assemblyName, projectDocument) : ConventionResult.Satisfied(assemblyName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var forbiddenUsages = type.ToTypeDefinition() .Methods .Where(method => method.HasBody) .SelectMany(method => method.Body.Instructions) .Where(DateTimeForbiddenPropertiesMatcher) .ToArray(); if (forbiddenUsages.Any()) { var failureMessage = FailureMessage.FormatWith(forbiddenUsages.Count(), type.FullName); return(ConventionResult.NotSatisfied(type.FullName, failureMessage)); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var failures = type.ToTypeDefinition() .Methods .Where(x => x.HasAttribute <AsyncStateMachineAttribute>()) .Where(AwaitingTasksWithoutConfigureAwait) .ToArray(); if (failures.Any()) { var details = string.Join(Environment.NewLine, failures.Select(info => "- " + type.Name + "." + info.Name)); var failureMessage = BuildFailureMessage(details); return(ConventionResult.NotSatisfied(type.FullName, failureMessage)); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var tuples = from genericTypeArgument in type.GetGenericArguments() from constraint in genericTypeArgument.GetGenericParameterConstraints() select new { genericTypeArgument, constraint }; foreach (var tuple in tuples) { if (tuple.constraint.IsInterface) { continue; } return(ConventionResult.NotSatisfied(type.FullName, $"Type constraint {tuple.constraint} is not an interface type")); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var properties = type .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => _propertyType.IsAssignableFrom(p.PropertyType)) .ToArray(); var failures = properties.Where(x => !x.GetCustomAttributes(_attributeType, false).Any()).ToArray(); if (failures.Any()) { return(ConventionResult.NotSatisfied(type.FullName, BuildFailureMessage(failures.Aggregate(string.Empty, (s, t) => s + "\t" + type.FullName + Environment.NewLine)).FormatWith(_propertyType.Name, _attributeType.Name))); } return(ConventionResult.Satisfied(type.FullName)); }
public override async Task <ConventionResult> IsSatisfiedBy(Type type) { var query = (IDapperQuery)Activator.CreateInstance(type, _connectionFactory); try { if (query.GetType().GetMethod("Execute").Invoke(query, new object[0]) is Task maybeAsyncResult) { await maybeAsyncResult; } } catch (Exception e) { return(ConventionResult.NotSatisfied(type.FullName, $"Query {type.FullName} failed to execute with exception: {e.Message}")); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var properties = type .GetDeclaredProperties() .Where(p => _propertyType.IsAssignableFrom(p.PropertyType)) .Where(p => _writablePropertiesOnly && p.CanWrite) .ToArray(); var failures = properties.Where(x => !x.GetCustomAttributes(_attributeType, false).Any()).ToArray(); if (failures.Any()) { return(ConventionResult.NotSatisfied(type.FullName, BuildFailureMessage(failures.Aggregate(string.Empty, (s, info) => s + "\t" + info.Name + Environment.NewLine)).FormatWith(_propertyType.Name, _attributeType.Name))); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var sourceType = _sourceTypes.FirstOrDefault(t => t.IsEnum && t.Name == type.Name); if (sourceType == null) { return(ConventionResult.NotSatisfied(type.Name, "does not match any of the supplied type names")); } var subjectValueNames = ToValueNameDictionary(type); var sourceValueNames = ToValueNameDictionary(sourceType); ConventionResult result = ConventionResult.Satisfied(type.Name); result = CompareEnums(subjectValueNames, sourceValueNames, result); result = CompareEnums(sourceValueNames, subjectValueNames, result); return(result); }
public override ConventionResult IsSatisfiedBy(Type type) { var enumerables = type .GetDeclaredProperties() .Select(p => p.PropertyType) .Where(t => t != typeof(string) && (typeof(IEnumerable).IsAssignableFrom(t))) .ToArray(); var failures = enumerables.Where(x => x.IsArray == false).ToArray(); if (failures.Any()) { return(ConventionResult.NotSatisfied(type.FullName, BuildFailureMessage(failures.Aggregate(string.Empty, (s, t) => s + "\t" + type.FullName + Environment.NewLine)))); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var typeDefinition = type.ToTypeDefinition(); var typeInstructions = typeDefinition .Methods .Where(method => method.HasBody) .SelectMany(method => method.Body.Instructions) .Union( typeDefinition .Methods .Where(x => x.HasAttribute <AsyncStateMachineAttribute>()) .SelectMany(x => x.GetAsyncStateMachineType().Methods.Where(method => method.HasBody)) .SelectMany(method => method.Body.Instructions)) .Union( typeDefinition .Methods .Where(x => x.HasAttribute <IteratorStateMachineAttribute>()) .SelectMany(x => x.GetIteratorStateMachineType().Methods.Where(method => method.HasBody)) .SelectMany(method => method.Body.Instructions)); var operandPredicate = _includeVirtualMethodCalls ? (Func <Instruction, bool>)(x => (x.OpCode == OpCodes.Call || x.OpCode == OpCodes.Callvirt) && x.Operand is MethodReference) : x => x.OpCode == OpCodes.Call && x.Operand is MethodReference; var assignments = typeInstructions .Where(operandPredicate) .Join(_methodInfos, x => (((MethodReference)x.Operand).DeclaringType.FullName, ((MethodReference)x.Operand).Name), g => (g.DeclaringType?.FullName, g.Name), (x, g) => x) .Distinct().ToArray(); if (assignments.Any()) { return(ConventionResult.NotSatisfied(type.FullName, FailureMessage.FormatWith(assignments.Count(), type.FullName))); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var constructor in constructors) { var actualParameterOrder = constructor.GetParameters(); var expectedParameterOrder = _sortParameters(actualParameterOrder).ToArray(); if (actualParameterOrder.SequenceEqual(expectedParameterOrder)) { continue; } var message = $"Expected order of constructor parameters is {expectedParameterOrder.Select(p => p.ParameterType.Name).ToArray().Join(", ")}."; return(ConventionResult.NotSatisfied(type.FullName, message)); } return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var nowAssignments = type.ToTypeDefinition() .Methods .Where(method => method.HasBody) .SelectMany(method => method.Body.Instructions) .Where( x => x.OpCode == OpCodes.Call && x.Operand is MethodReference && ((MethodReference)x.Operand).DeclaringType.FullName == "System.DateTime" && ((MethodReference)x.Operand).Name == "get_Now") .ToArray(); if (nowAssignments.Any()) { return(ConventionResult.NotSatisfied(type.FullName, FailureMessage.FormatWith(nowAssignments.Count()))); } return(ConventionResult.Satisfied(type.FullName)); }
protected override ConventionResult IsSatisfiedBy(string assemblyName, XDocument projectDocument) { // NOTE: The nesting we are looking for is Project > ItemGroup > Reference > HintPath // NOTE: <ItemGroup> // NOTE: <Reference Include = "Mono.Cecil, Version=0.9.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> // NOTE: <SpecificVersion> False </SpecificVersion> // NOTE: <HintPath>..\packages\Mono.Cecil.0.9.5.4\lib\net40\Mono.Cecil.dll </HintPath> // NOTE: </Reference> // NOTE: // NOTE: and // NOTE: // NOTE: <ItemGroup> // NOTE: <Reference Include="Microsoft.AspNetCore.Mvc.Core"> // NOTE: <HintPath>..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.mvc.core\2.0.3\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Core.dll</HintPath> // NOTE: </Reference> // NOTE: </ItemGroup> var references = projectDocument.Elements() .Single(x => x.Name.LocalName == "Project") .Elements() .Where(x => x.Name.LocalName == "ItemGroup") .SelectMany(x => x.Elements().Where(e => e.Name.LocalName == "Reference")); var failures = references .Where(x => x.Elements().Any(e => e.Name.LocalName == "HintPath" && Regex.IsMatch(e.Value, FindPattern))) .Select(x => new Failure( x.Attributes().Single(a => a.Name.LocalName == "Include").Value, x.Elements().Single(e => e.Name.LocalName == "HintPath").Value)) .ToArray(); if (!failures.Any()) { return(ConventionResult.Satisfied(assemblyName)); } var failureText = $"{FailureMessage.FormatWith(assemblyName)}{Environment.NewLine}{failures.Aggregate(string.Empty, (s, t) => $"{s}\t{t.Reference} ({t.Location}){Environment.NewLine}")}"; return(ConventionResult.NotSatisfied(assemblyName, failureText)); }
public override ConventionResult IsSatisfiedBy(Type type) { var typeDefinition = type.ToTypeDefinition(); var subjects = _propertyTypes.SelectMany(x => typeDefinition.GetPropertiesOfType(x)); var subjectPropertySetters = subjects .Where(p => p.SetMethod != null) .Select(p => p.SetMethod.Name) .ToArray(); var defaultConstructor = typeDefinition .GetConstructors() .SingleOrDefault(c => c.Parameters.Any() == false && c.IsStatic == false); if (defaultConstructor == null) { return(ConventionResult.Satisfied(type.FullName)); } ; var setters = defaultConstructor .Body .Instructions .Select(i => i.Operand) .OfType <MethodDefinition>() .Select(m => m.Name); if (setters.Count(subjectPropertySetters.Contains) == subjectPropertySetters.Count()) { return(ConventionResult.Satisfied(type.FullName)); } var propertyTypeNames = _propertyTypes.Aggregate(string.Empty, (x, t) => t.Name + ", " + x).TrimEnd(' ', ','); return(ConventionResult.NotSatisfied(type.FullName, FailureMessage.FormatWith(propertyTypeNames))); }
public override async Task <ConventionResult> IsSatisfiedBy(Type type) { var query = (IDapperQuery)Activator.CreateInstance(type, new ConnectionFactory(_connectionString)); var queryParametersType = type.GetInterfaces()[0].GetGenericArguments()[0]; var queryParameters = (IQueryParameters)Activator.CreateInstance(queryParametersType, nonPublic: true); foreach (var property in queryParameters.GetType().GetProperties()) { if (property.CanWrite) { property.SetValue(queryParameters, property.PropertyType.GetDefault()); } } var failures = new List <string>(); try { var maybeAsyncResult = query.GetType().GetMethod("Execute") .Invoke(query, new object[] { queryParameters }) as Task; if (maybeAsyncResult != null) { await maybeAsyncResult; } } catch (Exception e) when(!_exceptionalExceptions.Contains(e.GetType())) { failures.Add($"Query {type.FullName} failed to execute with exception: {e.Message}"); } catch (Exception) { // Not a failure } return(failures.Any() ? ConventionResult.NotSatisfied(type.FullName, failures.Aggregate(string.Empty, (s, s1) => s + s1 + Environment.NewLine)) : ConventionResult.Satisfied(type.FullName)); }
protected override ConventionResult IsSatisfiedByLegacyCsprojFormat(string assemblyName, XDocument projectDocument) { var files = AllMatchingFilesInFolder(ConventionTargetFolder); var normalisedIncludes = ItemGroupItem.FromProjectDocument(projectDocument) .Select(item => item.Include.Replace('\\', Path.DirectorySeparatorChar)); var failures = files.Where(file => normalisedIncludes.None(include => include == file.Replace(ProjectFolder, "").TrimStart(Path.DirectorySeparatorChar))) .ToArray(); if (failures.Any()) { var failureText = FailureMessage.FormatWith(_pattern, ConventionTargetFolder) + Environment.NewLine + string.Join(Environment.NewLine, failures.Select(igi => "- " + igi.ToString())); return(ConventionResult.NotSatisfied(assemblyName, failureText)); } return(ConventionResult.Satisfied(assemblyName)); }
public override ConventionResult IsSatisfiedBy(string solutionRoot) { var failures = new List <string>(); foreach (var filePath in DirectoryEx.GetFilesExceptOutput(solutionRoot, _fileSearchPattern).Where(x => _fileExemptions.Any(x.EndsWith) == false)) { var fileContents = File.ReadAllText(filePath); var matches = Regex.Matches( fileContents, CommentPattern.Replace("{0}", BuildPermittedComments(_permittedCommentDelimiters)), RegexOptions.IgnoreCase) .Cast <Match>() .ToArray(); if (matches.Any(x => x.Groups["badguys"].Success)) { var failureText = matches .Where(x => x.Groups["badguys"].Success) .SelectMany(x => x.Groups["badguys"].Captures.Cast <Capture>()) .Aggregate( filePath + Environment.NewLine, (current, capture) => current + "Line " + DeriveLineNumber(fileContents, capture.Index) + ": " + capture.Value) .Trim(); failures.Add(failureText); } } if (failures.Any()) { return(ConventionResult.NotSatisfied( SolutionConventionResultIdentifier, BuildFailureMessage(failures.Aggregate(string.Empty, (result, input) => result + Environment.NewLine + input).Trim()))); } return(ConventionResult.Satisfied(SolutionConventionResultIdentifier)); }
public override ConventionResult IsSatisfiedBy(Type type) { var methodsWithBodies = type.ToTypeDefinition().Methods.Where(method => method.HasBody).ToList(); var exceptions = methodsWithBodies.SelectMany(method => method.Body.Instructions .Select(instr => new { Method = method, MemberReference = instr.Operand as MemberReference }) .Where(m => m.MemberReference != null && m.MemberReference.DeclaringType != null && m.MemberReference.DeclaringType.FullName.EndsWith("Exception")) .Select(m => new KeyValuePair <TypeDefinition, string>( m.MemberReference.DeclaringType.Resolve(), m.Method.DeclaringType.FullName + "::" + m.Method.Name + "(" + m.MemberReference.DeclaringType.FullName + ")"))); var failures = exceptions.Where(x => x.Key.IsAssignableTo(_baseType) == false).ToArray(); if (failures.Any()) { return(ConventionResult.NotSatisfied(type.FullName, FailureMessage.FormatWith(_baseType.FullName) + Environment.NewLine + failures.Aggregate(string.Empty, (s, t) => s + t.Value + Environment.NewLine))); } return(ConventionResult.Satisfied(type.FullName)); }
public override async Task <ConventionResult> IsSatisfiedBy(Type type) { await Task.Delay(1); return(ConventionResult.Satisfied(type.FullName)); }
public override ConventionResult IsSatisfiedBy(Type type) { var constructors = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); var anyConstructorsUsingMel = constructors .SelectMany(c => c.GetParameters()) .Any(c => c.ParameterType == typeof(ILogger) || (c.ParameterType.IsGenericType && c.ParameterType.GetGenericTypeDefinition() == typeof(ILogger <>)) ); return(anyConstructorsUsingMel ? ConventionResult.NotSatisfied(type.FullName, FailureMessage) : ConventionResult.Satisfied(type.FullName)); }