public static MethodInfo GetKeySourceMethodInfo(this Type rootType, AssetDictionaryAttribute attribute) { if (attribute.UseAssetFileNameAsKey) { return(GetFileNameAsKey(rootType)); } var methodInfo = GetPropertyKeySourceMethodInfo(rootType, attribute, allowGeneral: false); if (methodInfo != null) { return(methodInfo); } methodInfo = GetCustomKeySourceMethodInfo(rootType, attribute, allowGeneral: false); if (methodInfo != null) { return(methodInfo); } methodInfo = GetPropertyKeySourceMethodInfo(rootType, attribute, allowGeneral: true); if (methodInfo != null) { return(methodInfo); } methodInfo = GetCustomKeySourceMethodInfo(rootType, attribute, allowGeneral: true); if (methodInfo != null) { return(methodInfo); } return(default(MethodInfo)); }
private static MethodInfo GetPropertyKeySourceMethodInfo(Type rootType, AssetDictionaryAttribute attribute, bool allowGeneral) { foreach (var propertyInfo in rootType.GetProperties()) { var propertyAttributes = propertyInfo.Get <DictionaryKeyAttribute>().ToArray(); if (propertyAttributes.Length == 0) { continue; } foreach (var propertyAttribute in propertyAttributes) { if (!propertyInfo.CanRead) { LogUtils.Error($"Property {propertyInfo.Name} is not readable and have {nameof(DictionaryKeyAttribute)}. It will be ignored."); continue; } if (allowGeneral && string.IsNullOrEmpty(propertyAttribute.GroupName)) { return(propertyInfo.GetGetMethod()); } if (propertyAttribute.GroupName == attribute.Group) { return(propertyInfo.GetGetMethod()); } } } return(null); }
protected Type GetKeyType(Type rootType, AssetDictionaryAttribute attribute) { if (attribute.IsSingleFile) { return(attribute.KeyType); } return(GetKeySourceMethodInfo(rootType, attribute) ?.ReturnType); }
private static MethodInfo GetCustomKeySourceMethodInfo(Type rootType, AssetDictionaryAttribute attribute, bool allowGeneral) { var keySourceType = attribute.KeySourceType ?? rootType; foreach (var methodInfo in keySourceType.GetMethods(BindingFlags.Static | BindingFlags.Public)) { foreach (var methodAttribute in methodInfo.Get <DictionaryKeySourceAttribute>()) { if (methodAttribute == null) { continue; } if (!allowGeneral && methodAttribute.Group != attribute.Group) { continue; } var parameters = methodInfo.GetParameters(); if (parameters.Length < 1 && parameters.Length > 2) { continue; } if (parameters.Length == 1 && parameters[0].ParameterType != rootType) { LogUtils.Error($"Method {methodInfo.Name} is not valid for selecting keys! Type {rootType.Name} is not assignable from param type {parameters[0].ParameterType.Name}."); continue; } var isValid = true; foreach (var parameterInfo in parameters) { if (parameterInfo.ParameterType != rootType && parameterInfo.ParameterType != typeof(TextAsset)) { LogUtils.Error($"Method {methodInfo.Name} is not valid for selecting keys! Method have invalid param type {parameterInfo.ParameterType}"); isValid = false; } } if (!isValid) { continue; } return(methodInfo); } } return(null); }
public static Type GetDictionaryKeyType(this Type rootType, AssetDictionaryAttribute a) { if (a == null) { return(null); } return(a.IsSingleFile ? a.KeyType : rootType.GetKeySourceMethodInfo(a)?.ReturnType); }
public void DictionaryStorageTypeContent(RootDefinition root, string storageTypeName, AssetDictionaryAttribute attribute) { var keyType = GetKeyType(root.Root, attribute); var valueType = root.Root; var dictionaryType = typeof(Dictionary <,>).MakeGenericType(keyType, valueType); var proxyDictionaryTypeName = GetTypeName(dictionaryType, true); var originDictionaryTypeName = GetTypeName(dictionaryType, false); GenericFieldDeclaration(proxy, proxyDictionaryTypeName, false, true); GenericFieldDeclaration(cache, originDictionaryTypeName, false, false); var originToProxy = GetTypeConversion(dictionaryType, "value", true); var proxyToOrigin = GetTypeConversion(dictionaryType, proxy, false); const string format = @" public <#=originDictionaryTypeName#> Value { get { <#=cache#> = <#=proxyToOrigin#>; return <#=cache#>; } set { <#=proxy#> = <#=originToProxy#>; <#=cache#> = value; } } public static implicit operator <#=originDictionaryTypeName#>(<#=storageTypeName#> storage) { return storage == null ? default(<#=originDictionaryTypeName#>) : storage.Value; } "; _stringBuilder .AppendLine() .Append(new StringBuilder(format) .Replace("<#=originDictionaryTypeName#>", originDictionaryTypeName) .Replace("<#=storageTypeName#>", storageTypeName) .Replace("<#=cache#>", cache) .Replace("<#=proxy#>", proxy) .Replace("<#=proxyToOrigin#>", proxyToOrigin) .Replace("<#=originToProxy#>", originToProxy)) .AppendLine(); foreach (var pair in DictionaryProxyGenericArguments) { DictionaryType(pair.Key, pair.Value); } }
protected static MethodInfo GetKeySourceMethodInfo(Type rootType, AssetDictionaryAttribute attribute) { foreach (var propertyInfo in rootType.GetProperties()) { if (!propertyInfo.CanRead) { continue; } var propertyAttributes = propertyInfo.Get <DictionaryKeyAttribute>().ToArray(); if (propertyAttributes.Length == 0) { continue; } if (propertyAttributes.Length == 1) { var propertyAttribute = propertyAttributes[0]; if (propertyAttribute.GroupName == null || propertyAttribute.GroupName == attribute.Group) { return(propertyInfo.GetGetMethod()); } } else { if (propertyAttributes.Any(a => a.GroupName == attribute.Group)) { return(propertyInfo.GetGetMethod()); } } } var keySourceType = attribute.KeySourceType ?? rootType; foreach (var methodInfo in keySourceType.GetMethods(BindingFlags.Static | BindingFlags.Public)) { var methodAttribute = methodInfo.GetSingle <DictionaryKeySourceAttribute>(); if (methodAttribute == null) { continue; } var parameters = methodInfo.GetParameters(); if (parameters.Length < 1 && parameters.Length > 2) { continue; } var isValid = true; foreach (var parameterInfo in parameters) { if (parameterInfo.ParameterType != rootType && parameterInfo.ParameterType != typeof(string)) { isValid = false; } } if (!isValid) { continue; } return(methodInfo); } return(default(MethodInfo)); }