예제 #1
0
        static void AddDependency(string assetPath, XElement templateNode, List <string> dependencies)
        {
            bool   hasSrc = false;
            string src    = null;

            foreach (var xAttribute in templateNode.Attributes())
            {
                switch (xAttribute.Name.LocalName)
                {
                case k_GenericSrcAttr:
                    hasSrc = true;
                    src    = xAttribute.Value;
                    break;
                }
            }

            if (hasSrc)
            {
                string errorMessage, projectRelativePath;

                URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, src, out errorMessage, out projectRelativePath);

                if (result == URIValidationResult.OK)
                {
                    dependencies.Add(projectRelativePath);
                }
            }
        }
        protected void VisitUrlFunction(PrimitiveTerm term)
        {
            string path = (string)term.Value;

            string projectRelativePath, errorMessage;

            URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, path, out errorMessage, out projectRelativePath);

            if (result != URIValidationResult.OK)
            {
                m_Errors.AddSemanticError(ConvertErrorCode(result), errorMessage);
            }
            else
            {
                UnityEngine.Object asset = DeclareDependencyAndLoad(projectRelativePath);

                if (asset is Texture2D || asset is Font)
                {
                    m_Builder.AddValue(asset);
                }
                else
                {
                    m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidURIProjectAssetType, string.Format("Invalid asset type {0}, only Font and Texture2D are supported", asset.GetType().Name));
                }
            }
        }
        protected void VisitUrlFunction(PrimitiveTerm term)
        {
            string path = (string)term.Value;

            string projectRelativePath, errorMessage;

            URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, path, out errorMessage, out projectRelativePath);

            if (result != URIValidationResult.OK)
            {
                m_Builder.AddValue(path, StyleValueType.MissingAssetReference);
                m_Errors.AddValidationWarning(errorMessage, m_Builder.currentProperty.line);
            }
            else
            {
                UnityEngine.Object asset = DeclareDependencyAndLoad(projectRelativePath);

                bool isTexture = asset is Texture2D;

                if (isTexture || asset is Font || asset is VectorImage)
                {
                    // Looking suffixed images files only
                    if (isTexture)
                    {
                        string hiResImageLocation = URIHelpers.InjectFileNameSuffix(projectRelativePath, "@2x");

                        if (File.Exists(hiResImageLocation))
                        {
                            UnityEngine.Object hiResImage = DeclareDependencyAndLoad(hiResImageLocation);

                            if (hiResImage is Texture2D)
                            {
                                m_Builder.AddValue(new ScalableImage()
                                {
                                    normalImage = asset as Texture2D, highResolutionImage = hiResImage as Texture2D
                                });
                            }
                            else
                            {
                                m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidHighResolutionImage, string.Format("Invalid asset type {0}, only Texture2D is supported for variants with @2x suffix", asset.GetType().Name));
                            }
                            return;
                        }
                        // If we didn't find an high res variant, tell ADB we depend on that potential file existing
                        DeclareDependencyAndLoad(hiResImageLocation);
                    }
                    m_Builder.AddValue(asset);
                }
                else
                {
                    m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidURIProjectAssetType, string.Format("Invalid asset type {0}, only Font, Texture2D and VectorImage are supported", asset.GetType().Name));
                }
            }
        }
예제 #4
0
        static void AddDependency(string assetPath, XElement templateNode, List <string> dependencies)
        {
            bool   hasSrc = false;
            string src    = null;

            foreach (var xAttribute in templateNode.Attributes())
            {
                switch (xAttribute.Name.LocalName)
                {
                case k_GenericSrcAttr:
                    hasSrc = true;
                    src    = xAttribute.Value;
                    break;
                }
            }

            if (!hasSrc)
            {
                return;
            }

            URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, src, out string errorMessage, out string projectRelativePath);

            if (result != URIValidationResult.OK)
            {
                return;
            }

            switch (templateNode.Name.LocalName)
            {
            case k_TemplateNode:
                var templateDependencies = new HashSet <string>();
                templateDependencies.Add(assetPath);

                if (!HasTemplateCircularDependencies(projectRelativePath, templateDependencies))
                {
                    dependencies.Add(projectRelativePath);
                }
                else
                {
                    logger.LogError(ImportErrorType.Semantic, ImportErrorCode.TemplateHasCircularDependency, projectRelativePath, Error.Level.Warning, templateNode);
                }
                break;

            default:
                dependencies.Add(projectRelativePath);
                break;
            }
        }
