From 59d3fb433bc6df0369deac0f6d51be6114e8660f Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Sun, 16 Jul 2017 14:02:53 -0700 Subject: [PATCH] Fix #1555 Revert validation that file-scoped directives appear before HTML or code. --- .../Legacy/CSharpCodeParser.cs | 33 --- .../Properties/Resources.Designer.cs | 14 -- .../Resources.resx | 3 - ...pleteDirectives_DesignTime.diagnostics.txt | 5 - ...completeDirectives_Runtime.diagnostics.txt | 5 - .../Legacy/CSharpDirectivesTest.cs | 213 ------------------ 6 files changed, 273 deletions(-) diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs index 881bf67150..8cd340785e 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs @@ -1787,39 +1787,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - if (descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring || - descriptor.Usage == DirectiveUsage.FileScopedMultipleOccurring) - { - var root = Context.Builder.ActiveBlocks.Last(); - for (var i = 0; i < root.Children.Count; i++) - { - // Directives, comments and whitespace are valid prior to an unnested directive. - - var child = root.Children[i]; - if (child is Legacy.Block block) - { - if (block.Type == BlockKindInternal.Directive || block.Type == BlockKindInternal.Comment) - { - continue; - } - } - else if (child is Span span) - { - if (span.Length == 0 || - span.Kind == SpanKindInternal.Comment || - span.Symbols.All(symbol => string.IsNullOrWhiteSpace(symbol.Content))) - { - continue; - } - } - - UsageError(Resources.FormatDirectiveMustExistBeforeMarkupOrCode(descriptor.Directive)); - return; - } - } - - return; - void UsageError(string message) { // There wil always be at least 1 child because of the `@` transition. diff --git a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs index 5ad23f1a9a..6d77589965 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Properties/Resources.Designer.cs @@ -528,20 +528,6 @@ namespace Microsoft.AspNetCore.Razor.Language internal static string FormatDuplicateDirective(object p0) => string.Format(CultureInfo.CurrentCulture, GetString("DuplicateDirective"), p0); - /// - /// The '{0}' directive must exist prior to markup or code. - /// - internal static string DirectiveMustExistBeforeMarkupOrCode - { - get => GetString("DirectiveMustExistBeforeMarkupOrCode"); - } - - /// - /// The '{0}' directive must exist prior to markup or code. - /// - internal static string FormatDirectiveMustExistBeforeMarkupOrCode(object p0) - => string.Format(CultureInfo.CurrentCulture, GetString("DirectiveMustExistBeforeMarkupOrCode"), p0); - /// /// Block directive '{0}' cannot be imported. /// diff --git a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx index b40cb967a9..d611f9b458 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Resources.resx +++ b/src/Microsoft.AspNetCore.Razor.Language/Resources.resx @@ -228,9 +228,6 @@ The '{0}' directive may only occur once per document. - - The '{0}' directive must exist prior to markup or code. - Block directive '{0}' cannot be imported. diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt index e76e803b55..2f95c8c58a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt @@ -1,17 +1,12 @@ TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ9999: The 'page' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ9999: The 'page' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ9999: The 'page' directive expects a string surrounded by double quotes. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,1): Error RZ9999: The 'model' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ9999: The 'model' directive expects a type name. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ9999: The 'model' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ9999: The 'model' directive expects a type name. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,1): Error RZ9999: The 'inject' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ9999: The 'inject' directive expects a type name. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,1): Error RZ9999: The 'inject' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ9999: The 'inject' directive expects a type name. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,1): Error RZ9999: The 'inject' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ9999: The 'inject' directive expects an identifier. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,1): Error RZ9999: The 'namespace' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ9999: The 'namespace' directive expects a namespace name. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ9999: The 'namespace' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ9999: The 'namespace' directive expects a namespace name. diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt index e76e803b55..2f95c8c58a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt @@ -1,17 +1,12 @@ TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ9999: The 'page' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ9999: The 'page' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ9999: The 'page' directive expects a string surrounded by double quotes. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,1): Error RZ9999: The 'model' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ9999: The 'model' directive expects a type name. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ9999: The 'model' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ9999: The 'model' directive expects a type name. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,1): Error RZ9999: The 'inject' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ9999: The 'inject' directive expects a type name. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,1): Error RZ9999: The 'inject' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ9999: The 'inject' directive expects a type name. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,1): Error RZ9999: The 'inject' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ9999: The 'inject' directive expects an identifier. -TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,1): Error RZ9999: The 'namespace' directive must exist prior to markup or code. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ9999: The 'namespace' directive expects a namespace name. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ9999: The 'namespace' directive may only occur once per document. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ9999: The 'namespace' directive expects a namespace name. diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs index dc3da3bb61..7d554e4c98 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs @@ -46,149 +46,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.EmptyHtml())); } - [Fact] - public void DirectiveDescriptor_FileScopedMultipleOccurring_MixedContentErrors() - { - // Arrange - var customDescriptor = DirectiveDescriptor.CreateDirective( - "custom", - DirectiveKind.SingleLine, - builder => - { - builder.Usage = DirectiveUsage.FileScopedMultipleOccurring; - builder.AddTypeToken(); - }); - var chunkGenerator = new DirectiveChunkGenerator(customDescriptor); - chunkGenerator.Diagnostics.Add( - RazorDiagnostic.Create( - new RazorError( - Resources.FormatDirectiveMustExistBeforeMarkupOrCode("custom"), - 151 + Environment.NewLine.Length * 4, 4, 0, 7))); - - // Act & Assert - ParseDocumentTest( -@"@custom System.Text.Encoding.ASCIIEncoding -@* There is invalid content beneath this *@ -

