private void RunDesignTimeTagHelpersTest(IEnumerable <TagHelperDescriptor> descriptors) { // Arrange var projectEngine = CreateProjectEngine(builder => { builder.ConfigureDocumentClassifier(); // Some of these tests use templates builder.AddTargetExtension(new TemplateTargetExtension()); InheritsDirective.Register(builder); SectionDirective.Register(builder); }); var projectItem = CreateProjectItemFromFile(); var imports = GetImports(projectEngine, projectItem); // Act var codeDocument = projectEngine.ProcessDesignTime(RazorSourceDocument.ReadFrom(projectItem), imports, descriptors.ToList()); // Assert AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode()); AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument()); AssertSourceMappingsMatchBaseline(codeDocument); }
// Internal for testing internal static void AddDefaultDirectivesImport(List <RazorSourceDocument> imports) { using (var stream = new MemoryStream()) using (var writer = new StreamWriter(stream, Encoding.UTF8)) { writer.WriteLine("@using System"); writer.WriteLine("@using System.Collections.Generic"); writer.WriteLine("@using System.Linq"); writer.WriteLine("@using System.Threading.Tasks"); writer.WriteLine("@using Microsoft.AspNetCore.Mvc"); writer.WriteLine("@using Microsoft.AspNetCore.Mvc.Rendering"); writer.WriteLine("@using Microsoft.AspNetCore.Mvc.ViewFeatures"); writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel> Html"); writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json"); writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component"); writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url"); writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider"); writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor"); writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor"); writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor"); writer.Flush(); stream.Position = 0; var defaultMvcImports = RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8); imports.Add(defaultMvcImports); } }
// Internal for testing internal static IReadOnlyList <RazorSourceDocument> GetImportSourceDocuments( IReadOnlyList <RazorProjectItem> importItems, bool suppressExceptions = false) { var imports = new List <RazorSourceDocument>(); for (var i = 0; i < importItems.Count; i++) { var importItem = importItems[i]; if (importItem.Exists) { try { // Normal import, has file paths, content etc. var sourceDocument = RazorSourceDocument.ReadFrom(importItem); imports.Add(sourceDocument); } catch (IOException) when(suppressExceptions) { // Something happened when trying to read the item from disk. // Catch the exception so we don't crash the editor. } } } return(imports); }
/// <summary> /// Gets <see cref="RazorSourceDocument"/> that are applicable to the specified <paramref name="projectItem"/>. /// </summary> /// <param name="projectItem">The <see cref="RazorProjectItem"/>.</param> /// <returns>The sequence of applicable <see cref="RazorSourceDocument"/>.</returns> public virtual IEnumerable <RazorSourceDocument> GetImports(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } var result = new List <RazorSourceDocument>(); var importProjectItems = GetImportItems(projectItem); foreach (var importItem in importProjectItems) { if (importItem.Exists) { // We want items in descending order. FindHierarchicalItems returns items in ascending order. result.Insert(0, RazorSourceDocument.ReadFrom(importItem)); } } if (Options.DefaultImports != null) { result.Insert(0, Options.DefaultImports); } return(result); }
public Task <GeneratedDocument> GenerateDocumentAsync(Guid projectIdBytes, string projectDebugName, string filePath, string text, CancellationToken cancellationToken = default(CancellationToken)) { var projectId = ProjectId.CreateFromSerialized(projectIdBytes, projectDebugName); var engine = RazorEngine.Create(); RazorSourceDocument source; using (var stream = new MemoryStream()) { var bytes = Encoding.UTF8.GetBytes(text); stream.Write(bytes, 0, bytes.Length); stream.Seek(0L, SeekOrigin.Begin); source = RazorSourceDocument.ReadFrom(stream, filePath, Encoding.UTF8); } var code = RazorCodeDocument.Create(source); engine.Process(code); var csharp = code.GetCSharpDocument(); if (csharp == null) { throw new InvalidOperationException(); } return(Task.FromResult(new GeneratedDocument() { Text = csharp.GeneratedCode, })); }
private static IReadOnlyList <RazorSourceDocument> GetImports(RazorProjectEngine projectEngine, RazorProjectItem projectItem) { var importFeatures = projectEngine.ProjectFeatures.OfType <IImportProjectFeature>(); var importItems = importFeatures.SelectMany(f => f.GetImports(projectItem)); var importSourceDocuments = importItems.Where(i => i.Exists).Select(i => RazorSourceDocument.ReadFrom(i)).ToList(); return(importSourceDocuments); }
public static bool TryGetPageDirective(ILogger logger, RazorProjectItem projectItem, out string template) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); return(TryGetPageDirective(logger, sourceDocument, out template)); }
public RazorViewCompiler(IFileSystem fileSystem, IRazorConfiguration razorConfiguration) { this.fileSystem = fileSystem; this.razorConfiguration = razorConfiguration; this.razorTemplateEngine = BuildRazorTemplateEngine(RazorProjectFileSystem.Create(this.fileSystem.GetFullPath("~/"))); var defaultTagHelpers = razorConfiguration.GetDefaultTagHelpers(); var defaultDirectivesProjectItem = new DefaultDirectivesProjectItem(this.razorConfiguration.GetDefaultNamespaces(), defaultTagHelpers); this.defaultImports = new[] { RazorSourceDocument.ReadFrom(defaultDirectivesProjectItem) }; this.GetReferenceAssemblies(); }
public void ReadFrom_EmptyStream_WithEncoding() { // Arrange var content = TestRazorSourceDocument.CreateStreamContent(content: string.Empty, encoding: Encoding.UTF32); // Act var document = RazorSourceDocument.ReadFrom(content, "file.cshtml", Encoding.UTF32); // Assert Assert.Equal("file.cshtml", document.FilePath); Assert.Same(Encoding.UTF32, Assert.IsType <StreamSourceDocument>(document).Encoding); }
static RazorCodeDocument CreateCodeDocument(string rootDir, string sourceFileName) { string detectedLayout = null; string detectedTagName = null; using (var ms = new MemoryStream()) { using (var sw = new StreamWriter(ms)) { var filesToIncludeInOrder = ViewImportsFromRootToSameDir(rootDir, sourceFileName) .Concat(new[] { sourceFileName }); var sourceLines = filesToIncludeInOrder.SelectMany(file => File.ReadAllLines(file)).ToList(); string lastInheritsLine = null; foreach (var line in sourceLines) { const string inheritsLinePrefix = "@inherits "; if (line.StartsWith(inheritsLinePrefix)) { lastInheritsLine = line.Substring(inheritsLinePrefix.Length).Replace("<TModel>", string.Empty); continue; } const string layoutLinePrefix = "@layout "; if (line.StartsWith(layoutLinePrefix)) { detectedLayout = line.Substring(layoutLinePrefix.Length); continue; } var tagNameRegex = new Regex("^\\s*\\@TagName\\(\\s*\\\"([^\\\"]+)\\\"\\s*\\)"); var tagNameMatch = tagNameRegex.Match(line); if (tagNameMatch.Success) { detectedTagName = tagNameMatch.Groups[1].Value; continue; } sw.WriteLine(line); } sw.Flush(); ms.Position = 0; var sourceDoc = RazorSourceDocument.ReadFrom(ms, sourceFileName); var codeDoc = RazorCodeDocument.Create(sourceDoc); codeDoc.Items["DetectedLayout"] = detectedLayout; codeDoc.Items["DetectedTagName"] = detectedTagName; codeDoc.Items["DetectedBaseClass"] = lastInheritsLine; return(codeDoc); } } }
public void ReadFrom_WithProjectItem_FallbackToFilePath_WhenRelativePhysicalPathIsNull() { // Arrange var filePath = "filePath.cshtml"; var projectItem = new TestRazorProjectItem(filePath, relativePhysicalPath: null); // Act var document = RazorSourceDocument.ReadFrom(projectItem); // Assert Assert.Equal(filePath, document.FilePath); Assert.Equal(filePath, document.RelativePath); }
public void ReadFrom() { // Arrange var content = TestRazorSourceDocument.CreateStreamContent(); // Act var document = RazorSourceDocument.ReadFrom(content, "file.cshtml"); // Assert Assert.IsType <StreamSourceDocument>(document); Assert.Equal("file.cshtml", document.FilePath); Assert.Same(Encoding.UTF8, document.Encoding); }
public void ReadFrom_ProjectItem_NoRelativePath() { // Arrange var projectItem = new TestRazorProjectItem("filePath.cshtml", "c:\\myapp\\filePath.cshtml", basePath: "c:\\myapp\\"); // Act var document = RazorSourceDocument.ReadFrom(projectItem); // Assert Assert.Equal("c:\\myapp\\filePath.cshtml", document.FilePath); Assert.Equal("filePath.cshtml", document.RelativePath); Assert.Equal(projectItem.Content, ReadContent(document)); }
public void ProcessDesignTime_WithNullImports_SetsEmptyListOnCodeDocument() { // Arrange var projectItem = new TestRazorProjectItem("Index.cshtml"); var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty); // Act var codeDocument = projectEngine.ProcessDesignTime(RazorSourceDocument.ReadFrom(projectItem), "test", importSources: null, tagHelpers: null); // Assert Assert.Empty(codeDocument.Imports); }
public void ReadFrom_WithProjectItem_UsesRelativePhysicalPath() { // Arrange var filePath = "filePath.cshtml"; var relativePhysicalPath = "relative-path.cshtml"; var projectItem = new TestRazorProjectItem(filePath, relativePhysicalPath: relativePhysicalPath); // Act var document = RazorSourceDocument.ReadFrom(projectItem); // Assert Assert.Equal(relativePhysicalPath, document.FilePath); Assert.Equal(relativePhysicalPath, document.RelativePath); }
public void ReadFrom_WithProperties() { // Arrange var content = TestRazorSourceDocument.CreateStreamContent(encoding: Encoding.UTF32); var properties = new RazorSourceDocumentProperties("c:\\myapp\\filePath.cshtml", "filePath.cshtml"); // Act var document = RazorSourceDocument.ReadFrom(content, Encoding.UTF32, properties); // Assert Assert.Equal("c:\\myapp\\filePath.cshtml", document.FilePath); Assert.Equal("filePath.cshtml", document.RelativePath); Assert.Same(Encoding.UTF32, Assert.IsType <StreamSourceDocument>(document).Encoding); }
public Type Load(string text) { var stream = new MemoryStream(); var writer = new StreamWriter(stream); writer.Write(text); writer.Flush(); stream.Seek(0L, SeekOrigin.Begin); var relativePath = "/TestPage"; var source = RazorSourceDocument.ReadFrom(stream, relativePath); return(Load(source, relativePath)); }
public virtual async Task <RazorCodeDocument> CreateCodeDocumentAsync(TkRazorProjectItem projectItem) { TkDebug.AssertArgumentNull(projectItem, nameof(projectItem), this); TkDebug.AssertArgument(projectItem.Exists, nameof(projectItem), $"Project can not find template with key {projectItem.Key}", this); using (var stream = projectItem.Read()) { RazorSourceDocument source = RazorSourceDocument.ReadFrom(stream, projectItem.Key); IEnumerable <RazorSourceDocument> imports = await GetImportsAsync(projectItem); return(RazorCodeDocument.Create(source, imports)); } }
public void Process_WithFileKind_SetsOnCodeDocument() { // Arrange var projectItem = new TestRazorProjectItem("Index.cshtml"); var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty); // Act var codeDocument = projectEngine.Process(RazorSourceDocument.ReadFrom(projectItem), "test", Array.Empty <RazorSourceDocument>(), tagHelpers: null); // Assert var actual = codeDocument.GetFileKind(); Assert.Equal("test", actual); }
public void ProcessDesignTime_WithNullTagHelpers_SetsOnCodeDocument() { // Arrange var projectItem = new TestRazorProjectItem("Index.cshtml"); var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty); // Act var codeDocument = projectEngine.ProcessDesignTime(RazorSourceDocument.ReadFrom(projectItem), "test", Array.Empty <RazorSourceDocument>(), tagHelpers: null); // Assert var tagHelpers = codeDocument.GetTagHelpers(); Assert.Null(tagHelpers); }
internal protected RazorSourceDocument GetNamespacesImports() { using (var stream = new MemoryStream()) using (var writer = new StreamWriter(stream, Encoding.UTF8)) { foreach (string @namespace in Namespaces) { writer.WriteLine($"@using {@namespace}"); } writer.Flush(); stream.Position = 0; return(RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8)); } }
internal protected RazorSourceDocument GetDefaultImports() { using (var stream = new MemoryStream()) using (var writer = new StreamWriter(stream, Encoding.UTF8)) { foreach (string line in GetDefaultImportLines()) { writer.WriteLine(line); } writer.Flush(); stream.Position = 0; return(RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8)); } }
/// <summary> /// Generates a <see cref="RazorCodeDocument"/> for the specified <paramref name="projectItem"/>. /// </summary> /// <param name="projectItem">The <see cref="RazorProjectItem"/>.</param> /// <returns>The created <see cref="RazorCodeDocument"/>.</returns> public virtual RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } if (!projectItem.Exists) { throw new InvalidOperationException(Resources.FormatRazorTemplateEngine_ItemCouldNotBeFound(projectItem.FilePath)); } var source = RazorSourceDocument.ReadFrom(projectItem); var imports = GetImports(projectItem); return(RazorCodeDocument.Create(source, imports)); }
private static RazorSourceDocument GetDefaultImports() { using (var stream = new MemoryStream()) using (var writer = new StreamWriter(stream, Encoding.UTF8)) { // TODO: Add other commonly-used Blazor namespaces here. Can't do so yet // because the tooling wouldn't know about it, so it would still look like // an error if you hadn't explicitly imported them. writer.WriteLine("@using System"); writer.WriteLine("@using System.Collections.Generic"); writer.WriteLine("@using System.Linq"); writer.WriteLine("@using System.Threading.Tasks"); writer.Flush(); stream.Position = 0; return(RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8)); } }
/// <summary> /// Gets <see cref="RazorSourceDocument"/> that are applicable to the specified <paramref name="projectItem"/>. /// </summary> /// <param name="projectItem">The <see cref="RazorLightProjectItem"/>.</param> /// <returns>The sequence of applicable <see cref="RazorSourceDocument"/>.</returns> public virtual async Task <IEnumerable <RazorSourceDocument> > GetImportsAsync(RazorLightProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } if (projectItem is TextSourceRazorProjectItem) { return(Enumerable.Empty <RazorSourceDocument>()); } var result = new List <RazorSourceDocument>(); IEnumerable <RazorLightProjectItem> importProjectItems = await Project.GetImportsAsync(projectItem.Key); foreach (var importItem in importProjectItems) { if (importItem.Exists) { using (var stream = importItem.Read()) { result.Insert(0, RazorSourceDocument.ReadFrom(stream, null)); } } } if (Namespaces != null) { RazorSourceDocument namespacesImports = GetNamespacesImports(); if (namespacesImports != null) { result.Insert(0, namespacesImports); } } if (DefaultImports != null) { result.Insert(0, DefaultImports); } return(result); }
private static RazorCodeDocument GetCodeDocument(TestRazorProjectItem projectItem, TestRazorProjectItem imports = null) { var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); var fileSystem = new VirtualRazorProjectFileSystem(); fileSystem.Add(projectItem); var codeDocument = RazorCodeDocument.Create(sourceDocument); if (imports != null) { fileSystem.Add(imports); codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { RazorSourceDocument.ReadFrom(imports) }); } var razorEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem).Engine; razorEngine.Process(codeDocument); return(codeDocument); }
/// <summary> /// Generates a <see cref="RazorCodeDocument"/> for the specified <paramref name="projectItem"/>. /// </summary> /// <param name="projectItem">The <see cref="RazorLightProjectItem"/>.</param> /// <returns>The created <see cref="RazorCodeDocument"/>.</returns> public virtual async Task <RazorCodeDocument> CreateCodeDocumentAsync(RazorLightProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } if (!projectItem.Exists) { throw new InvalidOperationException($"Project can not find template with key {projectItem.Key}"); } using (var stream = projectItem.Read()) { RazorSourceDocument source = RazorSourceDocument.ReadFrom(stream, projectItem.Key); IEnumerable <RazorSourceDocument> imports = await GetImportsAsync(projectItem); return(RazorCodeDocument.Create(source, imports)); } }
public SyntaxTreeGenerationBenchmark() { var current = new DirectoryInfo(AppContext.BaseDirectory); while (current != null && !File.Exists(Path.Combine(current.FullName, "MSN.cshtml"))) { current = current.Parent; } var root = current; var fileSystem = RazorProjectFileSystem.Create(root.FullName); ProjectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, b => RazorExtensions.Register(b));; var projectItem = fileSystem.GetItem(Path.Combine(root.FullName, "MSN.cshtml"), FileKinds.Legacy); MSN = RazorSourceDocument.ReadFrom(projectItem); var directiveFeature = ProjectEngine.EngineFeatures.OfType <IRazorDirectiveFeature>().FirstOrDefault(); Directives = directiveFeature?.Directives.ToArray() ?? Array.Empty <DirectiveDescriptor>(); }
// Internal for testing internal void AddHierarchicalImports(string sourceFilePath, List <RazorSourceDocument> imports) { // We want items in descending order. FindHierarchicalItems returns items in ascending order. var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(sourceFilePath, ImportsFileName).Reverse(); foreach (var importProjectItem in importProjectItems) { RazorSourceDocument importSourceDocument; if (importProjectItem.Exists) { importSourceDocument = RazorSourceDocument.ReadFrom(importProjectItem); } else { // File doesn't exist on disk so just add a marker source document as an identifier for "there could be something here". var sourceDocumentProperties = new RazorSourceDocumentProperties(importProjectItem.FilePath, importProjectItem.RelativePhysicalPath); importSourceDocument = RazorSourceDocument.Create(string.Empty, sourceDocumentProperties); } imports.Add(importSourceDocument); } }
public void ProcessDesignTime_WithImportsAndTagHelpers_SetsOnCodeDocument() { // Arrange var projectItem = new TestRazorProjectItem("Index.cshtml"); var importItem = new TestRazorProjectItem("_import.cshtml"); var expectedImports = new[] { RazorSourceDocument.ReadFrom(importItem) }; var expectedTagHelpers = new[] { TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly").Build(), TagHelperDescriptorBuilder.Create("Test2TagHelper", "TestAssembly").Build(), }; var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty); // Act var codeDocument = projectEngine.ProcessDesignTime(RazorSourceDocument.ReadFrom(projectItem), "test", expectedImports, expectedTagHelpers); // Assert var tagHelpers = codeDocument.GetTagHelpers(); Assert.Same(expectedTagHelpers, tagHelpers); Assert.Equal(expectedImports, codeDocument.Imports); }