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);
        }
Example #2
0
        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);
        }
Example #3
0
        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)
 {
 }
Example #5
0
        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;
            }));
        }
Example #8
0
        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));
        }
Example #9
0
        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>();
        }
Example #10
0
 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;
 }
Example #11
0
        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));
        }
Example #12
0
        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);
        }
Example #13
0
        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));
        }
Example #14
0
        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("");
        }
Example #15
0
        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);
                    }
                }
            }
                );
        }
Example #16
0
    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;
        }
    }
Example #17
0
        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();
        }
Example #18
0
        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);
Example #22
0
        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);
        }
Example #23
0
 public override RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure)
 {
     return(Engine ?? RazorProjectEngine.Create(configuration, fileSystem, configure ?? Configure));
 }
Example #24
0
        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);
Example #26
0
        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)));
        }
Example #27
0
        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);
        }
Example #28
0
        // 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);
        }
Example #29
0
        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);
        }
Example #30
0
        /// <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);
        }