public ViewCompilingVisitor(DefaultViewCompilerCodeEmitter emitter, IBindingCompiler bindingCompiler,
                             string className)
 {
     this.emitter         = emitter;
     this.className       = className;
     this.bindingCompiler = bindingCompiler;
 }
 public ViewCompilingVisitor(DefaultViewCompilerCodeEmitter emitter, IBindingCompiler bindingCompiler, string className, Func <ResolvedBinding, string> bindingIdGenerator)
 {
     this.emitter            = emitter;
     this.className          = className;
     this.bindingCompiler    = bindingCompiler;
     this.bindingIdGenerator = bindingIdGenerator;
 }
Beispiel #3
0
 public ViewCompilingVisitor(DefaultViewCompilerCodeEmitter emitter, IBindingCompiler bindingCompiler, string className, Func<ResolvedBinding, string> bindingIdGenerator)
 {
     this.emitter = emitter;
     this.className = className;
     this.bindingCompiler = bindingCompiler;
     this.bindingIdGenerator = bindingIdGenerator;
 }
Beispiel #4
0
        public virtual ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding, string id, Type expectedType)
        {
            var compilerAttribute = GetCompilationAttribute(binding.BindingType);
            var requirements      = compilerAttribute.GetRequirements(binding.BindingType);

            var expression = new Lazy <Expression>(() => compilerAttribute.GetExpression(binding));
            var compiled   = new CompiledBindingExpression();

            compiled.Delegate       = TryExecute(binding.BindingNode, "Error while compiling binding to delegate.", requirements.Delegate, () => CompileExpression(compilerAttribute.CompileToDelegate(binding.GetExpression(), binding.DataContextTypeStack, expectedType), binding.DebugInfo));
            compiled.UpdateDelegate = TryExecute(binding.BindingNode, "Error while compiling update delegate.", requirements.UpdateDelegate, () => compilerAttribute.CompileToUpdateDelegate(binding.GetExpression(), binding.DataContextTypeStack).Compile());
            compiled.OriginalString = TryExecute(binding.BindingNode, "hey, no, that should not happen. Really.", requirements.OriginalString, () => binding.Value);
            compiled.Expression     = TryExecute(binding.BindingNode, "Could not get binding expression.", requirements.Expression, () => binding.GetExpression());
            compiled.Id             = id;
            compiled.ActionFilters  = TryExecute(binding.BindingNode, "", requirements.ActionFilters, () => compilerAttribute.GetActionFilters(binding.GetExpression()).ToArray());

            compiled.Javascript = TryExecute(binding.BindingNode, "Could not compile binding to Javascript.", requirements.Javascript, () => compilerAttribute.CompileToJavascript(binding, compiled));

            var index = Interlocked.Increment(ref globalBindingIndex);

            if (!GlobalBindingList.TryAdd(index, compiled))
            {
                throw new Exception("internal bug");
            }
            return(EmitGetCompiledBinding(index));
        }
        protected ExpressionSyntax GetCompiledBindingCreation(DefaultViewCompilerCodeEmitter emitter, string methodName, string updateMethodName, string originalString, ExpressionSyntax[] actionFilters, string javascript, string id)
        {
            var dict = new Dictionary<string, ExpressionSyntax>();
            if (methodName != null) dict.Add(nameof(CompiledBindingExpression.Delegate), SyntaxFactory.ParseName(methodName));
            if (updateMethodName != null) dict.Add(nameof(CompiledBindingExpression.UpdateDelegate), SyntaxFactory.ParseName(updateMethodName));
            if (originalString != null) dict.Add(nameof(CompiledBindingExpression.OriginalString), emitter.EmitValue(originalString));
            if (javascript != null) dict.Add(nameof(CompiledBindingExpression.Javascript), emitter.EmitValue(javascript));
            if (id != null) dict.Add(nameof(CompiledBindingExpression.Id), emitter.EmitValue(id));
            if (actionFilters != null)
                dict.Add(nameof(CompiledBindingExpression.ActionFilters),
                    SyntaxFactory.ArrayCreationExpression(
                        SyntaxFactory.ArrayType(SyntaxFactory.ParseTypeName(typeof(ActionFilterAttribute).FullName))
                            .WithRankSpecifiers(
                                SyntaxFactory.SingletonList<ArrayRankSpecifierSyntax>(
                                    SyntaxFactory.ArrayRankSpecifier(
                                        SyntaxFactory.SingletonSeparatedList<ExpressionSyntax>(
                                            SyntaxFactory.OmittedArraySizeExpression())))),
                        SyntaxFactory.InitializerExpression(SyntaxKind.CollectionInitializerExpression,
                            SyntaxFactory.SeparatedList(actionFilters))));

            return SyntaxFactory.ObjectCreationExpression(
                SyntaxFactory.ParseTypeName(typeof(CompiledBindingExpression).FullName),
                SyntaxFactory.ArgumentList(),
                SyntaxFactory.InitializerExpression(SyntaxKind.ObjectInitializerExpression,
                    SyntaxFactory.SeparatedList(
                        dict.Select(p =>
                             (ExpressionSyntax)SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                SyntaxFactory.IdentifierName(p.Key),
                                p.Value
                            )
                        )
                    )
                )
            );
        }
