private void WriteMarkerToken(CodeRenderingContext context, DirectiveTokenIntermediateNode node)
 {
     // We want to map marker tokens to a location in the generated document
     // that will provide CSharp intellisense.
     context.AddSourceMappingFor(node);
     context.CodeWriter.Write(" ");
 }
        public void WriteDesignTimeDirective_ChildrenWithNoSource_WritesEmptyMethod_WithPragma()
        {
            // Arrange
            var extension = new DesignTimeDirectiveTargetExtension();
            var context   = TestCodeRenderingContext.CreateDesignTime();

            var node  = new DesignTimeDirectiveIntermediateNode();
            var token = new DirectiveTokenIntermediateNode()
            {
                Content        = "Value",
                DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.String),
            };

            node.Children.Add(token);

            // Act
            extension.WriteDesignTimeDirective(context, node);

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

            Assert.Equal(
                @"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
}
#pragma warning restore 219
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteDesignTimeDirective_WithNamespaceToken_WritesLambda()
        {
            // Arrange
            var extension = new DesignTimeDirectiveTargetExtension();
            var context   = TestCodeRenderingContext.CreateDesignTime();

            var node  = new DesignTimeDirectiveIntermediateNode();
            var token = new DirectiveTokenIntermediateNode()
            {
                Source         = new SourceSpan("test.cshtml", 0, 0, 0, 5),
                Content        = "System.Collections.Generic",
                DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Namespace),
            };

            node.Children.Add(token);

            // Act
            extension.WriteDesignTimeDirective(context, node);

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

            Assert.Equal(
                @"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
global::System.Object __typeHelper = nameof(System.Collections.Generic);
}
))();
}
#pragma warning restore 219
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Example #4
0
        public void WriteDesignTimeDirective_WithStringToken_WritesLambda()
        {
            // Arrange
            var extension = new DesignTimeDirectiveTargetExtension();
            var context   = TestCodeRenderingContext.CreateDesignTime();

            var node  = new DesignTimeDirectiveIntermediateNode();
            var token = new DirectiveTokenIntermediateNode()
            {
                Source         = new SourceSpan("test.cshtml", 0, 0, 0, 5),
                Content        = "Value",
                DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.String),
            };
            var tokenWithQuotedContent = new DirectiveTokenIntermediateNode()
            {
                Source         = new SourceSpan("test.cshtml", 0, 0, 0, 5),
                Content        = "\"Value\"",
                DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.String),
            };

            node.Children.Add(token);
            node.Children.Add(tokenWithQuotedContent);

            // Act
            extension.WriteDesignTimeDirective(context, node);

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

            Assert.Equal(
                @"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
#nullable restore
#line 1 ""test.cshtml""
global::System.Object __typeHelper = ""Value"";

#line default
#line hidden
#nullable disable
}
))();
((System.Action)(() => {
#nullable restore
#line 1 ""test.cshtml""
global::System.Object __typeHelper = ""Value"";

#line default
#line hidden
#nullable disable
}
))();
}
#pragma warning restore 219
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Example #5
0
 private void WriteMarkerToken(CodeRenderingContext context, DirectiveTokenIntermediateNode node)
 {
     // Marker tokens exist to be filled with other content a user might write. In an end-to-end
     // scenario markers prep the Razor documents C# projections to have an empty projection that
     // can be filled with other user content. This content can trigger a multitude of other events,
     // such as completion. In the case of completion, a completion session can occur when a marker
     // hasn't been filled and then we will fill it as a user types. The line pragma is necessary
     // for consistency so when a C# completion session starts, filling user code doesn't result in
     // a previously non-existent line pragma from being added and destroying the context in which
     // the completion session was started.
     using (context.CodeWriter.BuildLinePragma(node.Source, context))
     {
         context.AddSourceMappingFor(node);
         context.CodeWriter.Write(" ");
     }
 }
Example #6
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;
            }
        }
 public virtual void VisitDirectiveToken(DirectiveTokenIntermediateNode node)
 {
     VisitDefault(node);
 }
Example #8
0
 public override void VisitDirectiveToken(DirectiveTokenIntermediateNode node)
 {
     WriteContentNode(node, node.Content);
 }
