public ViewCompilingVisitor(DefaultViewCompilerCodeEmitter emitter, IBindingCompiler bindingCompiler, string className, Func <ResolvedBinding, string> bindingIdGenerator)
 {
     this.emitter            = emitter;
     this.className          = className;
     this.bindingCompiler    = bindingCompiler;
     this.bindingIdGenerator = bindingIdGenerator;
 }
Example #2
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, () => compilerAttribute.CompileToDelegate(binding.GetExpression(), binding.DataContextTypeStack, expectedType).Compile());
            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.CompileToJs(binding, compiled));

            var index = Interlocked.Increment(ref globalBindingIndex);

            if (!GlobalBindingList.TryAdd(index, compiled))
            {
                throw new Exception("internal bug");
            }
            return(EmitGetCompiledBinding(index));
        }
Example #3
0
        /// <summary>
        /// Builds the assembly.
        /// </summary>
        private Assembly BuildAssembly(DefaultViewCompilerCodeEmitter emitter, string assemblyName, string namespaceName, string className)
        {
            using (var ms = new MemoryStream())
            {
                // static references
                var staticReferences = new[]
                {
                    typeof(object).Assembly,
                    typeof(RuntimeBinderException).Assembly,
                    typeof(System.Runtime.CompilerServices.DynamicAttribute).Assembly,
                    Assembly.GetExecutingAssembly()
                }
                .Concat(configuration.Markup.Assemblies.Select(Assembly.Load)).Distinct()
                .Select(a => assemblyCache.GetAssemblyMetadata(a));

                // add dynamic references
                var dynamicReferences = emitter.UsedControlBuilderTypes.Select(t => t.Assembly).Concat(emitter.UsedAssemblies).Distinct()
                    .Select(a => assemblyCache.GetAssemblyMetadata(a));

                // compile
                var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
                var compilation = CSharpCompilation.Create(
                    assemblyName,
                    emitter.BuildTree(namespaceName, className),
                    Enumerable.Concat(staticReferences, dynamicReferences),
                    options);

                var result = compilation.Emit(ms);
                if (result.Success)
                {
                    var assembly = Assembly.Load(ms.ToArray());
                    assemblyCache.AddAssembly(assembly, compilation.ToMetadataReference());
                    return assembly;
                }
                else
                {
                    throw new Exception("The compilation failed! This is most probably bug in the DotVVM framework.\r\n\r\n"
                        + string.Join("\r\n", result.Diagnostics)
                        + "\r\n\r\n" + compilation.SyntaxTrees[0] + "\r\n\r\n");
                }
            }
        }
        /// <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));
        }
Example #5
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 IControlBuilder CompileView(IReader reader, string fileName, string assemblyName, 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);
            
            resolvedView.Accept(compilingVisitor);

            // create the assembly
            var assembly = BuildAssembly(emitter, assemblyName, namespaceName, className);
            var controlBuilder = (IControlBuilder)assembly.CreateInstance(namespaceName + "." + className);
            resolvedView.Metadata.ControlBuilderType = controlBuilder.GetType();
            return controlBuilder;
        }
Example #6
0
 public ViewCompilingVisitor(DefaultViewCompilerCodeEmitter emitter, IBindingCompiler bindingCompiler, string className)
 {
     this.emitter = emitter;
     this.className = className;
     this.bindingCompiler = bindingCompiler;
 }
        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))));
        }