コード例 #1
0
        private static void SetupOverwriteReferences(INameService service, ICollection <ModuleDefMD> modules, VTableSlot slot, TypeDef thisType)
        {
            var module        = thisType.Module;
            var methodDef     = slot.MethodDef;
            var baseSlot      = slot.Overrides;
            var baseMethodDef = baseSlot.MethodDef;

            var overrideRef = new OverrideDirectiveReference(slot, baseSlot);

            service.AddReference(methodDef, overrideRef);
            service.AddReference(slot.Overrides.MethodDef, overrideRef);

            var importer = new Importer(module, ImporterOptions.TryToUseTypeDefs);

            IMethodDefOrRef target;

            if (baseSlot.MethodDefDeclType is GenericInstSig declType)
            {
                MemberRef targetRef = new MemberRefUser(module, baseMethodDef.Name, baseMethodDef.MethodSig, declType.ToTypeDefOrRef());
                targetRef = importer.Import(targetRef);
                service.AddReference(baseMethodDef, new MemberRefReference(targetRef, baseMethodDef));
                SetupSignatureReferences(service, modules, module, targetRef.DeclaringType.ToTypeSig() as GenericInstSig);

                target = targetRef;
            }
            else
            {
                target = baseMethodDef;
                if (target.Module != module)
                {
                    target = (IMethodDefOrRef)importer.Import(baseMethodDef);
                    if (target is MemberRef memberRef)
                    {
                        service.AddReference(baseMethodDef, new MemberRefReference(memberRef, baseMethodDef));
                    }
                }
            }

            if (target is MemberRef methodRef)
            {
                AddImportReference(service, modules, module, baseMethodDef, methodRef);
            }

            if (TypeEqualityComparer.Instance.Equals(methodDef.DeclaringType, thisType))
            {
                if (methodDef.Overrides.Any(impl => IsMatchingOverride(impl, target)))
                {
                    return;
                }

                methodDef.Overrides.Add(new MethodOverride(methodDef, target));
            }
            else if (target is IMemberDef targetDef)
            {
                CreateOverrideReference(service, methodDef, targetDef);
            }
        }
コード例 #2
0
        private static void SetupOverwriteReferences(ConfuserContext context, INameService service, VTableSlot slot, ModuleDef module)
        {
            var methodDef     = slot.MethodDef;
            var baseSlot      = slot.Overrides;
            var baseMethodDef = baseSlot.MethodDef;

            var overrideRef = new OverrideDirectiveReference(slot, baseSlot);

            service.AddReference(methodDef, overrideRef);
            service.AddReference(slot.Overrides.MethodDef, overrideRef);

            var importer = new Importer(module, ImporterOptions.TryToUseTypeDefs);

            IMethod target;

            if (baseSlot.MethodDefDeclType is GenericInstSig declType)
            {
                var       signature = SetupSignatureReferences(context, service, module, declType);
                MemberRef targetRef = new MemberRefUser(module, baseMethodDef.Name, baseMethodDef.MethodSig, signature.ToTypeDefOrRef());
                targetRef = importer.Import(targetRef);
                service.AddReference(baseMethodDef, new MemberRefReference(targetRef, baseMethodDef));

                target = targetRef;
            }
            else
            {
                target = baseMethodDef;
                if (target.Module != module)
                {
                    target = importer.Import(baseMethodDef);
                    if (target is MemberRef memberRef)
                    {
                        service.AddReference(baseMethodDef, new MemberRefReference(memberRef, baseMethodDef));
                    }
                }
            }

            target.MethodSig = importer.Import(methodDef.MethodSig);
            if (target is MemberRef methodRef)
            {
                AddImportReference(context, service, module, baseMethodDef, methodRef);
            }

            if (methodDef.Overrides.Any(impl =>
                                        new SigComparer().Equals(impl.MethodDeclaration.MethodSig, target.MethodSig) &&
                                        new SigComparer().Equals(impl.MethodDeclaration.DeclaringType.ResolveTypeDef(), target.DeclaringType.ResolveTypeDef())))
            {
                return;
            }

            methodDef.Overrides.Add(new MethodOverride(methodDef, (IMethodDefOrRef)target));
        }
コード例 #3
0
ファイル: VTableAnalyzer.cs プロジェクト: jiargcn/ConfuserEx
        private static void SetupOverwriteReferences(INameService service, ICollection <ModuleDefMD> modules, VTableSlot slot, TypeDef thisType)
        {
            var module        = thisType.Module;
            var methodDef     = slot.MethodDef;
            var baseSlot      = slot.Overrides;
            var baseMethodDef = baseSlot.MethodDef;

            var overrideRef = new OverrideDirectiveReference(slot, baseSlot);

            service.AddReference(methodDef, overrideRef);
            service.AddReference(slot.Overrides.MethodDef, overrideRef);

            var importer = new Importer(module, ImporterOptions.TryToUseTypeDefs);

            IMethodDefOrRef target;

            if (baseSlot.MethodDefDeclType is GenericInstSig declType)
            {
                MemberRef targetRef = new MemberRefUser(module, baseMethodDef.Name, baseMethodDef.MethodSig, declType.ToTypeDefOrRef());
                targetRef = importer.Import(targetRef);
                service.AddReference(baseMethodDef, new MemberRefReference(targetRef, baseMethodDef));
                SetupSignatureReferences(service, modules, module, targetRef.DeclaringType.ToTypeSig() as GenericInstSig);

                target = targetRef;
            }
            else
            {
                target = baseMethodDef;
                if (target.Module != module)
                {
                    target = (IMethodDefOrRef)importer.Import(baseMethodDef);
                    if (target is MemberRef memberRef)
                    {
                        service.AddReference(baseMethodDef, new MemberRefReference(memberRef, baseMethodDef));
                    }
                }
            }

            if (target is MemberRef methodRef)
            {
                AddImportReference(service, modules, module, baseMethodDef, methodRef);
            }

            if (TypeEqualityComparer.Instance.Equals(methodDef.DeclaringType, thisType))
            {
                if (methodDef.Overrides.Any(impl => IsMatchingOverride(impl, target)))
                {
                    return;
                }

                methodDef.Overrides.Add(new MethodOverride(methodDef, target));
            }
            else if (target is IMemberDef targetDef)
            {
                // Reaching this place means that a slot of the base type is overwritten by a specific interface.
                // In case the this type is implementing the interface responsible for this, we need to declare
                // this as an override reference. If the base type is implementing the interface (as well), this
                // declaration is redundant.
                var overrideRefRequired = true;
                if (targetDef.DeclaringType.IsInterface)
                {
                    var baseTypeDef = thisType.BaseType?.ResolveTypeDef();
                    if (!(baseTypeDef is null))
                    {
                        var baseTypeVTable = service.GetVTables()[baseTypeDef];
                        if (baseTypeVTable.InterfaceSlots.TryGetValue(targetDef.DeclaringType.ToTypeSig(), out var ifcSlots))
                        {
                            overrideRefRequired = !ifcSlots.Contains(slot);
                        }
                    }
                }
                if (overrideRefRequired)
                {
                    CreateOverrideReference(service, methodDef, targetDef);
                }
            }
        }