예제 #5
0
        void LoadStyleReferenceNode(VisualElementAsset vea, XElement styleElt, VisualTreeAsset vta)
        {
            XAttribute pathAttr = styleElt.Attribute(k_GenericPathAttr);
            bool       hasPath  = pathAttr != null && !String.IsNullOrEmpty(pathAttr.Value);

            XAttribute srcAttr = styleElt.Attribute(k_GenericSrcAttr);
            bool       hasSrc  = srcAttr != null && !String.IsNullOrEmpty(srcAttr.Value);

            if (hasPath == hasSrc)
            {
                LogWarning(vta,
                           ImportErrorType.Semantic,
                           hasPath ? ImportErrorCode.StyleReferenceSrcAndPathBothSpecified : ImportErrorCode.StyleReferenceEmptyOrMissingPathOrSrcAttr,
                           null,
                           styleElt);
                return;
            }

            if (hasPath)
            {
                vea.stylesheetPaths.Add(pathAttr.Value);
            }
            else if (hasSrc)
            {
                string errorMessage, projectRelativePath;

                URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, srcAttr.Value, out errorMessage, out projectRelativePath);

                if (result != URIValidationResult.OK)
                {
                    LogError(vta, ImportErrorType.Semantic, ConvertErrorCode(result), errorMessage, styleElt);
                }
                else
                {
                    Object asset = DeclareDependencyAndLoad(projectRelativePath);

                    if (asset is StyleSheet)
                    {
                        vea.stylesheets.Add(asset as StyleSheet);
                    }
                    else
                    {
                        LogError(vta, ImportErrorType.Semantic, ImportErrorCode.ReferenceInvalidAssetType, projectRelativePath, styleElt);
                    }
                }
            }
        }
예제 #6
0
        static ImportErrorCode ConvertErrorCode(URIValidationResult result)
        {
            switch (result)
            {
            case URIValidationResult.InvalidURILocation:
                return(ImportErrorCode.ReferenceInvalidURILocation);

            case URIValidationResult.InvalidURIScheme:
                return(ImportErrorCode.ReferenceInvalidURIScheme);

            case URIValidationResult.InvalidURIProjectAssetPath:
                return(ImportErrorCode.ReferenceInvalidURIProjectAssetPath);

            default:
                throw new ArgumentOutOfRangeException(result.ToString());
            }
        }
        static protected StyleSheetImportErrorCode ConvertErrorCode(URIValidationResult result)
        {
            switch (result)
            {
            case URIValidationResult.InvalidURILocation:
                return(StyleSheetImportErrorCode.InvalidURILocation);

            case URIValidationResult.InvalidURIScheme:
                return(StyleSheetImportErrorCode.InvalidURIScheme);

            case URIValidationResult.InvalidURIProjectAssetPath:
                return(StyleSheetImportErrorCode.InvalidURIProjectAssetPath);

            default:
                return(StyleSheetImportErrorCode.Internal);
            }
        }
        internal static (StyleSheetImportErrorCode, string) ConvertErrorCode(URIValidationResult result)
        {
            switch (result)
            {
            case URIValidationResult.InvalidURILocation:
                return(StyleSheetImportErrorCode.InvalidURILocation, glossary.invalidUriLocation);

            case URIValidationResult.InvalidURIScheme:
                return(StyleSheetImportErrorCode.InvalidURIScheme, glossary.invalidUriScheme);

            case URIValidationResult.InvalidURIProjectAssetPath:
                return(StyleSheetImportErrorCode.InvalidURIProjectAssetPath, glossary.invalidAssetPath);

            default:
                return(StyleSheetImportErrorCode.Internal, glossary.internalErrorWithStackTrace);
            }
        }
