private static string[] GetImports( IImportProjectFeature[] importFeatures, RazorProjectItem file) { return(importFeatures .SelectMany(f => f.GetImports(file)) .Where(f => f.FilePath != null) .Select(f => f.FilePath) .ToArray()); }
public static Assembly CompileTemplate(string razorTemplateFileName, string dynamicAssemblyNamespace, string dynamicDllName) { PortableExecutableReference referenceToCallingAssembly = MetadataReference.CreateFromFile(Assembly.GetCallingAssembly().Location); // we will need to know what piece of code has called *this* code, so we need to make a note of this at first opportunity (this will be later added to a dynmic compilation item) RazorProjectFileSystem razorProjectFileSystem = InitialiseTemplateProject(dynamicAssemblyNamespace, out RazorProjectEngine razorProjectEngine); RazorProjectItem razorProjectItem = GetRazorProjectItem(razorProjectFileSystem, razorTemplateFileName); SyntaxTree cSharpSyntaxTree = GenerateSyntaxTree(razorProjectItem, razorProjectEngine); CSharpCompilation cSharpCompilation = CompileDynamicAssembly(dynamicDllName, cSharpSyntaxTree, referenceToCallingAssembly); return(StreamAssemblyInMemory(cSharpCompilation)); }
protected CompiledCSharpCode CompileToCSharp(RazorProjectItem projectItem, bool?designTime = null) { var compilation = CreateCompilation(); var references = compilation.References.Concat(new[] { compilation.ToMetadataReference(), }).ToArray(); var projectEngine = CreateProjectEngine(Configuration, references, ConfigureProjectEngine); var codeDocument = (designTime ?? DesignTime) ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem); return(new CompiledCSharpCode(CSharpCompilation.Create(compilation.AssemblyName + ".Views", references: references, options: CSharpCompilationOptions), codeDocument)); }
/// <summary> /// Gets the sequence of imports with the name specified by <see cref="RazorTemplateEngineOptions.ImportsFileName" /> /// that apply to <paramref name="projectItem"/>. /// </summary> /// <param name="projectItem">The <see cref="RazorProjectItem"/> to look up import items for.</param> /// <returns>A sequence of <see cref="RazorProjectItem"/> instances that apply to the /// <paramref name="projectItem"/>.</returns> public virtual IEnumerable <RazorProjectItem> GetImportItems(RazorProjectItem projectItem) { var importsFileName = Options.ImportsFileName; if (!string.IsNullOrEmpty(importsFileName)) { return(Project.FindHierarchicalItems(projectItem.FilePath, importsFileName)); } return(Enumerable.Empty <RazorProjectItem>()); }
public void Add(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } var filePath = NormalizeAndEnsureValidPath(projectItem.FilePath); _root.AddFile(new FileNode(filePath, projectItem)); }
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 virtual RazorCodeDocument ProcessDesignTime(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } var codeDocument = CreateCodeDocumentDesignTimeCore(projectItem); ProcessCore(codeDocument); return(codeDocument); }
private void AddActionDescriptors(IList <ActionDescriptor> actions, RazorProjectItem item) { var model = new PageModel(item.CominedPath, item.Path); model.Selectors.Add(new SelectorModel() { AttributeRouteModel = new AttributeRouteModel() { Template = GetRouteTemplate(item), } }); foreach (var convention in _pagesOptions.Conventions) { convention.Apply(model); } var filters = new List <FilterDescriptor>(_options.Filters.Count + model.Filters.Count); for (var i = 0; i < _options.Filters.Count; i++) { filters.Add(new FilterDescriptor(_options.Filters[i], FilterScope.Global)); } for (var i = 0; i < model.Filters.Count; i++) { filters.Add(new FilterDescriptor(model.Filters[i], FilterScope.Action)); } foreach (var selector in model.Selectors) { actions.Add(new PageActionDescriptor() { AttributeRouteInfo = new AttributeRouteInfo() { Name = selector.AttributeRouteModel.Name, Order = selector.AttributeRouteModel.Order ?? 0, Template = selector.AttributeRouteModel.Template, }, DisplayName = $"Page: {item.Path}", FilterDescriptors = filters, Properties = new Dictionary <object, object>(model.Properties), RelativePath = item.CominedPath, RouteValues = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { { "page", item.PathWithoutExtension }, }, ViewEnginePath = item.Path, }); } }
private bool IsAlreadyRegistered(PageRouteModelProviderContext context, RazorProjectItem projectItem) { for (var i = 0; i < context.RouteModels.Count; i++) { var routeModel = context.RouteModels[i]; if (string.Equals(routeModel.ViewEnginePath, projectItem.FilePathWithoutExtension, StringComparison.OrdinalIgnoreCase) && string.Equals(routeModel.RelativePath, projectItem.CombinedPath, StringComparison.OrdinalIgnoreCase)) { return(true); } } return(false); }
public override RazorProjectItem GetItem(string path, string fileKind) { RazorProjectItem razorProjectItem = null; foreach (var fileSystem in FileSystems) { razorProjectItem = fileSystem.GetItem(path, fileKind); if (razorProjectItem != null && razorProjectItem.Exists) { return(razorProjectItem); } } return(razorProjectItem); }
public override RazorCodeDocument ProcessDeclarationOnly(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } var codeDocument = CreateCodeDocumentCore(projectItem, configureParser: null, configureCodeGeneration: (builder) => { builder.SuppressPrimaryMethodBody = true; }); ProcessCore(codeDocument); return(codeDocument); }
public override RazorProjectItem GetItem(string path) { RazorProjectItem razorProjectItem = null; foreach (var project in Projects) { razorProjectItem = project.GetItem(path); if (razorProjectItem != null && razorProjectItem.Exists) { return(razorProjectItem); } } return(razorProjectItem); }
/// <summary> /// Parses the template specified by <paramref name="projectItem"/>. /// </summary> /// <param name="projectItem">The <see cref="RazorProjectItem"/>.</param> /// <returns>The <see cref="RazorCSharpDocument"/>.</returns> public RazorCSharpDocument GenerateCode(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } if (!projectItem.Exists) { throw new InvalidOperationException(Resources.FormatRazorTemplateEngine_ItemCouldNotBeFound(projectItem.FilePath)); } var codeDocument = CreateCodeDocument(projectItem); return(GenerateCode(codeDocument)); }
public IReadOnlyList <RazorProjectItem> GetImports(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } var imports = new List <RazorProjectItem>(); AddDefaultDirectivesImport(imports); // We add hierarchical imports second so any default directive imports can be overridden. AddHierarchicalImports(projectItem, imports); return(imports); }
/// <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 void GetChangeTokensFromImports(IList <IChangeToken> expirationTokens, RazorProjectItem projectItem) { // OK this means we can do compilation. For now let's just identify the other files we need to watch // so we can create the cache entry. Compilation will happen after we release the lock. var importFeature = _projectEngine.ProjectFeatures.OfType <IImportProjectFeature>().ToArray(); foreach (var feature in importFeature) { foreach (var file in feature.GetImports(projectItem)) { if (file.FilePath != null) { expirationTokens.Add(_fileProvider.Watch(file.FilePath)); } } } }
// Token: 0x06000181 RID: 385 RVA: 0x00007290 File Offset: 0x00005490 protected virtual CompiledViewDescriptor CompileAndEmit(string relativePath) { RazorProjectItem item = this._projectEngine.FileSystem.GetItem(relativePath); RazorCodeDocument razorCodeDocument = this._projectEngine.Process(item); RazorCSharpDocument csharpDocument = RazorCodeDocumentExtensions.GetCSharpDocument(razorCodeDocument); if (csharpDocument.Diagnostics.Count > 0) { //throw CompilationFailedExceptionFactory.Create(razorCodeDocument, csharpDocument.Diagnostics); throw new ApplicationException("csharpDocument.Diagnostics.Count > 0"); } Assembly assembly = this.CompileAndEmit(razorCodeDocument, csharpDocument.GeneratedCode); RazorCompiledItem item2 = new RazorCompiledItemLoader().LoadItems(assembly).SingleOrDefault <RazorCompiledItem>(); RazorViewAttribute customAttribute = assembly.GetCustomAttribute <RazorViewAttribute>(); return(new CompiledViewDescriptor(item2, customAttribute)); }
public IReadOnlyList <RazorProjectItem> GetImports(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } // Don't add Component imports for a non-component. if (!FileKinds.IsComponent(projectItem.FileKind)) { return(Array.Empty <RazorProjectItem>()); } var imports = new List <RazorProjectItem>() { new VirtualProjectItem(DefaultUsingImportContent), new VirtualProjectItem(@"@addTagHelper ""*, Microsoft.AspNetCore.Components"""), }; // Try and infer a namespace from the project directory. We don't yet have the ability to pass // the namespace through from the project. if (projectItem.PhysicalPath != null && projectItem.FilePath != null) { // Avoiding the path-specific APIs here, we want to handle all styles of paths // on all platforms var trimLength = projectItem.FilePath.Length + (projectItem.FilePath.StartsWith("/") ? 0 : 1); if (projectItem.PhysicalPath.Length > trimLength) { var baseDirectory = projectItem.PhysicalPath.Substring(0, projectItem.PhysicalPath.Length - trimLength); var lastSlash = baseDirectory.LastIndexOfAny(PathSeparators); var baseNamespace = lastSlash == -1 ? baseDirectory : baseDirectory.Substring(lastSlash + 1); if (!string.IsNullOrEmpty(baseNamespace)) { imports.Add(new VirtualProjectItem($@"@addTagHelper ""*, {baseNamespace}""")); } } } // We add hierarchical imports second so any default directive imports can be overridden. imports.AddRange(GetHierarchicalImports(ProjectEngine.FileSystem, projectItem)); return(imports); }
private RazorCompilerResult GetCompilerResult( RazorTemplateEngine templateEngine, RazorProjectItem projectItem) { var cSharpDocument = templateEngine.GenerateCode(projectItem); var result = new RazorCompilerResult(); if (cSharpDocument.Diagnostics.Any()) { var messages = cSharpDocument.Diagnostics.Select(d => d.GetMessage()); result.ProcessingException = new RazorCompilerException(messages, cSharpDocument.GeneratedCode); } else { result.GeneratedText = cSharpDocument.GeneratedCode; } return(result); }
private static RazorPageGeneratorResult GenerateCodeFile(RazorTemplateEngine templateEngine, RazorProjectItem projectItem) { var projectItemWrapper = new FileSystemRazorProjectItemWrapper(projectItem); var cSharpDocument = templateEngine.GenerateCode(projectItemWrapper); if (cSharpDocument.Diagnostics.Any()) { var diagnostics = string.Join(Environment.NewLine, cSharpDocument.Diagnostics); Console.WriteLine( $"One or more parse errors encountered. This will not prevent the generator from continuing: {Environment.NewLine}{diagnostics}."); } var generatedCodeFilePath = Path.ChangeExtension(projectItem.PhysicalPath, ".Designer.cs"); return(new RazorPageGeneratorResult { FilePath = generatedCodeFilePath, GeneratedCode = cSharpDocument.GeneratedCode, }); }
private string GetRouteTemplate(RazorProjectItem item) { var source = item.ToSourceDocument(); var syntaxTree = RazorParser.Parse(source); var template = PageDirectiveFeature.GetRouteTemplate(syntaxTree); if (template != null && template.Length > 0 && template[0] == '/') { return(template.Substring(1)); } if (template != null && template.Length > 1 && template[0] == '~' && template[1] == '/') { return(template.Substring(1)); } var @base = item.PathWithoutExtension.Substring(1); if (string.Equals("Index", @base, StringComparison.OrdinalIgnoreCase)) { @base = string.Empty; } if (@base == string.Empty && string.IsNullOrEmpty(template)) { return(string.Empty); } else if (string.IsNullOrEmpty(template)) { return(@base); } else if (@base == string.Empty) { return(template); } else { return(@base + "/" + template); } }
// Token: 0x06000180 RID: 384 RVA: 0x00007154 File Offset: 0x00005354 private ViewCompilerWorkItem CreateRuntimeCompilationWorkItem(string normalizedPath) { List <IChangeToken> list = new List <IChangeToken> { this._fileProvider.Watch(normalizedPath) }; RazorProjectItem item = this._projectEngine.FileSystem.GetItem(normalizedPath); if (!item.Exists) { this._logger.ViewCompilerCouldNotFindFileAtPath(normalizedPath); return(new ViewCompilerWorkItem { SupportsCompilation = false, Descriptor = new CompiledViewDescriptor { RelativePath = normalizedPath, ExpirationTokens = list }, ExpirationTokens = list }); } this._logger.ViewCompilerFoundFileToCompile(normalizedPath); IImportProjectFeature importProjectFeature = this._projectEngine.ProjectFeatures.OfType <IImportProjectFeature>().FirstOrDefault <IImportProjectFeature>(); IEnumerable <RazorProjectItem> enumerable = (importProjectFeature != null) ? importProjectFeature.GetImports(item) : null; foreach (RazorProjectItem razorProjectItem in from import in enumerable ?? Enumerable.Empty <RazorProjectItem>() where import.FilePath != null select import) { list.Add(this._fileProvider.Watch(razorProjectItem.FilePath)); } return(new ViewCompilerWorkItem { SupportsCompilation = true, NormalizedPath = normalizedPath, ExpirationTokens = list }); }
public IReadOnlyList <RazorProjectItem> GetImports(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } // Don't add MVC imports for a component - this shouldn't happen for v2, but just in case. if (FileKinds.IsComponent(projectItem.FileKind)) { return(Array.Empty <RazorProjectItem>()); } var imports = new List <RazorProjectItem>(); AddDefaultDirectivesImport(imports); // We add hierarchical imports second so any default directive imports can be overridden. AddHierarchicalImports(projectItem, imports); return(imports); }
/// <summary> /// Gets the Razor page for an input document stream. This is roughly modeled on /// DefaultRazorPageFactory and CompilerCache. Note that we don't actually bother /// with caching the page if it's from a live stream. /// </summary> private IRazorPage GetPageFromStream(IServiceProvider serviceProvider, RenderRequest request) { string relativePath = request.RelativePath; if (relativePath.StartsWith("~/", StringComparison.Ordinal)) { // For tilde slash paths, drop the leading ~ to make it work with the underlying IFileProvider. relativePath = relativePath.Substring(1); } // Get the file info by combining the stream content with info found at the document's original location (if any) StatiqRazorProjectFileSystem projectFileSystem = serviceProvider.GetRequiredService <StatiqRazorProjectFileSystem>(); RazorProjectItem projectItem = projectFileSystem.GetItem(relativePath, request.Input); // Compute a hash for the content since pipelines could have changed it from the underlying file // We have to pre-compute the hash (I.e., no CryptoStream) since we need to check for a hit before reading/compiling the view byte[] hash = SHA512.Create().ComputeHash(request.Input); request.Input.Position = 0; CompilationResult compilationResult = CompilePage(serviceProvider, request, hash, projectItem, projectFileSystem); return(compilationResult.GetPage(request.RelativePath)); }
public void GetItem_ReturnsFirstInstanceThatExists() { // Arrange var basePath = "base-path"; var filePath = "file-path"; var file1 = new NotFoundProjectItem(basePath, filePath, fileKind: null); var file2 = new TestRazorProjectItem(filePath); RazorProjectItem nullItem = null; var fileSystem1 = Mock.Of <RazorProjectFileSystem>( f => f.GetItem(filePath, null) == file1); var fileSystem2 = Mock.Of <RazorProjectFileSystem>( f => f.GetItem(filePath, null) == nullItem); var fileSystem3 = Mock.Of <RazorProjectFileSystem>( f => f.GetItem(filePath, null) == file2); var compositeRazorProjectFileSystem = new CompositeRazorProjectFileSystem(new[] { fileSystem1, fileSystem2, fileSystem3 }); // Act var result = compositeRazorProjectFileSystem.GetItem(filePath, fileKind: null); // Assert Assert.Same(file2, result); }
public IReadOnlyList <RazorProjectItem> GetImports(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } // Don't add Component imports for a non-component. if (!FileKinds.IsComponent(projectItem.FileKind)) { return(Array.Empty <RazorProjectItem>()); } var imports = new List <RazorProjectItem>() { new VirtualProjectItem(DefaultUsingImportContent), }; // We add hierarchical imports second so any default directive imports can be overridden. imports.AddRange(GetHierarchicalImports(ProjectEngine.FileSystem, projectItem)); return(imports); }
public override RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem) { if (projectItem == null) { throw new ArgumentNullException($"{nameof(projectItem)} is null!"); } if (!projectItem.Exists) { throw new InvalidOperationException($"{nameof(projectItem)} doesn't exist!"); } Console.WriteLine(); Console.WriteLine($"File: {projectItem.FileName}"); using (var inputStream = projectItem.Read()) { using (var reader = new StreamReader(inputStream)) { var text = reader.ReadToEnd(); var markupStart = text.IndexOf("<!DOCTYPE"); var directives = text.Substring(0, markupStart); var markup = text.Substring(markupStart); text = directives + Minify(markup); var byteArray = Encoding.UTF8.GetBytes(text); var minifiedInputStream = new MemoryStream(byteArray); var source = RazorSourceDocument.ReadFrom(minifiedInputStream, projectItem.PhysicalPath); var imports = GetImports(projectItem); return(RazorCodeDocument.Create(source, imports)); } } }
protected RazorCodeDocument CreateCodeDocumentCore( RazorProjectItem projectItem, Action <RazorParserOptionsBuilder> configureParser, Action <RazorCodeGenerationOptionsBuilder> configureCodeGeneration) { if (projectItem == null) { throw new ArgumentNullException(nameof(projectItem)); } var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); var importItems = new List <RazorProjectItem>(); var features = ProjectFeatures.OfType <IImportProjectFeature>(); foreach (var feature in features) { importItems.AddRange(feature.GetImports(projectItem)); } var importSourceDocuments = GetImportSourceDocuments(importItems); return(CreateCodeDocumentCore(sourceDocument, projectItem.FileKind, importSourceDocuments, tagHelpers: null, configureParser, configureCodeGeneration, cssScope: projectItem.CssScope)); }
public IReadOnlyList <RazorProjectItem> GetImports(RazorProjectItem projectItem) { if (_inner is null) { return(Array.Empty <RazorProjectItem>()); } var normalizedImports = new List <RazorProjectItem>(); var imports = _inner.GetImports(projectItem); foreach (var import in imports) { if (import.Exists) { var text = string.Empty; using (var stream = import.Read()) using (var reader = new StreamReader(stream)) { text = reader.ReadToEnd().Trim(); } // It's important that we normalize the newlines in the default imports. The default imports will // be created with Environment.NewLine, but we need to normalize to `\r\n` so that the indices // are the same on xplat. var normalizedText = NormalizeNewLines(text, _lineEnding); var normalizedImport = new TestRazorProjectItem(import.FilePath, import.PhysicalPath, import.RelativePhysicalPath, import.BasePath) { Content = normalizedText }; normalizedImports.Add(normalizedImport); } } return(normalizedImports); }
private static bool IsRouteable(RazorProjectItem item) { // Pages like _ViewImports should not be routable. return(!item.FileName.StartsWith("_", StringComparison.OrdinalIgnoreCase)); }