/// <summary>
        /// Compiles the view and returns a function that can be invoked repeatedly. The function builds full control tree and activates the page.
        /// </summary>
        public virtual CSharpCompilation CompileView(string sourceCode, string fileName, CSharpCompilation compilation, string namespaceName, string className)
        {
            // parse the document
            var tokenizer = new DothtmlTokenizer();

            tokenizer.Tokenize(sourceCode);
            var parser = new DothtmlParser();
            var node   = parser.Parse(tokenizer.Tokens);

            var resolvedView = (ResolvedTreeRoot)controlTreeResolver.ResolveTree(node, fileName);

            var errorCheckingVisitor = new ErrorCheckingVisitor();

            resolvedView.Accept(errorCheckingVisitor);

            foreach (var token in tokenizer.Tokens)
            {
                if (token.HasError && token.Error.IsCritical)
                {
                    throw new DotvvmCompilationException(token.Error.ErrorMessage, new[] { (token.Error as BeginWithLastTokenOfTypeTokenError <DothtmlToken, DothtmlTokenType>)?.LastToken ?? token });
                }
            }

            foreach (var n in node.EnumerateNodes())
            {
                if (n.HasNodeErrors)
                {
                    throw new DotvvmCompilationException(string.Join(", ", n.NodeErrors), n.Tokens);
                }
            }

            var styleVisitor = new StylingVisitor(configuration.Styles);

            resolvedView.Accept(styleVisitor);

            var validationVisitor = new Validation.ControlUsageValidationVisitor(configuration);

            resolvedView.Accept(validationVisitor);
            if (validationVisitor.Errors.Any())
            {
                var controlUsageError = validationVisitor.Errors.First();
                throw new DotvvmCompilationException(controlUsageError.ErrorMessage, controlUsageError.Nodes.SelectMany(n => n.Tokens));
            }

            if (configuration.Debug && configuration.ApplicationPhysicalPath != null)
            {
                var addExpressionDebugvisitor = new ExpressionDebugInfoAddingVisitor(Path.Combine(configuration.ApplicationPhysicalPath, fileName));
                addExpressionDebugvisitor.VisitView(resolvedView);
            }

            var emitter          = new DefaultViewCompilerCodeEmitter();
            var compilingVisitor = new ViewCompilingVisitor(emitter, configuration.ServiceLocator.GetService <IBindingCompiler>(), className,
                                                            b => configuration.ServiceLocator.GetService <IBindingIdGenerator>().GetId(b, fileName));

            resolvedView.Accept(compilingVisitor);

            return(AddToCompilation(compilation, emitter, fileName, namespaceName, className));
        }
Beispiel #2
0
        /// <summary>
        /// Compiles the view and returns a function that can be invoked repeatedly. The function builds full control tree and activates the page.
        /// </summary>
        public virtual (ControlBuilderDescriptor, Func <CSharpCompilation>) CompileView(string sourceCode, string fileName, CSharpCompilation compilation, string namespaceName, string className)
        {
            // parse the document
            var tokenizer = new DothtmlTokenizer();

            tokenizer.Tokenize(sourceCode);
            var parser = new DothtmlParser();
            var node   = parser.Parse(tokenizer.Tokens);

            var resolvedView = (ResolvedTreeRoot)controlTreeResolver.ResolveTree(node, fileName);

            return(new ControlBuilderDescriptor(resolvedView.DataContextTypeStack.DataContextType, resolvedView.Metadata.Type), () => {
                var errorCheckingVisitor = new ErrorCheckingVisitor();
                resolvedView.Accept(errorCheckingVisitor);

                foreach (var token in tokenizer.Tokens)
                {
                    if (token.HasError && token.Error.IsCritical)
                    {
                        throw new DotvvmCompilationException(token.Error.ErrorMessage, new[] { (token.Error as BeginWithLastTokenOfTypeTokenError <DothtmlToken, DothtmlTokenType>)?.LastToken ?? token });
                    }
                }

                foreach (var n in node.EnumerateNodes())
                {
                    if (n.HasNodeErrors)
                    {
                        throw new DotvvmCompilationException(string.Join(", ", n.NodeErrors), n.Tokens);
                    }
                }

                var bindingResourceRegisteringVisitor = this.bindingResourceRegisteringVisitor();
                resolvedView.Accept(bindingResourceRegisteringVisitor);

                var styleVisitor = new StylingVisitor(configuration);
                resolvedView.Accept(styleVisitor);

                var contextSpaceVisitor = new DataContextPropertyAssigningVisitor();
                resolvedView.Accept(contextSpaceVisitor);

                var validationVisitor = new Validation.ControlUsageValidationVisitor(configuration);
                resolvedView.Accept(validationVisitor);
                if (validationVisitor.Errors.Any())
                {
                    var controlUsageError = validationVisitor.Errors.First();
                    throw new DotvvmCompilationException(controlUsageError.ErrorMessage, controlUsageError.Nodes.SelectMany(n => n.Tokens));
                }

                var emitter = new DefaultViewCompilerCodeEmitter();
                var compilingVisitor = new ViewCompilingVisitor(emitter, configuration.ServiceLocator.GetService <IBindingCompiler>(), className);

                resolvedView.Accept(compilingVisitor);

                return AddToCompilation(compilation, emitter, fileName, namespaceName, className);
            }
                   );
        }
        /// <summary>
        /// Compiles the view and returns a function that can be invoked repeatedly. The function builds full control tree and activates the page.
        /// </summary>
        public virtual CSharpCompilation CompileView(IReader reader, string fileName, CSharpCompilation compilation, string namespaceName, string className)
        {
            // parse the document
            var tokenizer = new DothtmlTokenizer();

            tokenizer.Tokenize(reader);
            var parser = new DothtmlParser();
            var node   = parser.Parse(tokenizer.Tokens);

            var resolvedView = controlTreeResolver.ResolveTree(node, fileName);

            var styleVisitor = new StylingVisitor(configuration.Styles);

            resolvedView.Accept(styleVisitor);

            var emitter          = new DefaultViewCompilerCodeEmitter();
            var compilingVisitor = new ViewCompilingVisitor(emitter, configuration.ServiceLocator.GetService <IBindingCompiler>(), className,
                                                            b => configuration.ServiceLocator.GetService <IBindingIdGenerator>().GetId(b, fileName));

            resolvedView.Accept(compilingVisitor);

            return(AddToCompilation(compilation, emitter, fileName, namespaceName, className));
        }
