public override RazorProjectEngine Create(string projectPath, Action <RazorProjectEngineBuilder> configure) { if (projectPath == null) { throw new ArgumentNullException(nameof(projectPath)); } // In 15.5 we expect projectPath to be a directory, NOT the path to the csproj. var project = FindProject(projectPath); var configuration = (project?.Configuration as MvcExtensibilityConfiguration) ?? DefaultConfiguration; var razorLanguageVersion = configuration.LanguageVersion; var razorConfiguration = new RazorConfiguration(razorLanguageVersion, "unnamed", Array.Empty <RazorExtension>()); var fileSystem = RazorProjectFileSystem.Create(projectPath); RazorProjectEngine projectEngine; if (razorLanguageVersion.Major == 1) { projectEngine = RazorProjectEngine.Create(razorConfiguration, fileSystem, b => { configure?.Invoke(b); Mvc1_X.RazorExtensions.Register(b); if (configuration.MvcAssembly.Identity.Version.Minor >= 1) { Mvc1_X.RazorExtensions.RegisterViewComponentTagHelpers(b); } }); } else { projectEngine = RazorProjectEngine.Create(razorConfiguration, fileSystem, b => { configure?.Invoke(b); MvcLatest.RazorExtensions.Register(b); }); } return(projectEngine); }
private static RazorProjectEngine CreateProjectEngine(string rootNamespace, string projectDirectory) { var fileSystem = RazorProjectFileSystem.Create(projectDirectory); var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, builder => { builder .SetNamespace(rootNamespace) .ConfigureClass((document, @class) => { @class.ClassName = Path.GetFileNameWithoutExtension(document.Source.FilePath); }); #if NETSTANDARD2_0 FunctionsDirective.Register(builder); InheritsDirective.Register(builder); SectionDirective.Register(builder); #endif }); return(projectEngine); }
public RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { // Rewrite the assembly name into a full name just like this one, but with the name of the MVC design time assembly. var assemblyName = new AssemblyName(typeof(RazorProjectEngine).Assembly.FullName) { Name = AssemblyName }; var extension = new AssemblyExtension(configuration.ConfigurationName, Assembly.Load(assemblyName)); var initializer = extension.CreateInitializer(); return(RazorProjectEngine.Create(configuration, fileSystem, b => { CompilerFeatures.Register(b); initializer.Initialize(b); configure?.Invoke(b); })); }
public MyPageActionInvokerProvider( IPageLoader loader, IPageFactoryProvider pageFactoryProvider, IPageModelFactoryProvider modelFactoryProvider, IRazorPageFactoryProvider razorPageFactoryProvider, IActionDescriptorCollectionProvider collectionProvider, IEnumerable <IFilterProvider> filterProviders, ParameterBinder parameterBinder, IModelMetadataProvider modelMetadataProvider, IModelBinderFactory modelBinderFactory, ITempDataDictionaryFactory tempDataFactory, IOptions <MvcOptions> mvcOptions, IOptions <HtmlHelperOptions> htmlHelperOptions, IPageHandlerMethodSelector selector, RazorProjectFileSystem razorFileSystem, DiagnosticSource diagnosticSource, ILoggerFactory loggerFactory, IActionResultTypeMapper mapper) : base(loader, pageFactoryProvider, modelFactoryProvider, razorPageFactoryProvider, collectionProvider, filterProviders, parameterBinder, modelMetadataProvider, modelBinderFactory, tempDataFactory, mvcOptions, htmlHelperOptions, selector, razorFileSystem, diagnosticSource, loggerFactory, mapper) { }
public Task Run(string[] args) { string targetProjectDirectory = AppContext.BaseDirectory; string rootNamespace = System.IO.Path.GetFileNameWithoutExtension(System.IO.Path.GetTempFileName()).ToLowerInvariant(); RazorProjectFileSystem fileSystem = RazorProjectFileSystem.Create(targetProjectDirectory); RazorProjectEngine projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, builder => { builder .SetNamespace(rootNamespace) .SetBaseType("Microsoft.Extensions.RazorViews.BaseView") .ConfigureClass((document, @class) => { @class.ClassName = Path.GetFileNameWithoutExtension(document.Source.FilePath); @class.Modifiers.Clear(); @class.Modifiers.Add("internal"); }); FunctionsDirective.Register(builder); InheritsDirective.Register(builder); SectionDirective.Register(builder); //builder.Features.Add() //builder.Features.Add(new SuppressChecksumOptionsFeature()); //builder.Features.Add(new SuppressMetadataAttributesFeature()); // configure is always null //if (configure != null) //{ // configure(builder); //} builder.AddDefaultImports(@" @using System @using System.Threading.Tasks"); }); return(Task.Run(() => { Console.WriteLine("Do nothing"); })); } // public void Run(string[] args)
public override RazorProjectEngine Create( RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { if (!(fileSystem is DefaultRazorProjectFileSystem defaultFileSystem)) { Debug.Fail("Unexpected file system."); return(null); } var remoteFileSystem = new RemoteRazorProjectFileSystem(defaultFileSystem.Root, _filePathNormalizer); return(base.Create(configuration, remoteFileSystem, Configure)); void Configure(RazorProjectEngineBuilder builder) { configure(builder); builder.Features.Add(new RemoteCodeGenerationOptionsFeature(_optionsMonitor)); } }
public RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { // Rewrite the assembly name into a full name just like this one, but with the name of the MVC design time assembly. var assemblyName = new AssemblyName(typeof(LegacyProjectEngineFactory_3_0).Assembly.FullName); assemblyName.Name = AssemblyName; var extension = new AssemblyExtension(configuration.ConfigurationName, Assembly.Load(assemblyName)); var initializer = extension.CreateInitializer(); return(RazorProjectEngine.Create(configuration, fileSystem, b => { CompilerFeatures.Register(b); initializer.Initialize(b); configure?.Invoke(b); // See comments on MangleClassNames var componentDocumentClassifier = b.Features.OfType <ComponentDocumentClassifierPass>().Single().MangleClassNames = true; })); }
private RazorProjectEngine CreateCore(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { // When we're running in the editor, the editor provides a configure delegate that will include // the editor settings and tag helpers. // // This service is only used in process in Visual Studio, and any other callers should provide these // things also. configure = configure ?? ((b) => { }); // The default configuration currently matches MVC-2.0. Beyond MVC-2.0 we added SDK support for // properly detecting project versions, so that's a good version to assume when we can't find a // configuration. var configuration = project?.Configuration ?? DefaultConfiguration; // If there's no factory to handle the configuration then fall back to a very basic configuration. // // This will stop a crash from happening in this case (misconfigured project), but will still make // it obvious to the user that something is wrong. var factory = SelectFactory(configuration) ?? _defaultFactory; return(factory.Create(configuration, fileSystem, configure)); }
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>(); }
public PageActionInvokerProvider( IPageLoader loader, IPageFactoryProvider pageFactoryProvider, IPageModelFactoryProvider modelFactoryProvider, IRazorPageFactoryProvider razorPageFactoryProvider, IActionDescriptorCollectionProvider collectionProvider, IEnumerable <IFilterProvider> filterProviders, ParameterBinder parameterBinder, IModelMetadataProvider modelMetadataProvider, IModelBinderFactory modelBinderFactory, ITempDataDictionaryFactory tempDataFactory, IOptions <MvcOptions> mvcOptions, IOptions <HtmlHelperOptions> htmlHelperOptions, IPageHandlerMethodSelector selector, RazorProjectFileSystem razorFileSystem, DiagnosticSource diagnosticSource, ILoggerFactory loggerFactory, IActionResultTypeMapper mapper) { _loader = loader; _pageFactoryProvider = pageFactoryProvider; _modelFactoryProvider = modelFactoryProvider; _modelBinderFactory = modelBinderFactory; _razorPageFactoryProvider = razorPageFactoryProvider; _collectionProvider = collectionProvider; _filterProviders = filterProviders.ToArray(); _valueProviderFactories = mvcOptions.Value.ValueProviderFactories.ToArray(); _parameterBinder = parameterBinder; _modelMetadataProvider = modelMetadataProvider; _tempDataFactory = tempDataFactory; _mvcOptions = mvcOptions.Value; _htmlHelperOptions = htmlHelperOptions.Value; _selector = selector; _razorFileSystem = razorFileSystem; _diagnosticSource = diagnosticSource; _logger = loggerFactory.CreateLogger <PageActionInvoker>(); _mapper = mapper; }
private RazorProjectEngine CreateCore(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { // When we're running in the editor, the editor provides a configure delegate that will include // the editor settings and tag helpers. // // This service is only used in process in Visual Studio, and any other callers should provide these // things also. configure = configure ?? ((b) => { }); // The default configuration currently matches the newest MVC configuration. // // We typically want this because the language adds features over time - we don't want to a bunch of errors // to show up when a document is first opened, and then go away when the configuration loads, we'd prefer the opposite. var configuration = project?.Configuration ?? DefaultConfiguration; // If there's no factory to handle the configuration then fall back to a very basic configuration. // // This will stop a crash from happening in this case (misconfigured project), but will still make // it obvious to the user that something is wrong. var factory = SelectFactory(configuration) ?? _defaultFactory; return(factory.Create(configuration, fileSystem, configure)); }
private string Generate( Type templateBaseType, string template) { var engine = RazorProjectEngine.Create( RazorConfiguration.Default, RazorProjectFileSystem.Create(@"."), builder => { builder.SetNamespace(templateBaseType.Namespace); builder.SetBaseType(Regex.Replace(templateBaseType.ToString(), @"`\d+\[", "<").Replace(']', '>')); }); var document = RazorSourceDocument.Create(template, Path.GetRandomFileName()); var codeDocument = engine.Process( document, null, new List <RazorSourceDocument>(), new List <TagHelperDescriptor>()); return(codeDocument.GetCSharpDocument().GeneratedCode); }
public RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } // This is a very basic implementation that will provide reasonable support without crashing. // If the user falls into this situation, ideally they can realize that something is wrong and take // action. // // This has no support for: // - Tag Helpers // - Imports // - Default Imports // - and will have a very limited set of directives return(RazorProjectEngine.Create(configuration, fileSystem, configure)); }
private string GetCompiledViewCode() { #if DEBUG string view = @"..\InkBall\src\InkBall.Module\Areas\InkBall\Pages\Game.cshtml"; if (System.IO.File.Exists(Path.Combine(Directory.GetCurrentDirectory(), view))) { var projectEngine = RazorProjectEngine.Create( RazorConfiguration.Default, RazorProjectFileSystem.Create(Directory.GetCurrentDirectory())); var item = projectEngine.FileSystem.GetItem('\\' + view, FileKinds.Legacy); var output = projectEngine.Process(item); // Things available var syntaxTree = output.GetSyntaxTree(); var intermediateDocument = output.GetDocumentIntermediateNode(); var csharpDocument = output.GetCSharpDocument(); return(csharpDocument.GeneratedCode); } else #endif return(""); }
public RazorTemplater(string projectDirectory, string rootNamespace = null, Encoding encoding = null) { if (projectDirectory == null) { throw new ArgumentNullException(nameof(projectDirectory)); } if (!Directory.Exists(projectDirectory)) { throw new DirectoryNotFoundException($"Project directory '{projectDirectory}' not found"); } // normalize project directory (must not include trailing slash) ProjectDirectory = Path.GetFullPath(projectDirectory).TrimEnd(Path.DirectorySeparatorChar); RootNamespace = rootNamespace ?? Path.GetFileName(ProjectDirectory); Encoding = encoding ?? new UTF8Encoding(false); engine = RazorProjectEngine.Create( RazorConfiguration.Default, RazorProjectFileSystem.Create(ProjectDirectory), config => { //InheritsDirective.Register(config); config.Features.Add(new ChangeNamespacePass(ProjectDirectory, RootNamespace)); // this is horrible hack that will bite me in the bum var targetExtension = config.Features.OfType <IRazorTargetExtensionFeature>().FirstOrDefault(); if (targetExtension != null) { foreach (var metadataExtension in targetExtension.TargetExtensions.Where(x => x.GetType().FullName == "Microsoft.AspNetCore.Razor.Language.Extensions.MetadataAttributeTargetExtension").ToArray()) { targetExtension.TargetExtensions.Remove(metadataExtension); } } } ); }
public DefaultRazorProjectEngine( RazorConfiguration configuration, RazorEngine engine, RazorProjectFileSystem fileSystem, IReadOnlyList <IRazorProjectEngineFeature> projectFeatures) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (engine == null) { throw new ArgumentNullException(nameof(engine)); } if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } if (projectFeatures == null) { throw new ArgumentNullException(nameof(projectFeatures)); } Configuration = configuration; Engine = engine; FileSystem = fileSystem; ProjectFeatures = projectFeatures; for (var i = 0; i < projectFeatures.Count; i++) { projectFeatures[i].ProjectEngine = this; } }
public RazorTagHelperParsingBenchmark() { var current = new DirectoryInfo(AppContext.BaseDirectory); while (current != null && !File.Exists(Path.Combine(current.FullName, "taghelpers.json"))) { current = current.Parent; } var root = current; var tagHelpers = ReadTagHelpers(Path.Combine(root.FullName, "taghelpers.json")); var blazorServerTagHelpersFilePath = Path.Combine(root.FullName, "BlazorServerTagHelpers.razor"); var fileSystem = RazorProjectFileSystem.Create(root.FullName); ProjectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, b => RazorExtensions.Register(b)); BlazorServerTagHelpersDemoFile = fileSystem.GetItem(Path.Combine(blazorServerTagHelpersFilePath), FileKinds.Legacy); ComponentDirectiveVisitor = new ComponentDirectiveVisitor(blazorServerTagHelpersFilePath, tagHelpers, currentNamespace: null); var codeDocument = ProjectEngine.ProcessDesignTime(BlazorServerTagHelpersDemoFile); SyntaxTree = codeDocument.GetSyntaxTree(); }
private string GetGeneratorResultBak(IEnumerable <string> namespaces, TypeContext context) { #pragma warning disable 612, 618 var razorCompiledItemAssembly = typeof(RazorCompiledItemAttribute).Assembly; //手动加载程序集,防止编译 Razor 类时找不到 DLL var razorEngine = RazorEngine.Create(builder => { InheritsDirective.Register(builder); FunctionsDirective.Register(builder); SectionDirective.Register(builder); builder .SetNamespace(DynamicTemplateNamespace) //.SetBaseType("Microsoft.Extensions.RazorViews.BaseView") .SetBaseType(BuildTypeName(context.TemplateType, context.ModelType)) .ConfigureClass((document, @class) => { @class.ClassName = context.ClassName; //if (!str ing.IsNullOrWhiteSpace(document.Source.FilePath)) //{ // @class.ClassName = Path.GetFileNameWithoutExtension(document.Source.FilePath); //} @class.Modifiers.Clear(); @class.Modifiers.Add("internal"); }); builder.Features.Add(new SuppressChecksumOptionsFeature()); }); string importString = @" @using System @using System.Threading.Tasks "; importString += String.Join("\r\n", namespaces.Select(n => "@using " + n.Trim())) + "\r\n"; using (var reader = context.TemplateContent.GetTemplateReader()) { string path = null; if (string.IsNullOrWhiteSpace(context.TemplateContent.TemplateFile)) { path = Directory.GetCurrentDirectory(); } else { path = Path.GetDirectoryName(context.TemplateContent.TemplateFile); } var razorProject = RazorProjectFileSystem.Create(path); var templateEngine = new RazorTemplateEngine(razorEngine, razorProject); templateEngine.Options.DefaultImports = RazorSourceDocument.Create(importString, fileName: null); RazorPageGeneratorResult result; if (string.IsNullOrWhiteSpace(context.TemplateContent.TemplateFile)) { var item = RazorSourceDocument.Create(context.TemplateContent.Template, string.Empty); var imports = new List <RazorSourceDocument>(); imports.Add(templateEngine.Options.DefaultImports); var doc = RazorCodeDocument.Create(item, imports); result = GenerateCodeFile(templateEngine, doc); } else { var item = razorProject.GetItem(context.TemplateContent.TemplateFile); result = GenerateCodeFile(templateEngine, item); } return(InspectSource(result, context)); } }
public override RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { return(RazorProjectEngine.Create(configuration, fileSystem, b => RazorExtensions.Register(b))); }
public RazorProjectEngine Create(ProjectSnapshot project) { return(Create(project, RazorProjectFileSystem.Create(Path.GetDirectoryName(project.FilePath)), null)); }
public abstract RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure);
public async Task <ViewValidationException> ValidateAsync(string viewPath) { var fileSystem = RazorProjectFileSystem.Create("."); var engine = RazorProjectEngine.Create( RazorConfiguration.Default, fileSystem, (builder) => { InheritsDirective.Register(builder); ModelDirective.Register(builder); }); var item = fileSystem.GetItem(viewPath); var codeDocument = engine.Process(item); var csharpDocument = codeDocument.GetCSharpDocument(); var csharpTree = CSharpSyntaxTree.ParseText(csharpDocument.GeneratedCode); var rootNode = await csharpTree.GetRootAsync(); var memberAccesses = FetchChildrenRecursivelyFromNode( rootNode, SyntaxKind.SimpleMemberAccessExpression); foreach (var memberAccess in memberAccesses) { var simpleMemberAccess = memberAccess as MemberAccessExpressionSyntax; if (simpleMemberAccess == null) { continue; } while (simpleMemberAccess.Expression is MemberAccessExpressionSyntax) { simpleMemberAccess = (MemberAccessExpressionSyntax)simpleMemberAccess.Expression; } var identifier = simpleMemberAccess.Expression as IdentifierNameSyntax; if (identifier == null) { continue; } var propertyName = identifier.Identifier.Text; if (propertyName != "Model") { return(new ViewValidationException("The namespace " + propertyName + " is not allowed. You can only use Model when evaluating expressions.")); } var methodName = simpleMemberAccess.Name; var allowedMethodNames = new List <string>() { nameof(ApiModel.Get), nameof(ApiModel.GetCollection) }; if (!allowedMethodNames.Contains(methodName.Identifier.Text)) { return(new ViewValidationException("The method " + methodName + " on the model object is not allowed. You can only call the following methods on that object: " + allowedMethodNames.Aggregate((a, b) => a + ", " + b) + ".")); } } return(null); }
public override RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { return(Engine ?? RazorProjectEngine.Create(configuration, fileSystem, configure ?? Configure)); }
private int ExecuteCore( RazorConfiguration configuration, string projectDirectory, string tagHelperManifest, SourceItem[] sourceItems) { tagHelperManifest = Path.Combine(projectDirectory, tagHelperManifest); var tagHelpers = GetTagHelpers(tagHelperManifest); var compositeFileSystem = new CompositeRazorProjectFileSystem(new[] { GetVirtualRazorProjectSystem(sourceItems), RazorProjectFileSystem.Create(projectDirectory), }); var success = true; var engine = RazorProjectEngine.Create(configuration, compositeFileSystem, b => { b.Features.Add(new StaticTagHelperFeature() { TagHelpers = tagHelpers, }); b.Features.Add(new DefaultTypeNameFeature()); if (GenerateDeclaration.HasValue()) { b.Features.Add(new SetSuppressPrimaryMethodBodyOptionFeature()); } if (RootNamespace.HasValue()) { b.SetRootNamespace(RootNamespace.Value()); } if (CSharpLanguageVersion.HasValue()) { // Only set the C# language version if one was specified, otherwise it defaults to whatever // value was set in the corresponding RazorConfiguration's extensions. var rawLanguageVersion = CSharpLanguageVersion.Value(); if (LanguageVersionFacts.TryParse(rawLanguageVersion, out var csharpLanguageVersion)) { b.SetCSharpLanguageVersion(csharpLanguageVersion); } else { success = false; Error.WriteLine($"Unknown C# language version {rawLanguageVersion}."); } } }); var results = GenerateCode(engine, sourceItems); foreach (var result in results) { var errorCount = result.CSharpDocument.Diagnostics.Count; for (var i = 0; i < errorCount; i++) { var error = result.CSharpDocument.Diagnostics[i]; if (error.Severity == RazorDiagnosticSeverity.Error) { success = false; } if (i < 100) { Error.WriteLine(error.ToString()); // Only show the first 100 errors to prevent massive string allocations. if (i == 99) { Error.WriteLine($"And {errorCount - i + 1} more warnings/errors."); } } } if (success) { // Only output the file if we generated it without errors. var outputFilePath = result.InputItem.OutputPath; File.WriteAllText(outputFilePath, result.CSharpDocument.GeneratedCode); } } return(success ? ExitCodeSuccess : ExitCodeFailureRazorError); }
public abstract RazorProjectEngine Create(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure);
private CompilationResult CompilePage(IServiceProvider serviceProvider, RenderRequest request, byte[] hash, RazorProjectItem projectItem, RazorProjectFileSystem projectFileSystem) { CompilerCacheKey cacheKey = new CompilerCacheKey(request, hash); return(_compilationCache.GetOrAdd(cacheKey, _ => GetCompilation(projectItem, projectFileSystem))); }
private MemoryStream CreateAndCompileToStream(string templateSource, params Assembly[] linkedAssemblies) { RazorProjectEngine engine = RazorProjectEngine.Create( RazorConfiguration.Default, RazorProjectFileSystem.Create(@"."), (builder) => { builder.SetNamespace("TemplateNamespace"); }); string fileName = Path.GetRandomFileName(); RazorSourceDocument document = RazorSourceDocument.Create(templateSource, fileName); RazorCodeDocument codeDocument = engine.Process( document, null, new List <RazorSourceDocument>(), new List <TagHelperDescriptor>()); RazorCSharpDocument razorCSharpDocument = codeDocument.GetCSharpDocument(); List <PortableExecutableReference> portableExecutableReferences = new List <PortableExecutableReference> { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.CSharp")).Location), MetadataReference.CreateFromFile(typeof(RazorEngineTemplateBase).Assembly.Location), MetadataReference.CreateFromFile(typeof(ExpandoObject).Assembly.Location), MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location), MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location), }; foreach (Assembly assembly in linkedAssemblies) { portableExecutableReferences.Add(MetadataReference.CreateFromFile(assembly.Location)); } CSharpCompilation compilation = CSharpCompilation.Create( fileName, new[] { CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode) }, portableExecutableReferences, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); MemoryStream memoryStream = new MemoryStream(); EmitResult emitResult = compilation.Emit(memoryStream); if (!emitResult.Success) { List <Diagnostic> errors = emitResult.Diagnostics.ToList(); RazorEngineCompilationException exception = new RazorEngineCompilationException("Unable to compile template: " + errors.FirstOrDefault()?.ToString()); exception.Errors = errors; throw exception; } memoryStream.Position = 0; return(memoryStream); }
// Validates that we can use an existing precompiled view by comparing checksums with files on // disk. public static bool IsItemValid(RazorProjectFileSystem fileSystem, RazorCompiledItem item) { if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } if (item == null) { throw new ArgumentNullException(nameof(item)); } var checksums = item.GetChecksumMetadata(); // The checksum that matches 'Item.Identity' in this list is significant. That represents the main file. // // We don't really care about the validation unless the main file exists. This is because we expect // most sites to have some _ViewImports in common location. That means that in the case you're // using views from a 3rd party library, you'll always have **some** conflicts. // // The presence of the main file with the same content is a very strong signal that you're in a // development scenario. var primaryChecksum = checksums .FirstOrDefault(c => string.Equals(item.Identifier, c.Identifier, StringComparison.OrdinalIgnoreCase)); if (primaryChecksum == null) { // No primary checksum, assume valid. return(true); } var projectItem = fileSystem.GetItem(primaryChecksum.Identifier, fileKind: null); if (!projectItem.Exists) { // Main file doesn't exist - assume valid. return(true); } var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); if (!string.Equals(sourceDocument.GetChecksumAlgorithm(), primaryChecksum.ChecksumAlgorithm, StringComparison.OrdinalIgnoreCase) || !ChecksumsEqual(primaryChecksum.Checksum, sourceDocument.GetChecksum())) { // Main file exists, but checksums not equal. return(false); } for (var i = 0; i < checksums.Count; i++) { var checksum = checksums[i]; if (string.Equals(item.Identifier, checksum.Identifier, StringComparison.OrdinalIgnoreCase)) { // Ignore primary checksum on this pass. continue; } var importItem = fileSystem.GetItem(checksum.Identifier, fileKind: null); if (!importItem.Exists) { // Import file doesn't exist - assume invalid. return(false); } sourceDocument = RazorSourceDocument.ReadFrom(importItem); if (!string.Equals(sourceDocument.GetChecksumAlgorithm(), checksum.ChecksumAlgorithm) || !ChecksumsEqual(checksum.Checksum, sourceDocument.GetChecksum())) { // Import file exists, but checksums not equal. return(false); } } return(true); }
private int ExecuteCore( RazorConfiguration configuration, string projectDirectory, string tagHelperManifest, SourceItem[] sourceItems) { tagHelperManifest = Path.Combine(projectDirectory, tagHelperManifest); var tagHelpers = GetTagHelpers(tagHelperManifest); var compositeFileSystem = new CompositeRazorProjectFileSystem(new[] { GetVirtualRazorProjectSystem(sourceItems), RazorProjectFileSystem.Create(projectDirectory), }); var engine = RazorProjectEngine.Create(configuration, compositeFileSystem, b => { b.Features.Add(new StaticTagHelperFeature() { TagHelpers = tagHelpers, }); b.Features.Add(new InputDocumentKindClassifierPass(sourceItems)); if (GenerateDeclaration.HasValue()) { b.Features.Add(new SetSuppressPrimaryMethodBodyOptionFeature()); } }); var results = GenerateCode(engine, sourceItems); var success = true; foreach (var result in results) { var errorCount = result.CSharpDocument.Diagnostics.Count; if (errorCount > 0) { success = false; for (var i = 0; i < errorCount; i++) { var error = result.CSharpDocument.Diagnostics[i]; Error.WriteLine(error.ToString()); // Only show the first 100 errors to prevent massive string allocations. if (i == 99) { Error.WriteLine($"And {errorCount - i + 1} more errors."); break; } } } else { // Only output the file if we generated it without errors. var outputFilePath = result.InputItem.OutputPath; File.WriteAllText(outputFilePath, result.CSharpDocument.GeneratedCode); } } return(success ? ExitCodeSuccess : ExitCodeFailureRazorError); }
/// <summary> /// 将模板内容编译并输出内存流 /// </summary> /// <param name="templateSource"></param> /// <param name="options"></param> /// <returns></returns> private static MemoryStream CreateAndCompileToStream(string templateSource, ViewEngineOptions options) { templateSource = WriteDirectives(templateSource, options); var engine = RazorProjectEngine.Create( RazorConfiguration.Default, RazorProjectFileSystem.Create(@"."), (builder) => { builder.SetNamespace(options.TemplateNamespace); }); var fileName = Path.GetRandomFileName(); var document = RazorSourceDocument.Create(templateSource, fileName); var codeDocument = engine.Process( document, null, new List <RazorSourceDocument>(), new List <TagHelperDescriptor>()); var razorCSharpDocument = codeDocument.GetCSharpDocument(); var syntaxTree = CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode); var compilation = CSharpCompilation.Create( fileName, new[] { syntaxTree }, options.ReferencedAssemblies .Select(ass => { // MetadataReference.CreateFromFile(ass.Location) unsafe { ass.TryGetRawMetadata(out var blob, out var length); var moduleMetadata = ModuleMetadata.CreateFromMetadata((IntPtr)blob, length); var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata); var metadataReference = assemblyMetadata.GetReference(); return(metadataReference); } }) .Concat(options.MetadataReferences) .ToList(), new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); var memoryStream = new MemoryStream(); var emitResult = compilation.Emit(memoryStream); if (!emitResult.Success) { var errors = emitResult.Diagnostics.ToList(); var exception = new ViewEngineTemplateException($"Unable to compile template: {errors.FirstOrDefault()}") { Errors = errors, GeneratedCode = razorCSharpDocument.GeneratedCode }; throw exception; } memoryStream.Position = 0; return(memoryStream); }