コード例 #1
0
        public void DocumentProcessed_DoesNothingIfAlreadySynchronized()
        {
            // Arrange
            var router          = new TestRouter();
            var documentVersion = VersionStamp.Default.GetNewerVersion();
            var document        = TestDocumentSnapshot.Create("C:/path/file.cshtml", documentVersion);
            var cache           = new TestDocumentVersionCache(new Dictionary <DocumentSnapshot, long>()
            {
                [document] = 1337,
            });
            var csharpDocument = RazorCSharpDocument.Create("Anything", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());

            // Force the state to already be up-to-date
            document.State.HostDocument.GeneratedCodeContainer.SetOutput(document, csharpDocument, documentVersion.GetNewerVersion(), VersionStamp.Default);

            var listener = new UnsynchronizableContentDocumentProcessedListener(Dispatcher, cache, router);

            listener.Initialize(ProjectSnapshotManager);

            // Act
            listener.DocumentProcessed(document);

            // Assert
            Assert.Empty(router.SynchronizedDocuments);
        }
コード例 #2
0
        public void ReportUnsynchronizableContent_SynchronizesIfSourceVersionsAreIdenticalButSyncVersionNewer()
        {
            // Arrange
            var router       = new TestRouter();
            var lastVersion  = VersionStamp.Default.GetNewerVersion();
            var lastDocument = TestDocumentSnapshot.Create("C:/path/old.cshtml", lastVersion);
            var document     = TestDocumentSnapshot.Create("C:/path/file.cshtml", lastVersion);
            var cache        = new TestDocumentVersionCache(new Dictionary <DocumentSnapshot, long>()
            {
                [document]     = 1338,
                [lastDocument] = 1337,
            });
            var csharpDocument = RazorCSharpDocument.Create("Anything", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());

            // Force the state to already be up-to-date
            document.State.HostDocument.GeneratedCodeContainer.SetOutput(csharpDocument, lastDocument);

            var backgroundGenerator = new BackgroundDocumentGenerator(Dispatcher, cache, router, LoggerFactory);
            var work = new[] { new KeyValuePair <string, DocumentSnapshot>(document.FilePath, document) };

            // Act
            backgroundGenerator.ReportUnsynchronizableContent(work);

            // Assert
            var filePath = Assert.Single(router.SynchronizedDocuments);

            Assert.Equal(document.FilePath, filePath);
        }
コード例 #3
0
        public void DocumentProcessed_DoesNothingForOlderDocuments()
        {
            // Arrange
            var generatedDocumentPublisher = new Mock <GeneratedDocumentPublisher>(MockBehavior.Strict);
            var lastVersion  = VersionStamp.Default.GetNewerVersion();
            var lastDocument = TestDocumentSnapshot.Create("C:/path/old.cshtml", lastVersion);
            var oldDocument  = TestDocumentSnapshot.Create("C:/path/file.cshtml", VersionStamp.Default);
            var cache        = new TestDocumentVersionCache(new Dictionary <DocumentSnapshot, int?>()
            {
                [oldDocument]  = 1337,
                [lastDocument] = 1338,
            });
            var csharpDocument = RazorCSharpDocument.Create("Anything", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());
            var htmlDocument   = RazorHtmlDocument.Create("Anything", RazorCodeGenerationOptions.CreateDefault());
            var codeDocument   = CreateCodeDocument(csharpDocument, htmlDocument);

            // Force the state to already be up-to-date
            oldDocument.State.HostDocument.GeneratedDocumentContainer.SetOutput(lastDocument, codeDocument, lastVersion, VersionStamp.Default, VersionStamp.Default);

            var listener = new UnsynchronizableContentDocumentProcessedListener(Dispatcher, cache, generatedDocumentPublisher.Object);

            listener.Initialize(ProjectSnapshotManager);

            // Act & Assert
            listener.DocumentProcessed(oldDocument);
        }
