Ejemplo n.º 1
0
        List <IMethod> GetMethods(TypeDef declaringType, BabelMethodreference babelMethodRef)
        {
            var methods = new List <IMethod>();

            var gis = babelMethodRef.DeclaringType as GenericInstSig;
            var gim = babelMethodRef.GenericArguments;

            foreach (var method in declaringType.Methods)
            {
                if (CompareMethod(GenericArgsSubstitutor.Create(method, gis, gim), babelMethodRef))
                {
                    if (!babelMethodRef.IsGenericMethod)
                    {
                        methods.Add(memberRefConverter.Convert(method));
                    }
                    else
                    {
                        var gim2 = new GenericInstMethodSig(babelMethodRef.GenericArguments);
                        var ms   = module.UpdateRowId(new MethodSpecUser(memberRefConverter.Convert(method), gim2));
                        methods.Add(ms);
                    }
                }
            }

            return(methods);
        }
Ejemplo n.º 2
0
 public void InitializeFrom(MethodInstances other, GenericInstSig git)
 {
     foreach (var list in other.methodInstances.Values)
     {
         foreach (var methodInst in list)
         {
             var newMethod = GenericArgsSubstitutor.Create(methodInst.methodRef, git);
             Add(new MethodInst(methodInst.origMethodDef, newMethod));
         }
     }
 }
Ejemplo n.º 3
0
        public MethodBase Resolve(IMethod methodRef)
        {
            InitMethods();

            if (!methods.TryGetValue(methodRef.Name.String, out var list))
            {
                return(null);
            }

            methodRef = GenericArgsSubstitutor.Create(methodRef, methodRef.DeclaringType.TryGetGenericInstSig());

            foreach (var method in list)
            {
                if (ResolverUtils.CompareMethods(method, methodRef))
                {
                    return(method);
                }
            }

            return(null);
        }
Ejemplo n.º 4
0
        public FieldInfo Resolve(IField fieldRef)
        {
            InitFields();

            if (!fields.TryGetValue(fieldRef.Name.String, out var list))
            {
                return(null);
            }

            fieldRef = GenericArgsSubstitutor.Create(fieldRef, fieldRef.DeclaringType.TryGetGenericInstSig());

            foreach (var field in list)
            {
                if (ResolverUtils.CompareFields(field, fieldRef))
                {
                    return(field);
                }
            }

            return(null);
        }
