示例#1
0
        protected string GetStorageTypeName(Type rootType, AssetDeclarationAttributeBase attribute)
        {
            var groupName = CodeGenerationUtility.GetGroupName(attribute.Group);
            var typeName  = GetShortTypeName(GetTypeName(rootType, false));

            return($"{groupName}{typeName}Storage");
        }
        private CodeSnippetCompileUnit GenerateValidateMethods()
        {
            var sourceCode = new StringBuilder();

            sourceCode.AppendLine("using UnityEditor;");
            sourceCode.AppendLine("using Yamly.UnityEditor;");
            sourceCode.AppendLine($"namespace {TargetNamespace}");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("    public static class ValidateYamlyGeneratedUtility");
            sourceCode.AppendLine("{");
            foreach (var group in _groups.Where(CodeGenerationUtility.IsValidGroupName))
            {
                var groupName = CodeGenerationUtility.GetGroupName(group);
                sourceCode.AppendLine($"[MenuItem(\"Yamly/Validate/{group}\")]");
                sourceCode.AppendLine($"public static void Validate{groupName}()");
                sourceCode.AppendLine("{");
                sourceCode.AppendLine($"YamlyAssetPostprocessor.Validate(\"{group}\");");
                sourceCode.AppendLine("}");
            }

            sourceCode.AppendLine("}");
            sourceCode.AppendLine("}");

            return(new CodeSnippetCompileUnit(sourceCode.ToString()));
        }
        public UtilityAssemblyBuilder Build()
        {
            _compilerParameters.GenerateExecutable = false;
            _compilerParameters.GenerateInMemory   = false;
            _compilerParameters.ReferencedAssemblies.Add(typeof(YamlyAssetPostprocessor).Assembly.Location.ToUnityPath());
            _compilerParameters.ReferencedAssemblies.Add(CodeGenerationUtility.GetUnityEngineAssemblyPath());
            _compilerParameters.ReferencedAssemblies.Add(CodeGenerationUtility.GetUnityEditorAssemblyPath());

            var codeProvider = new CSharpCodeProvider();

            CompilerResults = codeProvider.CompileAssemblyFromDom(_compilerParameters,
                                                                  GenerateValidateMethods(),
                                                                  GenerateRebuildMethods());

            return(this);
        }
示例#4
0
        private CodeCompileUnit GenerateEnum()
        {
            var sourceCode = new StringBuilder();

            var groups = _proxyCodeGenerator.RootDefinitions.SelectMany(r => r.Attributes)
                         .Select(a => a.Group)
                         .Distinct()
                         .Where(CodeGenerationUtility.IsValidGroupName)
                         .ToArray();

            sourceCode.AppendLine($"namespace {TargetNamespace}");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("public enum Assets");
            sourceCode.AppendLine("{");
            for (var i = 0; i < groups.Length; i++)
            {
                sourceCode.Append(CodeGenerationUtility.GetGroupName(groups[i])).AppendLine(",");
            }

            sourceCode.AppendLine("}");

            sourceCode.AppendLine("public static class AssetsExtensions");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("public static string ToGroupName(this Assets assets)");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("switch(assets)");
            sourceCode.AppendLine("{");
            foreach (var group in groups)
            {
                var groupName = CodeGenerationUtility.GetGroupName(group);
                sourceCode.AppendLine($"case Assets.{groupName}:");
                sourceCode.AppendLine($"return \"{group}\";");
            }

            sourceCode.AppendLine("default: throw new System.NotSupportedException(assets.ToString());");
            sourceCode.AppendLine("}");
            sourceCode.AppendLine("}");
            sourceCode.AppendLine("}");

            sourceCode.AppendLine("}");

            return(new CodeSnippetCompileUnit(sourceCode.ToString()));
        }
示例#5
0
        private CodeCompileUnit GenerateEnum()
        {
            var sourceCode = new StringBuilder();

            var groups = Context.Groups;

            sourceCode.AppendLine($"namespace {TargetNamespace}");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("public enum Assets");
            sourceCode.AppendLine("{");
            for (var i = 0; i < groups.Count; i++)
            {
                sourceCode.Append(CodeGenerationUtility.GetGroupName(groups[i])).AppendLine(",");
            }

            sourceCode.AppendLine("}");

            sourceCode.AppendLine("public static class AssetsExtensions");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("public static string ToGroupName(this Assets assets)");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("switch(assets)");
            sourceCode.AppendLine("{");
            foreach (var group in groups)
            {
                var groupName = CodeGenerationUtility.GetGroupName(group);
                sourceCode.AppendLine($"case Assets.{groupName}:");
                sourceCode.AppendLine($"return \"{group}\";");
            }

            sourceCode.AppendLine("default: throw new System.NotSupportedException(assets.ToString());");
            sourceCode.AppendLine("}");
            sourceCode.AppendLine("}");
            sourceCode.AppendLine("}");

            sourceCode.AppendLine("}");

            return(new CodeSnippetCompileUnit(sourceCode.ToString()));
        }
