Skip to content
This repository has been archived by the owner on Dec 19, 2018. It is now read-only.

Commit

Permalink
[Fixes #980] Generate parser error for unquoted string token directives
Browse files Browse the repository at this point in the history
  • Loading branch information
ajaybhargavb committed Mar 17, 2017
1 parent 8f9ff1a commit 5aab5a8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,13 @@ private void HandleDirective(DirectiveDescriptor descriptor)
outputKind = SpanKind.Code;
break;
case DirectiveTokenKind.String:
if (!At(CSharpSymbolType.StringLiteral))
{
Context.ErrorSink.OnError(
CurrentStart,
LegacyResources.FormatDirectiveExpectsQuotedStringLiteral(descriptor.Name),
CurrentSymbol.Content.Length);
}
AcceptUntil(CSharpSymbolType.WhiteSpace, CSharpSymbolType.NewLine);
break;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Microsoft.AspNetCore.Razor.Evolution/LegacyResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@
<data name="DirectiveExpectsIdentifier" xml:space="preserve">
<value>The '{0}' directive expects an identifier.</value>
</data>
<data name="DirectiveExpectsQuotedStringLiteral" xml:space="preserve">
<value>The '{0}' directive expects a string surrounded by double quotes.</value>
</data>
<data name="DirectiveExpectsTypeName" xml:space="preserve">
<value>The '{0}' directive expects a type name.</value>
</data>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ public void DirectiveDescriptor_UnderstandsStringTokens()
// Arrange
var descriptor = DirectiveDescriptorBuilder.Create("custom").AddString().Build();

// Act & Assert
ParseCodeBlockTest(
"@custom \"AString\"",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "\"AString\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}

[Fact]
public void DirectiveDescriptor_StringToken_ParserErrorForUnquotedValue()
{
// Arrange
var descriptor = DirectiveDescriptorBuilder.Create("custom").AddString().Build();
var expectedError = new RazorError(
LegacyResources.FormatDirectiveExpectsQuotedStringLiteral("custom"),
new SourceLocation(8, 0, 8),
length: 7);

// Act & Assert
ParseCodeBlockTest(
"@custom AString",
Expand All @@ -67,7 +91,7 @@ public void DirectiveDescriptor_UnderstandsStringTokens()
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "AString", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace)));
.Accepts(AcceptedCharacters.NonWhiteSpace)), expectedError);
}

[Fact]
Expand All @@ -82,7 +106,7 @@ public void DirectiveDescriptor_UnderstandsMultipleTokens()

