/// <summary>
        /// Creates compilation syntax unit from the specified external type information and validation.
        /// </summary>
        /// <param name="info">The container external type information.</param>
        /// <param name="validation">The container type validation to use.</param>
        /// <param name="compilation">The project compilation.</param>
        /// <param name="generator">The syntax generator.</param>
        public static SyntaxNode CreateUnit(ICodeGenerateContainerInfo info, ICodeGenerateContainerValidation validation, Compilation compilation = null, SyntaxGenerator generator = null)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }
            if (validation == null)
            {
                throw new ArgumentNullException(nameof(validation));
            }
            if (compilation == null)
            {
                compilation = CodeAnalysisEditorUtility.ProjectCompilation;
            }
            if (generator == null)
            {
                generator = CodeAnalysisEditorUtility.Generator;
            }

            if (!info.TryGetTargetType(out Type type))
            {
                throw new ArgumentException("The specified container external type info has invalid target type information.", nameof(info));
            }

            CodeGenerateContainer container = CreateContainer(info, validation, compilation);

            return(CodeGenerateContainerEditorUtility.CreateUnit(container, generator, type.Namespace));
        }
        /// <summary>
        /// Creates container external type information from the specified type and validation.
        /// </summary>
        /// <param name="type">The target type.</param>
        /// <param name="validation">The container type validation to use.</param>
        public static CodeGenerateContainerInfo CreateInfo(Type type, ICodeGenerateContainerValidation validation)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (validation == null)
            {
                throw new ArgumentNullException(nameof(validation));
            }

            var info = new CodeGenerateContainerInfo {
                TypeName = type.AssemblyQualifiedName
            };
            IEnumerable <FieldInfo>    fields     = validation.GetFields(type);
            IEnumerable <PropertyInfo> properties = validation.GetProperties(type);

            foreach (FieldInfo field in fields)
            {
                if (validation.Validate(field))
                {
                    info.Members.Add(new CodeGenerateContainerInfo.MemberInfo
                    {
                        Active = true,
                        Name   = field.Name
                    });
                }
            }

            foreach (PropertyInfo property in properties)
            {
                if (validation.Validate(property))
                {
                    info.Members.Add(new CodeGenerateContainerInfo.MemberInfo
                    {
                        Active = true,
                        Name   = property.Name
                    });
                }
            }

            return(info);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates container from the specified type using specified validation.
        /// <para>
        /// The specified validation will not be used to validate specified type.
        /// </para>
        /// </summary>
        /// <param name="type">The target type.</param>
        /// <param name="validation">The type validation to use.</param>
        /// <param name="compilation">The project compilation.</param>
        public static CodeGenerateContainer Create(Type type, ICodeGenerateContainerValidation validation = null, Compilation compilation = null)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (validation == null)
            {
                validation = DefaultValidation;
            }
            if (compilation == null)
            {
                compilation = CodeAnalysisEditorUtility.ProjectCompilation;
            }

            var container = new CodeGenerateContainer(type.Name, type.IsValueType);

            foreach (FieldInfo field in validation.GetFields(type))
            {
                if (validation.Validate(field))
                {
                    if (TryCreateField(compilation, field.Name, field.FieldType, false, out CodeGenerateContainerField containerField))
                    {
                        container.Fields.Add(containerField);
                    }
                }
            }

            foreach (PropertyInfo property in validation.GetProperties(type))
            {
                if (validation.Validate(property))
                {
                    if (TryCreateField(compilation, property.Name, property.PropertyType, true, out CodeGenerateContainerField containerField))
                    {
                        container.Fields.Add(containerField);
                    }
                }
            }

            return(container);
        }