Beispiel #4
0
        protected ViewCompilationResult CompileView(string fileName)
        {
            var file = fileLoader.GetMarkup(configuration, fileName);

            // parse the document
            var tokenizer = new DothtmlTokenizer();

            tokenizer.Tokenize(file.ContentsReaderFactory());
            var parser = new DothtmlParser();
            var node   = parser.Parse(tokenizer.Tokens);

            var resolvedView = (ResolvedTreeRoot)controlTreeResolver.ResolveTree(node, fileName);

            var errorCheckingVisitor = new ErrorCheckingVisitor();

            resolvedView.Accept(errorCheckingVisitor);

            foreach (var n in node.EnumerateNodes())
            {
                if (n.HasNodeErrors)
                {
                    throw new DotvvmCompilationException(string.Join(", ", n.NodeErrors), n.Tokens);
                }
            }

            var contextSpaceVisitor = new DataContextPropertyAssigningVisitor();

            resolvedView.Accept(contextSpaceVisitor);

            var styleVisitor = new StylingVisitor(configuration);

            resolvedView.Accept(styleVisitor);

            //TODO: fix usage validator
            //var validationVisitor = new ControlUsageValidationVisitor(configuration);
            //resolvedView.Accept(validationVisitor);
            //if (validationVisitor.Errors.Any())
            //{
            //    var controlUsageError = validationVisitor.Errors.First();
            //    throw new DotvvmCompilationException(controlUsageError.ErrorMessage, controlUsageError.Nodes.SelectMany(n => n.Tokens));
            //}

            DefaultViewCompilerCodeEmitter emitter = null;
            string fullClassName = null;

            if (Options.FullCompile)
            {
                var namespaceName = DefaultControlBuilderFactory.GetNamespaceFromFileName(file.FileName, file.LastWriteDateTimeUtc);
                var className     = DefaultControlBuilderFactory.GetClassFromFileName(file.FileName) + "ControlBuilder";
                fullClassName = namespaceName + "." + className;
                emitter       = new CompileTimeCodeEmitter(configuration.ServiceProvider.GetService <RefObjectSerializer>(), ObjectsClassName);
                var compilingVisitor = new ViewCompilingVisitor(emitter, configuration.ServiceProvider.GetService <IBindingCompiler>(), className);

                resolvedView.Accept(compilingVisitor);

                // compile master pages
                if (resolvedView.Directives.ContainsKey("masterPage"))
                {
                    CompileFile(resolvedView.Directives["masterPage"].Single().Value);
                }

                compilation = compilation
                              .AddSyntaxTrees(emitter.BuildTree(namespaceName, className, fileName))
                              .AddReferences(emitter.UsedAssemblies
                                             .Select(a => CompiledAssemblyCache.Instance.GetAssemblyMetadata(a.Key)));
            }

            Program2.WriteInfo($"The view { fileName } compiled successfully.");

            var res = new ViewCompilationResult {
                BuilderClassName = fullClassName,
                ControlType      = resolvedView.Metadata.Type,
                DataContextType  = emitter?.BuilderDataContextType,
                ResolvedTree     = Options.OutputResolvedDothtmlMap ? resolvedView : null
            };

            BuildFileResult(fileName, res);
            return(res);
        }