private void CreateTypeInferenceMethod(DocumentIntermediateNode documentNode, ComponentIntermediateNode node)
            {
                var @namespace = documentNode.FindPrimaryNamespace().Content;

                @namespace  = string.IsNullOrEmpty(@namespace) ? "__Blazor" : "__Blazor." + @namespace;
                @namespace += "." + documentNode.FindPrimaryClass().ClassName;

                var typeInferenceNode = new ComponentTypeInferenceMethodIntermediateNode()
                {
                    Component = node,

                    // Method name is generated and guaranteed not to collide, since it's unique for each
                    // component call site.
                    MethodName   = $"Create{CSharpIdentifier.SanitizeIdentifier(node.TagName)}_{_id++}",
                    FullTypeName = @namespace + ".TypeInference",
                };

                node.TypeInferenceNode = typeInferenceNode;

                // Now we need to insert the type inference node into the tree.
                var namespaceNode = documentNode.Children
                                    .OfType <NamespaceDeclarationIntermediateNode>()
                                    .Where(n => n.Annotations.Contains(new KeyValuePair <object, object>(ComponentMetadata.Component.GenericTypedKey, bool.TrueString)))
                                    .FirstOrDefault();

                if (namespaceNode == null)
                {
                    namespaceNode = new NamespaceDeclarationIntermediateNode()
                    {
                        Annotations =
                        {
                            { ComponentMetadata.Component.GenericTypedKey, bool.TrueString },
                        },
                        Content = @namespace,
                    };

                    documentNode.Children.Add(namespaceNode);
                }

                var classNode = namespaceNode.Children
                                .OfType <ClassDeclarationIntermediateNode>()
                                .Where(n => n.ClassName == "TypeInference")
                                .FirstOrDefault();

                if (classNode == null)
                {
                    classNode = new ClassDeclarationIntermediateNode()
                    {
                        ClassName = "TypeInference",
                        Modifiers =
                        {
                            "internal",
                            "static",
                        },
                    };
                    namespaceNode.Children.Add(classNode);
                }

                classNode.Children.Add(typeInferenceNode);
            }
Example #2
0
            public Context(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class)
            {
                Namespace = @namespace;
                Class     = @class;

                _tagHelpers = new Dictionary <TagHelperDescriptor, (string, string, string)>();
            }
Example #3
0
 public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
 {
     using (Context.CodeWriter.BuildClassDeclaration(node.Modifiers, node.ClassName, node.BaseType, node.Interfaces))
     {
         VisitDefault(node);
     }
 }
        protected override void ExecuteCore(RazorCodeDocument codeDocument)
        {
            DocumentIntermediateNode documentNode = codeDocument.GetDocumentIntermediateNode();

            NamespaceDeclarationIntermediateNode namespaceDeclaration =
                documentNode.Children.OfType <NamespaceDeclarationIntermediateNode>().Single();

            // Get the current model type, replacing default of dynamic with IDocument
            string modelType = ModelDirective.GetModelType(documentNode);

            modelType = modelType == "dynamic" ? "IDocument" : modelType;

            // Set the base page type and perform default model type substitution here
            ClassDeclarationIntermediateNode classDeclaration =
                namespaceDeclaration.Children.OfType <ClassDeclarationIntermediateNode>().Single();

            classDeclaration.BaseType = _baseType.Replace("<TModel>", "<" + modelType + ">");

            // Add namespaces
            int insertIndex = namespaceDeclaration.Children.IndexOf(
                namespaceDeclaration.Children.OfType <UsingDirectiveIntermediateNode>().First());

            foreach (string ns in _namespaces)
            {
                namespaceDeclaration.Children.Insert(
                    insertIndex,
                    new UsingDirectiveIntermediateNode()
                {
                    Content = ns
                });
            }

            codeDocument.SetDocumentIntermediateNode(documentNode);
        }
Example #5
0
            public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
            {
                _classDeclaration    = node;
                _variableCountOffset = node.Children.Count;

                VisitDefault(node);
            }