示例#6
0
        private CodeCompileUnit GenerateStorageExtensionMethods()
        {
            var sourceCode = new StringBuilder();

            var groups = _proxyCodeGenerator.RootDefinitions.SelectMany(r => r.Attributes)
                         .Select(a => a.Group)
                         .Distinct()
                         .Where(CodeGenerationUtility.IsValidGroupName)
                         .ToArray();

            var g = new Dictionary <string, Type>();

            foreach (var definition in _proxyCodeGenerator.RootDefinitions)
            {
                foreach (var attribute in definition.Attributes)
                {
                    switch (attribute.GetDeclarationType())
                    {
                    case DeclarationType.Single:
                        g[attribute.Group] = definition.Root;
                        break;

                    case DeclarationType.List:
                        var elementType = definition.Root;
                        g[attribute.Group] = typeof(List <>).MakeGenericType(elementType);
                        break;

                    case DeclarationType.Dictionary:
                        var dictionaryAttribute = (AssetDictionaryAttribute)attribute;
                        if (dictionaryAttribute.IsSingleFile)
                        {
                            g[attribute.Group] = dictionaryAttribute.KeyType;
                        }

                        var keySourceMethodInfo = definition.Root.GetKeySourceMethodInfo(dictionaryAttribute);
                        if (keySourceMethodInfo == null)
                        {
                            continue;
                        }

                        var keyType   = keySourceMethodInfo.ReturnType;
                        var valueType = definition.Root;
                        g[attribute.Group] = typeof(Dictionary <,>).MakeGenericType(keyType, valueType);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }

            sourceCode.AppendLine($"namespace {TargetNamespace}");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("using System.Collections.Generic;");
            sourceCode.AppendLine("public static class StorageDefinitionExtensions");
            sourceCode.AppendLine("{");

            sourceCode.AppendLine($"public static T Get<T>(this {nameof(Storage)} s, {TargetNamespace}.Assets asset)");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("return s.Get<T>(asset.ToGroupName());");
            sourceCode.AppendLine("}");

            sourceCode.AppendLine($"public static bool Contains(this {nameof(Storage)} s, {TargetNamespace}.Assets asset)");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("return s.Contains(asset.ToGroupName());");
            sourceCode.AppendLine("}");

            sourceCode.AppendLine($"public static bool Contains<T>(this {nameof(Storage)} s, {TargetNamespace}.Assets asset)");
            sourceCode.AppendLine("{");
            sourceCode.AppendLine("return s.Contains<T>(asset.ToGroupName());");
            sourceCode.AppendLine("}");

            for (var i = 0; i < groups.Length; i++)
            {
                var group     = groups[i];
                var groupName = CodeGenerationUtility.GetGroupName(group);
                var typeName  = _proxyCodeGenerator.GetTypeName(g[group]);
                sourceCode.AppendLine($"public static {typeName} Get{groupName}(this Storage s)");
                sourceCode.AppendLine("{");
                sourceCode.AppendLine($"return s.Get<{typeName}>(\"{group}\");");
                sourceCode.AppendLine("}");
            }

            sourceCode.AppendLine("}");
            sourceCode.AppendLine("}");

            return(new CodeSnippetCompileUnit(sourceCode.ToString()));
        }
示例#7
0
        protected override void Generate(StringBuilder sourceCode)
        {
            if (IgnoreAssemblies == null)
            {
                IgnoreAssemblies = new Assembly[0];
            }
            var roots = GetRootDefinitions()
                        .Where(r => r.Types.Length >= 1)
                        .Where(r => IgnoreAssemblies.All(a => r.Assembly != a)).ToList();

            foreach (var root in roots)
            {
                Log(root.ToString());
            }

            var namespaces = new List <string>
            {
                "System",
                "System.Collections",
                "System.Collections.Generic",
                "System.Runtime.InteropServices",

                "Yamly",
                "Yamly.Proxy",

                "UnityEngine"
            };

            foreach (var root in roots)
            {
                namespaces.Add(GetProxyNamespaceName(root.Root));
                namespaces.AddRange(root.Namespaces);
                foreach (var attribute in root.Attributes)
                {
                    var dictionaryAttribute = attribute as AssetDictionaryAttribute;
                    if (dictionaryAttribute == null)
                    {
                        continue;
                    }

                    var keyType = GetKeyType(root.Root, dictionaryAttribute);
                    if (keyType != null && keyType.Namespace != null)
                    {
                        namespaces.Add(keyType.Namespace);
                    }
                }
            }

            Include(namespaces.Distinct());

            foreach (var root in roots)
            {
                Namespace(GetProxyNamespaceName(root.Root), () =>
                {
                    ListProxyGenericArguments.Clear();
                    DictionaryProxyGenericArguments.Clear();
                    NullableProxyGenericArguments.Clear();

                    foreach (var type in root.Types)
                    {
                        ProxyType(type);
                    }

                    foreach (var listTypeName in ListProxyGenericArguments)
                    {
                        ListType(listTypeName);
                    }

                    foreach (var pair in DictionaryProxyGenericArguments)
                    {
                        DictionaryType(pair.Key, pair.Value);
                    }

                    foreach (var valueTypeName in NullableProxyGenericArguments)
                    {
                        NullableType(valueTypeName);
                    }
                });
            }

            Namespace(StorageOutputNamespace, () =>
            {
                ListProxyGenericArguments.Clear();
                DictionaryProxyGenericArguments.Clear();
                NullableProxyGenericArguments.Clear();

                var generated = new HashSet <string>();
                foreach (var root in roots)
                {
                    foreach (var attribute in root.Attributes)
                    {
                        if (!CodeGenerationUtility.IsValidGroupName(attribute.Group))
                        {
                            continue;
                        }

                        var storageTypeName = GetStorageTypeName(root.Root, attribute);
                        if (generated.Contains(storageTypeName))
                        {
                            continue;
                        }

                        StorageType(root, attribute);

                        generated.Add(storageTypeName);
                    }
                }
            });

            ReferencedAssemblies = roots.SelectMany(r => r.Types)
                                   .Select(t => t.Assembly)
                                   .Distinct()
                                   .ToArray();

            RootDefinitions = roots.ToArray();
        }