예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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}.");
            }
        }
예제 #4
0
        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;
            }
        }
예제 #5
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);
        }