Example #6
0
        protected override void OnDocumentStructureCreated(
            RazorCodeDocument codeDocument,
            NamespaceDeclarationIntermediateNode @namespace,
            ClassDeclarationIntermediateNode @class,
            MethodDeclarationIntermediateNode method)
        {
            base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);

            @namespace.Content = "AspNetCore";

            @class.BaseType = "global::Microsoft.AspNetCore.Mvc.RazorPages.Page";

            var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;

            @class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);

            @class.Modifiers.Clear();
            @class.Modifiers.Add("public");

            method.MethodName = "ExecuteAsync";
            method.Modifiers.Clear();
            method.Modifiers.Add("public");
            method.Modifiers.Add("async");
            method.Modifiers.Add("override");
            method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";

            var document = codeDocument.GetDocumentIntermediateNode();

            PageDirective.TryGetPageDirective(document, out var pageDirective);

            EnsureValidPageDirective(codeDocument, pageDirective);

            AddRouteTemplateMetadataAttribute(@namespace, @class, pageDirective);
        }
Example #7
0
        public void Execute_HasRequiredInfo_AddsItemAndSourceChecksum()
        {
            // Arrange
            var engine = CreateEngine();
            var pass   = new MetadataAttributePass()
            {
                Engine = engine,
            };

            var sourceDocument = TestRazorSourceDocument.Create();
            var codeDocument   = RazorCodeDocument.Create(sourceDocument);

            codeDocument.SetIdentifier("Foo/Bar");

            var irDocument = new DocumentIntermediateNode()
            {
                DocumentKind = "test",
                Options      = RazorCodeGenerationOptions.Create((o) => { }),
            };
            var builder    = IntermediateNodeBuilder.Create(irDocument);
            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
                },
                Content = "Some.Namespace"
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
                ClassName = "Test",
            };

            builder.Add(@class);

            // Act
            pass.Execute(codeDocument, irDocument);

            // Assert
            Assert.Equal(2, irDocument.Children.Count);

            var item = Assert.IsType <RazorCompiledItemAttributeIntermediateNode>(irDocument.Children[0]);

            Assert.Equal("Foo/Bar", item.Identifier);
            Assert.Equal("test", item.Kind);
            Assert.Equal("Some.Namespace.Test", item.TypeName);

            Assert.Equal(2, @namespace.Children.Count);
            var checksum = Assert.IsType <RazorSourceChecksumAttributeIntermediateNode>(@namespace.Children[0]);

            Assert.NotNull(checksum.Checksum); // Not verifying the checksum here
            Assert.Equal("SHA1", checksum.ChecksumAlgorithm);
            Assert.Equal("Foo/Bar", checksum.Identifier);
        }
        protected override void OnDocumentStructureCreated(
            RazorCodeDocument codeDocument,
            NamespaceDeclarationIntermediateNode @namespace,
            ClassDeclarationIntermediateNode @class,
            MethodDeclarationIntermediateNode method)
        {
            base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);

            @namespace.Content = "AspNetCore";

            var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;

            if (string.IsNullOrEmpty(filePath))
            {
                // It's possible for a Razor document to not have a file path.
                // Eg. When we try to generate code for an in memory document like default imports.
                var checksum = BytesToString(codeDocument.Source.GetChecksum());
                @class.ClassName = $"AspNetCore_{checksum}";
            }
            else
            {
                @class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
            }

            @class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
            @class.Modifiers.Clear();
            @class.Modifiers.Add("public");

            method.MethodName = "ExecuteAsync";
            method.Modifiers.Clear();
            method.Modifiers.Add("public");
            method.Modifiers.Add("async");
            method.Modifiers.Add("override");
            method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";
        }
