Пример #1
0
        private static void AddInstrumentation(InstrumentationItem item)
        {
            var beginContextMethodName = "BeginContext"; // ORIGINAL: BeginContextMethodName
            var endContextMethodName   = "EndContext";   // ORIGINAL: EndContextMethodName

            var beginNode = new CSharpCodeIntermediateNode();

            beginNode.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}({1}, {2}, {3});",
                    beginContextMethodName,
                    item.Source.AbsoluteIndex.ToString(CultureInfo.InvariantCulture),
                    item.Source.Length.ToString(CultureInfo.InvariantCulture),
                    item.IsLiteral ? "true" : "false")
            });

            var endNode = new CSharpCodeIntermediateNode();

            endNode.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = string.Format(CultureInfo.InvariantCulture, "{0}();", endContextMethodName)
            });

            var nodeIndex = item.Parent.Children.IndexOf(item.Node);

            item.Parent.Children.Insert(nodeIndex, beginNode);
            item.Parent.Children.Insert(nodeIndex + 2, endNode);
        }
Пример #2
0
            public override void VisitCSharpStatementLiteral(CSharpStatementLiteralSyntax node)
            {
                var context = node.GetSpanContext();

                if (context == null || context.ChunkGenerator is StatementChunkGenerator)
                {
                    var isAttributeValue = _builder.Current is CSharpCodeAttributeValueIntermediateNode;

                    if (!isAttributeValue)
                    {
                        var statementNode = new CSharpCodeIntermediateNode()
                        {
                            Source = BuildSourceSpanFromNode(node)
                        };
                        _builder.Push(statementNode);
                    }

                    _builder.Add(new IntermediateToken()
                    {
                        Content = node.GetContent(),
                        Kind    = TokenKind.CSharp,
                        Source  = BuildSourceSpanFromNode(node),
                    });

                    if (!isAttributeValue)
                    {
                        _builder.Pop();
                    }
                }

                base.VisitCSharpStatementLiteral(node);
            }
Пример #3
0
    protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
    {
        var @namespace = documentNode.FindPrimaryNamespace();
        var @class     = documentNode.FindPrimaryClass();

        if (@namespace == null || @class == null)
        {
            return;
        }

        var classIndex = @namespace.Children.IndexOf(@class);

        foreach (var attribute in documentNode.FindDirectiveReferences(AttributeDirective.Directive))
        {
            var token = ((DirectiveIntermediateNode)attribute.Node).Tokens.FirstOrDefault();
            if (token != null)
            {
                var node = new CSharpCodeIntermediateNode
                {
                    Source = token.Source
                };

                node.Children.Add(new IntermediateToken()
                {
                    Content = token.Content,
                    Source  = token.Source,
                    Kind    = TokenKind.CSharp,
                });

                @namespace.Children.Insert(classIndex++, node);
            }
        }
    }
            public override void VisitStatementSpan(StatementChunkGenerator chunkGenerator, Span span)
            {
                var isAttributeValue = _builder.Current is CSharpCodeAttributeValueIntermediateNode;

                if (!isAttributeValue)
                {
                    var statementNode = new CSharpCodeIntermediateNode()
                    {
                        Source = BuildSourceSpanFromNode(span)
                    };
                    _builder.Push(statementNode);
                }

                _builder.Add(new IntermediateToken()
                {
                    Content = span.Content,
                    Kind    = TokenKind.CSharp,
                    Source  = BuildSourceSpanFromNode(span),
                });

                if (!isAttributeValue)
                {
                    _builder.Pop();
                }
            }
        public void WriteCSharpCode_WhitespaceContentWithSource_WritesContent()
        {
            // Arrange
            var writer  = new DesignTimeNodeWriter();
            var context = TestCodeRenderingContext.CreateDesignTime();

            var node = new CSharpCodeIntermediateNode()
            {
                Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
            };

            IntermediateNodeBuilder.Create(node)
            .Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = "    "
            });

            // Act
            writer.WriteCSharpCode(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"    
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteCSharpCode_SkipsLinePragma_WithoutSource()
        {
            // Arrange
            var writer  = new DesignTimeNodeWriter();
            var context = TestCodeRenderingContext.CreateDesignTime();

            var node = new CSharpCodeIntermediateNode();

            IntermediateNodeBuilder.Create(node)
            .Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = "if (true) { }"
            });

            // Act
            writer.WriteCSharpCode(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"if (true) { }
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteCSharpCode_WritesPadding_WithSource()
        {
            // Arrange
            var writer  = new DesignTimeNodeWriter();
            var context = TestCodeRenderingContext.CreateDesignTime();

            var node = new CSharpCodeIntermediateNode()
            {
                Source = new SourceSpan("test.cshtml", 0, 0, 0, 17),
            };

            IntermediateNodeBuilder.Create(node)
            .Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = "    if (true) { }",
            });

            // Act
            writer.WriteCSharpCode(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"#line 1 ""test.cshtml""
    if (true) { }

#line default
#line hidden
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeIntermediateNode node)
        {
            var isWhitespaceStatement = true;

            for (var i = 0; i < node.Children.Count; i++)
            {
                var token = node.Children[i] as IntermediateToken;
                if (token == null || !string.IsNullOrWhiteSpace(token.Content))
                {
                    isWhitespaceStatement = false;
                    break;
                }
            }

            if (isWhitespaceStatement)
            {
                return;
            }

            for (var i = 0; i < node.Children.Count; i++)
            {
                if (node.Children[i] is IntermediateToken token && token.IsCSharp)
                {
                    context.CodeWriter.Write(token.Content);
                }
Пример #9
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind)
            {
                return;
            }

            var modelType = ModelDirective.GetModelType(documentNode);
            var visitor   = new Visitor();

            visitor.Visit(documentNode);

            var @class = visitor.Class;

            var viewDataType = $"global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<{modelType}>";
            var vddProperty  = new CSharpCodeIntermediateNode();

            vddProperty.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = $"public {viewDataType} ViewData => ({viewDataType})PageContext?.ViewData;",
            });
            @class.Children.Add(vddProperty);

            var modelProperty = new CSharpCodeIntermediateNode();

            modelProperty.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = $"public {modelType} Model => ViewData.Model;",
            });
            @class.Children.Add(modelProperty);
        }
