[Fixes #217] Applying error squiggly to full directive

This commit is contained in:
Ajay Bhargav Baaskaran 2015-05-13 17:21:41 -07:00
parent 0882ff4a13
commit 2fe78d70db
9 changed files with 70 additions and 40 deletions

View File

@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Razor
/// <param name="message">A message describing the error.</param> /// <param name="message">A message describing the error.</param>
public void OnError(SourceLocation location, string message) public void OnError(SourceLocation location, string message)
{ {
_errors.Add(new RazorError(message, location)); OnError(location, message, RazorError.DefaultErrorLength);
} }
/// <summary> /// <summary>

View File

@ -2,10 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNet.Razor.Editor;
using Microsoft.AspNet.Razor.Generator; using Microsoft.AspNet.Razor.Generator;
using Microsoft.AspNet.Razor.Parser.SyntaxTree; using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Tokenizer.Symbols; using Microsoft.AspNet.Razor.Tokenizer.Symbols;
@ -57,15 +55,19 @@ namespace Microsoft.AspNet.Razor.Parser
// Verify we're on "section" and accept // Verify we're on "section" and accept
AssertDirective(SyntaxConstants.CSharp.SectionKeyword); AssertDirective(SyntaxConstants.CSharp.SectionKeyword);
var startLocation = CurrentLocation;
AcceptAndMoveNext(); AcceptAndMoveNext();
if (nested) if (nested)
{ {
Context.OnError(CurrentLocation, RazorResources.FormatParseError_Sections_Cannot_Be_Nested(RazorResources.SectionExample_CS)); Context.OnError(
startLocation,
RazorResources.FormatParseError_Sections_Cannot_Be_Nested(RazorResources.SectionExample_CS),
Span.GetContent().Value.Length);
errorReported = true; errorReported = true;
} }
IEnumerable<CSharpSymbol> ws = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false)); var whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));
// Get the section name // Get the section name
var sectionName = string.Empty; var sectionName = string.Empty;
@ -79,19 +81,19 @@ namespace Microsoft.AspNet.Razor.Parser
} }
PutCurrentBack(); PutCurrentBack();
PutBack(ws); PutBack(whitespace);
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false)); AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
} }
else else
{ {
Accept(ws); Accept(whitespace);
sectionName = CurrentSymbol.Content; sectionName = CurrentSymbol.Content;
AcceptAndMoveNext(); AcceptAndMoveNext();
} }
Context.CurrentBlock.CodeGenerator = new SectionCodeGenerator(sectionName); Context.CurrentBlock.CodeGenerator = new SectionCodeGenerator(sectionName);
var errorLocation = CurrentLocation; var errorLocation = CurrentLocation;
ws = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false)); whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));
// Get the starting brace // Get the starting brace
var sawStartingBrace = At(CSharpSymbolType.LeftBrace); var sawStartingBrace = At(CSharpSymbolType.LeftBrace);
@ -104,7 +106,7 @@ namespace Microsoft.AspNet.Razor.Parser
} }
PutCurrentBack(); PutCurrentBack();
PutBack(ws); PutBack(whitespace);
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false)); AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
Optional(CSharpSymbolType.NewLine); Optional(CSharpSymbolType.NewLine);
Output(SpanKind.MetaCode); Output(SpanKind.MetaCode);
@ -113,7 +115,7 @@ namespace Microsoft.AspNet.Razor.Parser
} }
else else
{ {
Accept(ws); Accept(whitespace);
} }
// Set up edit handler // Set up edit handler
@ -184,7 +186,7 @@ namespace Microsoft.AspNet.Razor.Parser
if (!At(CSharpSymbolType.RightBrace)) if (!At(CSharpSymbolType.RightBrace))
{ {
editHandler.AutoCompleteString = "}"; editHandler.AutoCompleteString = "}";
Context.OnError(block.Start, RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, "}", "{")); Context.OnError(blockStart, RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, "}", "{"));
CompleteBlock(); CompleteBlock();
Output(SpanKind.Code); Output(SpanKind.Code);
} }
@ -225,11 +227,15 @@ namespace Microsoft.AspNet.Razor.Parser
protected void BaseTypeDirective(string noTypeNameError, Func<string, SpanCodeGenerator> createCodeGenerator) protected void BaseTypeDirective(string noTypeNameError, Func<string, SpanCodeGenerator> createCodeGenerator)
{ {
var keywordStartLocation = Span.Start;
// Set the block type // Set the block type
Context.CurrentBlock.Type = BlockType.Directive; Context.CurrentBlock.Type = BlockType.Directive;
var keywordLength = Span.GetContent().Value.Length;
// Accept whitespace // Accept whitespace
var remainingWs = AcceptSingleWhiteSpaceCharacter(); var remainingWhitespace = AcceptSingleWhiteSpaceCharacter();
if (Span.Symbols.Count > 1) if (Span.Symbols.Count > 1)
{ {
@ -238,15 +244,19 @@ namespace Microsoft.AspNet.Razor.Parser
Output(SpanKind.MetaCode); Output(SpanKind.MetaCode);
if (remainingWs != null) if (remainingWhitespace != null)
{ {
Accept(remainingWs); Accept(remainingWhitespace);
} }
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true));
if (EndOfFile || At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine)) if (EndOfFile || At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine))
{ {
Context.OnError(CurrentLocation, noTypeNameError); Context.OnError(
keywordStartLocation,
noTypeNameError,
keywordLength);
} }
// Parse to the end of the line // Parse to the end of the line
@ -271,6 +281,7 @@ namespace Microsoft.AspNet.Razor.Parser
private void TagHelperDirective(string keyword, Func<string, ISpanCodeGenerator> buildCodeGenerator) private void TagHelperDirective(string keyword, Func<string, ISpanCodeGenerator> buildCodeGenerator)
{ {
AssertDirective(keyword); AssertDirective(keyword);
var keywordStartLocation = CurrentLocation;
// Accept the directive name // Accept the directive name
AcceptAndMoveNext(); AcceptAndMoveNext();
@ -278,6 +289,8 @@ namespace Microsoft.AspNet.Razor.Parser
// Set the block type // Set the block type
Context.CurrentBlock.Type = BlockType.Directive; Context.CurrentBlock.Type = BlockType.Directive;
var keywordLength = Span.GetContent().Value.Length;
var foundWhitespace = At(CSharpSymbolType.WhiteSpace); var foundWhitespace = At(CSharpSymbolType.WhiteSpace);
AcceptWhile(CSharpSymbolType.WhiteSpace); AcceptWhile(CSharpSymbolType.WhiteSpace);
@ -287,7 +300,10 @@ namespace Microsoft.AspNet.Razor.Parser
if (EndOfFile || At(CSharpSymbolType.NewLine)) if (EndOfFile || At(CSharpSymbolType.NewLine))
{ {
Context.OnError(CurrentLocation, RazorResources.FormatParseError_DirectiveMustHaveValue(keyword)); Context.OnError(
keywordStartLocation,
RazorResources.FormatParseError_DirectiveMustHaveValue(keyword),
keywordLength);
} }
else else
{ {
@ -318,8 +334,10 @@ namespace Microsoft.AspNet.Razor.Parser
if (!startsWithQuote || if (!startsWithQuote ||
!rawValue.EndsWith("\"", StringComparison.OrdinalIgnoreCase)) !rawValue.EndsWith("\"", StringComparison.OrdinalIgnoreCase))
{ {
Context.OnError(startLocation, Context.OnError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(keyword)); startLocation,
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(keyword),
rawValue.Length);
} }
} }

View File

@ -208,6 +208,14 @@ namespace Microsoft.AspNet.Razor.Parser
_errorSink.OnError(location, message); _errorSink.OnError(location, message);
} }
public void OnError(SourceLocation location, string message, int length)
{
EnusreNotTerminated();
AssertOnOwnerTask();
_errorSink.OnError(location, message, length);
}
public void OnError(SourceLocation location, string message, params object[] args) public void OnError(SourceLocation location, string message, params object[] args)
{ {
EnusreNotTerminated(); EnusreNotTerminated();

View File

@ -9,13 +9,15 @@ namespace Microsoft.AspNet.Razor
{ {
public class RazorError : IEquatable<RazorError> public class RazorError : IEquatable<RazorError>
{ {
internal const int DefaultErrorLength = 1;
public RazorError() public RazorError()
: this(message: string.Empty, location: SourceLocation.Undefined) : this(message: string.Empty, location: SourceLocation.Undefined)
{ {
} }
public RazorError(string message, SourceLocation location) public RazorError(string message, SourceLocation location)
: this(message, location, 1) : this(message, location, DefaultErrorLength)
{ {
} }
@ -77,7 +79,8 @@ namespace Microsoft.AspNet.Razor
{ {
return other != null && return other != null &&
string.Equals(other.Message, Message, StringComparison.Ordinal) && string.Equals(other.Message, Message, StringComparison.Ordinal) &&
Location.Equals(other.Location); Location.Equals(other.Location) &&
Length.Equals(other.Length);
} }
} }
} }

View File

@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
AutoCompleteString = "}" AutoCompleteString = "}"
})), })),
new RazorError(RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"), new RazorError(RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
1, 0, 1)); 10, 0, 10));
} }
[Fact] [Fact]
@ -79,7 +79,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
AutoCompleteString = "}" AutoCompleteString = "}"
})), })),
new RazorError(RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"), new RazorError(RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
1, 0, 1)); 10, 0, 10));
} }
[Fact] [Fact]

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustHaveValue( RazorResources.FormatParseError_DirectiveMustHaveValue(
SyntaxConstants.CSharp.TagHelperPrefixKeyword), SyntaxConstants.CSharp.TagHelperPrefixKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 1, lineIndex: 0, columnIndex: 1, length: 15));
} }
[Fact] [Fact]
@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.TagHelperPrefixKeyword), SyntaxConstants.CSharp.TagHelperPrefixKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 17, lineIndex: 0, columnIndex: 17, length: 4));
} }
[Fact] [Fact]
@ -93,7 +93,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.TagHelperPrefixKeyword), SyntaxConstants.CSharp.TagHelperPrefixKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 17, lineIndex: 0, columnIndex: 17, length: 4));
} }
[Fact] [Fact]
@ -111,7 +111,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.TagHelperPrefixKeyword), SyntaxConstants.CSharp.TagHelperPrefixKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 17, lineIndex: 0, columnIndex: 17, length: 3));
} }
[Fact] [Fact]
@ -153,7 +153,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustHaveValue( RazorResources.FormatParseError_DirectiveMustHaveValue(
SyntaxConstants.CSharp.RemoveTagHelperKeyword), SyntaxConstants.CSharp.RemoveTagHelperKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 1, lineIndex: 0, columnIndex: 1, length: 15));
} }
[Fact] [Fact]
@ -172,7 +172,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.RemoveTagHelperKeyword), SyntaxConstants.CSharp.RemoveTagHelperKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 17, lineIndex: 0, columnIndex: 17, length: 4));
} }
[Fact] [Fact]
@ -192,7 +192,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.RemoveTagHelperKeyword), SyntaxConstants.CSharp.RemoveTagHelperKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 17, lineIndex: 0, columnIndex: 17, length: 4));
} }
[Fact] [Fact]
@ -209,7 +209,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.RemoveTagHelperKeyword), SyntaxConstants.CSharp.RemoveTagHelperKeyword),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17)); absoluteIndex: 17, lineIndex: 0, columnIndex: 17, length: 3));
} }
[Fact] [Fact]
@ -249,7 +249,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
.Accepts(AcceptedCharacters.AnyExceptNewline)), .Accepts(AcceptedCharacters.AnyExceptNewline)),
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustHaveValue(SyntaxConstants.CSharp.AddTagHelperKeyword), RazorResources.FormatParseError_DirectiveMustHaveValue(SyntaxConstants.CSharp.AddTagHelperKeyword),
absoluteIndex: 14, lineIndex: 0, columnIndex: 14)); absoluteIndex: 1, lineIndex: 0, columnIndex: 1, length: 12));
} }
[Fact] [Fact]
@ -268,7 +268,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.AddTagHelperKeyword), SyntaxConstants.CSharp.AddTagHelperKeyword),
absoluteIndex: 14, lineIndex: 0, columnIndex: 14)); absoluteIndex: 14, lineIndex: 0, columnIndex: 14, length: 4));
} }
[Fact] [Fact]
@ -288,7 +288,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.AddTagHelperKeyword), SyntaxConstants.CSharp.AddTagHelperKeyword),
absoluteIndex: 14, lineIndex: 0, columnIndex: 14)); absoluteIndex: 14, lineIndex: 0, columnIndex: 14, length: 4));
} }
[Fact] [Fact]
@ -305,7 +305,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
new RazorError( new RazorError(
RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes( RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(
SyntaxConstants.CSharp.AddTagHelperKeyword), SyntaxConstants.CSharp.AddTagHelperKeyword),
absoluteIndex: 14, lineIndex: 0, columnIndex: 14)); absoluteIndex: 14, lineIndex: 0, columnIndex: 14, length: 3));
} }
[Fact] [Fact]

