public void TryComputeNamespace_ComputesNamespaceWithSuffix(string basePath, string relativePath, string expectedNamespace)
    {
        // Arrange
        var sourceDocument = TestRazorSourceDocument.Create(
            filePath: Path.Combine(basePath, relativePath),
            relativePath: relativePath);
        var codeDocument = TestRazorCodeDocument.Create(sourceDocument, Array.Empty <RazorSourceDocument>());

        codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(sourceDocument, RazorParserOptions.Create(options =>
        {
            options.Directives.Add(NamespaceDirective.Directive);
        })));

        var importRelativePath   = "_ViewImports.cshtml";
        var importSourceDocument = TestRazorSourceDocument.Create(
            content: "@namespace Base",
            filePath: Path.Combine(basePath, importRelativePath),
            relativePath: importRelativePath);

        codeDocument.SetImportSyntaxTrees(new[]
        {
            RazorSyntaxTree.Parse(importSourceDocument, RazorParserOptions.Create(options =>
            {
                options.Directives.Add(NamespaceDirective.Directive);
            }))
        });

        // Act
        codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var @namespace);

        // Assert
        Assert.Equal(expectedNamespace, @namespace);
    }
        private static RazorCodeActionContext CreateRazorCodeActionContext(RazorCodeActionParams request, SourceLocation location, string filePath, string text, bool supportsFileCreation = true)
        {
            var codeDocument = TestRazorCodeDocument.CreateEmpty();

            codeDocument.SetFileKind(FileKinds.Component);

            var sourceDocument = TestRazorSourceDocument.Create(text, filePath: filePath, relativePath: filePath);
            var options        = RazorParserOptions.Create(o =>
            {
                o.Directives.Add(ComponentCodeDirective.Directive);
                o.Directives.Add(FunctionsDirective.Directive);
            });
            var syntaxTree = RazorSyntaxTree.Parse(sourceDocument, options);

            codeDocument.SetSyntaxTree(syntaxTree);

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

            var sourceText = SourceText.From(text);

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

            return(context);
        }
    public void TryComputeNamespace_ForNonRelatedFiles_UsesNamespaceVerbatim()
    {
        // Arrange
        var sourceDocument = TestRazorSourceDocument.Create(
            filePath: "c:\\foo\\bar\\bleh.cshtml",
            relativePath: "bar\\bleh.cshtml");
        var codeDocument = TestRazorCodeDocument.Create(sourceDocument, Array.Empty <RazorSourceDocument>());

        codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(sourceDocument, RazorParserOptions.Create(options =>
        {
            options.Directives.Add(NamespaceDirective.Directive);
        })));

        var importSourceDocument = TestRazorSourceDocument.Create(
            content: "@namespace Base",
            filePath: "c:\\foo\\baz\\bleh.cshtml",
            relativePath: "baz\\bleh.cshtml");

        codeDocument.SetImportSyntaxTrees(new[]
        {
            RazorSyntaxTree.Parse(importSourceDocument, RazorParserOptions.Create(options =>
            {
                options.Directives.Add(NamespaceDirective.Directive);
            }))
        });

        // Act
        codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var @namespace);

        // Assert
        Assert.Equal("Base", @namespace);
    }
    public void TryComputeNamespace_RespectsNamespaceDirective()
    {
        // Arrange
        var sourceDocument = TestRazorSourceDocument.Create(
            content: "@namespace My.Custom.NS",
            filePath: "C:\\Hello\\Components\\Test.cshtml",
            relativePath: "\\Components\\Test.cshtml");
        var codeDocument = TestRazorCodeDocument.Create(sourceDocument, Array.Empty <RazorSourceDocument>());

        codeDocument.SetFileKind(FileKinds.Component);
        codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(sourceDocument, RazorParserOptions.Create(options =>
        {
            options.Directives.Add(NamespaceDirective.Directive);
        })));

        var documentNode = new DocumentIntermediateNode()
        {
            Options = RazorCodeGenerationOptions.Create(c =>
            {
                c.RootNamespace = "Hello.World";
            })
        };

        codeDocument.SetDocumentIntermediateNode(documentNode);

        // Act
        codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var @namespace);

        // Assert
        Assert.Equal("My.Custom.NS", @namespace);
    }
    public void Execute_AutomaticallyOverridesImportedSingleLineSinglyOccurringDirective_MainDocument()
    {
        // Arrange
        var directive = DirectiveDescriptor.CreateSingleLineDirective(
            "custom",
            builder =>
        {
            builder.AddStringToken();
            builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
        });
        var phase  = new DefaultRazorIntermediateNodeLoweringPhase();
        var engine = RazorProjectEngine.CreateEmpty(b =>
        {
            b.Phases.Add(phase);
            b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
            b.AddDirective(directive);
        });
        var options      = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
        var importSource = TestRazorSourceDocument.Create("@custom \"hello\"", filePath: "import.cshtml");
        var codeDocument = TestRazorCodeDocument.Create("@custom \"world\"");

        codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
        codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });

        // Act
        phase.Execute(codeDocument);

        // Assert
        var documentNode     = codeDocument.GetDocumentIntermediateNode();
        var customDirectives = documentNode.FindDirectiveReferences(directive);
        var customDirective  = (DirectiveIntermediateNode)Assert.Single(customDirectives).Node;
        var stringToken      = Assert.Single(customDirective.Tokens);

        Assert.Equal("\"world\"", stringToken.Content);
    }
    public void Execute_ErrorsForRazorBlockFileScopedSinglyOccurringDirectives()
    {
        // Arrange
        var directive = DirectiveDescriptor.CreateRazorBlockDirective("custom", b => b.Usage = DirectiveUsage.FileScopedSinglyOccurring);
        var phase     = new DefaultRazorIntermediateNodeLoweringPhase();
        var engine    = RazorProjectEngine.CreateEmpty(b =>
        {
            b.Phases.Add(phase);
            b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
            b.AddDirective(directive);
        });
        var options      = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
        var importSource = TestRazorSourceDocument.Create("@custom { }", filePath: "import.cshtml");
        var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");

        codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
        codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });
        var expectedDiagnostic = RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported("custom");

        // Act
        phase.Execute(codeDocument);

        // Assert
        var documentNode = codeDocument.GetDocumentIntermediateNode();
        var directives   = documentNode.Children.OfType <DirectiveIntermediateNode>();

        Assert.Empty(directives);
        var diagnostic = Assert.Single(documentNode.GetAllDiagnostics());

        Assert.Equal(expectedDiagnostic, diagnostic);
    }