// Act & Assert
ParseCodeBlockTest(
"@custom System.Text.Encoding.ASCIIEncoding Some_Member AString",
"@custom System.Text.Encoding.ASCIIEncoding Some_Member \"AString\"",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Expand All @@ -100,7 +124,7 @@ public void DirectiveDescriptor_UnderstandsMultipleTokens()
.Accepts(AcceptedCharacters.NonWhiteSpace),

Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "AString", markup: false)
Factory.Span(SpanKind.Markup, "\"AString\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[2]))
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
Expand All @@ -113,14 +137,14 @@ public void DirectiveDescriptor_UnderstandsRazorBlocks()

// Act & Assert
ParseCodeBlockTest(
"@custom Header { <p>F{o}o</p> }",
"@custom \"Header\" { <p>F{o}o</p> }",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "Header", markup: false)
Factory.Span(SpanKind.Markup, "\"Header\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace),
Expand All @@ -146,14 +170,14 @@ public void DirectiveDescriptor_UnderstandsCodeBlocks()

// Act & Assert
ParseCodeBlockTest(
"@custom Name { foo(); bar(); }",
"@custom \"Name\" { foo(); bar(); }",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "Name", markup: false)
Factory.Span(SpanKind.Markup, "\"Name\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace),
Expand Down Expand Up @@ -226,14 +250,14 @@ public void DirectiveDescriptor_NoErrorsSemicolonAfterDirective()

// Act & Assert
ParseCodeBlockTest(
"@custom hello ; ",
"@custom \"hello\" ; ",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "hello", markup: false)
Factory.Span(SpanKind.Markup, "\"hello\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace),
Factory.Span(SpanKind.Markup, " ; ", markup: false).Accepts(AcceptedCharacters.WhiteSpace)));
Expand All @@ -246,19 +270,19 @@ public void DirectiveDescriptor_ErrorsExtraContentAfterDirective()
var descriptor = DirectiveDescriptorBuilder.Create("custom").AddString().Build();
var expectedErorr = new RazorError(
LegacyResources.FormatUnexpectedDirectiveLiteral("custom", Environment.NewLine),
new SourceLocation(14, 0, 14),
length: 5);
new SourceLocation(16, 0, 16),
length: 7);

// Act & Assert
ParseCodeBlockTest(
"@custom hello world",
"@custom \"hello\" \"world\"",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "hello", markup: false)
Factory.Span(SpanKind.Markup, "\"hello\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace),

Expand All @@ -273,19 +297,19 @@ public void DirectiveDescriptor_ErrorsWhenExtraContentBeforeBlockStart()
var descriptor = DirectiveDescriptorBuilder.CreateCodeBlock("custom").AddString().Build();
var expectedErorr = new RazorError(
LegacyResources.FormatUnexpectedDirectiveLiteral("custom", "{"),
new SourceLocation(14, 0, 14),
new SourceLocation(16, 0, 16),
length: 5);

// Act & Assert
ParseCodeBlockTest(
"@custom Hello World { foo(); bar(); }",
"@custom \"Hello\" World { foo(); bar(); }",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "Hello", markup: false)
Factory.Span(SpanKind.Markup, "\"Hello\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace),

Expand All @@ -300,19 +324,19 @@ public void DirectiveDescriptor_ErrorsWhenEOFBeforeDirectiveBlockStart()
var descriptor = DirectiveDescriptorBuilder.CreateCodeBlock("custom").AddString().Build();
var expectedErorr = new RazorError(
LegacyResources.FormatUnexpectedEOFAfterDirective("custom", "{"),
new SourceLocation(13, 0, 13),
new SourceLocation(15, 0, 15),
length: 1);

// Act & Assert
ParseCodeBlockTest(
"@custom Hello",
"@custom \"Hello\"",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "Hello", markup: false)
Factory.Span(SpanKind.Markup, "\"Hello\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace)),
expectedErorr);
Expand All @@ -325,19 +349,19 @@ public void DirectiveDescriptor_ErrorsWhenMissingEndBrace()
var descriptor = DirectiveDescriptorBuilder.CreateCodeBlock("custom").AddString().Build();
var expectedErorr = new RazorError(
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("custom", "}", "{"),
new SourceLocation(14, 0, 14),
new SourceLocation(16, 0, 16),
length: 1);

// Act & Assert
ParseCodeBlockTest(
"@custom Hello {",
"@custom \"Hello\" {",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "Hello", markup: false)
Factory.Span(SpanKind.Markup, "\"Hello\"", markup: false)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
.Accepts(AcceptedCharacters.NonWhiteSpace),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace),
Expand Down Expand Up @@ -781,14 +805,14 @@ public void OptionalDirectiveTokens_WithSimpleTokens_AreParsed()

// Act & Assert
ParseCodeBlockTest(
"@custom simple-value",
"@custom \"simple-value\"",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "simple-value", markup: false)
Factory.Span(SpanKind.Markup, "\"simple-value\"", markup: false)
.Accepts(AcceptedCharacters.NonWhiteSpace)
.With(chunkGenerator)));
}
Expand All @@ -802,14 +826,14 @@ public void OptionalDirectiveTokens_WithBraces_AreParsed()

// Act & Assert
ParseCodeBlockTest(
"@custom {formaction}?/{id}?",
"@custom \"{formaction}?/{id}?\"",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "{formaction}?/{id}?", markup: false)
Factory.Span(SpanKind.Markup, "\"{formaction}?/{id}?\"", markup: false)
.Accepts(AcceptedCharacters.NonWhiteSpace)
.With(chunkGenerator)));
}
Expand All @@ -822,14 +846,14 @@ public void OptionalDirectiveTokens_WithMultipleOptionalTokens_AreParsed()

// Act & Assert
ParseCodeBlockTest(
"@custom {formaction}?/{id}? System.String",
"@custom \"{formaction}?/{id}?\" System.String",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Factory.Span(SpanKind.Markup, "{formaction}?/{id}?", markup: false)
Factory.Span(SpanKind.Markup, "\"{formaction}?/{id}?\"", markup: false)
.Accepts(AcceptedCharacters.NonWhiteSpace)
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens.First())),
Factory.Span(SpanKind.Code, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
Expand Down

0 comments on commit 5aab5a8

Please sign in to comment.