// Returns the members of the type bound by memberTypes. For DynamicallyAccessedMemberTypes.All, this returns a single null result.
        // This sentinel value allows callers to handle the case where DynamicallyAccessedMemberTypes.All conceptually binds to the entire type
        // including all recursive nested members.
        public static IEnumerable <IMetadataTokenProvider> GetDynamicallyAccessedMembers(this TypeDefinition typeDefinition, LinkContext context, DynamicallyAccessedMemberTypes memberTypes)
        {
            if (memberTypes == DynamicallyAccessedMemberTypes.All)
            {
                yield return(null);

                yield break;
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: m => m.IsPublic && m.Parameters.Count == 0))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicNestedTypes))
            {
                foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(t);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicNestedTypes))
            {
                foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(t);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(e);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(e);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypesOverlay.Interfaces))
            {
                foreach (var i in typeDefinition.GetAllInterfaceImplementations(context))
                {
                    yield return(i);
                }
            }
        }
        // Returns the members of the type bound by memberTypes. For DynamicallyAccessedMemberTypes.All, this returns all members of the type and its
        // nested types, including interface implementations, plus the same or any base types or implemented interfaces.
        // DynamicallyAccessedMemberTypes.PublicNestedTypes and NonPublicNestedTypes do the same for members of the selected nested types.
        public static IEnumerable <TypeSystemEntity> GetDynamicallyAccessedMembers(this TypeDesc typeDefinition, DynamicallyAccessedMemberTypes memberTypes, bool declaredOnly = false)
        {
            if (memberTypes == DynamicallyAccessedMemberTypes.None)
            {
                yield break;
            }

            if (memberTypes == DynamicallyAccessedMemberTypes.All)
            {
                var members = new List <TypeSystemEntity>();
                typeDefinition.GetAllOnType(declaredOnly, members);
                foreach (var m in members)
                {
                    yield return(m);
                }
                yield break;
            }

            var declaredOnlyFlags = declaredOnly ? BindingFlags.DeclaredOnly : BindingFlags.Default;

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: m => m.IsPublic() && m.Signature.Length == 0))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicNestedTypes))
            {
                foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(t);

                    var members = new List <TypeSystemEntity>();
                    t.GetAllOnType(declaredOnly: false, members);
                    foreach (var m in members)
                    {
                        yield return(m);
                    }
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicNestedTypes))
            {
                foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(t);

                    var members = new List <TypeSystemEntity>();
                    t.GetAllOnType(declaredOnly: false, members);
                    foreach (var m in members)
                    {
                        yield return(m);
                    }
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(e);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(e);
                }
            }
        }
Beispiel #3
0
 public MethodParameterValue(int parameterIndex, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberKinds)
 {
     Kind           = ValueNodeKind.MethodParameter;
     ParameterIndex = parameterIndex;
     DynamicallyAccessedMemberKinds = dynamicallyAccessedMemberKinds;
 }
Beispiel #4
0
 public MethodReturnValue(DynamicallyAccessedMemberTypes dynamicallyAccessedMemberKinds)
 {
     Kind = ValueNodeKind.MethodReturn;
     DynamicallyAccessedMemberKinds = dynamicallyAccessedMemberKinds;
 }
