/// <summary> /// Adds only the specified members to the whitelist. /// </summary> /// <param name="target"></param> /// <param name="members"></param> public void AllowMembers(MyWhitelistTarget target, params MemberInfo[] members) { if (members.IsNullOrEmpty()) { throw new MyWhitelistException("Needs at least one member"); } AssertVitality(); for (var index = 0; index < members.Length; index++) { var member = members[index]; if (member == null) { throw new MyWhitelistException("Element " + index + " is null"); } var typeSymbol = ResolveTypeSymbol(member.DeclaringType); var candidates = typeSymbol.GetMembers().Where(m => m.MetadataName == member.Name).ToList(); var method = member as MethodInfo; ParameterInfo[] methodParameters = null; if (method != null) { // Sanity check. I don't think this is actually possible. Debug.Assert(candidates.All(m => m is IMethodSymbol), "Illogical failure: Found more than one non-method with the same name?!?"); methodParameters = method.GetParameters(); candidates.RemoveAll(s => ((IMethodSymbol)s).Parameters.Length != methodParameters.Length); if (method.IsGenericMethodDefinition) { candidates.RemoveAll(s => !((IMethodSymbol)s).IsGenericMethod); } else { candidates.RemoveAll(s => ((IMethodSymbol)s).IsGenericMethod); } if (method.IsSpecialName && method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) { throw new MyWhitelistException("Whitelist the actual properties, not their access methods"); } } switch (candidates.Count) { case 0: throw new MyWhitelistException(string.Format("Cannot add {0} to the whitelist because its symbol variant could not be found.", member)); case 1: Whitelist.RegisterMember(target, candidates[0], member); break; default: // Sanity check. I don't think this is actually possible. Debug.Assert(method != null, "Illogical failure: Found more than one non-method with the same name?!?"); var methodSymbol = FindMethodOverload(candidates, methodParameters); if (methodSymbol == null) { throw new MyWhitelistException(string.Format("Cannot add {0} to the whitelist because its symbol variant could not be found.", member)); } Whitelist.RegisterMember(target, methodSymbol, member); break; } } }