コード例 #4
0
        private static RazorCodeActionContext CreateRazorCodeActionContext(
            CodeActionParams request,
            SourceLocation location,
            string filePath,
            string text,
            SourceSpan componentSourceSpan,
            bool supportsFileCreation      = true,
            bool supportsCodeActionResolve = true)
        {
            var tagHelpers     = Array.Empty <TagHelperDescriptor>();
            var sourceDocument = TestRazorSourceDocument.Create(text, filePath: filePath, relativePath: filePath);
            var projectEngine  = RazorProjectEngine.Create(builder => builder.AddTagHelpers(tagHelpers));
            var codeDocument   = projectEngine.ProcessDesignTime(sourceDocument, FileKinds.Component, Array.Empty <RazorSourceDocument>(), tagHelpers);

            var cSharpDocument               = codeDocument.GetCSharpDocument();
            var diagnosticDescriptor         = new RazorDiagnosticDescriptor("RZ10012", () => "", RazorDiagnosticSeverity.Error);
            var diagnostic                   = RazorDiagnostic.Create(diagnosticDescriptor, componentSourceSpan);
            var cSharpDocumentWithDiagnostic = RazorCSharpDocument.Create(cSharpDocument.GeneratedCode, cSharpDocument.Options, new[] { diagnostic });

            codeDocument.SetCSharpDocument(cSharpDocumentWithDiagnostic);

            var documentSnapshot = Mock.Of <DocumentSnapshot>(document =>
                                                              document.GetGeneratedOutputAsync() == Task.FromResult(codeDocument) &&
                                                              document.GetTextAsync() == Task.FromResult(codeDocument.GetSourceText()) &&
                                                              document.Project.TagHelpers == tagHelpers, MockBehavior.Strict);

            var sourceText = SourceText.From(text);

            var context = new RazorCodeActionContext(request, documentSnapshot, codeDocument, location, sourceText, supportsFileCreation, supportsCodeActionResolve);

            return(context);
        }
コード例 #5
0
        public void SetOutput_InvokesChangedEvent()
        {
            // Arrange
            using var workspace = TestWorkspace.Create();

            var services     = workspace.Services;
            var hostProject  = new HostProject("C:/project.csproj", RazorConfiguration.Default, "project");
            var projectState = ProjectState.Create(services, hostProject);
            var project      = new DefaultProjectSnapshot(projectState);

            var text           = SourceText.From("...");
            var textAndVersion = TextAndVersion.Create(text, VersionStamp.Default);
            var hostDocument   = new HostDocument("C:/file.cshtml", "C:/file.cshtml");
            var documentState  = new DocumentState(services, hostDocument, text, VersionStamp.Default, () => Task.FromResult(textAndVersion));
            var document       = new DefaultDocumentSnapshot(project, documentState);
            var csharpDocument = RazorCSharpDocument.Create("...", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());
            var htmlDocument   = RazorHtmlDocument.Create("...", RazorCodeGenerationOptions.CreateDefault());

            var version       = VersionStamp.Create();
            var container     = new GeneratedDocumentContainer();
            var csharpChanged = false;
            var htmlChanged   = false;

            container.GeneratedCSharpChanged += (o, a) => { csharpChanged = true; };
            container.GeneratedHtmlChanged   += (o, a) => { htmlChanged = true; };

            // Act
            container.SetOutput(document, csharpDocument, htmlDocument, version, version, version);

            // Assert
            Assert.NotNull(container.LatestDocument);
            Assert.True(csharpChanged);
            Assert.True(htmlChanged);
        }
コード例 #6
0
        private static RazorCodeActionContext CreateRazorCodeActionContext(RazorCodeActionParams request, SourceLocation location, string filePath, string text, SourceSpan componentSourceSpan, bool supportsFileCreation = true)
        {
            var shortComponent = TagHelperDescriptorBuilder.Create(ComponentMetadata.Component.TagHelperKind, "Fully.Qualified.Component", "TestAssembly");

            shortComponent.TagMatchingRule(rule => rule.TagName = "Component");
            var fullyQualifiedComponent = TagHelperDescriptorBuilder.Create(ComponentMetadata.Component.TagHelperKind, "Fully.Qualified.Component", "TestAssembly");

            fullyQualifiedComponent.TagMatchingRule(rule => rule.TagName = "Fully.Qualified.Component");

            var tagHelpers = new[] { shortComponent.Build(), fullyQualifiedComponent.Build() };

            var sourceDocument = TestRazorSourceDocument.Create(text, filePath: filePath, relativePath: filePath);
            var projectEngine  = RazorProjectEngine.Create(builder => {
                builder.AddTagHelpers(tagHelpers);
            });
            var codeDocument = projectEngine.ProcessDesignTime(sourceDocument, FileKinds.Component, Array.Empty <RazorSourceDocument>(), tagHelpers);

            var cSharpDocument               = codeDocument.GetCSharpDocument();
            var diagnosticDescriptor         = new RazorDiagnosticDescriptor("RZ10012", () => "", RazorDiagnosticSeverity.Error);
            var diagnostic                   = RazorDiagnostic.Create(diagnosticDescriptor, componentSourceSpan);
            var cSharpDocumentWithDiagnostic = RazorCSharpDocument.Create(cSharpDocument.GeneratedCode, cSharpDocument.Options, new[] { diagnostic });

            codeDocument.SetCSharpDocument(cSharpDocumentWithDiagnostic);

            var documentSnapshot = Mock.Of <DocumentSnapshot>(document =>
                                                              document.GetGeneratedOutputAsync() == Task.FromResult(codeDocument) &&
                                                              document.GetTextAsync() == Task.FromResult(codeDocument.GetSourceText()) &&
                                                              document.Project.TagHelpers == tagHelpers);

            var sourceText = SourceText.From(text);

            var context = new RazorCodeActionContext(request, documentSnapshot, codeDocument, location, sourceText, supportsFileCreation);

            return(context);
        }
