Exemplo n.º 1
0
    public override void Execute()
    {
        Imports = new Imports(FindType, ModuleDefinition, this);

        try
        {
            TypeDefinition unusedType = CreateUnusedType();
            ModuleDefinition.Types.Add(unusedType);

            var assemblyNames = new HashSet <string>();
            var mappedTypes   = new List <TypeMap>();
            foreach (TypeDefinition type in ModuleDefinition.GetAllTypes())
            {
                TypeDefinition mirrorType = ProcessMirrorType(type, unusedType);
                if (mirrorType != null)
                {
                    mappedTypes.Add(new TypeMap(type, mirrorType));
                }
            }

            foreach (TypeMap typeMap in mappedTypes)
            {
                FieldDefinition instanceField = typeMap.ExternType.GetInstanceField();

                foreach (MethodDefinition externMethod in typeMap.ExternType.Methods.Where(x => x.IsExtern() && x.Parameters.All(p => p.ParameterType.FullName != unusedType.FullName)))
                {
                    if (externMethod.IsGetter || externMethod.IsSetter)
                    {
                        PropertyDefinition externProperty = typeMap.ExternType.Properties.Single(p =>
                                                                                                 p.GetMethod == externMethod || p.SetMethod == externMethod);
                        string             mirrorTargetName = externProperty.GetMirrorTargetName();
                        PropertyDefinition mirroredProperty = GetMirroredProperty(typeMap.MirrorType, externMethod, mirrorTargetName);
                        if (mirroredProperty != null)
                        {
                            try
                            {
                                ForwardMethodToProperty(externMethod, mirroredProperty, instanceField, unusedType);
                                assemblyNames.Add(mirroredProperty.Module.Assembly.Name.Name);
                            }
                            catch
                            {
                                LogError($"Error in {mirroredProperty.Name} {externMethod.Name}");
                                throw;
                            }
                        }
                        else
                        {
                            FieldDefinition mirroredField = GetMirroredField(typeMap.MirrorType, externMethod,
                                                                             externProperty.PropertyType, mirrorTargetName);
                            if (mirroredField != null)
                            {
                                ForwardMethodToField(externMethod, ModuleDefinition.ImportReference(mirroredField), instanceField, unusedType);
                                assemblyNames.Add(mirroredField.Module.Assembly.Name.Name);
                            }
                            else
                            {
                                LogError($"Could not find mirrored property or field {typeMap.MirrorType.FullName}.{mirrorTargetName}");
                            }
                        }
                    }
                    else
                    {
                        MethodDefinition mirroredMethod = GetMirroredMethod(typeMap.MirrorType, externMethod);
                        if (mirroredMethod != null)
                        {
                            ForwardMethodToMethod(ModuleDefinition.ImportReference(mirroredMethod),
                                                  externMethod, instanceField, unusedType);

                            assemblyNames.Add(mirroredMethod.Module.Assembly.Name.Name);
                        }
                        else
                        {
                            string parameters = string.Join(", ",
                                                            externMethod.Parameters.Select(p => p.ParameterType.Resolve().GetMirrorTargetName()));
                            LogError($"Could not find mirrored method {typeMap.MirrorType.FullName}.{externMethod.GetMirrorTargetName()}({parameters})");
                        }
                    }
                }
            }

            TypeDefinition  ignoreChecksAttribute = GetIgnoresAccessChecksToAttribute();
            MethodReference attributeCtor         = ignoreChecksAttribute.GetConstructors()
                                                    .Single(c => c.Parameters.Count == 1 && c.Parameters[0].ParameterType.FullName == typeof(string).FullName);

            foreach (var assembly in assemblyNames)
            {
                byte[] blob = GetAttributeBlob(assembly).ToArray();
                ModuleDefinition.Assembly.CustomAttributes.Add(new CustomAttribute(attributeCtor, blob));
            }
        }
        catch (Exception e)
        {
            LogError(e.ToString());
        }
    }