Пример #10
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();

            if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
            {
                // No namespace node or it's incomplete. Skip.
                return;
            }

            var @class = documentNode.FindPrimaryClass();

            if (@class == null || string.IsNullOrEmpty(@class.ClassName))
            {
                // No class node or it's incomplete. Skip.
                return;
            }

            var generatedTypeName = $"{@namespace.Content}.{@class.ClassName}";

            // The MVC attributes require a relative path to be specified so that we can make a view engine path.
            // We can't use a rooted path because we don't know what the project root is.
            //
            // If we can't sanitize the path, we'll just set it to null and let is blow up at runtime - we don't
            // want to create noise if this code has to run in some unanticipated scenario.
            var escapedPath = MakeVerbatimStringLiteral(ConvertToViewEnginePath(codeDocument.Source.RelativePath));

            string attribute;

            if (documentNode.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind)
            {
                attribute = $"[assembly:{RazorViewAttribute}({escapedPath}, typeof({generatedTypeName}))]";
            }
            else if (documentNode.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
                     PageDirective.TryGetPageDirective(documentNode, out var pageDirective))
            {
                var escapedRoutePrefix = MakeVerbatimStringLiteral(pageDirective.RouteTemplate);
                attribute = $"[assembly:{RazorPageAttribute}({escapedPath}, typeof({generatedTypeName}), {escapedRoutePrefix})]";
            }
            else
            {
                return;
            }

            var index = documentNode.Children.IndexOf(@namespace);

            Debug.Assert(index >= 0);

            var pageAttribute = new CSharpCodeIntermediateNode();

            pageAttribute.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = attribute,
            });

            documentNode.Children.Insert(index, pageAttribute);
        }
        /// <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);
        }
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();

            if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
            {
                // No namespace node or it's incomplete. Skip.
                return;
            }

            var @class = documentNode.FindPrimaryClass();

            if (@class == null || string.IsNullOrEmpty(@class.ClassName))
            {
                // No class node or it's incomplete. Skip.
                return;
            }

            var generatedTypeName = $"{@namespace.Content}.{@class.ClassName}";
            var path        = codeDocument.GetRelativePath();
            var escapedPath = EscapeAsVerbatimLiteral(path);

            string attribute;

            if (documentNode.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind)
            {
                attribute = $"[assembly:{RazorViewAttribute}({escapedPath}, typeof({generatedTypeName}))]";
            }
            else if (documentNode.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
                     PageDirective.TryGetPageDirective(documentNode, out var pageDirective))
            {
                var escapedRoutePrefix = EscapeAsVerbatimLiteral(pageDirective.RouteTemplate);
                attribute = $"[assembly:{RazorPageAttribute}({escapedPath}, typeof({generatedTypeName}), {escapedRoutePrefix})]";
            }
            else
            {
                return;
            }

            var index = documentNode.Children.IndexOf(@namespace);

            Debug.Assert(index >= 0);

            var pageAttribute = new CSharpCodeIntermediateNode();

            pageAttribute.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = attribute,
            });

            documentNode.Children.Insert(index, pageAttribute);
        }
