bool ValidatesReflectionAccessPatterns(TypeDefinition testCaseTypeDefinition) { if (testCaseTypeDefinition.HasNestedTypes) { var nestedTypes = new Queue <TypeDefinition> (testCaseTypeDefinition.NestedTypes.ToList()); while (nestedTypes.Count > 0) { if (ValidatesReflectionAccessPatterns(nestedTypes.Dequeue())) { return(true); } } } if (testCaseTypeDefinition.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(VerifyAllReflectionAccessPatternsAreValidatedAttribute)) || testCaseTypeDefinition.AllMembers().Concat(testCaseTypeDefinition.AllDefinedTypes()).Any(m => m.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(RecognizedReflectionAccessPatternAttribute) || attr.AttributeType.Name == nameof(UnrecognizedReflectionAccessPatternAttribute)))) { return(true); } return(false); }
protected virtual void VerifyTypeDefinition(TypeDefinition original, TypeDefinition linked) { if (linked != null && verifiedGeneratedTypes.Contains(linked.FullName)) { return; } ModuleDefinition linkedModule = linked?.Module; // // Little bit complex check to allow easier test writing to match // - It has [Kept] attribute or any variation of it // - It contains Main method // - It contains at least one member which has [Kept] attribute (not recursive) // bool expectedKept = original.HasAttributeDerivedFrom(nameof(KeptAttribute)) || (linked != null && linkedModule.Assembly.EntryPoint?.DeclaringType == linked) || original.AllMembers().Any(l => l.HasAttribute(nameof(KeptAttribute))); if (!expectedKept) { if (linked != null) { Assert.Fail($"Type `{original}' should have been removed"); } return; } VerifyTypeDefinitionKept(original, linked); }
protected virtual void VerifyTypeDefinition(TypeDefinition original, TypeDefinition?linked) { if (linked != null && verifiedGeneratedTypes.Contains(linked.FullName)) { return; } ModuleDefinition?linkedModule = linked?.Module; // // Little bit complex check to allow easier test writing to match // - It has [Kept] attribute or any variation of it // - It contains Main method // - It contains at least one member which has [Kept] attribute (not recursive) // bool expectedKept = original.HasAttributeDerivedFrom(nameof(KeptAttribute)) || (linked != null && linkedModule !.Assembly.EntryPoint?.DeclaringType == linked) || original.AllMembers().Any(l => l.HasAttribute(nameof(KeptAttribute))); if (!expectedKept) { if (linked != null) { Assert.True(false, $"Type `{original}' should have been removed"); } return; } bool prev = checkNames; checkNames |= original.HasAttribute(nameof(VerifyMetadataNamesAttribute)); VerifyTypeDefinitionKept(original, linked); checkNames = prev; if (original.HasAttribute(nameof(CreatedMemberAttribute))) { foreach (var attr in original.CustomAttributes.Where(l => l.AttributeType.Name == nameof(CreatedMemberAttribute))) { var newName = original.FullName + "::" + attr.ConstructorArguments[0].Value.ToString(); if (linkedMembers !.RemoveWhere(l => l.Contains(newName)) != 1) { Assert.True(false, $"Newly created member '{newName}' was not found"); } } } }
public static IEnumerable <MethodDefinition> AllMethods(this TypeDefinition type) { foreach (var m in type.AllMembers()) { switch (m) { case MethodDefinition method: yield return(method); break; case PropertyDefinition @property: if (@property.GetMethod != null) { yield return(@property.GetMethod); } if (@property.SetMethod != null) { yield return(@property.SetMethod); } break; case EventDefinition @event: if (@event.AddMethod != null) { yield return(@event.AddMethod); } if (@event.RemoveMethod != null) { yield return(@event.RemoveMethod); } break; default: break; } } }
bool ValidatesLogMessages(TypeDefinition testCaseTypeDefinition) { if (testCaseTypeDefinition.HasNestedTypes) { var nestedTypes = new Queue <TypeDefinition> (testCaseTypeDefinition.NestedTypes.ToList()); while (nestedTypes.Count > 0) { if (ValidatesLogMessages(nestedTypes.Dequeue())) { return(true); } } } if (testCaseTypeDefinition.AllMembers().Concat(testCaseTypeDefinition.AllDefinedTypes()).Append(testCaseTypeDefinition) .Any(m => m.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(LogContainsAttribute) || attr.AttributeType.Name == nameof(LogDoesNotContainAttribute)))) { return(true); } return(false); }
protected virtual void VerifyTypeDefinition(TypeDefinition original, TypeDefinition linked) { ModuleDefinition linkedModule = linked?.Module; // // Little bit complex check to allow easier test writting to match // - It has [Kept] attribute or any variation of it // - It contains Main method // - It contains at least one member which has [Kept] attribute (not recursive) // bool expectedKept = original.HasAttributeDerivedFrom(nameof(KeptAttribute)) || (linked != null && linkedModule.Assembly.EntryPoint.DeclaringType == linked) || original.AllMembers().Any(l => l.HasAttribute(nameof(KeptAttribute))); if (!expectedKept) { if (linked != null) { Assert.Fail($"Type `{original}' should have been removed"); } return; } if (linked == null) { Assert.Fail($"Type `{original}' should have been kept"); } if (!original.IsInterface) { VerifyBaseType(original, linked); } VerifyInterfaces(original, linked); VerifyGenericParameters(original, linked); VerifyCustomAttributes(original, linked); VerifySecurityAttributes(original, linked); foreach (var td in original.NestedTypes) { VerifyTypeDefinition(td, linked?.NestedTypes.FirstOrDefault(l => td.FullName == l.FullName)); linkedMembers.Remove(td.FullName); } // Need to check properties before fields so that the KeptBackingFieldAttribute is handled correctly foreach (var p in original.Properties) { VerifyProperty(p, linked?.Properties.FirstOrDefault(l => p.Name == l.Name), linked); linkedMembers.Remove(p.FullName); } // Need to check events before fields so that the KeptBackingFieldAttribute is handled correctly foreach (var e in original.Events) { VerifyEvent(e, linked?.Events.FirstOrDefault(l => e.Name == l.Name), linked); linkedMembers.Remove(e.FullName); } foreach (var f in original.Fields) { if (verifiedBackingFields.Contains(f.FullName)) { continue; } VerifyField(f, linked?.Fields.FirstOrDefault(l => f.Name == l.Name)); linkedMembers.Remove(f.FullName); } foreach (var m in original.Methods) { if (verifiedEventMethods.Contains(m.FullName)) { continue; } VerifyMethod(m, linked?.Methods.FirstOrDefault(l => m.GetSignature() == l.GetSignature())); linkedMembers.Remove(m.FullName); } }
public virtual TestCaseLinkerOptions GetLinkerOptions(NPath inputPath) { var tclo = new TestCaseLinkerOptions { Il8n = GetOptionAttributeValue(nameof(Il8nAttribute), "none"), IgnoreDescriptors = GetOptionAttributeValue(nameof(IgnoreDescriptorsAttribute), true), IgnoreSubstitutions = GetOptionAttributeValue(nameof(IgnoreSubstitutionsAttribute), true), KeepTypeForwarderOnlyAssemblies = GetOptionAttributeValue(nameof(KeepTypeForwarderOnlyAssembliesAttribute), string.Empty), KeepDebugMembers = GetOptionAttributeValue(nameof(SetupLinkerKeepDebugMembersAttribute), string.Empty), LinkSymbols = GetOptionAttributeValue(nameof(SetupLinkerLinkSymbolsAttribute), string.Empty), CoreAssembliesAction = GetOptionAttributeValue <string> (nameof(SetupLinkerCoreActionAttribute), null), UserAssembliesAction = GetOptionAttributeValue <string> (nameof(SetupLinkerUserActionAttribute), null), SkipUnresolved = GetOptionAttributeValue(nameof(SkipUnresolvedAttribute), false), StripDescriptors = GetOptionAttributeValue(nameof(StripDescriptorsAttribute), true), StripSubstitutions = GetOptionAttributeValue(nameof(StripSubstitutionsAttribute), true), }; foreach (var assemblyAction in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerActionAttribute))) { var ca = assemblyAction.ConstructorArguments; tclo.AssembliesAction.Add(new KeyValuePair <string, string> ((string)ca[0].Value, (string)ca[1].Value)); } foreach (var subsFile in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerSubstitutionFileAttribute))) { var ca = subsFile.ConstructorArguments; var file = (string)ca[0].Value; tclo.Substitutions.Add(Path.Combine(inputPath, file)); } foreach (var subsFile in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerAttributeDefinitionsFile))) { var ca = subsFile.ConstructorArguments; var file = (string)ca[0].Value; tclo.AttributeDefinitions.Add(Path.Combine(inputPath, file)); } foreach (var additionalArgumentAttr in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerArgumentAttribute))) { var ca = additionalArgumentAttr.ConstructorArguments; var values = ((CustomAttributeArgument[])ca[1].Value)?.Select(arg => arg.Value.ToString()).ToArray(); // Since custom attribute arguments need to be constant expressions, we need to add // the path to the temp directory (where the custom assembly is located) here. if ((string)ca[0].Value == "--custom-step") { int pos = values[0].IndexOf(","); if (pos != -1) { string custom_assembly_path = values[0].Substring(pos + 1); if (!Path.IsPathRooted(custom_assembly_path)) { values[0] = values[0].Substring(0, pos + 1) + Path.Combine(inputPath, custom_assembly_path); } } } tclo.AdditionalArguments.Add(new KeyValuePair <string, string[]> ((string)ca[0].Value, values)); } if (_testCaseTypeDefinition.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(LogContainsAttribute) || attr.AttributeType.Name == nameof(LogDoesNotContainAttribute)) || _testCaseTypeDefinition.AllMembers().Any(method => method.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(LogContainsAttribute) || attr.AttributeType.Name == nameof(LogDoesNotContainAttribute)))) { tclo.AdditionalArguments.Add(new KeyValuePair <string, string[]> ("--verbose", new string[] { })); } return(tclo); }