public void WriteDesignTimeDirective(CodeRenderingContext context, DesignTimeDirectiveIntermediateNode node) { context.CodeWriter .WriteLine("#pragma warning disable 219") .WriteLine($"private void {DirectiveTokenHelperMethodName}() {{"); for (var i = 0; i < node.Children.Count; i++) { if (node.Children[i] is DirectiveTokenIntermediateNode n) { WriteDesignTimeDirectiveToken(context, n); } } context.CodeWriter .WriteLine("}") .WriteLine("#pragma warning restore 219"); }
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); }
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)(() => { #nullable restore #line 1 ""test.cshtml"" global::System.Object __typeHelper = nameof(System.Collections.Generic); #line default #line hidden #nullable disable } ))(); } #pragma warning restore 219 ", csharp, ignoreLineEndingDifferences: true); }
public void WriteDesignTimeDirective_NoChildren_WritesEmptyMethod_WithPragma() { // Arrange var extension = new DesignTimeDirectiveTargetExtension(); var context = TestCodeRenderingContext.CreateDesignTime(); var node = new DesignTimeDirectiveIntermediateNode(); // 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); }
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("))();"); }