Example #9
0
        public void Execute_AddsRazorPagettribute_ToPage()
        {
            // Arrange
            var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName), null)]";
            var irDocument        = new DocumentIntermediateNode
            {
                DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind,
            };
            var builder       = IntermediateNodeBuilder.Create(irDocument);
            var pageDirective = new DirectiveIntermediateNode
            {
                Directive = PageDirective.Directive,
            };

            builder.Add(pageDirective);

            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Content     = "SomeNamespace",
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
                },
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                ClassName   = "SomeName",
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
            };

            builder.Add(@class);

            var pass = new AssemblyAttributeInjectionPass
            {
                Engine = RazorEngine.Create(),
            };

            var source   = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml"));
            var document = RazorCodeDocument.Create(source);

            // Act
            pass.Execute(document, irDocument);

            // Assert
            Assert.Collection(irDocument.Children,
                              node => Assert.Same(pageDirective, node),
                              node =>
            {
                var csharpCode = Assert.IsType <CSharpCodeIntermediateNode>(node);
                var token      = Assert.IsType <IntermediateToken>(Assert.Single(csharpCode.Children));
                Assert.Equal(TokenKind.CSharp, token.Kind);
                Assert.Equal(expectedAttribute, token.Content);
            },
                              node => Assert.Same(@namespace, node));
        }
        protected override void OnDocumentStructureCreated(
            RazorCodeDocument codeDocument,
            NamespaceDeclarationIntermediateNode @namespace,
            ClassDeclarationIntermediateNode @class,
            MethodDeclarationIntermediateNode method)
        {
            var configuration = Engine.GetFeature <DefaultDocumentClassifierPassFeature>();

            if (configuration != null)
            {
                for (var i = 0; i < configuration.ConfigureClass.Count; i++)
                {
                    var configureClass = configuration.ConfigureClass[i];
                    configureClass(codeDocument, @class);
                }

                for (var i = 0; i < configuration.ConfigureNamespace.Count; i++)
                {
                    var configureNamespace = configuration.ConfigureNamespace[i];
                    configureNamespace(codeDocument, @namespace);
                }

                for (var i = 0; i < configuration.ConfigureMethod.Count; i++)
                {
                    var configureMethod = configuration.ConfigureMethod[i];
                    configureMethod(codeDocument, @method);
                }
            }
        }
Example #11
0
        public void Pass_SetsNamespaceAndClassName_ComputedFromSource_ForView()
        {
            // Arrange
            var document = new DocumentIntermediateNode();
            var builder  = IntermediateNodeBuilder.Create(document);

            // This will be ignored.
            builder.Push(new DirectiveIntermediateNode()
            {
                Directive = NamespaceDirective.Directive,
                Source    = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0),
            });
            builder.Add(new DirectiveTokenIntermediateNode()
            {
                Content = "ignored"
            });
            builder.Pop();

            // This will be used.
            builder.Push(new DirectiveIntermediateNode()
            {
                Directive = NamespaceDirective.Directive,
                Source    = new SourceSpan("/Account/Manage/AddUser.cshtml", 0, 0, 0, 0),
            });
            builder.Add(new DirectiveTokenIntermediateNode()
            {
                Content = "WebApplication.Account.Manage"
            });
            builder.Pop();

            var @namespace = new NamespaceDeclarationIntermediateNode()
            {
                Content = "default"
            };

            builder.Push(@namespace);

            var @class = new ClassDeclarationIntermediateNode()
            {
                ClassName = "default"
            };

            builder.Add(@class);

            document.DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind;

            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));

            var pass = new NamespaceDirective.Pass();

            pass.Engine = RazorEngine.CreateEmpty(b => { });

            // Act
            pass.Execute(codeDocument, document);

            // Assert
            Assert.Equal("WebApplication.Account.Manage", @namespace.Content);
            Assert.Equal("AddUser_View", @class.ClassName);
        }
Example #12
0
 protected virtual void OnDocumentStructureCreated(
     RazorCodeDocument codeDocument,
     NamespaceDeclarationIntermediateNode @namespace,
     ClassDeclarationIntermediateNode @class,
     MethodDeclarationIntermediateNode @method)
 {
     // Intentionally empty.
 }