Exemplo n.º 4
0
        public static void GenerateResolver(string assetPath, ICodeGenerateContainerValidation validation = null, Compilation compilation = null, SyntaxGenerator generator = null)
        {
            if (string.IsNullOrEmpty(assetPath))
            {
                throw new ArgumentException("Value cannot be null or empty.", nameof(assetPath));
            }

            var    info   = AssetInfoEditorUtility.LoadInfo <Utf8JsonResolverAssetInfo>(assetPath);
            string source = GenerateResolver(info, validation, compilation, generator);
            string path   = GetDestinationSourcePath(assetPath, info.ResolverName, info.DestinationSource);

            File.WriteAllText(path, source);
            AssetDatabase.ImportAsset(path);

            if (info.DestinationSource == null)
            {
                info.DestinationSource = AssetDatabase.LoadAssetAtPath <TextAsset>(path);

                AssetInfoEditorUtility.SaveInfo(assetPath, info);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates compilation unit from the specified container type using validation.
        /// </summary>
        /// <param name="type">The type of the container.</param>
        /// <param name="validation">The validation to use.</param>
        /// <param name="compilation">The project compilation.</param>
        /// <param name="generator">The syntax generator.</param>
        public static SyntaxNode CreateUnit(Type type, ICodeGenerateContainerValidation validation = null, Compilation compilation = null, SyntaxGenerator generator = null)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (validation == null)
            {
                validation = DefaultValidation;
            }
            if (compilation == null)
            {
                compilation = CodeAnalysisEditorUtility.ProjectCompilation;
            }
            if (generator == null)
            {
                generator = CodeAnalysisEditorUtility.Generator;
            }

            CodeGenerateContainer container = Create(type, validation, compilation);

            return(CreateUnit(container, generator, type.Namespace));
        }
Exemplo n.º 6
0
        public static void GenerateResolverAll(ICodeGenerateContainerValidation validation = null, Compilation compilation = null, SyntaxGenerator generator = null)
        {
            const string resolverSearchPattern = "*." + RESOLVER_ASSET_EXTENSION_NAME;

            string[] underAssets   = Directory.GetFiles("Assets", resolverSearchPattern, SearchOption.AllDirectories);
            string[] underPackages = Directory.GetFiles("Packages", resolverSearchPattern, SearchOption.AllDirectories);

            for (int i = 0; i < underAssets.Length; i++)
            {
                string path = underAssets[i];

                GenerateResolver(path, validation, compilation, generator);
            }

            for (int i = 0; i < underPackages.Length; i++)
            {
                string path = underPackages[i];

                if (CanGenerateResolver(path))
                {
                    GenerateResolver(path, validation, compilation, generator);
                }
            }
        }
Exemplo n.º 7
0
        public static string GenerateExternalSources(IReadOnlyList <string> externalPaths, ICollection <string> sourcePaths, Type attributeType = null, ICodeGenerateContainerValidation validation = null, Compilation compilation = null, SyntaxGenerator generator = null)
        {
            if (externalPaths == null)
            {
                throw new ArgumentNullException(nameof(externalPaths));
            }
            if (sourcePaths == null)
            {
                throw new ArgumentNullException(nameof(sourcePaths));
            }
            if (validation == null)
            {
                validation = CodeGenerateContainerAssetEditorUtility.DefaultValidation;
            }
            if (compilation == null)
            {
                compilation = CodeAnalysisEditorUtility.ProjectCompilation;
            }
            if (generator == null)
            {
                generator = CodeAnalysisEditorUtility.Generator;
            }

            string externalsTempPath = FileUtil.GetUniqueTempPathInProject();
            var    types             = new HashSet <Type>();
            CSharpSyntaxRewriter rewriterAddAttribute = null;

            if (attributeType != null && compilation.TryConstructTypeSymbol(attributeType, out ITypeSymbol typeSymbol))
            {
                rewriterAddAttribute = GetAttributeRewriter(compilation, generator, typeSymbol);
            }

            Directory.CreateDirectory(externalsTempPath);

            for (int i = 0; i < externalPaths.Count; i++)
            {
                string externalPath = externalPaths[i];
                var    info         = AssetInfoEditorUtility.LoadInfo <CodeGenerateContainerInfo>(externalPath);

                if (info.TryGetTargetType(out Type type))
                {
                    if (types.Add(type))
                    {
                        SyntaxNode unit = CodeGenerateContainerInfoEditorUtility.CreateUnit(info, validation, compilation, generator);

                        if (rewriterAddAttribute != null)
                        {
                            unit = rewriterAddAttribute.Visit(unit);
                        }

                        string sourcePath = $"{externalsTempPath}/{Guid.NewGuid():N}.cs";
                        string source     = unit.NormalizeWhitespace().ToFullString();

                        File.WriteAllText(sourcePath, source);

                        sourcePaths.Add(sourcePath);
                    }
                    else
                    {
                        Debug.LogWarning($"The specified type already generated: '{type}'.");
                    }
                }
            }

            return(externalsTempPath);
        }
Exemplo n.º 8
0
        public static string GenerateResolver(Utf8JsonResolverAssetInfo info, ICodeGenerateContainerValidation validation = null, Compilation compilation = null, SyntaxGenerator generator = null)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }
            if (validation == null)
            {
                validation = CodeGenerateContainerAssetEditorUtility.DefaultValidation;
            }
            if (compilation == null)
            {
                compilation = CodeAnalysisEditorUtility.ProjectCompilation;
            }
            if (generator == null)
            {
                generator = CodeAnalysisEditorUtility.Generator;
            }

            var    sourcePaths   = new List <string>();
            string resolverName  = Utf8JsonEditorUtility.FormatResolverName(info.ResolverName);
            string namespaceRoot = info.NamespaceRoot;
            string externalsTemp = string.Empty;
            Type   attributeType = null;

            var generateArguments = new Utf8JsonGenerateArguments
            {
                IgnoreReadOnly         = info.IgnoreReadOnly,
                IgnoreEmpty            = info.IgnoreEmpty,
                IsTypeRequireAttribute = info.AttributeRequired,
            };

            if (info.AttributeRequired && info.TryGetAttributeType(out attributeType))
            {
                generateArguments.TypeRequiredAttributeShortName = attributeType.Name;
            }

            if (info.Sources.Count > 0)
            {
                var externals = new List <string>();

                for (int i = 0; i < info.Sources.Count; i++)
                {
                    TextAsset asset = info.Sources[i];
                    string    path  = AssetDatabase.GetAssetPath(asset);

                    if (!string.IsNullOrEmpty(path))
                    {
                        if (path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase))
                        {
                            sourcePaths.Add(path);
                        }
                        else if (path.EndsWith(Utf8JsonExternalTypeEditorUtility.EXTERNAL_TYPE_ASSET_EXTENSION, StringComparison.OrdinalIgnoreCase))
                        {
                            externals.Add(path);
                        }
                    }
                }

                if (externals.Count > 0)
                {
                    externalsTemp = Utf8JsonExternalTypeEditorUtility.GenerateExternalSources(externals, sourcePaths, attributeType, validation, compilation, generator);
                }
            }

            string source = Utf8JsonEditorUtility.GenerateResolver(sourcePaths, resolverName, namespaceRoot, generateArguments);

            if (!string.IsNullOrEmpty(externalsTemp))
            {
                FileUtil.DeleteFileOrDirectory(externalsTemp);
            }

            if (info.ResolverAsset)
            {
                source = AppendResolverAsset(source, resolverName, namespaceRoot, compilation, generator);
            }

            return(source);
        }
        /// <summary>
        /// Creates container from the specified external type information and validation.
        /// </summary>
        /// <param name="info">The container external type information.</param>
        /// <param name="validation">The container type validation to use.</param>
        /// <param name="compilation">The project compilation.</param>
        public static CodeGenerateContainer CreateContainer(ICodeGenerateContainerInfo info, ICodeGenerateContainerValidation validation, Compilation compilation = null)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }
            if (validation == null)
            {
                throw new ArgumentNullException(nameof(validation));
            }
            if (compilation == null)
            {
                compilation = CodeAnalysisEditorUtility.ProjectCompilation;
            }

            if (!info.TryGetTargetType(out Type type))
            {
                throw new ArgumentException("The specified container external type info has invalid target type information.", nameof(info));
            }

            var container = new CodeGenerateContainer(type.Name, type.IsValueType);
            IEnumerable <FieldInfo>    fields     = validation.GetFields(type);
            IEnumerable <PropertyInfo> properties = validation.GetProperties(type);

            foreach (FieldInfo field in fields)
            {
                if (info.TryGetMember(field.Name, out CodeGenerateContainerInfo.MemberInfo member) && member.Active)
                {
                    if (CodeGenerateContainerEditorUtility.TryCreateField(compilation, field.Name, field.FieldType, false, out CodeGenerateContainerField containerField))
                    {
                        container.Fields.Add(containerField);
                    }
                }
            }

            foreach (PropertyInfo property in properties)
            {
                if (info.TryGetMember(property.Name, out CodeGenerateContainerInfo.MemberInfo member) && member.Active)
                {
                    if (CodeGenerateContainerEditorUtility.TryCreateField(compilation, property.Name, property.PropertyType, true, out CodeGenerateContainerField containerField))
                    {
                        container.Fields.Add(containerField);
                    }
                }
            }

            return(container);
        }