コード例 #7
0
        public void SetOutput_AcceptsSameVersionedDocuments()
        {
            // Arrange
            using var workspace = TestWorkspace.Create();

            var services     = workspace.Services;
            var hostProject  = new HostProject("C:/project.csproj", RazorConfiguration.Default, "project");
            var projectState = ProjectState.Create(services, hostProject);
            var project      = new DefaultProjectSnapshot(projectState);

            var text           = SourceText.From("...");
            var textAndVersion = TextAndVersion.Create(text, VersionStamp.Default);
            var hostDocument   = new HostDocument("C:/file.cshtml", "C:/file.cshtml");
            var documentState  = new DocumentState(services, hostDocument, text, VersionStamp.Default, () => Task.FromResult(textAndVersion));
            var document       = new DefaultDocumentSnapshot(project, documentState);
            var newDocument    = new DefaultDocumentSnapshot(project, documentState);

            var csharpDocument = RazorCSharpDocument.Create("...", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());
            var htmlDocument   = RazorHtmlDocument.Create("...", RazorCodeGenerationOptions.CreateDefault());

            var version   = VersionStamp.Create();
            var container = new GeneratedDocumentContainer();

            container.SetOutput(document, csharpDocument, htmlDocument, version, version, version);

            // Act
            container.SetOutput(newDocument, csharpDocument, htmlDocument, version, version, version);

            // Assert
            Assert.Same(newDocument, container.LatestDocument);
        }
コード例 #8
0
        public void DocumentProcessed_SynchronizesIfSourceVersionsAreIdenticalButSyncVersionNewer()
        {
            // Arrange
            var lastVersion     = VersionStamp.Default.GetNewerVersion();
            var lastDocument    = TestDocumentSnapshot.Create("C:/path/old.cshtml", lastVersion);
            var document        = TestDocumentSnapshot.Create("C:/path/file.cshtml", lastVersion);
            var csharpPublisher = new Mock <CSharpPublisher>();

            csharpPublisher.Setup(publisher => publisher.Publish(It.IsAny <string>(), It.IsAny <SourceText>(), It.IsAny <long>()))
            .Callback <string, SourceText, long>((filePath, sourceText, hostDocumentVersion) =>
            {
                Assert.Equal(document.FilePath, filePath);
            })
            .Verifiable();
            var cache = new TestDocumentVersionCache(new Dictionary <DocumentSnapshot, long>()
            {
                [document]     = 1338,
                [lastDocument] = 1337,
            });
            var csharpDocument = RazorCSharpDocument.Create("Anything", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());

            // Force the state to already be up-to-date
            document.State.HostDocument.GeneratedCodeContainer.SetOutput(lastDocument, csharpDocument, lastVersion, VersionStamp.Default);

            var listener = new UnsynchronizableContentDocumentProcessedListener(Dispatcher, cache, csharpPublisher.Object);

            listener.Initialize(ProjectSnapshotManager);

            // Act
            listener.DocumentProcessed(document);

            // Assert
            csharpPublisher.VerifyAll();
        }