예제 #7
0
        public static ParseResult Parse(Input input)
        {
            var document = CreateSourceDocument(input.Content);
            var options  = RazorParserOptions.Create(builder => {
                foreach (var directive in GetDirectives())
                {
                    builder.Directives.Add(directive);
                }

                builder.SetDesignTime(input.DesignTime);
            });

            // Syntax tree
            var context      = new ParserContext(document, options);
            var codeParser   = new CSharpCodeParser(GetDirectives(), context);
            var markupParser = new HtmlMarkupParser(context);

            codeParser.HtmlParser   = markupParser;
            markupParser.CodeParser = codeParser;
            var root = markupParser.ParseDocument().CreateRed();

            // IR tree
            RazorCodeDocument codeDocument;
            var engine = RazorProjectEngine.Create(configure: null);

            if (input.DesignTime)
            {
                codeDocument = engine.ProcessDesignTime(document, null, null, TestTagHelpers.GetDescriptors());
            }
            else
            {
                codeDocument = engine.Process(document, null, null, TestTagHelpers.GetDescriptors());
            }
            if (input.TagHelperPhase)
            {
                root = codeDocument.GetSyntaxTree().Root;
            }

            var syntaxTreeRoot = TreeSerializer.Serialize(root);

            var intermediateNode = codeDocument.GetDocumentIntermediateNode();
            var intermediateRoot = IRSerializer.Serialize(intermediateNode);

            // Generated code
            var cSharpDocument = codeDocument.GetCSharpDocument();
            var generatedCode  = new GeneratedCodeResult {
                Code = cSharpDocument.GeneratedCode
            };

            return(new ParseResult
            {
                SyntaxTreeRoot = syntaxTreeRoot,
                IntermediateRoot = intermediateRoot,
                GeneratedCode = generatedCode
            });
        }
        private static TextBufferCodeDocumentProvider CreateCodeDocumentProvider(string content)
        {
            var sourceDocument = TestRazorSourceDocument.Create(content);
            var syntaxTree     = RazorSyntaxTree.Parse(sourceDocument, RazorParserOptions.Create(opt => opt.Directives.Add(FunctionsDirective.Directive)));
            var codeDocument   = TestRazorCodeDocument.Create(content);

            codeDocument.SetSyntaxTree(syntaxTree);
            var codeDocumentProvider = Mock.Of <TextBufferCodeDocumentProvider>(provider => provider.TryGetFromBuffer(It.IsAny <ITextBuffer>(), out codeDocument), MockBehavior.Strict);

            return(codeDocumentProvider);
        }
