Example #1
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            var sw = new Stopwatch();

            sw.Start();
            var componentModel    = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
            var workspace         = componentModel.GetService <VisualStudioWorkspace>();
            var docIds            = workspace.CurrentSolution.GetDocumentIdsWithFilePath(wszInputFilePath);
            var project           = FindContainingProject(workspace.CurrentSolution.Projects.ToList(), wszInputFilePath);
            var compilationResult = HbsCompiler.Compile(bstrInputFileContents, wszDefaultNamespace, Path.GetFileNameWithoutExtension(wszInputFilePath), project);

            sw.Stop();
            if (compilationResult.Item2.Any())
            {
                foreach (var error in compilationResult.Item2)
                {
                    pGenerateProgress.GeneratorError(0, 1, error.Message, (uint)error.Line - 1, (uint)error.Column - 1);
                }
            }
            byte[] bytes = Encoding.UTF8.GetBytes(compilationResult.Item1);
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(bytes.Length);
            Marshal.Copy(bytes, 0, rgbOutputFileContents[0], bytes.Length);
            pcbOutput = (uint)bytes.Length;
            return(compilationResult.Item2.Any()?VSConstants.E_FAIL:VSConstants.S_OK);
        }
 private static Tuple <string, IEnumerable <HandlebarsException> > CompileHandlebarsTemplate(string content, string @namespace, string name, Project containingProject, CompilerOptions options)
 {
     if (options.DryRun)
     {
         Console.WriteLine($"Compile file '{name}' in namespace '{@namespace}'");
         return(null);
     }
     else
     {
         Console.WriteLine($"Compiling '{name}'...");
         return(HbsCompiler.Compile(content, @namespace, name, containingProject));
     }
 }
        protected static Assembly CompileTemplatesToAssembly(Type testClassType)
        {
            var solutionFile = Path.Combine(Directory.CreateDirectory(Environment.CurrentDirectory).Parent.Parent.Parent.FullName, "CompiledHandlebars.sln");
            List <SyntaxTree> compiledTemplates = new List <SyntaxTree>();
            var workspace       = MSBuildWorkspace.Create();
            var sol             = workspace.OpenSolutionAsync(solutionFile).Result;
            var project         = sol.Projects.First(x => x.Name.Equals("CompiledHandlebars.CompilerTests"));
            var folderStructure = new List <string>();

            folderStructure.Add("TestTemplates");
            folderStructure.AddRange(testClassType.Namespace.Split('.').Skip(2));
            folderStructure.Add(testClassType.Name);
            foreach (MethodInfo methodInfo in (testClassType).GetMethods())
            {
                var attrList = methodInfo.GetCustomAttributes(typeof(RegisterHandlebarsTemplateAttribute), false) as RegisterHandlebarsTemplateAttribute[];
                foreach (var template in attrList)
                {//Get compiled templates
                    var code = HbsCompiler.Compile(template._contents, template._overridenNameSpace ?? testClassType.Namespace, template._name, project);
                    compiledCode.Add(template._name, code);
                    if (template._include)
                    {
                        //Check if template already exits
                        var doc = project.Documents.FirstOrDefault(x => x.Name.Equals(string.Concat(template._name, ".cs")));
                        if (doc != null)
                        {//And change it if it does
                            project = doc.WithSyntaxRoot(CSharpSyntaxTree.ParseText(SourceText.From(AppendErrorsToCode(code.Item1, code.Item2))).GetRoot()).Project;
                        }
                        else
                        {//Otherwise add a new document
                            project = project.AddDocument(string.Concat(template._name, ".cs"), SourceText.From(AppendErrorsToCode(code.Item1, code.Item2)), folderStructure).Project;
                        }
                        //Then add the new version
                        compiledTemplates.Add(CSharpSyntaxTree.ParseText(code.Item1));
                        workspace.TryApplyChanges(project.Solution);
                        project = workspace.CurrentSolution.Projects.First(x => x.Name.Equals("CompiledHandlebars.CompilerTests"));
                    }
                }
            }
            string assemblyName = Path.GetRandomFileName();

            MetadataReference[] references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(WebUtility).Assembly.Location),
                MetadataReference.CreateFromFile(testClassType.Assembly.Location),
            };
            var compilation = CSharpCompilation.Create(
                assemblyName,
                compiledTemplates,
                references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var ms = new MemoryStream())
            {
                var emitResult = compilation.Emit(ms);

                if (!emitResult.Success)
                {
                    IEnumerable <Diagnostic> failures = emitResult.Diagnostics.Where(diagnostic =>
                                                                                     diagnostic.IsWarningAsError ||
                                                                                     diagnostic.Severity == DiagnosticSeverity.Error);


                    throw new Exception(failures.First().GetMessage());
                }
                ms.Seek(0, SeekOrigin.Begin);
                return(Assembly.Load(ms.ToArray()));
            }
        }