Ejemplo n.º 5
0
        void InitializeInterfaceMethods(MethodNameGroups groups)
        {
            InitializeAllInterfaces();

            if (TypeDef.IsInterface)
            {
                return;
            }

            //--- Partition II 12.2 Implementing virtual methods on interfaces:
            //--- The VES shall use the following algorithm to determine the appropriate
            //--- implementation of an interface's virtual abstract methods:
            //---
            //--- * If the base class implements the interface, start with the same virtual methods
            //---	that it provides; otherwise, create an interface that has empty slots for all
            //---	virtual functions.
            // Done. See initializeAllInterfaces().

            var methodsDict = new Dictionary <IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.DontCompareDeclaringTypes);

            //--- * If this class explicitly specifies that it implements the interface (i.e., the
            //---	interfaces that appear in this class‘ InterfaceImpl table, §22.23)
            //---	* If the class defines any public virtual newslot methods whose name and
            //---	  signature match a virtual method on the interface, then use these new virtual
            //---	  methods to implement the corresponding interface method.
            if (interfaces.Count > 0)
            {
                methodsDict.Clear();
                foreach (var method in methods.GetValues())
                {
                    if (!method.IsPublic() || !method.IsVirtual() || !method.IsNewSlot())
                    {
                        continue;
                    }
                    methodsDict[method.MethodDef] = method;
                }

                foreach (var ifaceInfo in interfaces)
                {
                    foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.GetMethods())
                    {
                        if (methodsList.Count < 1)
                        {
                            continue;
                        }
                        var methodInst  = methodsList[0];
                        var ifaceMethod = methodInst.origMethodDef;
                        if (!ifaceMethod.IsVirtual())
                        {
                            continue;
                        }
                        var        ifaceMethodRef = GenericArgsSubstitutor.Create(methodInst.methodRef, ifaceInfo.typeRef.TryGetGenericInstSig());
                        MMethodDef classMethod;
                        if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod))
                        {
                            continue;
                        }
                        interfaceMethodInfos.AddMethod(ifaceInfo, ifaceMethod, classMethod);
                    }
                }
            }

            //--- * If there are any virtual methods in the interface that still have empty slots,
            //---	see if there are any public virtual methods, but not public virtual newslot
            //---	methods, available on this class (directly or inherited) having the same name
            //---	and signature, then use these to implement the corresponding methods on the
            //---	interface.
            methodsDict.Clear();
            foreach (var methodInstList in virtualMethodInstances.GetMethods())
            {
                // This class' method is at the end
                for (int i = methodInstList.Count - 1; i >= 0; i--)
                {
                    var classMethod = methodInstList[i];
                    // These methods are guaranteed to be virtual.
                    // We should allow newslot methods, despite what the official doc says.
                    if (!classMethod.origMethodDef.IsPublic())
                    {
                        continue;
                    }
                    methodsDict[classMethod.methodRef] = classMethod.origMethodDef;
                    break;
                }
            }
            foreach (var ifaceInfo in allImplementedInterfaces.Keys)
            {
                foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.GetMethods())
                {
                    if (methodsList.Count < 1)
                    {
                        continue;
                    }
                    var ifaceMethod = methodsList[0].origMethodDef;
                    if (!ifaceMethod.IsVirtual())
                    {
                        continue;
                    }
                    var        ifaceMethodRef = GenericArgsSubstitutor.Create(ifaceMethod.MethodDef, ifaceInfo.typeRef.TryGetGenericInstSig());
                    MMethodDef classMethod;
                    if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod))
                    {
                        continue;
                    }
                    interfaceMethodInfos.AddMethodIfEmpty(ifaceInfo, ifaceMethod, classMethod);
                }
            }

            //--- * Apply all MethodImpls that are specified for this class, thereby placing
            //---	explicitly specified virtual methods into the interface in preference to those
            //---	inherited or chosen by name matching.
            methodsDict.Clear();
            var ifaceMethodsDict = new Dictionary <IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.CompareDeclaringTypes);

            foreach (var ifaceInfo in allImplementedInterfaces.Keys)
            {
                var git = ifaceInfo.typeRef.TryGetGenericInstSig();
                foreach (var ifaceMethod in ifaceInfo.typeDef.methods.GetValues())
                {
                    IMethodDefOrRef ifaceMethodRef = ifaceMethod.MethodDef;
                    if (git != null)
                    {
                        ifaceMethodRef = SimpleClone(ifaceMethod.MethodDef, ifaceInfo.typeRef);
                    }
                    ifaceMethodsDict[ifaceMethodRef] = ifaceMethod;
                }
            }
            foreach (var classMethod in methods.GetValues())
            {
                if (!classMethod.IsVirtual())
                {
                    continue;
                }
                foreach (var overrideMethod in classMethod.MethodDef.Overrides)
                {
                    MMethodDef ifaceMethod;
                    if (!ifaceMethodsDict.TryGetValue(overrideMethod.MethodDeclaration, out ifaceMethod))
                    {
                        // We couldn't find the interface method (eg. interface not resolved) or
                        // it overrides a base class method, and not an interface method.
                        continue;
                    }

                    interfaceMethodInfos.AddMethod(overrideMethod.MethodDeclaration.DeclaringType, ifaceMethod, classMethod);
                }
            }

            //--- * If the current class is not abstract and there are any interface methods that
            //---	still have empty slots, then the program is invalid.
            // Check it anyway. C# requires a method, even if it's abstract. I don't think anyone
            // writes pure CIL assemblies.
            foreach (var info in interfaceMethodInfos.AllInfos)
            {
                foreach (var pair in info.IfaceMethodToClassMethod)
                {
                    if (pair.Value != null)
                    {
                        continue;
                    }
                    if (!ResolvedAllInterfaces() || !ResolvedBaseClasses())
                    {
                        continue;
                    }
                    // Ignore if COM class
                    if (!TypeDef.IsImport &&
                        !HasAttribute("System.Runtime.InteropServices.ComImportAttribute") &&
                        !HasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute"))
                    {
                        Logger.w("Could not find interface method {0} ({1:X8}). Type: {2} ({3:X8})",
                                 Utils.RemoveNewlines(pair.Key.methodDef.MethodDef),
                                 pair.Key.methodDef.MethodDef.MDToken.ToInt32(),
                                 Utils.RemoveNewlines(TypeDef),
                                 TypeDef.MDToken.ToInt32());
                    }
                }
            }

            foreach (var info in interfaceMethodInfos.AllInfos)
            {
                foreach (var pair in info.IfaceMethodToClassMethod)
                {
                    if (pair.Value == null)
                    {
                        continue;
                    }
                    if (pair.Key.methodDef.MethodDef.Name != pair.Value.MethodDef.Name)
                    {
                        continue;
                    }
                    groups.Same(pair.Key.methodDef, pair.Value);
                }
            }
        }
Ejemplo n.º 6
0
 public TypeInfo(TypeInfo other, GenericInstSig git)
 {
     this.typeRef = GenericArgsSubstitutor.Create(other.typeRef, git);
     this.typeDef = other.typeDef;
 }