예제 #9
0
        private static RazorSyntaxTree GetSyntaxTree(string content)
        {
            var syntaxTree = RazorSyntaxTree.Parse(
                TestRazorSourceDocument.Create(content),
                RazorParserOptions.Create(options =>
            {
                options.Directives.Add(FunctionsDirective.Directive);
                options.Directives.Add(SectionDirective.Directive);
            }));

            return(syntaxTree);
        }
예제 #10
0
        public void AtApplicableRazorBlock_AtMetacode_ReturnsTrue()
        {
            // Arrange
            var parseOptions   = RazorParserOptions.Create(options => options.Directives.Add(FunctionsDirective.Directive));
            var syntaxTree     = RazorSyntaxTree.Parse(TestRazorSourceDocument.Create("@functions {}"), parseOptions);
            var changePosition = 12;

            // Act
            var result = BraceSmartIndenter.AtApplicableRazorBlock(changePosition, syntaxTree);

            // Assert
            Assert.True(result);
        }
        private static RazorSyntaxTree CreateSyntaxTree(string text, params DirectiveDescriptor[] directives)
        {
            var sourceDocument = TestRazorSourceDocument.Create(text);
            var options        = RazorParserOptions.Create(builder =>
            {
                foreach (var directive in directives)
                {
                    builder.Directives.Add(directive);
                }
            });
            var syntaxTree = RazorSyntaxTree.Parse(sourceDocument, options);

            return(syntaxTree);
        }
예제 #12
0
        public IActionResult Parse([FromBody] Source source)
        {
            var document = RazorSourceDocument.Create(source.Content, fileName: null);
            var options  = RazorParserOptions.Create(builder => {
                foreach (var directive in GetDirectives())
                {
                    builder.Directives.Add(directive);
                }
            });
            var parser = new RazorParser(options);
            var tree   = parser.Parse(document, legacy: true);
            var result = TreeSerializer.Serialize(tree);

            return(Content(result));
        }
예제 #13
0
        public void SyntaxTreeGeneration_Runtime_LargeStaticFile()
        {
            var options = RazorParserOptions.Create(o =>
            {
                foreach (var directive in Directives)
                {
                    o.Directives.Add(directive);
                }
            });
            var syntaxTree = RazorSyntaxTree.Parse(MSN, options);

            if (syntaxTree.Diagnostics.Count != 0)
            {
                throw new Exception("Error!" + Environment.NewLine + string.Join(Environment.NewLine, syntaxTree.Diagnostics));
            }
        }
예제 #14
0
        public void Parse_UseDirectiveTokenizer_ParsesUntilFirstDirective()
        {
            // Arrange
            var source  = TestRazorSourceDocument.Create("\r\n  \r\n    @*SomeComment*@ \r\n  @tagHelperPrefix \"SomePrefix\"\r\n<html>\r\n@if (true) {\r\n @if(false) { <div>@something.</div> } \r\n}");
            var options = RazorParserOptions.Create(builder => builder.ParseLeadingDirectives = true);

            // Act
            var syntaxTree = RazorSyntaxTree.Parse(source, options);

            // Assert
            Assert.NotNull(syntaxTree);
            Assert.Equal(6, syntaxTree.Root.Children.Count);
            var block = Assert.IsType <Block>(syntaxTree.Root.Children[4]);

            Assert.Equal(BlockKindInternal.Directive, block.Type);
            Assert.Empty(syntaxTree.Diagnostics);
        }
예제 #15
0
        public void Parse_UseDirectiveTokenizer_ParsesUntilFirstDirective()
        {
            // Arrange
            var source  = TestRazorSourceDocument.Create("\r\n  \r\n    @*SomeComment*@ \r\n  @tagHelperPrefix \"SomePrefix\"\r\n<html>\r\n@if (true) {\r\n @if(false) { <div>@something.</div> } \r\n}");
            var options = RazorParserOptions.Create(builder => builder.ParseLeadingDirectives = true);

            // Act
            var syntaxTree = RazorSyntaxTree.Parse(source, options);

            // Assert
            var root = syntaxTree.Root;

            Assert.NotNull(syntaxTree);
            Assert.Equal(61, root.EndPosition);
            Assert.Single(root.DescendantNodes().Where(n => n is RazorDirectiveBodySyntax body && body.Keyword.GetContent() == "tagHelperPrefix"));
            Assert.Empty(root.DescendantNodes().Where(n => n is MarkupTagBlockSyntax));
            Assert.Empty(syntaxTree.Diagnostics);
        }
