コード例 #1
0
 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));
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        /// <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>());
        }
コード例 #5
0
        public void Add(RazorProjectItem projectItem)
        {
            if (projectItem == null)
            {
                throw new ArgumentNullException(nameof(projectItem));
            }

            var filePath = NormalizeAndEnsureValidPath(projectItem.FilePath);

            _root.AddFile(new FileNode(filePath, projectItem));
        }
コード例 #6
0
        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));
        }
コード例 #7
0
    public virtual RazorCodeDocument ProcessDesignTime(RazorProjectItem projectItem)
    {
        if (projectItem == null)
        {
            throw new ArgumentNullException(nameof(projectItem));
        }

        var codeDocument = CreateCodeDocumentDesignTimeCore(projectItem);

        ProcessCore(codeDocument);
        return(codeDocument);
    }
コード例 #8
0
        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,
                });
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
    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);
    }
コード例 #12
0
        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);
        }
コード例 #13
0
        /// <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));
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        /// <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));
        }
コード例 #16
0
    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));
                }
            }
        }
    }
コード例 #17
0
        // 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));
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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);
        }
コード例 #20
0
        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,
            });
        }
コード例 #21
0
        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);
            }
        }
コード例 #22
0
        // 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
            });
        }
コード例 #23
0
        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);
        }
コード例 #24
0
        /// <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));
        }
コード例 #25
0
        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);
        }
コード例 #26
0
    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);
    }
コード例 #27
0
        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));
                }
            }
        }
コード例 #28
0
    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));
    }
コード例 #29
0
            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));
 }