Beispiel #6
0
 public ViewCompilingVisitor(DefaultViewCompilerCodeEmitter emitter, CompiledAssemblyCache compiledAssemblyCache, IBindingCompiler bindingCompiler,
                             string className)
 {
     this.emitter = emitter;
     this.compiledAssemblyCache = compiledAssemblyCache;
     this.className             = className;
     this.bindingCompiler       = bindingCompiler;
 }
        /// <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 #8
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);
            }
                   );
        }
 public override ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding, string id, Type expectedType)
 {
     var info = PrecompileBinding(binding, id, expectedType);
     if (emitter != null)
     {
         return GetCachedInitializer(emitter, GetCompiledBindingCreation(emitter, info.MethodName, info.UpdateMethodName, info.OriginalString, this.GetAttributeInitializers(info.ActionFilters, emitter)?.ToArray(), info.Javascript, id));
     }
     else return null;
 }
Beispiel #10
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 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 = (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 #11
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);
                    }
                }

                foreach (var visitor in config.TreeVisitors)
                {
                    visitor().ApplyAction(resolvedView.Accept).ApplyAction(v => (v as IDisposable)?.Dispose());
                }


                var validationVisitor = this.controlValidatorFactory.Invoke();
                validationVisitor.VisitAndAssert(resolvedView);

                var emitter = new DefaultViewCompilerCodeEmitter();
                var compilingVisitor = new ViewCompilingVisitor(emitter, bindingCompiler, className);

                resolvedView.Accept(compilingVisitor);

                return AddToCompilation(compilation, emitter, fileName, namespaceName, className);
            }
                   );
        }
        protected virtual CSharpCompilation AddToCompilation(CSharpCompilation compilation, DefaultViewCompilerCodeEmitter emitter, string fileName, string namespaceName, string className)
        {
            var tree = emitter.BuildTree(namespaceName, className, fileName);

            return(compilation
                   .AddSyntaxTrees(tree)
                   .AddReferences(emitter.UsedAssemblies
                                  .Select(a => assemblyCache.GetAssemblyMetadata(a))));
        }
 protected IEnumerable<ExpressionSyntax> GetAttributeInitializers(IEnumerable<CustomAttributeData> attributes, DefaultViewCompilerCodeEmitter emitter)
 {
     return attributes?.Select(a => emitter?.EmitAttributeInitializer(a)).ToArray();
 }
Beispiel #14
0
 protected virtual CSharpCompilation AddToCompilation(CSharpCompilation compilation, DefaultViewCompilerCodeEmitter emitter, string fileName, string namespaceName, string className)
 {
     var tree = emitter.BuildTree(namespaceName, className, fileName);
     return compilation
         .AddSyntaxTrees(tree)
         .AddReferences(emitter.UsedAssemblies
             .Select(a => assemblyCache.GetAssemblyMetadata(a)));
 }
        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 styleVisitor = new StylingVisitor(configuration.Styles);
            resolvedView.Accept(styleVisitor);

            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 DefaultViewCompilerCodeEmitter();
                var compilingVisitor = new ViewCompilingVisitor(emitter, configuration.ServiceLocator.GetService<IBindingCompiler>(), className, b => configuration.ServiceLocator.GetService<IBindingIdGenerator>().GetId(b, fileName));

                resolvedView.Accept(compilingVisitor);

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

                compilation = compilation
                    .AddSyntaxTrees(emitter.BuildTree(namespaceName, className, fileName)/*.Select(t => SyntaxFactory.ParseSyntaxTree(t.GetRoot().NormalizeWhitespace().ToString()))*/)
                    .AddReferences(emitter.UsedAssemblies
                        .Select(a => CompiledAssemblyCache.Instance.GetAssemblyMetadata(a)));
            }

            Program.WriteInfo($"view { fileName } compiled");

            var res = new ViewCompilationResult
            {
                BuilderClassName = fullClassName,
                ControlType = resolvedView.Metadata.Type,
                DataContextType = emitter?.BuilderDataContextType,
                ResolvedTree = Options.OutputResolvedDothtmlMap ? resolvedView : null
            };
            BuildFileResult(fileName, res);
            return res;
        }
        public virtual ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding)
        {
            var newbinding = CreateMinimalClone(binding);

            return(emitter.EmitValue(newbinding));
        }
Beispiel #17
0
 protected ExpressionSyntax EmitCreateArray(Type elementType, System.Collections.IEnumerable values)
 {
     return(DefaultViewCompilerCodeEmitter.EmitCreateArray(UseType(elementType), values.Cast <object>().Select(EmitValue)));
 }
Beispiel #18
0
        protected virtual CSharpCompilation AddToCompilation(CSharpCompilation compilation, DefaultViewCompilerCodeEmitter emitter, string fileName, string namespaceName, string className)
        {
            var tree = emitter.BuildTree(namespaceName, className, fileName);

            return(compilation
                   .AddSyntaxTrees(tree)
                   .AddReferences(emitter.UsedAssemblies
                                  .Select(a => GetAssemblyCache().GetAssemblyMetadata(a.Key).WithAliases(ImmutableArray.Create(a.Value, "global")))));
        }
 protected ExpressionSyntax GetCachedInitializer(DefaultViewCompilerCodeEmitter emitter, ExpressionSyntax constructor)
 {
     // emit (cache ?? (cache = ctor()))
     var cacheId = GetCacheName(typeof(CompiledBindingExpression));
     return SyntaxFactory.BinaryExpression(SyntaxKind.CoalesceExpression, cacheId,
         SyntaxFactory.ParenthesizedExpression(
             SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                 cacheId, constructor)));
 }