Beispiel #5
0
        internal static string GetDynamicallyAccessedMemberTypesDescription(DynamicallyAccessedMemberTypes memberTypes)
        {
            if (memberTypes == DynamicallyAccessedMemberTypes.All)
            {
                return(DynamicallyAccessedMemberTypes.All.ToString());
            }

            var results = new List <DynamicallyAccessedMemberTypes> ();

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicConstructors))
            {
                results.Add(DynamicallyAccessedMemberTypes.NonPublicConstructors);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors))
            {
                results.Add(DynamicallyAccessedMemberTypes.PublicConstructors);
            }
            else if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor))
            {
                results.Add(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicMethods))
            {
                results.Add(DynamicallyAccessedMemberTypes.NonPublicMethods);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicMethods))
            {
                results.Add(DynamicallyAccessedMemberTypes.PublicMethods);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicProperties))
            {
                results.Add(DynamicallyAccessedMemberTypes.NonPublicProperties);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicProperties))
            {
                results.Add(DynamicallyAccessedMemberTypes.PublicProperties);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicFields))
            {
                results.Add(DynamicallyAccessedMemberTypes.NonPublicFields);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicFields))
            {
                results.Add(DynamicallyAccessedMemberTypes.PublicFields);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicEvents))
            {
                results.Add(DynamicallyAccessedMemberTypes.NonPublicEvents);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicEvents))
            {
                results.Add(DynamicallyAccessedMemberTypes.PublicEvents);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicNestedTypes))
            {
                results.Add(DynamicallyAccessedMemberTypes.NonPublicNestedTypes);
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicNestedTypes))
            {
                results.Add(DynamicallyAccessedMemberTypes.PublicNestedTypes);
            }

            if (results.Count == 0)
            {
                return(DynamicallyAccessedMemberTypes.None.ToString());
            }

            return(string.Join(" | ", results.Select(r => r.ToString())));
        }
Beispiel #6
0
 public LoadFieldValue(FieldDefinition fieldToLoad, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberKinds)
 {
     Kind  = ValueNodeKind.LoadField;
     Field = fieldToLoad;
     DynamicallyAccessedMemberKinds = dynamicallyAccessedMemberKinds;
 }
Beispiel #7
0
 public DynamicDependency(DynamicallyAccessedMemberTypes memberTypes, TypeReference type)
 {
     MemberTypes = memberTypes;
     Type        = type;
 }
Beispiel #8
0
 public DynamicDependency(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName)
 {
     MemberTypes  = memberTypes;
     TypeName     = typeName;
     AssemblyName = assemblyName;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="DynamicallyAccessedMembersAttribute"/> class
 /// with the specified member types.
 /// </summary>
 /// <param name="memberTypes">The types of members dynamically accessed.</param>
 public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
 {
     MemberTypes = memberTypes;
 }
Beispiel #10
0
        // Returns the members of the type bound by memberTypes. For DynamicallyAccessedMemberTypes.All, this returns all members of the type and its
        // nested types, including interface implementations, plus the same or any base types or implemented interfaces.
        // DynamicallyAccessedMemberTypes.PublicNestedTypes and NonPublicNestedTypes do the same for members of the selected nested types.
        public static IEnumerable <ISymbol> GetDynamicallyAccessedMembers(this ITypeSymbol typeDefinition, DynamicallyAccessedMemberTypes memberTypes, bool declaredOnly = false)
        {
            if (memberTypes == DynamicallyAccessedMemberTypes.None)
            {
                yield break;
            }

            if (memberTypes == DynamicallyAccessedMemberTypes.All)
            {
                var members = new List <ISymbol> ();
                typeDefinition.GetAllOnType(declaredOnly, members);
                foreach (var m in members)
                {
                    yield return(m);
                }
                yield break;
            }

            var declaredOnlyFlags = declaredOnly ? BindingFlags.DeclaredOnly : BindingFlags.Default;

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: m => (m.DeclaredAccessibility == Accessibility.Public) && m.Parameters.Length == 0))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicNestedTypes))
            {
                foreach (var nested in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(nested);

                    var members = new List <ISymbol> ();
                    nested.GetAllOnType(declaredOnly: false, members);
                    foreach (var m in members)
                    {
                        yield return(m);
                    }
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicNestedTypes))
            {
                foreach (var nested in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(nested);

                    var members = new List <ISymbol> ();
                    nested.GetAllOnType(declaredOnly: false, members);
                    foreach (var m in members)
                    {
                        yield return(m);
                    }
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(e);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(e);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.Interfaces))
            {
                foreach (var i in typeDefinition.GetAllInterfaceImplementations(declaredOnly))
                {
                    yield return(i);
                }
            }
        }
