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()); }
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()); }