Пример #1
0
        /// <summary>
        /// Parses document updates from the IDE and return the class associated
        /// with the changes.
        /// </summary>
        /// <returns>The class declaration that changed.</returns>
        /// <param name="fileName">File name changed.</param>
        /// <param name="text">Text changed.</param>
        /// <param name="syntaxTree">Syntax tree.</param>
        /// <param name="semanticModel">Semantic model.</param>
        public static async Task <FormsViewClassDeclaration> ParseDocument(string fileName,
                                                                           string text,
                                                                           SyntaxTree syntaxTree,
                                                                           SemanticModel semanticModel)
        {
            XAMLDocument xamlDocument = null;
            FormsViewClassDeclaration formsViewClass = null;

            // FIXME: Support any kind of types, not just Xamarin.Forms views
            if (!fileName.EndsWith(".xaml") && !fileName.EndsWith(".xaml.cs") && !fileName.EndsWith(".cs"))
            {
                return(null);
            }

            // Check if we have already an instance of the class declaration for that file
            if (!FormsViewClassDeclaration.TryGetByFileName(fileName, out formsViewClass))
            {
                if (fileName.EndsWith(".xaml"))
                {
                    xamlDocument = XAMLDocument.Parse(fileName, text);
                    // Check if we have an instance of class by namespace
                    if (!FormsViewClassDeclaration.TryGetByFullNamespace(xamlDocument.Type, out formsViewClass))
                    {
                        formsViewClass = await CreateFromXaml(xamlDocument);
                    }
                }
                else
                {
                    formsViewClass = await CreateFromCodeBehind(fileName, syntaxTree, semanticModel);
                }
            }

            if (formsViewClass == null)
            {
                return(null);
            }

            // The document is a XAML file
            if (fileName.EndsWith(".xaml") && xamlDocument == null)
            {
                xamlDocument = XAMLDocument.Parse(fileName, text);
                await formsViewClass.UpdateXaml(xamlDocument);
            }
            // The document is code behind or a view without XAML
            if (fileName.EndsWith(".cs"))
            {
                var classDeclaration = FormsViewClassDeclaration.FindClass(syntaxTree, formsViewClass.ClassName);
                if (formsViewClass.NeedsClassInitialization)
                {
                    formsViewClass.FillClassInfo(classDeclaration, semanticModel);
                }
                formsViewClass.UpdateCode(classDeclaration, semanticModel);
            }
            return(formsViewClass);
        }
Пример #2
0
        static bool GetOrCreate(string fileName,
                                string text,
                                SyntaxTree syntaxTree,
                                SemanticModel semanticModel,
                                out FormsViewClassDeclaration xamlClass,
                                out XAMLDocument xamlDocument)
        {
            string xaml = null, xamlFilePath = null, codeBehindFilePath = null;

            xamlDocument = null;

            // Check if we have already an instance of the class declaration for that file
            if (FormsViewClassDeclaration.TryGetByFileName(fileName, out xamlClass))
            {
                return(true);
            }

            if (fileName.EndsWith(".xaml"))
            {
                xaml         = text;
                xamlFilePath = fileName;
                var candidate = xamlFilePath + ".cs";
                if (File.Exists(candidate))
                {
                    codeBehindFilePath = candidate;
                }
            }
            else
            {
                codeBehindFilePath = fileName;
                var candidate = fileName.Substring(0, fileName.Length - 3);
                if (File.Exists(candidate))
                {
                    xamlFilePath = candidate;
                    xaml         = File.ReadAllText(xamlFilePath);
                }
            }

            // FIXME: Handle XF views without XAML
            // Parse the XAML file
            xamlDocument = XAMLDocument.Parse(xamlFilePath, xaml);
            if (xamlDocument == null)
            {
                Log.Error("Error parsing XAML");
                return(false);
            }

            // Check if we have an instance of class by namespace
            if (FormsViewClassDeclaration.TryGetByFullNamespace(xamlDocument.Type, out xamlClass))
            {
                return(true);
            }

            // This is the first time we have an update for this type

            // Create a new class declaration instance from the syntax tree
            if (syntaxTree != null)
            {
                var className        = xamlDocument.Type.Split('.').Last();
                var classDeclaration = FormsViewClassDeclaration.FindClass(syntaxTree, className);
                xamlClass = new FormsViewClassDeclaration(classDeclaration, semanticModel,
                                                          codeBehindFilePath, xamlDocument);
            }
            // Create a new class declaration instance from the XAML
            else
            {
                xamlClass = new FormsViewClassDeclaration(codeBehindFilePath, xamlDocument);
            }
            return(true);
        }