Should cause error

-@* There is invalid content above this *@ -@custom Else", - new[] { customDescriptor }, - new MarkupBlock( - Factory.EmptyHtml(), - new DirectiveBlock(new DirectiveChunkGenerator(customDescriptor), - Factory.CodeTransition(), - Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(customDescriptor.Tokens[0]), - Factory.MetaCode(Environment.NewLine).Accepts(AcceptedCharactersInternal.WhiteSpace)), - Factory.EmptyHtml(), - new CommentBlock( - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(" There is invalid content beneath this ", HtmlSymbolType.RazorComment)).Accepts(AcceptedCharactersInternal.Any), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None)), - Factory.Markup(Environment.NewLine), - BlockFactory.MarkupTagBlock("

"), - Factory.Markup("Should cause error"), - BlockFactory.MarkupTagBlock("

"), - Factory.Markup(Environment.NewLine), - new CommentBlock( - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(" There is invalid content above this ", HtmlSymbolType.RazorComment)).Accepts(AcceptedCharactersInternal.Any), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None)), - Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null), - new DirectiveBlock(chunkGenerator, - Factory.CodeTransition(), - Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Else", markup: false).AsDirectiveToken(customDescriptor.Tokens[0])), - Factory.EmptyHtml())); - } - - [Theory] - [InlineData(DirectiveUsage.FileScopedSinglyOccurring)] - [InlineData(DirectiveUsage.FileScopedMultipleOccurring)] - public void DirectiveDescriptor_FileScopedSinglyOccurring_ErrorsIfNestedInCode(DirectiveUsage directiveUsage) - { - // Arrange - var descriptor = DirectiveDescriptor.CreateDirective( - "custom", - DirectiveKind.SingleLine, - builder => - { - builder.Usage = directiveUsage; - builder.AddTypeToken(); - }); - var chunkGenerator = new DirectiveChunkGenerator(descriptor); - chunkGenerator.Diagnostics.Add( - RazorDiagnostic.Create( - new RazorError( - Resources.FormatDirectiveMustExistBeforeMarkupOrCode("custom"), - 1 + Environment.NewLine.Length, 1, 0, 7))); - - // Act & Assert - ParseCodeBlockTest( -@"{ -@custom System.Text.Encoding.ASCIIEncoding -}", - new[] { descriptor }, - new StatementBlock( - Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), - Factory.Code(Environment.NewLine) - .AsStatement() - .AutoCompleteWith(autoCompleteString: null, atEndOfSpan: false), - new DirectiveBlock(chunkGenerator, - Factory.CodeTransition(), - Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]), - Factory.MetaCode(Environment.NewLine).Accepts(AcceptedCharactersInternal.WhiteSpace)), - Factory.EmptyCSharp().AsStatement(), - Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None))); - } - - [Theory] - [InlineData(DirectiveUsage.FileScopedSinglyOccurring)] - [InlineData(DirectiveUsage.FileScopedMultipleOccurring)] - public void DirectiveDescriptor_FileScoped_ErrorsIfNestedInHtml(DirectiveUsage directiveUsage) - { - // Arrange - var descriptor = DirectiveDescriptor.CreateDirective( - "custom", - DirectiveKind.SingleLine, - builder => - { - builder.Usage = directiveUsage; - builder.AddTypeToken(); - }); - var chunkGenerator = new DirectiveChunkGenerator(descriptor); - chunkGenerator.Diagnostics.Add( - RazorDiagnostic.Create( - new RazorError( - Resources.FormatDirectiveMustExistBeforeMarkupOrCode("custom"), - 3 + Environment.NewLine.Length, 1, 0, 7))); - - // Act & Assert - ParseDocumentTest( -@"

-@custom System.Text.Encoding.ASCIIEncoding -

", - new[] { descriptor }, - new MarkupBlock( - BlockFactory.MarkupTagBlock("

"), - Factory.Markup(Environment.NewLine), - new DirectiveBlock(chunkGenerator, - Factory.CodeTransition(), - Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]), - Factory.MetaCode(Environment.NewLine).Accepts(AcceptedCharactersInternal.WhiteSpace)), - BlockFactory.MarkupTagBlock("

"))); - } - [Fact] public void DirectiveDescriptor_FileScopedSinglyOccurring_ErrorsIfDuplicate() { @@ -335,76 +192,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy BlockFactory.MarkupTagBlock("

"))); } - [Fact] - public void DirectiveDescriptor_FileScopedSinglyOccurring_MixedContentErrors() - { - // Arrange - var customDescriptor = DirectiveDescriptor.CreateDirective( - "custom", - DirectiveKind.SingleLine, - builder => - { - builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; - builder.AddTypeToken(); - }); - var somethingDescriptor = DirectiveDescriptor.CreateDirective( - "something", - DirectiveKind.SingleLine, - builder => - { - builder.Usage = DirectiveUsage.FileScopedSinglyOccurring; - builder.AddMemberToken(); - }); - var chunkGenerator = new DirectiveChunkGenerator(somethingDescriptor); - chunkGenerator.Diagnostics.Add( - RazorDiagnostic.Create( - new RazorError( - Resources.FormatDirectiveMustExistBeforeMarkupOrCode("something"), - 151 + Environment.NewLine.Length * 4, 4, 0, 10))); - - // Act & Assert - ParseDocumentTest( -@"@custom System.Text.Encoding.ASCIIEncoding -@* There is invalid content beneath this *@ -

Should cause error

-@* There is invalid content above this *@ -@something Else", - new[] { customDescriptor, somethingDescriptor }, - new MarkupBlock( - Factory.EmptyHtml(), - new DirectiveBlock(new DirectiveChunkGenerator(customDescriptor), - Factory.CodeTransition(), - Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(customDescriptor.Tokens[0]), - Factory.MetaCode(Environment.NewLine).Accepts(AcceptedCharactersInternal.WhiteSpace)), - Factory.EmptyHtml(), - new CommentBlock( - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(" There is invalid content beneath this ", HtmlSymbolType.RazorComment)).Accepts(AcceptedCharactersInternal.Any), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None)), - Factory.Markup(Environment.NewLine), - BlockFactory.MarkupTagBlock("

"), - Factory.Markup("Should cause error"), - BlockFactory.MarkupTagBlock("

"), - Factory.Markup(Environment.NewLine), - new CommentBlock( - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(" There is invalid content above this ", HtmlSymbolType.RazorComment)).Accepts(AcceptedCharactersInternal.Any), - Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None), - Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None)), - Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null), - new DirectiveBlock(chunkGenerator, - Factory.CodeTransition(), - Factory.MetaCode("something").Accepts(AcceptedCharactersInternal.None), - Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Else", markup: false).AsDirectiveToken(somethingDescriptor.Tokens[0])), - Factory.EmptyHtml())); - } - [Fact] public void DirectiveDescriptor_TokensMustBeSeparatedBySpace() {