コード例 #9
0
        public void DocumentProcessed_SynchronizesIfSourceVersionsAreIdenticalButSyncVersionNewer()
        {
            // Arrange
            var router       = new TestRouter();
            var lastVersion  = VersionStamp.Default.GetNewerVersion();
            var lastDocument = TestDocumentSnapshot.Create("C:/path/old.cshtml", lastVersion);
            var document     = TestDocumentSnapshot.Create("C:/path/file.cshtml", lastVersion);
            var cache        = new TestDocumentVersionCache(new Dictionary <DocumentSnapshot, long>()
            {
                [document]     = 1338,
                [lastDocument] = 1337,
            });
            var csharpDocument = RazorCSharpDocument.Create("Anything", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());

            // Force the state to already be up-to-date
            document.State.HostDocument.GeneratedCodeContainer.SetOutput(lastDocument, csharpDocument, lastVersion, VersionStamp.Default);

            var listener = new UnsynchronizableContentDocumentProcessedListener(Dispatcher, cache, router);

            listener.Initialize(ProjectSnapshotManager);

            // Act
            listener.DocumentProcessed(document);

            // Assert
            var filePath = Assert.Single(router.SynchronizedDocuments);

            Assert.Equal(document.FilePath, filePath);
        }
コード例 #10
0
        public void ReportUnsynchronizableContent_DoesNothingForOlderDocuments()
        {
            // Arrange
            var router       = new TestRouter();
            var lastVersion  = VersionStamp.Default.GetNewerVersion();
            var lastDocument = TestDocumentSnapshot.Create("C:/path/old.cshtml", lastVersion);
            var oldDocument  = TestDocumentSnapshot.Create("C:/path/file.cshtml", VersionStamp.Default);
            var cache        = new TestDocumentVersionCache(new Dictionary <DocumentSnapshot, long>()
            {
                [oldDocument]  = 1337,
                [lastDocument] = 1338,
            });
            var csharpDocument = RazorCSharpDocument.Create("Anything", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());

            // Force the state to already be up-to-date
            oldDocument.State.HostDocument.GeneratedCodeContainer.SetOutput(lastDocument, csharpDocument, lastVersion, VersionStamp.Default);

            var backgroundGenerator = new BackgroundDocumentGenerator(Dispatcher, cache, Listeners, router, LoggerFactory);
            var work = new[] { new KeyValuePair <string, DocumentSnapshot>(oldDocument.FilePath, oldDocument) };

            // Act
            backgroundGenerator.ReportUnsynchronizableContent(work);

            // Assert
            Assert.Empty(router.SynchronizedDocuments);
        }
コード例 #11
0
        private static RazorCodeDocument CreateCodeDocument(params RazorDiagnostic[] diagnostics)
        {
            var codeDocument        = TestRazorCodeDocument.CreateEmpty();
            var razorCSharpDocument = RazorCSharpDocument.Create(string.Empty, RazorCodeGenerationOptions.CreateDefault(), diagnostics);

            codeDocument.SetCSharpDocument(razorCSharpDocument);

            return(codeDocument);
        }
コード例 #12
0
        private static RazorCodeDocument CreateCodeDocumentWithCSharpProjection(string razorSource, string projectedCSharpSource, IEnumerable <SourceMapping> sourceMappings)
        {
            var codeDocument   = CreateCodeDocument(razorSource, Array.Empty <TagHelperDescriptor>());
            var csharpDocument = RazorCSharpDocument.Create(
                projectedCSharpSource,
                RazorCodeGenerationOptions.CreateDefault(),
                Enumerable.Empty <RazorDiagnostic>(),
                sourceMappings,
                Enumerable.Empty <LinePragma>());

            codeDocument.SetCSharpDocument(csharpDocument);
            return(codeDocument);
        }
コード例 #13
0
    public void SetCSharpDocument_SetsCSharpDocument()
    {
        // Arrange
        var codeDocument = TestRazorCodeDocument.CreateEmpty();

        var expected = RazorCSharpDocument.Create("", RazorCodeGenerationOptions.CreateDefault(), Array.Empty <RazorDiagnostic>());

        // Act
        codeDocument.SetCSharpDocument(expected);

        // Assert
        Assert.Same(expected, codeDocument.Items[typeof(RazorCSharpDocument)]);
    }
コード例 #14
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument)
        {
            var documentNode = codeDocument.GetDocumentIntermediateNode();

            ThrowForMissingDocumentDependency(documentNode);

            var cSharpDocument = RazorCSharpDocument.Create(
                UnsupportedDisclaimer,
                documentNode.Options,
                Enumerable.Empty <RazorDiagnostic>());

            codeDocument.SetCSharpDocument(cSharpDocument);
            codeDocument.SetUnsupported();
        }
