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; }
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, () => 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 ) ) ) ) ); }
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)); }
/// <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; }
/// <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); }
/// <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(); }
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)); }
protected ExpressionSyntax EmitCreateArray(Type elementType, System.Collections.IEnumerable values) { return(DefaultViewCompilerCodeEmitter.EmitCreateArray(UseType(elementType), values.Cast <object>().Select(EmitValue))); }
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))); }