Example #9
0
        private void WriteDesignTimeDirectiveToken(CodeRenderingContext context, DesignTimeDirectiveIntermediateNode parent, DirectiveTokenIntermediateNode node, int currentIndex)
        {
            var tokenKind = node.DirectiveToken.Kind;

            if (!node.Source.HasValue ||
                !string.Equals(
                    context.SourceDocument?.FilePath,
                    node.Source.Value.FilePath,
                    StringComparison.OrdinalIgnoreCase))
            {
                // We don't want to handle directives from imports.
                return;
            }

            if (tokenKind == DirectiveTokenKind.Attribute)
            {
                // We don't need to do anything special here.
                // We let the Roslyn take care of providing syntax errors for C# attributes.
                return;
            }

            // Wrap the directive token in a lambda to isolate variable names.
            context.CodeWriter
            .Write("((")
            .Write(typeof(Action).FullName)
            .Write(")(");
            using (context.CodeWriter.BuildLambda())
            {
                var originalIndent = context.CodeWriter.CurrentIndent;
                context.CodeWriter.CurrentIndent = 0;
                switch (tokenKind)
                {
                case DirectiveTokenKind.Type:

                    if (string.IsNullOrEmpty(node.Content))
                    {
                        // This is most likely a marker token.
                        WriteMarkerToken(context, node);
                        break;
                    }

                    // {node.Content} __typeHelper = default({node.Content});
                    using (context.CodeWriter.BuildLinePragma(node.Source, context))
                    {
                        context.AddSourceMappingFor(node);
                        context.CodeWriter
                        .Write(node.Content)
                        .Write(" ")
                        .WriteStartAssignment(TypeHelper)
                        .Write("default");

                        if (!context.Options.SuppressNullabilityEnforcement)
                        {
                            context.CodeWriter.Write("!");
                        }

                        context.CodeWriter.WriteLine(";");
                    }
                    break;

                case DirectiveTokenKind.Member:

                    if (string.IsNullOrEmpty(node.Content))
                    {
                        // This is most likely a marker token.
                        WriteMarkerToken(context, node);
                        break;
                    }

                    // global::System.Object {node.content} = null;
                    using (context.CodeWriter.BuildLinePragma(node.Source, context))
                    {
                        context.CodeWriter
                        .Write("global::")
                        .Write(typeof(object).FullName)
                        .Write(" ");

                        context.AddSourceMappingFor(node);
                        context.CodeWriter
                        .Write(node.Content)
                        .Write(" = null");

                        if (!context.Options.SuppressNullabilityEnforcement)
                        {
                            context.CodeWriter.Write("!");
                        }

                        context.CodeWriter.WriteLine(";");
                    }
                    break;

                case DirectiveTokenKind.Namespace:

                    if (string.IsNullOrEmpty(node.Content))
                    {
                        // This is most likely a marker token.
                        WriteMarkerToken(context, node);
                        break;
                    }

                    // global::System.Object __typeHelper = nameof({node.Content});
                    using (context.CodeWriter.BuildLinePragma(node.Source, context))
                    {
                        context.CodeWriter
                        .Write("global::")
                        .Write(typeof(object).FullName)
                        .Write(" ")
                        .WriteStartAssignment(TypeHelper);

                        context.CodeWriter.Write("nameof(");

                        context.AddSourceMappingFor(node);
                        context.CodeWriter
                        .Write(node.Content)
                        .WriteLine(");");
                    }
                    break;

                case DirectiveTokenKind.String:

                    // global::System.Object __typeHelper = "{node.Content}";
                    using (context.CodeWriter.BuildLinePragma(node.Source, context))
                    {
                        context.CodeWriter
                        .Write("global::")
                        .Write(typeof(object).FullName)
                        .Write(" ")
                        .WriteStartAssignment(TypeHelper);

                        if (node.Content.StartsWith("\"", StringComparison.Ordinal))
                        {
                            context.AddSourceMappingFor(node);
                            context.CodeWriter.Write(node.Content);
                        }
                        else
                        {
                            context.CodeWriter.Write("\"");
                            context.AddSourceMappingFor(node);
                            context.CodeWriter
                            .Write(node.Content)
                            .Write("\"");
                        }

                        context.CodeWriter.WriteLine(";");
                    }
                    break;

                case DirectiveTokenKind.Boolean:
                    // global::System.Boolean __typeHelper = {node.Content};
                    using (context.CodeWriter.BuildLinePragma(node.Source, context))
                    {
                        context.CodeWriter
                        .Write("global::")
                        .Write(typeof(bool).FullName)
                        .Write(" ")
                        .WriteStartAssignment(TypeHelper);

                        context.AddSourceMappingFor(node);
                        context.CodeWriter.Write(node.Content);
                        context.CodeWriter.WriteLine(";");
                    }
                    break;

                case DirectiveTokenKind.GenericTypeConstraint:
                    // We generate a generic local function with a generic parameter using the
                    // same name and apply the constraints, like below.
                    // The two warnings that we disable are:
                    // * Hiding the class type parameter with the parameter on the method
                    // * The function is defined but not used.
                    // static void TypeConstraints_TParamName<TParamName>() where TParamName ...;
                    context.CodeWriter.WriteLine("#pragma warning disable CS0693");
                    context.CodeWriter.WriteLine("#pragma warning disable CS8321");
                    using (context.CodeWriter.BuildLinePragma(node.Source, context))
                    {
                        // It's OK to do this since a GenericTypeParameterConstraint token is always preceded by a member token.
                        var genericTypeParamName = (DirectiveTokenIntermediateNode)parent.Children[currentIndex - 1];
                        context.CodeWriter
                        .Write("void __TypeConstraints_")
                        .Write(genericTypeParamName.Content)
                        .Write("<")
                        .Write(genericTypeParamName.Content)
                        .Write(">() ");

                        context.AddSourceMappingFor(node);
                        context.CodeWriter.Write(node.Content);
                        context.CodeWriter.WriteLine();
                        context.CodeWriter.WriteLine("{");
                        context.CodeWriter.WriteLine("}");
                        context.CodeWriter.WriteLine("#pragma warning restore CS0693");
                        context.CodeWriter.WriteLine("#pragma warning restore CS8321");
                    }
                    break;
                }
                context.CodeWriter.CurrentIndent = originalIndent;
            }
            context.CodeWriter.WriteLine("))();");
        }
        private void WriteDesignTimeDirectiveToken(CodeRenderingContext context, DirectiveTokenIntermediateNode node)
        {
            var tokenKind = node.DirectiveToken.Kind;

            if (!node.Source.HasValue ||
                !string.Equals(
                    context.SourceDocument?.FilePath,
                    node.Source.Value.FilePath,
                    StringComparison.OrdinalIgnoreCase))
            {
                // We don't want to handle directives from imports.
                return;
            }

            // Wrap the directive token in a lambda to isolate variable names.
            context.CodeWriter
            .Write("((")
            .Write(typeof(Action).FullName)
            .Write(")(");
            using (context.CodeWriter.BuildLambda())
            {
                var originalIndent = context.CodeWriter.CurrentIndent;
                context.CodeWriter.CurrentIndent = 0;
                switch (tokenKind)
                {
                case DirectiveTokenKind.Type:

                    if (string.IsNullOrEmpty(node.Content))
                    {
                        // This is most likely a marker token.
                        WriteMarkerToken(context, node);
                        break;
                    }

                    // {node.Content} __typeHelper = default({node.Content});
                    using (context.CodeWriter.BuildLinePragma(node.Source))
                    {
                        context.AddSourceMappingFor(node);
                        context.CodeWriter
                        .Write(node.Content)
                        .Write(" ")
                        .WriteStartAssignment(TypeHelper)
                        .Write("default(")
                        .Write(node.Content)
                        .WriteLine(");");
                    }
                    break;

                case DirectiveTokenKind.Member:

                    if (string.IsNullOrEmpty(node.Content))
                    {
                        // This is most likely a marker token.
                        WriteMarkerToken(context, node);
                        break;
                    }

                    // global::System.Object {node.content} = null;
                    using (context.CodeWriter.BuildLinePragma(node.Source))
                    {
                        context.CodeWriter
                        .Write("global::")
                        .Write(typeof(object).FullName)
                        .Write(" ");

                        context.AddSourceMappingFor(node);
                        context.CodeWriter
                        .Write(node.Content)
                        .WriteLine(" = null;");
                    }
                    break;

                case DirectiveTokenKind.Namespace:

                    if (string.IsNullOrEmpty(node.Content))
                    {
                        // This is most likely a marker token.
                        WriteMarkerToken(context, node);
                        break;
                    }

                    // global::System.Object __typeHelper = nameof({node.Content});
                    using (context.CodeWriter.BuildLinePragma(node.Source))
                    {
                        context.CodeWriter
                        .Write("global::")
                        .Write(typeof(object).FullName)
                        .Write(" ")
                        .WriteStartAssignment(TypeHelper);

                        context.CodeWriter.Write("nameof(");

                        context.AddSourceMappingFor(node);
                        context.CodeWriter
                        .Write(node.Content)
                        .WriteLine(");");
                    }
                    break;

                case DirectiveTokenKind.String:

                    // global::System.Object __typeHelper = "{node.Content}";
                    using (context.CodeWriter.BuildLinePragma(node.Source))
                    {
                        context.CodeWriter
                        .Write("global::")
                        .Write(typeof(object).FullName)
                        .Write(" ")
                        .WriteStartAssignment(TypeHelper);

                        if (node.Content.StartsWith("\"", StringComparison.Ordinal))
                        {
                            context.AddSourceMappingFor(node);
                            context.CodeWriter.Write(node.Content);
                        }
                        else
                        {
                            context.CodeWriter.Write("\"");
                            context.AddSourceMappingFor(node);
                            context.CodeWriter
                            .Write(node.Content)
                            .Write("\"");
                        }

                        context.CodeWriter.WriteLine(";");
                    }
                    break;
                }
                context.CodeWriter.CurrentIndent = originalIndent;
            }
            context.CodeWriter.WriteLine("))();");
        }
 public override void VisitDirectiveToken(DirectiveTokenIntermediateNode node)
 {
     _directiveNode.Children.Add(node);
 }