コード例 #15
0
    public void GetCSharpDocument_ReturnsCSharpDocument()
    {
        // Arrange
        var codeDocument = TestRazorCodeDocument.CreateEmpty();

        var expected = RazorCSharpDocument.Create("", RazorCodeGenerationOptions.CreateDefault(), Array.Empty <RazorDiagnostic>());

        codeDocument.Items[typeof(RazorCSharpDocument)] = expected;

        // Act
        var actual = codeDocument.GetCSharpDocument();

        // Assert
        Assert.Same(expected, actual);
    }
コード例 #16
0
        private void _Init(string templateNamespace, string typeName, string basePath)
        {
            if (string.IsNullOrWhiteSpace(templateNamespace))
            {
                throw new ArgumentNullException(nameof(templateNamespace), "Cannot be null or empty.");
            }

            if (string.IsNullOrWhiteSpace(typeName))
            {
                throw new ArgumentNullException(nameof(typeName), "Cannot be null or empty.");
            }

            // customize the default engine a little bit
            var engine = RazorEngine.Create(b =>
            {
                InheritsDirective.Register(b);     // make sure the engine understand the @inherits directive in the input templates
                FunctionsDirective.Register(b);    // make sure the engine understand the @function directive in the input templates
                SectionDirective.Register(b);      // make sure the engine understand the @section directive in the input templates
                b.SetNamespace(templateNamespace); // define a namespace for the Template class
                b.Build();
            });

            var project        = RazorProject.Create(HostingEnvironment.ContentRootPath);
            var templateEngine = new RazorTemplateEngine(engine, project);

            // get a razor-templated file. My "hello.txt" template file is defined like this:
            //
            // @inherits RazorTemplate.MyTemplate
            // Hello @Model.Name, welcome to Razor World!
            //

            var fileInfo = _FindView(typeName, basePath, out var filepath);

            // ... parse and generate C# code ...
            var codeDoc = RazorCSharpDocument.Create();
            var cs      = templateEngine.GenerateCode(codeDoc);

            // ... use roslyn to parse the C# code ...
            //
            var tree = CSharpSyntaxTree.ParseText(cs.GeneratedCode);

            // ... name the assembly ...
            //
            string dllName = templateNamespace + "." + typeName;

            var compilation = CSharpCompilation.Create(dllName, new[] { tree },
                                                       new[]
コード例 #17
0
        public void SetOutput_AcceptsInitialOutput()
        {
            // Arrange
            var csharpDocument = RazorCSharpDocument.Create("...", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());
            var hostProject    = new HostProject("C:/project.csproj", RazorConfiguration.Default);
            var services       = TestWorkspace.Create().Services;
            var projectState   = ProjectState.Create(services, hostProject);
            var project        = new DefaultProjectSnapshot(projectState);
            var hostDocument   = new HostDocument("C:/file.cshtml", "C:/file.cshtml");
            var text           = SourceText.From("...");
            var textAndVersion = TextAndVersion.Create(text, VersionStamp.Default);
            var documentState  = new DocumentState(services, hostDocument, text, VersionStamp.Default, () => Task.FromResult(textAndVersion));
            var document       = new DefaultDocumentSnapshot(project, documentState);
            var container      = new GeneratedCodeContainer();

            // Act
            container.SetOutput(csharpDocument, document);

            // Assert
            Assert.NotNull(container.LatestDocument);
        }
コード例 #18
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument)
        {
            var documentNode = codeDocument.GetDocumentIntermediateNode();

            ThrowForMissingDocumentDependency(documentNode);
#pragma warning disable CS0618
            var writer = new DocumentWriterWorkaround().Create(documentNode.Target, documentNode.Options);
#pragma warning restore CS0618
            try
            {
                var cSharpDocument = writer.WriteDocument(codeDocument, documentNode);
                codeDocument.SetCSharpDocument(cSharpDocument);
            }
            catch (RazorCompilerException ex)
            {
                // Currently the Blazor code generation has some 'fatal errors' that can cause code generation
                // to fail completely. This class is here to make that implementation work gracefully.
                var cSharpDocument = RazorCSharpDocument.Create("", documentNode.Options, new[] { ex.Diagnostic });
                codeDocument.SetCSharpDocument(cSharpDocument);
            }
        }