Example #13
0
            public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
            {
                if (Class == null)
                {
                    Class = node;
                }

                base.VisitClassDeclaration(node);
            }
        public void Execute_SuppressMetadataSourceChecksumAttributes_DoesNotGenerateSourceChecksumAttributes()
        {
            // Arrange
            var engine = CreateEngine();
            var pass   = new MetadataAttributePass()
            {
                Engine = engine,
            };

            var sourceDocument = TestRazorSourceDocument.Create("", new RazorSourceDocumentProperties(null, "Foo\\Bar.cshtml"));
            var import         = TestRazorSourceDocument.Create("@using System", new RazorSourceDocumentProperties(null, "Foo\\Import.cshtml"));
            var codeDocument   = RazorCodeDocument.Create(sourceDocument, new[] { import, });

            var irDocument = new DocumentIntermediateNode()
            {
                DocumentKind = "test",
                Options      = RazorCodeGenerationOptions.Create(o => o.SuppressMetadataSourceChecksumAttributes = true),
            };
            var builder    = IntermediateNodeBuilder.Create(irDocument);
            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
                },
                Content = "Some.Namespace"
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
                ClassName = "Test",
            };

            builder.Add(@class);

            // Act
            pass.Execute(codeDocument, irDocument);

            // Assert
            Assert.Equal(2, irDocument.Children.Count);

            var item = Assert.IsType <RazorCompiledItemAttributeIntermediateNode>(irDocument.Children[0]);

            Assert.Equal("/Foo/Bar.cshtml", item.Identifier);
            Assert.Equal("test", item.Kind);
            Assert.Equal("Some.Namespace.Test", item.TypeName);

            var child = Assert.Single(@namespace.Children);

            Assert.IsType <ClassDeclarationIntermediateNode>(child);
        }
 protected override void OnDocumentStructureCreated(
     RazorCodeDocument codeDocument,
     NamespaceDeclarationIntermediateNode @namespace,
     ClassDeclarationIntermediateNode @class,
     MethodDeclarationIntermediateNode method)
 {
     @namespace.Content = Namespace;
     @class.ClassName   = Class;
     @method.MethodName = Method;
 }
        /// <inheritdoc />
        protected override void OnDocumentStructureCreated(
            RazorCodeDocument codeDocument,
            NamespaceDeclarationIntermediateNode @namespace,
            ClassDeclarationIntermediateNode @class,
            MethodDeclarationIntermediateNode method)
        {
            if (!TryComputeNamespaceAndClass(
                    codeDocument.Source.FilePath,
                    codeDocument.Source.RelativePath,
                    out var computedNamespace,
                    out var computedClass))
            {
                // If we can't compute a nice namespace (no relative path) then just generate something
                // mangled.
                computedNamespace = BaseNamespace;
                computedClass     = CSharpIdentifier.GetClassNameFromPath(codeDocument.Source.FilePath) ?? "__BlazorComponent";
            }

            if (MangleClassNames)
            {
                computedClass = "__" + computedClass;
            }

            @namespace.Content = computedNamespace;

            @class.BaseType  = BlazorApi.BlazorComponent.FullTypeName;
            @class.ClassName = computedClass;
            @class.Modifiers.Clear();
            @class.Modifiers.Add("public");

            method.ReturnType = "void";
            method.MethodName = BlazorApi.BlazorComponent.BuildRenderTree;
            method.Modifiers.Clear();
            method.Modifiers.Add("protected");
            method.Modifiers.Add("override");

            method.Parameters.Clear();
            method.Parameters.Add(new MethodParameter()
            {
                ParameterName = "builder",
                TypeName      = BlazorApi.RenderTreeBuilder.FullTypeName,
            });

            // We need to call the 'base' method as the first statement.
            var callBase = new CSharpCodeIntermediateNode();

            callBase.Annotations.Add(BuildRenderTreeBaseCallAnnotation, true);
            callBase.Children.Add(new IntermediateToken
            {
                Kind    = TokenKind.CSharp,
                Content = $"base.{BlazorApi.BlazorComponent.BuildRenderTree}(builder);"
            });
            method.Children.Insert(0, callBase);
        }
        public void Execute_EscapesViewPathAndRouteWhenAddingAttributeToPage()
        {
            // Arrange
            var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/test/\"\"Index.cshtml\", typeof(SomeNamespace.SomeName))]";
            var irDocument        = new DocumentIntermediateNode
            {
                DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind,
                Options      = RazorCodeGenerationOptions.CreateDefault(),
            };
            var builder    = IntermediateNodeBuilder.Create(irDocument);
            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Content     = "SomeNamespace",
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
                },
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                ClassName   = "SomeName",
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
            };

            builder.Add(@class);

            var pass = new AssemblyAttributeInjectionPass
            {
                Engine = RazorProjectEngine.Create().Engine,
            };

            var source   = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "test\\\"Index.cshtml"));
            var document = RazorCodeDocument.Create(source);

            // Act
            pass.Execute(document, irDocument);

            // Assert
            Assert.Collection(irDocument.Children,
                              node =>
            {
                var csharpCode = Assert.IsType <CSharpCodeIntermediateNode>(node);
                var token      = Assert.IsType <IntermediateToken>(Assert.Single(csharpCode.Children));
                Assert.Equal(TokenKind.CSharp, token.Kind);
                Assert.Equal(expectedAttribute, token.Content);
            },
                              node => Assert.Same(@namespace, node));
        }