Пример #13
0
        private static bool IsEmpty(CSharpCodeIntermediateNode node)
        {
            for (var i = 0; i < node.Children.Count; i++)
            {
                if (!(node.Children[i] is IntermediateToken token && string.IsNullOrWhiteSpace(token.Content)))
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #14
0
        public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeIntermediateNode node)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            var isWhitespaceStatement = true;

            for (var i = 0; i < node.Children.Count; i++)
            {
                var token = node.Children[i] as IntermediateToken;
                if (token == null || !string.IsNullOrWhiteSpace(token.Content))
                {
                    isWhitespaceStatement = false;
                    break;
                }
            }

            if (isWhitespaceStatement)
            {
                // The runtime and design time code differ in their handling of whitespace-only
                // statements. At runtime we can discard them completely. At design time we need
                // to keep them for the editor.
                return;
            }

            IDisposable linePragmaScope = null;

            if (node.Source != null)
            {
                linePragmaScope = context.CodeWriter.BuildLinePragma(node.Source.Value);
                context.CodeWriter.WritePadding(0, node.Source.Value, context);
            }

            for (var i = 0; i < node.Children.Count; i++)
            {
                if (node.Children[i] is IntermediateToken token && token.IsCSharp)
                {
                    _scopeStack.IncrementCurrentScopeChildCount(context);
                    context.AddSourceMappingFor(token);
                    context.CodeWriter.Write(token.Content);
                }
        private void AddTagHelperClass(Context context, TagHelperDescriptor tagHelper)
        {
            var writer = new CodeWriter();

            WriteClass(context, writer, tagHelper);

            var code = new CSharpCodeIntermediateNode();

            code.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = writer.GenerateCode()
            });

            context.Class.Children.Add(code);
        }
Пример #16
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();

            if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
            {
                // No namespace node or it's incomplete. Skip.
                return;
            }

            var @class = documentNode.FindPrimaryClass();

            if (@class == null || string.IsNullOrEmpty(@class.ClassName))
            {
                // No class node or it's incomplete. Skip.
                return;
            }

            string generatedTypeName  = $"{@namespace.Content}.{@class.ClassName}";
            string templateKey        = codeDocument.Source.FilePath;
            string escapedTemplateKey = EscapeAsVerbatimLiteral(templateKey);

            string attribute;

            if (documentNode.DocumentKind == RazorLightTemplateDocumentClassifierPass.RazorLightTemplateDocumentKind)
            {
                attribute = $"[assembly:{RazorLightTemplateAttribute}({escapedTemplateKey}, typeof({generatedTypeName}))]";
            }
            else
            {
                return;
            }

            int index = documentNode.Children.IndexOf(@namespace);

            Debug.Assert(index >= 0);

            var pageAttribute = new CSharpCodeIntermediateNode();

            pageAttribute.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = attribute,
            });

            documentNode.Children.Insert(index, pageAttribute);
        }
Пример #17
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();
            var @class     = documentNode.FindPrimaryClass();

            if (@namespace == null || @class == null)
            {
                return;
            }

            var directives = documentNode.FindDirectiveReferences(ComponentLayoutDirective.Directive);

            if (directives.Count == 0)
            {
                return;
            }

            var token = ((DirectiveIntermediateNode)directives[0].Node).Tokens.FirstOrDefault();

            if (token == null)
            {
                return;
            }

            var attributeNode = new CSharpCodeIntermediateNode();

            attributeNode.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = $"[{ComponentsApi.LayoutAttribute.FullTypeName}(typeof({token.Content}))]",
            });

            // Insert the new attribute on top of the class
            for (var i = 0; i < @namespace.Children.Count; i++)
            {
                if (object.ReferenceEquals(@namespace.Children[i], @class))
                {
                    @namespace.Children.Insert(i, attributeNode);
                    break;
                }
            }
        }
Пример #18
0
        protected override void HandleMatchedContent(RazorCodeDocument codeDocument, IEnumerable <string> matchedContent)
        {
            var chosenLayoutType = matchedContent.Last();
            var attributeNode    = new CSharpCodeIntermediateNode();

            attributeNode.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = $"[{LayoutAttributeTypeName}(typeof ({chosenLayoutType}))]" + Environment.NewLine,
            });

            var docNode        = codeDocument.GetDocumentIntermediateNode();
            var namespaceNode  = docNode.FindPrimaryNamespace();
            var classNode      = docNode.FindPrimaryClass();
            var classNodeIndex = namespaceNode
                                 .Children
                                 .IndexOf(classNode);

            namespaceNode.Children.Insert(classNodeIndex, attributeNode);
        }
        public void WriteCSharpCode_WhitespaceContent_DoesNothing()
        {
            // Arrange
            var writer  = new DesignTimeNodeWriter();
            var context = TestCodeRenderingContext.CreateDesignTime();

            var node = new CSharpCodeIntermediateNode();

            IntermediateNodeBuilder.Create(node)
            .Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = "  \t"
            });

            // Act
            writer.WriteCSharpCode(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Empty(csharp);
        }