예제 #9
0
        internal static bool HasTemplateCircularDependencies(XElement templateElement, HashSet <string> templateDependencies, string rootAssetPath)
        {
            bool hasCircularDependencies = false;

            var elements = templateElement.Elements();

            foreach (var child in elements)
            {
                switch (child.Name.LocalName)
                {
                case k_TemplateNode:
                    var attributes = child.Attributes();

                    foreach (var xAttribute in attributes)
                    {
                        if (xAttribute.Name.LocalName != k_GenericSrcAttr)
                        {
                            continue;
                        }

                        var src = xAttribute.Value;
                        URIValidationResult result = URIHelpers.ValidAssetURL(rootAssetPath, src, out string errorMessage, out string projectRelativePath);
                        hasCircularDependencies = HasTemplateCircularDependencies(projectRelativePath, templateDependencies);

                        if (!hasCircularDependencies)
                        {
                            templateDependencies.Remove(projectRelativePath);
                        }
                    }

                    break;

                default:
                    hasCircularDependencies = HasTemplateCircularDependencies(child, templateDependencies, rootAssetPath);
                    break;
                }

                if (hasCircularDependencies)
                {
                    break;
                }
            }

            return(hasCircularDependencies);
        }
예제 #10
0
        void LoadTemplateNode(VisualTreeAsset vta, XElement elt, XElement child)
        {
            bool   hasPath = false;
            bool   hasSrc  = false;
            string name    = null;
            string path    = null;
            string src     = null;

            foreach (var xAttribute in child.Attributes())
            {
                switch (xAttribute.Name.LocalName)
                {
                case k_GenericPathAttr:
                    hasPath = true;
                    path    = xAttribute.Value;
                    break;

                case k_GenericSrcAttr:
                    hasSrc = true;
                    src    = xAttribute.Value;
                    break;

                case k_TemplateNameAttr:
                    name = xAttribute.Value;
                    if (String.IsNullOrEmpty(name))
                    {
                        logger.LogError(ImportErrorType.Semantic,
                                        ImportErrorCode.TemplateHasEmptyName,
                                        child,
                                        Error.Level.Fatal,
                                        child
                                        );
                    }
                    break;

                default:
                    logger.LogError(ImportErrorType.Semantic,
                                    ImportErrorCode.UnknownAttribute,
                                    xAttribute.Name.LocalName,
                                    Error.Level.Fatal,
                                    child
                                    );
                    break;
                }
            }

            if (hasPath == hasSrc)
            {
                logger.LogError(ImportErrorType.Semantic,
                                hasPath ? ImportErrorCode.TemplateSrcAndPathBothSpecified : ImportErrorCode.TemplateMissingPathOrSrcAttribute,
                                null,
                                Error.Level.Fatal,
                                elt
                                );
                return;
            }

            if (String.IsNullOrEmpty(name))
            {
                name = Path.GetFileNameWithoutExtension(path);
            }

            if (vta.TemplateExists(name))
            {
                logger.LogError(ImportErrorType.Semantic,
                                ImportErrorCode.DuplicateTemplateName,
                                name,
                                Error.Level.Fatal,
                                elt
                                );
                return;
            }

            if (hasPath)
            {
                vta.RegisterTemplate(name, path);
            }
            else if (hasSrc)
            {
                string errorMessage, projectRelativePath;

                URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, src, out errorMessage, out projectRelativePath);

                if (result != URIValidationResult.OK)
                {
                    logger.LogError(ImportErrorType.Semantic, ConvertErrorCode(result), errorMessage, Error.Level.Fatal, elt);
                }
                else
                {
                    Object asset = DeclareDependencyAndLoad(projectRelativePath);

                    if (asset is VisualTreeAsset)
                    {
                        vta.RegisterTemplate(name, asset as VisualTreeAsset);
                    }
                    else
                    {
                        logger.LogError(ImportErrorType.Semantic, ImportErrorCode.ReferenceInvalidAssetType, projectRelativePath, Error.Level.Fatal, elt);
                    }
                }
            }
        }
        protected void ImportParserStyleSheet(UnityStyleSheet asset, ParserStyleSheet styleSheet)
        {
            m_Errors.assetPath = assetPath;

            if (styleSheet.Errors.Count > 0)
            {
                foreach (StylesheetParseError error in styleSheet.Errors)
                {
                    m_Errors.AddSyntaxError(error.ToString());
                }
            }
            else
            {
                try
                {
                    VisitSheet(styleSheet);
                }
                catch (Exception exc)
                {
                    Debug.LogException(exc);
                    m_Errors.AddInternalError(exc.StackTrace);
                }
            }

            bool success = !m_Errors.hasErrors;

            if (success)
            {
                m_Builder.BuildTo(asset);

                if (!s_StyleSheetsWithCircularImportDependencies.Contains(assetPath))
                {
                    var importDirectivesCount = styleSheet.ImportDirectives.Count;
                    asset.imports = new UnityStyleSheet.ImportStruct[importDirectivesCount];
                    for (int i = 0; i < importDirectivesCount; ++i)
                    {
                        var importedPath = styleSheet.ImportDirectives[i].Href;

                        string projectRelativePath, errorMessage;

                        URIValidationResult importResult = URIHelpers.ValidAssetURL(assetPath, importedPath, out errorMessage, out projectRelativePath);

                        UnityStyleSheet importedStyleSheet = null;
                        if (importResult != URIValidationResult.OK)
                        {
                            m_Errors.AddSemanticError(ConvertErrorCode(importResult), errorMessage);
                        }
                        else
                        {
                            importedStyleSheet = DeclareDependencyAndLoad(projectRelativePath) as UnityStyleSheet;
                            m_Context.DependsOnImportedAsset(projectRelativePath);
                        }

                        asset.imports[i] = new UnityStyleSheet.ImportStruct
                        {
                            styleSheet   = importedStyleSheet,
                            mediaQueries = styleSheet.ImportDirectives[i].Media.ToArray()
                        };
                    }

                    if (importDirectivesCount > 0)
                    {
                        asset.FlattenImportedStyleSheetsRecursive();
                    }
                }
                else
                {
                    asset.imports = new UnityStyleSheet.ImportStruct[0];
                    var errorMsg = $"The {assetPath} contains circular @import dependencies. All @import directives will be ignored for this StyleSheet.";
                    Debug.LogError(errorMsg);
                    m_Errors.AddInternalError(errorMsg);
                }

                OnImportSuccess(asset);
            }

            if (!success || m_Errors.hasWarning)
            {
                OnImportError(m_Errors);
            }
        }
        protected void VisitUrlFunction(PrimitiveTerm term)
        {
            string path = (string)term.Value;

            string projectRelativePath, subAssetPath, errorMessage;

            URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, path, out errorMessage, out projectRelativePath, out subAssetPath);

            if (result != URIValidationResult.OK)
            {
                m_Builder.AddValue(path, StyleValueType.MissingAssetReference);
                m_Errors.AddValidationWarning(errorMessage, m_Builder.currentProperty.line);
            }
            else
            {
                UnityEngine.Object asset = DeclareDependencyAndLoad(projectRelativePath, subAssetPath);

                bool   isTexture   = asset is Texture2D;
                Sprite spriteAsset = asset as Sprite;

                if (isTexture && string.IsNullOrEmpty(subAssetPath))
                {
                    // Try to load a sprite sub-asset associated with this texture.
                    // Sprites have extra data, such as slices and tight-meshes that
                    // aren't stored in plain textures.
                    spriteAsset = AssetDatabase.LoadAssetAtPath <Sprite>(projectRelativePath);
                }

                if (isTexture || spriteAsset != null || asset is Font || IsFontAssetInternal(asset) || asset is VectorImage || asset is RenderTexture)
                {
                    // Looking suffixed images files only
                    if (isTexture)
                    {
                        string hiResImageLocation = URIHelpers.InjectFileNameSuffix(projectRelativePath, "@2x");

                        if (File.Exists(hiResImageLocation))
                        {
                            UnityEngine.Object hiResImage = DeclareDependencyAndLoad(hiResImageLocation);

                            if (hiResImage is Texture2D)
                            {
                                m_Builder.AddValue(new ScalableImage()
                                {
                                    normalImage = asset as Texture2D, highResolutionImage = hiResImage as Texture2D
                                });
                            }
                            else
                            {
                                m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidHighResolutionImage, string.Format("Invalid asset type {0}, only Texture2D is supported for variants with @2x suffix", asset.GetType().Name));
                            }
                            return;
                        }
                        // If we didn't find an high res variant, tell ADB we depend on that potential file existing
                        if (spriteAsset != null)
                        {
                            DeclareDependencyAndLoad(hiResImageLocation);
                        }
                    }

                    m_Builder.AddValue(spriteAsset != null ? spriteAsset : asset);
                }
                else
                {
                    m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidURIProjectAssetType, string.Format("Invalid asset type {0}, only Font, FontAssets, Sprite, Texture2D and VectorImage are supported", asset.GetType().Name));
                }
            }
        }