Example #18
0
    protected override void OnDocumentStructureCreated(
        RazorCodeDocument codeDocument,
        NamespaceDeclarationIntermediateNode @namespace,
        ClassDeclarationIntermediateNode @class,
        MethodDeclarationIntermediateNode method)
    {
        base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);

        if (!codeDocument.TryComputeNamespace(fallbackToRootNamespace: false, out var namespaceName))
        {
            @namespace.Content = _useConsolidatedMvcViews ? "AspNetCoreGeneratedDocument" : "AspNetCore";
        }
 public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
 {
     using (Context.CodeWriter.BuildClassDeclaration(
                node.Modifiers,
                node.ClassName,
                node.BaseType,
                node.Interfaces,
                node.TypeParameters.Select(p => (p.ParameterName, p.Constraints)).ToArray()))
     {
         VisitDefault(node);
     }
 }
Example #20
0
        public void Execute_AddsRazorViewAttribute_ToViews()
        {
            // Arrange
            var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName))]";
            var irDocument        = new DocumentIntermediateNode
            {
                DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind,
            };
            var builder    = IntermediateNodeBuilder.Create(irDocument);
            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Content     = "SomeNamespace",
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
                },
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                ClassName   = "SomeName",
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
            };

            builder.Add(@class);

            var pass = new AssemblyAttributeInjectionPass
            {
                Engine = RazorEngine.Create(),
            };
            var document = TestRazorCodeDocument.CreateEmpty();

            document.SetRelativePath("/Views/Index.cshtml");

            // Act
            pass.Execute(document, irDocument);

            // Assert
            Assert.Collection(irDocument.Children,
                              node =>
            {
                var csharpCode = Assert.IsType <CSharpCodeIntermediateNode>(node);
                var token      = Assert.IsType <IntermediateToken>(Assert.Single(csharpCode.Children));
                Assert.Equal(TokenKind.CSharp, token.Kind);
                Assert.Equal(expectedAttribute, token.Content);
            },
                              node => Assert.Same(@namespace, node));
        }