예제 #16
0
        private static RazorParserOptions CreateParserOptions(IEnumerable <DirectiveDescriptor> directives, bool designTime)
        {
            if (designTime)
            {
                return(RazorParserOptions.CreateDesignTime(ConfigureOptions));
            }
            else
            {
                return(RazorParserOptions.Create(ConfigureOptions));
            }

            void ConfigureOptions(RazorParserOptionsBuilder builder)
            {
                foreach (var directive in directives)
                {
                    builder.Directives.Add(directive);
                }
            }
        }
        private static Lazy <RazorCodeDocumentProvider> CreateCodeDocumentProvider(string text, IEnumerable <DirectiveDescriptor> directives)
        {
            var codeDocumentProvider = new Mock <RazorCodeDocumentProvider>();
            var codeDocument         = TestRazorCodeDocument.CreateEmpty();
            var sourceDocument       = TestRazorSourceDocument.Create(text);
            var options = RazorParserOptions.Create(builder =>
            {
                foreach (var directive in directives)
                {
                    builder.Directives.Add(directive);
                }
            });
            var syntaxTree = RazorSyntaxTree.Parse(sourceDocument, options);

            codeDocument.SetSyntaxTree(syntaxTree);
            codeDocumentProvider.Setup(provider => provider.TryGetFromDocument(It.IsAny <TextDocument>(), out codeDocument))
            .Returns(true);

            return(new Lazy <RazorCodeDocumentProvider>(() => codeDocumentProvider.Object));
        }
예제 #18
0
        public IActionResult ParseIR([FromBody] Source source)
        {
            var document = RazorSourceDocument.Create(source.Content, fileName: null);
            var options  = RazorParserOptions.Create(builder => {
                foreach (var directive in GetDirectives())
                {
                    builder.Directives.Add(directive);
                }
            });

            var sourceDocument = CreateSourceDocument(source.Content);
            var engine         = RazorProjectEngine.Create();
            var codeDocument   = engine.Process(sourceDocument, null, null);

            var irDocument = codeDocument.GetDocumentIntermediateNode();
            var output     = SerializeIR(irDocument);

            //output = NormalizeNewLines(output, replaceWith: "LF");
            return(Json(output));
        }
예제 #19
0
        public IActionResult NewParse([FromBody] Source source)
        {
            var document = RazorSourceDocument.Create(source.Content, fileName: null);
            var options  = RazorParserOptions.Create(builder => {
                foreach (var directive in GetDirectives())
                {
                    builder.Directives.Add(directive);
                }
            });
            var context      = new ParserContext(document, options);
            var codeParser   = new CSharpCodeParser(GetDirectives(), context);
            var markupParser = new HtmlMarkupParser(context);

            codeParser.HtmlParser   = markupParser;
            markupParser.CodeParser = codeParser;

            var root   = markupParser.ParseDocument().CreateRed();
            var result = NewTreeSerializer.Serialize(root);

            return(Content(result));
        }
    public void Execute_DoesNotImportNonFileScopedSinglyOccurringDirectives_Block()
    {
        // Arrange
        var codeBlockDirective  = DirectiveDescriptor.CreateCodeBlockDirective("code", b => b.AddStringToken());
        var razorBlockDirective = DirectiveDescriptor.CreateRazorBlockDirective("razor", b => b.AddStringToken());
        var phase  = new DefaultRazorIntermediateNodeLoweringPhase();
        var engine = RazorProjectEngine.CreateEmpty(b =>
        {
            b.Phases.Add(phase);
            b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
            b.AddDirective(codeBlockDirective);
            b.AddDirective(razorBlockDirective);
        });
        var options = RazorParserOptions.Create(builder =>
        {
            builder.Directives.Add(codeBlockDirective);
            builder.Directives.Add(razorBlockDirective);
        });
        var importSource = TestRazorSourceDocument.Create(
            @"@code ""code block"" { }
@razor ""razor block"" { }",
            filePath: "testImports.cshtml");
        var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");

        codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
        codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });

        // Act
        phase.Execute(codeDocument);

        // Assert
        var documentNode = codeDocument.GetDocumentIntermediateNode();
        var directives   = documentNode.Children.OfType <DirectiveIntermediateNode>();

        Assert.Empty(directives);
    }