private IReadOnlyList <ScriptExportProperty> CreateProperties(IScriptExportManager manager)
        {
            if (Definition == null || Definition.BaseType == null || Definition.BaseType.Module == null)
            {
                return(Array.Empty <ScriptExportProperty>());
            }

            // we need to export only such properties that are declared as asbtract inside builin assemblies
            // and not overridden anywhere except current type
            List <PropertyDefinition> overrides = new List <PropertyDefinition>();

            foreach (PropertyDefinition property in Definition.Properties)
            {
                MethodDefinition method = property.GetMethod == null ? property.SetMethod : property.GetMethod;
                if (method.IsVirtual && method.IsReuseSlot)
                {
                    overrides.Add(property);
                }
            }

            List <ScriptExportProperty> properties = new List <ScriptExportProperty>();
            MonoTypeContext             context    = new MonoTypeContext(Definition);
            TypeDefinition definition = Definition;

            while (true)
            {
                if (overrides.Count == 0)
                {
                    break;
                }
                if (definition.BaseType == null || definition.BaseType.Module == null)
                {
                    break;
                }

                context    = context.GetBase();
                definition = context.Type.Resolve();
                if (definition == null)
                {
                    break;
                }

                string module    = GetModuleName(context.Type);
                bool   isBuiltIn = ScriptExportManager.IsBuiltinLibrary(module);
                foreach (PropertyDefinition property in definition.Properties)
                {
                    MethodDefinition method = property.GetMethod == null ? property.SetMethod : property.GetMethod;
                    if (method.IsVirtual && (method.IsNewSlot || method.IsReuseSlot))
                    {
                        for (int i = 0; i < overrides.Count; i++)
                        {
                            PropertyDefinition @override = overrides[i];
                            if (@override.Name == property.Name)
                            {
                                if (isBuiltIn && method.IsAbstract)
                                {
                                    ScriptExportProperty exportProperty = manager.RetrieveProperty(@override);
                                    properties.Add(exportProperty);
                                }

                                overrides.RemoveAt(i);
                                break;
                            }
                        }
                    }
                }
            }
            return(properties.ToArray());
        }
Example #2
0
        public static bool AreSame(MethodDefinition method, MonoTypeContext checkContext, MethodDefinition checkMethod)
        {
            if (method.Name != checkMethod.Name)
            {
                return(false);
            }
            if (method.HasGenericParameters)
            {
                if (!checkMethod.HasGenericParameters)
                {
                    return(false);
                }
                if (method.GenericParameters.Count != checkMethod.GenericParameters.Count)
                {
                    return(false);
                }
                checkContext = checkContext.Merge(checkMethod);
            }
            if (!AreSame(method.ReturnType, checkContext, checkMethod.ReturnType))
            {
                return(false);
            }

            if (method.IsVarArg())
            {
                if (!checkMethod.IsVarArg())
                {
                    return(false);
                }
                if (method.Parameters.Count >= checkMethod.Parameters.Count)
                {
                    return(false);
                }
                if (checkMethod.GetSentinelPosition() != method.Parameters.Count)
                {
                    return(false);
                }
            }

            if (method.HasParameters)
            {
                if (!checkMethod.HasParameters)
                {
                    return(false);
                }
                if (method.Parameters.Count != checkMethod.Parameters.Count)
                {
                    return(false);
                }

                for (int i = 0; i < method.Parameters.Count; i++)
                {
                    if (!AreSame(method.Parameters[i].ParameterType, checkContext, checkMethod.Parameters[i].ParameterType))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        private IReadOnlyList <ScriptExportMethod> CreateMethods(IScriptExportManager manager)
        {
            if (Definition == null || Definition.BaseType == null)
            {
                return(Array.Empty <ScriptExportMethod>());
            }

            // we need to export only such methods that are declared as abstract inside builtin assemblies
            // and not overridden anywhere except current type
            List <ScriptExportMethod> methods   = new List <ScriptExportMethod>();
            List <MethodDefinition>   overrides = new List <MethodDefinition>();

            foreach (MethodDefinition method in Definition.Methods)
            {
                if (method.IsVirtual && method.IsReuseSlot && !method.IsGetter && !method.IsSetter)
                {
                    overrides.Add(method);
                }
            }

            TypeDefinition  definition = Definition;
            MonoTypeContext context    = new MonoTypeContext(Definition);

            while (true)
            {
                if (overrides.Count == 0)
                {
                    break;
                }
                if (definition.BaseType == null || definition.BaseType.Module == null)
                {
                    break;
                }

                context    = context.GetBase();
                definition = context.Type.Resolve();
                if (definition == null)
                {
                    break;
                }

                string module    = GetModuleName(definition);
                bool   isBuiltIn = ScriptExportManager.IsBuiltinLibrary(module);
                IReadOnlyDictionary <GenericParameter, TypeReference> arguments = context.GetContextArguments();
                // definition is a Template for GenericInstance, so we must recreate context
                MonoTypeContext definitionContext = new MonoTypeContext(definition, arguments);
                foreach (MethodDefinition method in definition.Methods)
                {
                    if (method.IsVirtual && (method.IsNewSlot || method.IsReuseSlot))
                    {
                        for (int i = 0; i < overrides.Count; i++)
                        {
                            MethodDefinition @override = overrides[i];
                            if (MonoUtils.AreSame(@override, definitionContext, method))
                            {
                                if (isBuiltIn && method.IsAbstract)
                                {
                                    ScriptExportMethod exportMethod = manager.RetrieveMethod(@override);
                                    methods.Add(exportMethod);
                                }

                                overrides.RemoveAt(i);
                                break;
                            }
                        }
                    }
                }
            }
            return(methods.ToArray());
        }