Example #21
0
        public void Pass_DoesNothing_ForUnknownDocumentKind()
        {
            // Arrange
            var document = new DocumentIntermediateNode();
            var builder  = IntermediateNodeBuilder.Create(document);

            builder.Push(new DirectiveIntermediateNode()
            {
                Directive = NamespaceDirective.Directive,
                Source    = new SourceSpan(null, 0, 0, 0, 0),
            });
            builder.Add(new DirectiveTokenIntermediateNode()
            {
                Content = "WebApplication.Account"
            });
            builder.Pop();

            var @namespace = new NamespaceDeclarationIntermediateNode()
            {
                Content = "default"
            };

            builder.Push(@namespace);

            var @class = new ClassDeclarationIntermediateNode()
            {
                ClassName = "default"
            };

            builder.Add(@class);

            document.DocumentKind = null;

            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));

            var pass = new NamespaceDirective.Pass();

            pass.Engine = RazorEngine.CreateEmpty(b => { });

            // Act
            pass.Execute(codeDocument, document);

            // Assert
            Assert.Equal("default", @namespace.Content);
            Assert.Equal("default", @class.ClassName);
        }
        public void Pass_SetsNamespace_VerbatimFromImports()
        {
            // Arrange
            var document = new DocumentIntermediateNode();
            var builder  = IntermediateNodeBuilder.Create(document);

            builder.Push(new DirectiveIntermediateNode()
            {
                Directive = NamespaceDirective.Directive,
                Source    = new SourceSpan(null, 0, 0, 0, 0),
            });
            builder.Add(new DirectiveTokenIntermediateNode()
            {
                Content = "WebApplication.Account"
            });
            builder.Pop();

            var @namespace = new NamespaceDeclarationIntermediateNode()
            {
                Content = "default"
            };

            builder.Push(@namespace);

            var @class = new ClassDeclarationIntermediateNode()
            {
                ClassName = "default"
            };

            builder.Add(@class);

            document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind;

            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));

            var pass = new NamespaceDirective.Pass();

            pass.Engine = Mock.Of <RazorEngine>();

            // Act
            pass.Execute(codeDocument, document);

            // Assert
            Assert.Equal("WebApplication.Account", @namespace.Content);
            Assert.Equal("default", @class.ClassName);
        }
        public void Execute_NoOps_ForDesignTime()
        {
            // Arrange
            var irDocument = new DocumentIntermediateNode
            {
                DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind,
                Options      = RazorCodeGenerationOptions.CreateDesignTimeDefault(),
            };
            var builder    = IntermediateNodeBuilder.Create(irDocument);
            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Content     = "SomeNamespace",
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
                },
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                ClassName   = "SomeName",
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
            };

            builder.Add(@class);

            var pass = new AssemblyAttributeInjectionPass
            {
                Engine = RazorProjectEngine.Create().Engine,
            };

            var source   = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml"));
            var document = RazorCodeDocument.Create(source);

            // Act
            pass.Execute(document, irDocument);

            // Assert
            Assert.Collection(
                irDocument.Children,
                node => Assert.Same(@namespace, node));
        }
Example #24
0
        public void Execute_NoIdentifier_Noops()
        {
            // Arrange
            var engine = CreateEngine();
            var pass   = new MetadataAttributePass()
            {
                Engine = engine,
            };

            var sourceDocument = TestRazorSourceDocument.Create("", new RazorSourceDocumentProperties(null, null));
            var codeDocument   = RazorCodeDocument.Create(sourceDocument);

            var irDocument = new DocumentIntermediateNode()
            {
                DocumentKind = "test",
                Options      = RazorCodeGenerationOptions.Create((o) => { }),
            };
            var builder    = IntermediateNodeBuilder.Create(irDocument);
            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
                },
                Content = "Some.Namespace"
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
                ClassName = "Test",
            };

            builder.Add(@class);

            // Act
            pass.Execute(codeDocument, irDocument);

            // Assert
            SingleChild <NamespaceDeclarationIntermediateNode>(irDocument);
        }