Beispiel #11
0
        public static DynamicallyAccessedMemberTypes GetMissingMemberTypes(DynamicallyAccessedMemberTypes requiredMemberTypes, DynamicallyAccessedMemberTypes availableMemberTypes)
        {
            if (availableMemberTypes.HasFlag(requiredMemberTypes))
            {
                return(DynamicallyAccessedMemberTypes.None);
            }

            if (requiredMemberTypes == DynamicallyAccessedMemberTypes.All)
            {
                return(DynamicallyAccessedMemberTypes.All);
            }

            var missingMemberTypes = requiredMemberTypes & ~availableMemberTypes;

            // PublicConstructors is a special case since its value is 3 - so PublicParameterlessConstructor (1) | _PublicConstructor_WithMoreThanOneParameter_ (2)
            // The above bit logic only works for value with single bit set.
            if (requiredMemberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors) &&
                !availableMemberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors))
            {
                missingMemberTypes |= DynamicallyAccessedMemberTypes.PublicConstructors;
            }

            return(missingMemberTypes);
        }
        public bool Invoke(MethodProxy calledMethod, MultiValue instanceValue, IReadOnlyList <MultiValue> argumentValues, out MultiValue methodReturnValue)
        {
            MultiValue?returnValue = null;

            bool requiresDataFlowAnalysis = MethodRequiresDataFlowAnalysis(calledMethod);
            DynamicallyAccessedMemberTypes returnValueDynamicallyAccessedMemberTypes = requiresDataFlowAnalysis ?
                                                                                       GetReturnValueAnnotation(calledMethod) : 0;

            switch (Intrinsics.GetIntrinsicIdForMethod(calledMethod))
            {
            case IntrinsicId.IntrospectionExtensions_GetTypeInfo:
                Debug.Assert(instanceValue.IsEmpty());
                Debug.Assert(argumentValues.Count == 1);

                // typeof(Foo).GetTypeInfo()... will be commonly present in code targeting
                // the dead-end reflection refactoring. The call doesn't do anything and we
                // don't want to lose the annotation.
                returnValue = argumentValues[0];
                break;

            case IntrinsicId.TypeInfo_AsType:
                // someType.AsType()... will be commonly present in code targeting
                // the dead-end reflection refactoring. The call doesn't do anything and we
                // don't want to lose the annotation.
                returnValue = instanceValue;
                break;

            //
            // UnderlyingSystemType
            //
            case IntrinsicId.Type_get_UnderlyingSystemType:
                // This is identity for the purposes of the analysis.
                returnValue = instanceValue;
                break;

            case IntrinsicId.Type_GetTypeFromHandle:
                // Infrastructure piece to support "typeof(Foo)" in IL and direct calls everywhere
                if (argumentValues[0].IsEmpty())
                {
                    returnValue = MultiValueLattice.Top;
                    break;
                }

                foreach (var value in argumentValues[0])
                {
                    if (value is RuntimeTypeHandleValue typeHandle)
                    {
                        AddReturnValue(new SystemTypeValue(typeHandle.RepresentedType));
                    }
                    else if (value is RuntimeTypeHandleForGenericParameterValue typeHandleForGenericParameter)
                    {
                        AddReturnValue(GetGenericParameterValue(typeHandleForGenericParameter.GenericParameter));
                    }
                    else
                    {
                        AddReturnValue(GetMethodReturnValue(calledMethod, returnValueDynamicallyAccessedMemberTypes));
                    }
                }
                break;

            case IntrinsicId.Type_get_TypeHandle:
                if (instanceValue.IsEmpty())
                {
                    returnValue = MultiValueLattice.Top;
                    break;
                }

                foreach (var value in instanceValue)
                {
                    if (value is SystemTypeValue typeValue)
                    {
                        AddReturnValue(new RuntimeTypeHandleValue(typeValue.RepresentedType));
                    }
                    else if (value is GenericParameterValue genericParameterValue)
                    {
                        AddReturnValue(new RuntimeTypeHandleForGenericParameterValue(genericParameterValue.GenericParameter));
                    }
                    else if (value == NullValue.Instance)
                    {
                        // Throws if the input is null, so no return value.
                        returnValue ??= MultiValueLattice.Top;
                    }
                    else
                    {
                        AddReturnValue(GetMethodReturnValue(calledMethod, returnValueDynamicallyAccessedMemberTypes));
                    }
                }
                break;

            //
            // GetInterface (String)
            // GetInterface (String, bool)
            //
            case IntrinsicId.Type_GetInterface: {
                if (instanceValue.IsEmpty() || argumentValues[0].IsEmpty())
                {
                    returnValue = MultiValueLattice.Top;
                    break;
                }

                var targetValue = GetMethodThisParameterValue(calledMethod, DynamicallyAccessedMemberTypesOverlay.Interfaces);
                foreach (var value in instanceValue)
                {
                    foreach (var interfaceName in argumentValues[0])
                    {
                        if (interfaceName == NullValue.Instance)
                        {
                            // Throws on null string, so no return value.
                            returnValue ??= MultiValueLattice.Top;
                        }
                        else if (interfaceName is KnownStringValue stringValue && stringValue.Contents.Length == 0)
                        {
                            AddReturnValue(NullValue.Instance);
                        }
        // Returns the members of the type bound by memberTypes. For DynamicallyAccessedMemberTypes.All, this returns all members of the type and its
        // nested types, including interface implementations, plus the same or any base types or implemented interfaces.
        // DynamicallyAccessedMemberTypes.PublicNestedTypes and NonPublicNestedTypes do the same for members of the selected nested types.
        public static IEnumerable <IMetadataTokenProvider> GetDynamicallyAccessedMembers(this TypeDefinition typeDefinition, LinkContext context, DynamicallyAccessedMemberTypes memberTypes, bool declaredOnly = false)
        {
            if (memberTypes == DynamicallyAccessedMemberTypes.None)
            {
                yield break;
            }

            if (memberTypes == DynamicallyAccessedMemberTypes.All)
            {
                var members = new List <IMetadataTokenProvider> ();
                typeDefinition.GetAllOnType(context, declaredOnly, members);
                foreach (var m in members)
                {
                    yield return(m);
                }
                yield break;
            }

            var declaredOnlyFlags = declaredOnly ? BindingFlags.DeclaredOnly : BindingFlags.Default;

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor))
            {
                foreach (var c in typeDefinition.GetConstructorsOnType(filter: m => m.IsPublic && m.Parameters.Count == 0))
                {
                    yield return(c);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicMethods))
            {
                foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(m);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicFields))
            {
                foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(f);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicNestedTypes))
            {
                foreach (var nested in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
                {
                    yield return(nested);

                    var members = new List <IMetadataTokenProvider> ();
                    nested.GetAllOnType(context, declaredOnly: false, members);
                    foreach (var m in members)
                    {
                        yield return(m);
                    }
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicNestedTypes))
            {
                foreach (var nested in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public))
                {
                    yield return(nested);

                    var members = new List <IMetadataTokenProvider> ();
                    nested.GetAllOnType(context, declaredOnly: false, members);
                    foreach (var m in members)
                    {
                        yield return(m);
                    }
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicProperties))
            {
                foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(p);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
                {
                    yield return(e);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicEvents))
            {
                foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags))
                {
                    yield return(e);
                }
            }

            if (memberTypes.HasFlag(DynamicallyAccessedMemberTypesOverlay.Interfaces))
            {
                foreach (var i in typeDefinition.GetAllInterfaceImplementations(context, declaredOnly))
                {
                    yield return(i);
                }
            }
        }