public CompilationResult Execute() { Program2.WriteInfo("Initializing..."); Init(); Program2.WriteInfo("Compiling views..."); foreach (var file in Options.DothtmlFiles) { try { var viewCompilationResult = CompileFile(file); } catch (DotvvmCompilationException exception) { result.Files.Add(file, new FileCompilationResult { Errors = new List <Exception>() { exception } }); } } if (Options.FullCompile) { Program2.WriteInfo("Emitting assemblies..."); Save(); } Program2.WriteInfo("Building compilation results..."); return(result); }
/// <summary> /// Tries to find and load assembly from folder specified in options and environment variable at the start of the app. /// </summary> private static bool TryLoadAssemblyFromUserFolders(string name, out Assembly loadAssemblyFromFile) { foreach (var path in Program2.assemblySearchPaths) { Program2.WriteInfo($"Searching in {path}"); var assemblyPath = Path.Combine(path, new AssemblyName(name).Name); if (File.Exists(assemblyPath + ".dll")) { { loadAssemblyFromFile = LoadAssemblyFromFile(assemblyPath + ".dll"); Program2.WriteInfo($"Assembly found at {assemblyPath + ".dll"}"); return(true); } } if (File.Exists(assemblyPath + ".exe")) { { loadAssemblyFromFile = LoadAssemblyFromFile(assemblyPath + ".exe"); Program2.WriteInfo($"Assembly found at {assemblyPath + ".exe"}"); return(true); } } } loadAssemblyFromFile = null; return(false); }
private void Save() { if (Options.FullCompile) { var bindingsAssemblyPath = bindingCompiler.OutputFileName; var(builder, fields) = configuration.ServiceProvider.GetService <RefObjectSerializer>().CreateBuilder(configuration); bindingCompiler.AddSerializedObjects(ObjectsClassName, builder, fields); bindingCompiler.SaveAssembly(); Program2.WriteInfo($"Bindings saved to {bindingsAssemblyPath}."); compilation = compilation.AddReferences(MetadataReference.CreateFromFile(Path.GetFullPath(bindingsAssemblyPath))); var compiledViewsFileName = Path.Combine(Options.OutputPath, Options.AssemblyName + "_Views" + ".dll"); var result = compilation.Emit(compiledViewsFileName); if (!result.Success) { throw new Exception("The compilation failed!"); } //TODO: merge emitted assemblies //var merger = new ILMerging.ILMerge() { // OutputFile = Path.Combine(Options.OutputPath, Options.AssemblyName + ".dll"), //}; //merger.SetInputAssemblies(new[] { compiledViewsFileName, bindingsAssemblyPath }); //merger.SetSearchDirectories(new[] { Path.GetDirectoryName(Options.WebSiteAssembly) }); //merger.Merge(); //File.Delete(compiledViewsFileName); //File.Delete(bindingsAssemblyPath); Program2.WriteInfo($"Compiled views saved to {compiledViewsFileName}."); } }
internal static Assembly ResolveAssembly(object sender, ResolveEventArgs args) { if (Interlocked.CompareExchange(ref isResolveRunning, 1, 0) != 0) { return(null); } try { Program2.WriteInfo($"Resolving assembly `{args.Name}`."); var r = LoadFromAlternativeFolder(args.Name); if (r != null) { return(r); } Program2.WriteInfo($"Assembly `{args.Name}` resolve failed."); //We cannot do typeof(something).Assembly, because besides the compiler there are no dlls, doing that will try to load the dll from the disk //which fails, so this event is called again call this event... return(null); } finally { isResolveRunning = 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); }