Example #25
0
    private void Rewrite(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
    {
        // Rewrite the document from a flat structure to use a sensible default structure,
        // a namespace and class declaration with a single 'razor' method.
        var children = new List <IntermediateNode>(documentNode.Children);

        documentNode.Children.Clear();

        var @namespace = new NamespaceDeclarationIntermediateNode();

        @namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace;

        var @class = new ClassDeclarationIntermediateNode();

        @class.Annotations[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass;

        var method = new MethodDeclarationIntermediateNode();

        method.Annotations[CommonAnnotations.PrimaryMethod] = CommonAnnotations.PrimaryMethod;

        var documentBuilder = IntermediateNodeBuilder.Create(documentNode);

        var namespaceBuilder = IntermediateNodeBuilder.Create(documentBuilder.Current);

        namespaceBuilder.Push(@namespace);

        var classBuilder = IntermediateNodeBuilder.Create(namespaceBuilder.Current);

        classBuilder.Push(@class);

        var methodBuilder = IntermediateNodeBuilder.Create(classBuilder.Current);

        methodBuilder.Push(method);

        var visitor = new Visitor(documentBuilder, namespaceBuilder, classBuilder, methodBuilder);

        for (var i = 0; i < children.Count; i++)
        {
            visitor.Visit(children[i]);
        }

        // Note that this is called at the *end* of rewriting so that user code can see the tree
        // and look at its content to make a decision.
        OnDocumentStructureCreated(codeDocument, @namespace, @class, method);
    }
Example #26
0
        public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
        {
            var entries = new List <string>()
            {
                string.Join(" ", node.Modifiers),
                node.ClassName,
                node.BaseType,
                string.Join(", ", node.Interfaces ?? Array.Empty <string>())
            };

            // Avoid adding the type parameters to the baseline if they aren't present.
            if (node.TypeParameters != null && node.TypeParameters.Count > 0)
            {
                entries.Add(string.Join(", ", node.TypeParameters.Select(p => p.ParameterName)));
            }

            WriteContentNode(node, entries.ToArray());
        }
    public void FindPrimaryClass_FindsClassWithAnnotation()
    {
        // Arrange
        var document = new DocumentIntermediateNode();
        var @class   = new ClassDeclarationIntermediateNode();

        @class.Annotations[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass;

        var builder = IntermediateNodeBuilder.Create(document);

        builder.Add(@class);

        // Act
        var result = document.FindPrimaryClass();

        // Assert
        Assert.Same(@class, result);
    }
            public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
            {
                node.Children.Insert(0, new CSharpCodeIntermediateNode()
                {
                    Children =
                    {
                        new IntermediateToken()
                        {
                            Kind    = TokenKind.CSharp,
                            Content = "#pragma warning disable 0414",
                        }
                    }
                });
                node.Children.Insert(1, new CSharpCodeIntermediateNode()
                {
                    Children =
                    {
                        new IntermediateToken()
                        {
                            Kind    = TokenKind.CSharp,
                            Content = $"private static {typeof(object).FullName} {DesignTimeVariable} = null;",
                        }
                    }
                });
                node.Children.Insert(2, new CSharpCodeIntermediateNode()
                {
                    Children =
                    {
                        new IntermediateToken()
                        {
                            Kind    = TokenKind.CSharp,
                            Content = "#pragma warning restore 0414",
                        }
                    }
                });

                _directiveNode = new DesignTimeDirectiveIntermediateNode();

                VisitDefault(node);

                node.Children.Insert(0, _directiveNode);
            }
Example #29
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            ClassDeclarationIntermediateNode primaryClass = documentNode.FindPrimaryClass();

            if (primaryClass == null)
            {
                return;
            }

            string fullClassName = null;

            foreach (IntermediateNodeReference directiveReference in documentNode.FindDirectiveReferences(InheritsDirective.Directive))
            {
                DirectiveTokenIntermediateNode intermediateNode =
                    ((DirectiveIntermediateNode)directiveReference.Node).Tokens
                    .FirstOrDefault <DirectiveTokenIntermediateNode>();
                if (intermediateNode != null)
                {
                    fullClassName = intermediateNode.Content;
                    break;
                }
            }
            if (fullClassName == null)
            {
                return;
            }


            if (PartialClassMode)
            {
                var info = new TypeReferenceInfo(fullClassName);

                var pns = documentNode.FindPrimaryNamespace().Content = info.Namespace;
                primaryClass.BaseType = null;
                primaryClass.Modifiers.Add("partial");
                primaryClass.ClassName = info.Name;
            }
            else
            {
                primaryClass.BaseType = fullClassName;
            }
        }
Example #30
0
        protected override void OnDocumentStructureCreated(
            RazorCodeDocument codeDocument,
            NamespaceDeclarationIntermediateNode @namespace,
            ClassDeclarationIntermediateNode @class,
            MethodDeclarationIntermediateNode method)
        {
            var documentNode = codeDocument.GetDocumentIntermediateNode();

            foreach (var @using in @namespace.Children.OfType <UsingDirectiveIntermediateNode>())
            {
                documentNode.Children.Add(@using);
            }
            foreach (var child in method.Children)
            {
                documentNode.Children.Add(child);
            }

            documentNode.Children.Remove(@namespace);

            return;
        }