View File

@ -272,7 +272,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
.AutoCompleteWith("}")), .AutoCompleteWith("}")),
new RazorError( new RazorError(
RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", '}', '{'), RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", '}', '{'),
SourceLocation.Zero)); new SourceLocation(10, 0, 10)));
} }
[Fact] [Fact]

View File

@ -141,8 +141,9 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)), Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()), Factory.EmptyHtml()),
new RazorError( new RazorError(
RazorResources.FormatParseError_Sections_Cannot_Be_Nested(RazorResources.SectionExample_CS), RazorResources.FormatParseError_Sections_Cannot_Be_Nested(RazorResources.SectionExample_CS),
23, 0, 23)); new SourceLocation(16, 0, 16),
7));
} }
[Fact] [Fact]

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
), ),
new RazorError( new RazorError(
RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName,
new SourceLocation(8, 0, 8))); new SourceLocation(0, 0, 0), 8));
} }
[Fact] [Fact]
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
Factory.Code(" " + Environment.NewLine) Factory.Code(" " + Environment.NewLine)
.AsBaseType(string.Empty) .AsBaseType(string.Empty)
), ),
new RazorError(RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, 24, 0, 24)); new RazorError(RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, 0, 0, 0, 8));
} }
[Fact] [Fact]
@ -165,7 +165,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
), ),
new RazorError( new RazorError(
RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"), RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
SourceLocation.Zero)); new SourceLocation(10, 0, 10)));
} }
[Fact] [Fact]