Пример #20
0
        private void ConvertToBlazorPrimaryMethod(DocumentIntermediateNode documentNode)
        {
            // Replaces the default "ExecuteAsync" method with Blazor's "BuildRenderTree".
            // Note that DefaultDocumentWriter's VisitMethodDeclaration is hardcoded to
            // emit methods with no parameters, so there's no way of setting the parameters
            // from here. We inject the parameter later in RazorCompiler.
            var primaryMethod = documentNode.FindPrimaryMethod();

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

            var line = new CSharpCodeIntermediateNode();

            line.Children.Add(new IntermediateToken
            {
                Kind    = TokenKind.CSharp,
                Content = $"base.{primaryMethod.MethodName}(builder);" + Environment.NewLine
            });
            primaryMethod.Children.Insert(0, line);
        }
Пример #21
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var visitor = new Visitor();

            visitor.Visit(documentNode);

            if (visitor.DidFindLayoutDeclaration)
            {
                visitor.MethodNode.Children.Remove(visitor.LayoutNode);

                var attributeNode = new CSharpCodeIntermediateNode();
                attributeNode.Children.Add(new IntermediateToken()
                {
                    Kind    = TokenKind.CSharp,
                    Content = $"[{LayoutAttributeTypeName}(typeof ({visitor.LayoutType}))]" + Environment.NewLine,
                });

                var classNodeIndex = visitor
                                     .NamespaceNode
                                     .Children
                                     .IndexOf(visitor.ClassNode);
                visitor.NamespaceNode.Children.Insert(classNodeIndex, attributeNode);
            }
        }
        protected override void OnDocumentStructureCreated(RazorCodeDocument codeDocument, NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, MethodDeclarationIntermediateNode method)
        {
            base.OnDocumentStructureCreated(codeDocument, @namespace, @class, 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 = "AspNetCore";
                var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
                computedClass = $"AspNetCore_{checksum}";
            }

            @namespace.Content = computedNamespace;

            @class.ClassName = computedClass;
            @class.BaseType  = $"global::{CodeGenerationConstants.RazorComponent.FullTypeName}";
            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 = Checksum.BytesToString(codeDocument.Source.GetChecksum());
                @class.ClassName = $"AspNetCore_{checksum}";
            }
            else
            {
                @class.ClassName = CSharpIdentifier.SanitizeIdentifier(Path.GetFileNameWithoutExtension(filePath));
            }

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

            method.MethodName = CodeGenerationConstants.RazorComponent.BuildRenderTree;
            method.ReturnType = "void";
            method.Modifiers.Clear();
            method.Modifiers.Add("public");
            method.Modifiers.Add("override");

            method.Parameters.Clear();
            method.Parameters.Add(new MethodParameter()
            {
                TypeName      = CodeGenerationConstants.RenderTreeBuilder.FullTypeName,
                ParameterName = CodeGenerationConstants.RazorComponent.BuildRenderTreeParameter,
            });

            // 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.{CodeGenerationConstants.RazorComponent.BuildRenderTree}({CodeGenerationConstants.RazorComponent.BuildRenderTreeParameter});"
            });
            method.Children.Insert(0, callBase);
        }
Пример #23
0
        /// <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  = ComponentsApi.ComponentBase.FullTypeName;
            @class.ClassName = computedClass;
            @class.Modifiers.Clear();
            @class.Modifiers.Add("public");

            var documentNode        = codeDocument.GetDocumentIntermediateNode();
            var typeParamReferences = documentNode.FindDirectiveReferences(TypeParamDirective.Directive);

            for (var i = 0; i < typeParamReferences.Count; i++)
            {
                var typeParamNode = (DirectiveIntermediateNode)typeParamReferences[i].Node;
                if (typeParamNode.HasDiagnostics)
                {
                    continue;
                }

                @class.TypeParameters.Add(new TypeParameter()
                {
                    ParameterName = typeParamNode.Tokens.First().Content,
                });
            }

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

            method.Parameters.Clear();
            method.Parameters.Add(new MethodParameter()
            {
                ParameterName = "builder",
                TypeName      = ComponentsApi.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.{ComponentsApi.ComponentBase.BuildRenderTree}(builder);"
            });
            method.Children.Insert(0, callBase);
        }
Пример #24
0
 public virtual void VisitCSharpCode(CSharpCodeIntermediateNode node)
 {
     VisitDefault(node);
 }
Пример #25
0
 public override void VisitCSharpCode(CSharpCodeIntermediateNode node)
 {
     Context.NodeWriter.WriteCSharpCode(Context, node);
 }
 internal static bool IsBuildRenderTreeBaseCall(CSharpCodeIntermediateNode node)
 => node.Annotations[BuildRenderTreeBaseCallAnnotation] != null;
Пример #27
0
 public abstract void WriteCSharpCode(CodeRenderingContext context, CSharpCodeIntermediateNode node);