public ViewCompilingVisitor(DefaultViewCompilerCodeEmitter emitter, IBindingCompiler bindingCompiler, string className, Func <ResolvedBinding, string> bindingIdGenerator) { this.emitter = emitter; this.className = className; this.bindingCompiler = bindingCompiler; this.bindingIdGenerator = bindingIdGenerator; }
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)); }
/// <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)); }
/// <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; }
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)))); }