Change `RazorError`s to consistently provide error lengths.
- Updated `TagHelper` errors to no longer highlight the entire tag as an error, instead just the tag name is marked as an error. This is now consistent with nested tags in `@{ ... }` errors.
- Updated `RazorError` and corresponding error logging constructs to disallow creation without providing lengths.
- Updated `TagHelperDescriptorResolver` and related classes to properly determine assembly locations within directives. This allows for exact error locations in the `@addTagHelper` directive.
#386
This commit is contained in:
parent
43fce8c927
commit
ad5bfc5b66
|
|
@ -315,7 +315,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
{
|
{
|
||||||
errorSink.OnError(SourceLocation.Zero, whitespaceError);
|
errorSink.OnError(SourceLocation.Zero, whitespaceError, length: 0);
|
||||||
|
|
||||||
validName = false;
|
validName = false;
|
||||||
}
|
}
|
||||||
|
|
@ -327,7 +327,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
InvalidNonWhitespaceNameCharacters.Contains(character))
|
InvalidNonWhitespaceNameCharacters.Contains(character))
|
||||||
{
|
{
|
||||||
var error = characterErrorBuilder(character);
|
var error = characterErrorBuilder(character);
|
||||||
errorSink.OnError(SourceLocation.Zero, error);
|
errorSink.OnError(SourceLocation.Zero, error, length: 0);
|
||||||
|
|
||||||
validName = false;
|
validName = false;
|
||||||
}
|
}
|
||||||
|
|
@ -379,7 +379,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
type.FullName,
|
type.FullName,
|
||||||
property.Name,
|
property.Name,
|
||||||
typeof(HtmlAttributeNameAttribute).FullName,
|
typeof(HtmlAttributeNameAttribute).FullName,
|
||||||
nameof(HtmlAttributeNameAttribute.Name)));
|
nameof(HtmlAttributeNameAttribute.Name)),
|
||||||
|
length: 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,7 +439,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
SourceLocation.Zero,
|
SourceLocation.Zero,
|
||||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty(
|
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty(
|
||||||
parentType.FullName,
|
parentType.FullName,
|
||||||
attributeDescriptor.PropertyName));
|
attributeDescriptor.PropertyName),
|
||||||
|
length: 0);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -492,7 +494,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace(
|
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace(
|
||||||
parentType.FullName,
|
parentType.FullName,
|
||||||
propertyName,
|
propertyName,
|
||||||
nameOrPrefix));
|
nameOrPrefix),
|
||||||
|
length: 0);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -508,7 +511,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
propertyName,
|
propertyName,
|
||||||
nameOrPrefix,
|
nameOrPrefix,
|
||||||
attributeNameOrPrefix,
|
attributeNameOrPrefix,
|
||||||
DataDashPrefix));
|
DataDashPrefix),
|
||||||
|
length: 0);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -525,7 +529,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
propertyName,
|
propertyName,
|
||||||
nameOrPrefix,
|
nameOrPrefix,
|
||||||
attributeNameOrPrefix,
|
attributeNameOrPrefix,
|
||||||
character));
|
character),
|
||||||
|
length: 0);
|
||||||
|
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
|
|
@ -576,7 +581,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
property.Name,
|
property.Name,
|
||||||
nameof(HtmlAttributeNameAttribute),
|
nameof(HtmlAttributeNameAttribute),
|
||||||
nameof(HtmlAttributeNameAttribute.DictionaryAttributePrefix),
|
nameof(HtmlAttributeNameAttribute.DictionaryAttributePrefix),
|
||||||
"IDictionary<string, TValue>"));
|
"IDictionary<string, TValue>"),
|
||||||
|
length: 0);
|
||||||
}
|
}
|
||||||
else if (attributeNameAttribute != null && !hasPublicSetter)
|
else if (attributeNameAttribute != null && !hasPublicSetter)
|
||||||
{
|
{
|
||||||
|
|
@ -589,7 +595,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
parentType.FullName,
|
parentType.FullName,
|
||||||
property.Name,
|
property.Name,
|
||||||
nameof(HtmlAttributeNameAttribute),
|
nameof(HtmlAttributeNameAttribute),
|
||||||
"IDictionary<string, TValue>"));
|
"IDictionary<string, TValue>"),
|
||||||
|
length: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -608,7 +615,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
property.Name,
|
property.Name,
|
||||||
nameof(HtmlAttributeNameAttribute),
|
nameof(HtmlAttributeNameAttribute),
|
||||||
nameof(HtmlAttributeNameAttribute.DictionaryAttributePrefix),
|
nameof(HtmlAttributeNameAttribute.DictionaryAttributePrefix),
|
||||||
"IDictionary<string, TValue>"));
|
"IDictionary<string, TValue>"),
|
||||||
|
length: 0);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
{
|
{
|
||||||
var descriptors = ResolveDescriptorsInAssembly(
|
var descriptors = ResolveDescriptorsInAssembly(
|
||||||
lookupInfo.AssemblyName,
|
lookupInfo.AssemblyName,
|
||||||
directiveDescriptor.Location,
|
lookupInfo.AssemblyNameLocation,
|
||||||
context.ErrorSink);
|
context.ErrorSink);
|
||||||
|
|
||||||
// Only use descriptors that match our lookup info
|
// Only use descriptors that match our lookup info
|
||||||
|
|
@ -101,7 +101,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
Resources.FormatTagHelperDescriptorResolver_EncounteredUnexpectedError(
|
Resources.FormatTagHelperDescriptorResolver_EncounteredUnexpectedError(
|
||||||
"@" + directiveName,
|
"@" + directiveName,
|
||||||
directiveDescriptor.DirectiveText,
|
directiveDescriptor.DirectiveText,
|
||||||
ex.Message));
|
ex.Message),
|
||||||
|
GetErrorLength(directiveDescriptor.DirectiveText));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,7 +184,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
context.ErrorSink.OnError(
|
context.ErrorSink.OnError(
|
||||||
directive.Location,
|
directive.Location,
|
||||||
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperDirective(
|
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperDirective(
|
||||||
SyntaxConstants.CSharp.TagHelperPrefixKeyword));
|
SyntaxConstants.CSharp.TagHelperPrefixKeyword),
|
||||||
|
GetErrorLength(directive.DirectiveText));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,7 +215,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperPrefixValue(
|
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperPrefixValue(
|
||||||
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
|
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
|
||||||
character,
|
character,
|
||||||
prefix));
|
prefix),
|
||||||
|
prefix.Length);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -241,8 +244,9 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
return regex.IsMatch(descriptor.TypeName);
|
return regex.IsMatch(descriptor.TypeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LookupInfo GetLookupInfo(TagHelperDirectiveDescriptor directiveDescriptor,
|
private static LookupInfo GetLookupInfo(
|
||||||
ErrorSink errorSink)
|
TagHelperDirectiveDescriptor directiveDescriptor,
|
||||||
|
ErrorSink errorSink)
|
||||||
{
|
{
|
||||||
var lookupText = directiveDescriptor.DirectiveText;
|
var lookupText = directiveDescriptor.DirectiveText;
|
||||||
var lookupStrings = lookupText?.Split(new[] { ',' });
|
var lookupStrings = lookupText?.Split(new[] { ',' });
|
||||||
|
|
@ -256,23 +260,42 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
{
|
{
|
||||||
errorSink.OnError(
|
errorSink.OnError(
|
||||||
directiveDescriptor.Location,
|
directiveDescriptor.Location,
|
||||||
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(lookupText));
|
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(lookupText),
|
||||||
|
GetErrorLength(lookupText));
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var trimmedAssemblyName = lookupStrings[1].Trim();
|
||||||
|
|
||||||
|
// + 1 is for the comma separator in the lookup text.
|
||||||
|
var assemblyNameIndex = lookupStrings[0].Length + 1 + lookupStrings[1].IndexOf(trimmedAssemblyName);
|
||||||
|
var assemblyNamePrefix = directiveDescriptor.DirectiveText.Substring(0, assemblyNameIndex);
|
||||||
|
var assemblyNameLocation = SourceLocation.Advance(directiveDescriptor.Location, assemblyNamePrefix);
|
||||||
|
|
||||||
return new LookupInfo
|
return new LookupInfo
|
||||||
{
|
{
|
||||||
TypePattern = lookupStrings[0].Trim(),
|
TypePattern = lookupStrings[0].Trim(),
|
||||||
AssemblyName = lookupStrings[1].Trim()
|
AssemblyName = trimmedAssemblyName,
|
||||||
|
AssemblyNameLocation = assemblyNameLocation,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int GetErrorLength(string directiveText)
|
||||||
|
{
|
||||||
|
var nonNullLength = directiveText == null ? 1 : directiveText.Length;
|
||||||
|
var normalizeEmptyStringLength = Math.Max(nonNullLength, 1);
|
||||||
|
|
||||||
|
return normalizeEmptyStringLength;
|
||||||
|
}
|
||||||
|
|
||||||
private class LookupInfo
|
private class LookupInfo
|
||||||
{
|
{
|
||||||
public string AssemblyName { get; set; }
|
public string AssemblyName { get; set; }
|
||||||
|
|
||||||
public string TypePattern { get; set; }
|
public string TypePattern { get; set; }
|
||||||
|
|
||||||
|
public SourceLocation AssemblyNameLocation { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -35,14 +35,18 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// <see cref="ITagHelper"/> <see cref="Type"/>s.</param>
|
/// <see cref="ITagHelper"/> <see cref="Type"/>s.</param>
|
||||||
/// <returns>An <see cref="IEnumerable{Type}"/> of valid <see cref="ITagHelper"/> <see cref="Type"/>s.
|
/// <returns>An <see cref="IEnumerable{Type}"/> of valid <see cref="ITagHelper"/> <see cref="Type"/>s.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public IEnumerable<Type> Resolve(string name,
|
public IEnumerable<Type> Resolve(
|
||||||
SourceLocation documentLocation,
|
string name,
|
||||||
[NotNull] ErrorSink errorSink)
|
SourceLocation documentLocation,
|
||||||
|
[NotNull] ErrorSink errorSink)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(name))
|
if (string.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
errorSink.OnError(documentLocation,
|
var errorLength = name == null ? 1 : Math.Max(name.Length, 1);
|
||||||
Resources.TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull);
|
errorSink.OnError(
|
||||||
|
documentLocation,
|
||||||
|
Resources.TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull,
|
||||||
|
errorLength);
|
||||||
|
|
||||||
return Type.EmptyTypes;
|
return Type.EmptyTypes;
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +64,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
documentLocation,
|
documentLocation,
|
||||||
Resources.FormatTagHelperTypeResolver_CannotResolveTagHelperAssembly(
|
Resources.FormatTagHelperTypeResolver_CannotResolveTagHelperAssembly(
|
||||||
assemblyName.Name,
|
assemblyName.Name,
|
||||||
ex.Message));
|
ex.Message),
|
||||||
|
name.Length);
|
||||||
|
|
||||||
return Type.EmptyTypes;
|
return Type.EmptyTypes;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,16 +40,6 @@ namespace Microsoft.AspNet.Razor
|
||||||
_errors.Add(error);
|
_errors.Add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates and tracks a new <see cref="RazorError"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location"><see cref="SourceLocation"/> of the error.</param>
|
|
||||||
/// <param name="message">A message describing the error.</param>
|
|
||||||
public void OnError(SourceLocation location, string message)
|
|
||||||
{
|
|
||||||
OnError(location, message, RazorError.DefaultErrorLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates and tracks a new <see cref="RazorError"/>.
|
/// Creates and tracks a new <see cref="RazorError"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
if (!errorReported)
|
if (!errorReported)
|
||||||
{
|
{
|
||||||
errorReported = true;
|
errorReported = true;
|
||||||
Context.OnError(errorLocation, RazorResources.ParseError_MissingOpenBraceAfterSection);
|
Context.OnError(
|
||||||
|
errorLocation,
|
||||||
|
RazorResources.ParseError_MissingOpenBraceAfterSection,
|
||||||
|
length: 1 /* { */);
|
||||||
}
|
}
|
||||||
|
|
||||||
PutCurrentBack();
|
PutCurrentBack();
|
||||||
|
|
@ -133,9 +136,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
if (!Optional(CSharpSymbolType.RightBrace))
|
if (!Optional(CSharpSymbolType.RightBrace))
|
||||||
{
|
{
|
||||||
editHandler.AutoCompleteString = "}";
|
editHandler.AutoCompleteString = "}";
|
||||||
Context.OnError(CurrentLocation,
|
Context.OnError(
|
||||||
RazorResources.FormatParseError_Expected_X(
|
CurrentLocation,
|
||||||
Language.GetSample(CSharpSymbolType.RightBrace)));
|
RazorResources.FormatParseError_Expected_X(Language.GetSample(CSharpSymbolType.RightBrace)),
|
||||||
|
length: 1 /* } */);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -160,8 +164,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
|
|
||||||
if (!At(CSharpSymbolType.LeftBrace))
|
if (!At(CSharpSymbolType.LeftBrace))
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation,
|
Context.OnError(
|
||||||
RazorResources.FormatParseError_Expected_X(Language.GetSample(CSharpSymbolType.LeftBrace)));
|
CurrentLocation,
|
||||||
|
RazorResources.FormatParseError_Expected_X(Language.GetSample(CSharpSymbolType.LeftBrace)),
|
||||||
|
length: 1 /* { */);
|
||||||
CompleteBlock();
|
CompleteBlock();
|
||||||
Output(SpanKind.MetaCode);
|
Output(SpanKind.MetaCode);
|
||||||
return;
|
return;
|
||||||
|
|
@ -186,7 +192,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
if (!At(CSharpSymbolType.RightBrace))
|
if (!At(CSharpSymbolType.RightBrace))
|
||||||
{
|
{
|
||||||
editHandler.AutoCompleteString = "}";
|
editHandler.AutoCompleteString = "}";
|
||||||
Context.OnError(blockStart, RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, "}", "{"));
|
Context.OnError(
|
||||||
|
blockStart,
|
||||||
|
RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, "}", "{"),
|
||||||
|
length: 1 /* } */);
|
||||||
CompleteBlock();
|
CompleteBlock();
|
||||||
Output(SpanKind.Code);
|
Output(SpanKind.Code);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
|
|
||||||
protected virtual void ReservedDirective(bool topLevel)
|
protected virtual void ReservedDirective(bool topLevel)
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation, RazorResources.FormatParseError_ReservedWord(CurrentSymbol.Content));
|
Context.OnError(
|
||||||
|
CurrentLocation,
|
||||||
|
RazorResources.FormatParseError_ReservedWord(CurrentSymbol.Content),
|
||||||
|
CurrentSymbol.Content.Length);
|
||||||
AcceptAndMoveNext();
|
AcceptAndMoveNext();
|
||||||
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
|
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
|
||||||
Span.ChunkGenerator = SpanChunkGenerator.Null;
|
Span.ChunkGenerator = SpanChunkGenerator.Null;
|
||||||
|
|
@ -109,7 +112,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
// using Identifier ==> Using Declaration
|
// using Identifier ==> Using Declaration
|
||||||
if (!topLevel)
|
if (!topLevel)
|
||||||
{
|
{
|
||||||
Context.OnError(block.Start, RazorResources.ParseError_NamespaceImportAndTypeAlias_Cannot_Exist_Within_CodeBlock);
|
Context.OnError(
|
||||||
|
block.Start,
|
||||||
|
RazorResources.ParseError_NamespaceImportAndTypeAlias_Cannot_Exist_Within_CodeBlock,
|
||||||
|
block.Name.Length);
|
||||||
StandardStatement();
|
StandardStatement();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -327,10 +333,12 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
// Check for "{" to make sure we're at a block
|
// Check for "{" to make sure we're at a block
|
||||||
if (!At(CSharpSymbolType.LeftBrace))
|
if (!At(CSharpSymbolType.LeftBrace))
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation,
|
Context.OnError(
|
||||||
RazorResources.FormatParseError_SingleLine_ControlFlowStatements_Not_Allowed(
|
CurrentLocation,
|
||||||
Language.GetSample(CSharpSymbolType.LeftBrace),
|
RazorResources.FormatParseError_SingleLine_ControlFlowStatements_Not_Allowed(
|
||||||
CurrentSymbol.Content));
|
Language.GetSample(CSharpSymbolType.LeftBrace),
|
||||||
|
CurrentSymbol.Content),
|
||||||
|
CurrentSymbol.Content.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the statement and then we're done
|
// Parse the statement and then we're done
|
||||||
|
|
@ -480,7 +488,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
{
|
{
|
||||||
if (type == CSharpSymbolType.Transition && !isSingleLineMarkup)
|
if (type == CSharpSymbolType.Transition && !isSingleLineMarkup)
|
||||||
{
|
{
|
||||||
Context.OnError(loc, RazorResources.ParseError_AtInCode_Must_Be_Followed_By_Colon_Paren_Or_Identifier_Start);
|
Context.OnError(
|
||||||
|
loc,
|
||||||
|
RazorResources.ParseError_AtInCode_Must_Be_Followed_By_Colon_Paren_Or_Identifier_Start,
|
||||||
|
length: 1 /* @ */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Markup block
|
// Markup block
|
||||||
|
|
@ -560,7 +571,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
// Throw errors as necessary, but continue parsing
|
// Throw errors as necessary, but continue parsing
|
||||||
if (At(CSharpSymbolType.LeftBrace))
|
if (At(CSharpSymbolType.LeftBrace))
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation, RazorResources.ParseError_Unexpected_Nested_CodeBlock);
|
Context.OnError(
|
||||||
|
CurrentLocation,
|
||||||
|
RazorResources.ParseError_Unexpected_Nested_CodeBlock,
|
||||||
|
length: 1 /* { */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @( or @foo - Nested expression, parse a child block
|
// @( or @foo - Nested expression, parse a child block
|
||||||
|
|
@ -649,7 +663,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
|
|
||||||
if (EndOfFile)
|
if (EndOfFile)
|
||||||
{
|
{
|
||||||
Context.OnError(block.Start, RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, '}', '{'));
|
Context.OnError(
|
||||||
|
block.Start,
|
||||||
|
RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, '}', '{'),
|
||||||
|
length: 1 /* { OR } */);
|
||||||
}
|
}
|
||||||
else if (acceptTerminatingBrace)
|
else if (acceptTerminatingBrace)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -256,15 +256,25 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
};
|
};
|
||||||
if (At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine))
|
if (At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine))
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation, RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS);
|
Context.OnError(
|
||||||
|
CurrentLocation,
|
||||||
|
RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS,
|
||||||
|
CurrentSymbol.Content.Length);
|
||||||
}
|
}
|
||||||
else if (EndOfFile)
|
else if (EndOfFile)
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation, RazorResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock);
|
Context.OnError(
|
||||||
|
CurrentLocation,
|
||||||
|
RazorResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock,
|
||||||
|
length: 1 /* end of file */);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation, RazorResources.FormatParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS(CurrentSymbol.Content));
|
Context.OnError(
|
||||||
|
CurrentLocation,
|
||||||
|
RazorResources.FormatParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS(
|
||||||
|
CurrentSymbol.Content),
|
||||||
|
CurrentSymbol.Content.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
@ -529,7 +539,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
AcceptUntil(CSharpSymbolType.LessThan);
|
AcceptUntil(CSharpSymbolType.LessThan);
|
||||||
Context.OnError(block.Start, RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, ")", "("));
|
Context.OnError(
|
||||||
|
block.Start,
|
||||||
|
RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, ")", "("),
|
||||||
|
length: 1 /* ( */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If necessary, put an empty-content marker symbol here
|
// If necessary, put an empty-content marker symbol here
|
||||||
|
|
@ -556,7 +569,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
{
|
{
|
||||||
if (Context.IsWithin(BlockType.Template))
|
if (Context.IsWithin(BlockType.Template))
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation, RazorResources.ParseError_InlineMarkup_Blocks_Cannot_Be_Nested);
|
Context.OnError(
|
||||||
|
CurrentLocation,
|
||||||
|
RazorResources.ParseError_InlineMarkup_Blocks_Cannot_Be_Nested,
|
||||||
|
length: 1 /* @ */);
|
||||||
}
|
}
|
||||||
Output(SpanKind.Code);
|
Output(SpanKind.Code);
|
||||||
using (Context.StartBlock(BlockType.Template))
|
using (Context.StartBlock(BlockType.Template))
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
{
|
{
|
||||||
public partial class HtmlMarkupParser
|
public partial class HtmlMarkupParser
|
||||||
{
|
{
|
||||||
|
private const string ScriptTagName = "script";
|
||||||
|
|
||||||
private SourceLocation _lastTagStart = SourceLocation.Zero;
|
private SourceLocation _lastTagStart = SourceLocation.Zero;
|
||||||
private HtmlSymbol _bufferedOpenAngle;
|
private HtmlSymbol _bufferedOpenAngle;
|
||||||
|
|
||||||
|
|
@ -62,7 +64,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentSymbol.Start, RazorResources.ParseError_MarkupBlock_Must_Start_With_Tag);
|
Context.OnError(
|
||||||
|
CurrentSymbol.Start,
|
||||||
|
RazorResources.ParseError_MarkupBlock_Must_Start_With_Tag,
|
||||||
|
CurrentSymbol.Content.Length);
|
||||||
}
|
}
|
||||||
Output(SpanKind.Markup);
|
Output(SpanKind.Markup);
|
||||||
}
|
}
|
||||||
|
|
@ -221,7 +226,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
}
|
}
|
||||||
if (tags.Count == 0)
|
if (tags.Count == 0)
|
||||||
{
|
{
|
||||||
Context.OnError(CurrentLocation, RazorResources.ParseError_OuterTagMissingName);
|
Context.OnError(
|
||||||
|
CurrentLocation,
|
||||||
|
RazorResources.ParseError_OuterTagMissingName,
|
||||||
|
length: 1 /* end of file */);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -346,11 +354,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
|
|
||||||
private bool EndTextTag(HtmlSymbol solidus, IDisposable tagBlockWrapper)
|
private bool EndTextTag(HtmlSymbol solidus, IDisposable tagBlockWrapper)
|
||||||
{
|
{
|
||||||
var start = _bufferedOpenAngle.Start;
|
|
||||||
|
|
||||||
Accept(_bufferedOpenAngle);
|
Accept(_bufferedOpenAngle);
|
||||||
Accept(solidus);
|
Accept(solidus);
|
||||||
|
|
||||||
|
var textLocation = CurrentLocation;
|
||||||
Assert(HtmlSymbolType.Text);
|
Assert(HtmlSymbolType.Text);
|
||||||
AcceptAndMoveNext();
|
AcceptAndMoveNext();
|
||||||
|
|
||||||
|
|
@ -358,7 +365,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
|
|
||||||
if (!seenCloseAngle)
|
if (!seenCloseAngle)
|
||||||
{
|
{
|
||||||
Context.OnError(start, RazorResources.ParseError_TextTagCannotContainAttributes);
|
Context.OnError(
|
||||||
|
textLocation,
|
||||||
|
RazorResources.ParseError_TextTagCannotContainAttributes,
|
||||||
|
length: 4 /* text */);
|
||||||
|
|
||||||
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
|
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any;
|
||||||
RecoverTextTag();
|
RecoverTextTag();
|
||||||
|
|
@ -751,6 +761,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
Span.ChunkGenerator = SpanChunkGenerator.Null;
|
Span.ChunkGenerator = SpanChunkGenerator.Null;
|
||||||
|
|
||||||
Accept(_bufferedOpenAngle);
|
Accept(_bufferedOpenAngle);
|
||||||
|
var textLocation = CurrentLocation;
|
||||||
Assert(HtmlSymbolType.Text);
|
Assert(HtmlSymbolType.Text);
|
||||||
|
|
||||||
AcceptAndMoveNext();
|
AcceptAndMoveNext();
|
||||||
|
|
@ -771,7 +782,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
{
|
{
|
||||||
Context.Source.Position = bookmark;
|
Context.Source.Position = bookmark;
|
||||||
NextToken();
|
NextToken();
|
||||||
Context.OnError(tag.Item2, RazorResources.ParseError_TextTagCannotContainAttributes);
|
Context.OnError(
|
||||||
|
textLocation,
|
||||||
|
RazorResources.ParseError_TextTagCannotContainAttributes,
|
||||||
|
length: 4 /* text */);
|
||||||
|
|
||||||
RecoverTextTag();
|
RecoverTextTag();
|
||||||
}
|
}
|
||||||
|
|
@ -821,7 +835,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
var seenClose = Optional(HtmlSymbolType.CloseAngle);
|
var seenClose = Optional(HtmlSymbolType.CloseAngle);
|
||||||
if (!seenClose)
|
if (!seenClose)
|
||||||
{
|
{
|
||||||
Context.OnError(tag.Item2, RazorResources.FormatParseError_UnfinishedTag(tag.Item1.Content));
|
Context.OnError(
|
||||||
|
SourceLocation.Advance(tag.Item2, "<"),
|
||||||
|
RazorResources.FormatParseError_UnfinishedTag(tag.Item1.Content),
|
||||||
|
Math.Max(tag.Item1.Content.Length, 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -883,7 +900,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
Context.Source.Position = bookmark;
|
Context.Source.Position = bookmark;
|
||||||
NextToken();
|
NextToken();
|
||||||
}
|
}
|
||||||
else if (string.Equals(tagName, "script", StringComparison.OrdinalIgnoreCase))
|
else if (string.Equals(tagName, ScriptTagName, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
CompleteTagBlockWithSpan(tagBlockWrapper, AcceptedCharacters.None, SpanKind.Markup);
|
CompleteTagBlockWithSpan(tagBlockWrapper, AcceptedCharacters.None, SpanKind.Markup);
|
||||||
|
|
||||||
|
|
@ -916,7 +933,8 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
var solidus = CurrentSymbol;
|
var solidus = CurrentSymbol;
|
||||||
NextToken(); // Skip over '/', current should be text
|
NextToken(); // Skip over '/', current should be text
|
||||||
|
|
||||||
if (At(HtmlSymbolType.Text) && string.Equals(CurrentSymbol.Content, "script", StringComparison.OrdinalIgnoreCase))
|
if (At(HtmlSymbolType.Text) &&
|
||||||
|
string.Equals(CurrentSymbol.Content, ScriptTagName, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
seenEndScript = true;
|
seenEndScript = true;
|
||||||
}
|
}
|
||||||
|
|
@ -944,7 +962,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
SkipToAndParseCode(HtmlSymbolType.CloseAngle);
|
SkipToAndParseCode(HtmlSymbolType.CloseAngle);
|
||||||
if (!Optional(HtmlSymbolType.CloseAngle))
|
if (!Optional(HtmlSymbolType.CloseAngle))
|
||||||
{
|
{
|
||||||
Context.OnError(tagStart, RazorResources.FormatParseError_UnfinishedTag("script"));
|
Context.OnError(
|
||||||
|
SourceLocation.Advance(tagStart, "</"),
|
||||||
|
RazorResources.FormatParseError_UnfinishedTag(ScriptTagName),
|
||||||
|
ScriptTagName.Length);
|
||||||
}
|
}
|
||||||
Output(SpanKind.Markup);
|
Output(SpanKind.Markup);
|
||||||
}
|
}
|
||||||
|
|
@ -999,11 +1020,17 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
}
|
}
|
||||||
if (currentTag != null)
|
if (currentTag != null)
|
||||||
{
|
{
|
||||||
Context.OnError(currentTag.Item2, RazorResources.FormatParseError_MissingEndTag(currentTag.Item1.Content));
|
Context.OnError(
|
||||||
|
SourceLocation.Advance(currentTag.Item2, "<"),
|
||||||
|
RazorResources.FormatParseError_MissingEndTag(currentTag.Item1.Content),
|
||||||
|
currentTag.Item1.Content.Length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Context.OnError(tagStart, RazorResources.FormatParseError_UnexpectedEndTag(tagName));
|
Context.OnError(
|
||||||
|
SourceLocation.Advance(tagStart, "</"),
|
||||||
|
RazorResources.FormatParseError_UnexpectedEndTag(tagName),
|
||||||
|
tagName.Length);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1018,7 +1045,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
tags.Pop();
|
tags.Pop();
|
||||||
}
|
}
|
||||||
var tag = tags.Pop();
|
var tag = tags.Pop();
|
||||||
Context.OnError(tag.Item2, RazorResources.FormatParseError_MissingEndTag(tag.Item1.Content));
|
Context.OnError(
|
||||||
|
SourceLocation.Advance(tag.Item2, "<"),
|
||||||
|
RazorResources.FormatParseError_MissingEndTag(tag.Item1.Content),
|
||||||
|
tag.Item1.Content.Length);
|
||||||
}
|
}
|
||||||
else if (complete)
|
else if (complete)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -200,14 +200,6 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
_errorSink.OnError(error);
|
_errorSink.OnError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnError(SourceLocation location, string message)
|
|
||||||
{
|
|
||||||
EnusreNotTerminated();
|
|
||||||
AssertOnOwnerTask();
|
|
||||||
|
|
||||||
_errorSink.OnError(location, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnError(SourceLocation location, string message, int length)
|
public void OnError(SourceLocation location, string message, int length)
|
||||||
{
|
{
|
||||||
EnusreNotTerminated();
|
EnusreNotTerminated();
|
||||||
|
|
@ -216,12 +208,12 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
_errorSink.OnError(location, message, length);
|
_errorSink.OnError(location, message, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnError(SourceLocation location, string message, params object[] args)
|
public void OnError(SourceLocation location, string message, int length, params object[] args)
|
||||||
{
|
{
|
||||||
EnusreNotTerminated();
|
EnusreNotTerminated();
|
||||||
AssertOnOwnerTask();
|
AssertOnOwnerTask();
|
||||||
|
|
||||||
OnError(location, string.Format(CultureInfo.CurrentCulture, message, args));
|
OnError(location, string.Format(CultureInfo.CurrentCulture, message, args), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParserResults CompleteParse()
|
public ParserResults CompleteParse()
|
||||||
|
|
|
||||||
|
|
@ -296,8 +296,10 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
|
|
||||||
if (childSpan == null || childSpan.Kind != SpanKind.Markup)
|
if (childSpan == null || childSpan.Kind != SpanKind.Markup)
|
||||||
{
|
{
|
||||||
errorSink.OnError(block.Children.First().Start,
|
errorSink.OnError(
|
||||||
RazorResources.FormatTagHelpers_CannotHaveCSharpInTagDeclaration(tagName));
|
block.Start,
|
||||||
|
RazorResources.FormatTagHelpers_CannotHaveCSharpInTagDeclaration(tagName),
|
||||||
|
block.Length);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +318,10 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
|
|
||||||
if (name == null)
|
if (name == null)
|
||||||
{
|
{
|
||||||
errorSink.OnError(childSpan.Start, RazorResources.FormatTagHelpers_AttributesMustHaveAName(tagName));
|
errorSink.OnError(
|
||||||
|
childSpan.Start,
|
||||||
|
RazorResources.FormatTagHelpers_AttributesMustHaveAName(tagName),
|
||||||
|
childSpan.Length);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,11 +67,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
chunkGenerator.RemoveTagHelperDescriptors ?
|
chunkGenerator.RemoveTagHelperDescriptors ?
|
||||||
TagHelperDirectiveType.RemoveTagHelper :
|
TagHelperDirectiveType.RemoveTagHelper :
|
||||||
TagHelperDirectiveType.AddTagHelper;
|
TagHelperDirectiveType.AddTagHelper;
|
||||||
|
var textLocation = GetSubTextSourceLocation(span, chunkGenerator.LookupText);
|
||||||
|
|
||||||
var directiveDescriptor = new TagHelperDirectiveDescriptor
|
var directiveDescriptor = new TagHelperDirectiveDescriptor
|
||||||
{
|
{
|
||||||
DirectiveText = chunkGenerator.LookupText,
|
DirectiveText = chunkGenerator.LookupText,
|
||||||
Location = span.Start,
|
Location = textLocation,
|
||||||
DirectiveType = directive
|
DirectiveType = directive
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -80,16 +81,26 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
else if (span.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator)
|
else if (span.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator)
|
||||||
{
|
{
|
||||||
var chunkGenerator = (TagHelperPrefixDirectiveChunkGenerator)span.ChunkGenerator;
|
var chunkGenerator = (TagHelperPrefixDirectiveChunkGenerator)span.ChunkGenerator;
|
||||||
|
var textLocation = GetSubTextSourceLocation(span, chunkGenerator.Prefix);
|
||||||
|
|
||||||
var directiveDescriptor = new TagHelperDirectiveDescriptor
|
var directiveDescriptor = new TagHelperDirectiveDescriptor
|
||||||
{
|
{
|
||||||
DirectiveText = chunkGenerator.Prefix,
|
DirectiveText = chunkGenerator.Prefix,
|
||||||
Location = span.Start,
|
Location = textLocation,
|
||||||
DirectiveType = TagHelperDirectiveType.TagHelperPrefix
|
DirectiveType = TagHelperDirectiveType.TagHelperPrefix
|
||||||
};
|
};
|
||||||
|
|
||||||
_directiveDescriptors.Add(directiveDescriptor);
|
_directiveDescriptors.Add(directiveDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SourceLocation GetSubTextSourceLocation(Span span, string text)
|
||||||
|
{
|
||||||
|
var startOffset = span.Content.IndexOf(text);
|
||||||
|
var offsetContent = span.Content.Substring(0, startOffset);
|
||||||
|
var offsetTextLocation = SourceLocation.Advance(span.Start, offsetContent);
|
||||||
|
|
||||||
|
return offsetTextLocation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -208,12 +208,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
{
|
{
|
||||||
// End tag TagHelper that states it shouldn't have an end tag.
|
// End tag TagHelper that states it shouldn't have an end tag.
|
||||||
context.ErrorSink.OnError(
|
context.ErrorSink.OnError(
|
||||||
tagBlock.Start,
|
SourceLocation.Advance(tagBlock.Start, "</"),
|
||||||
RazorResources.FormatTagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag(
|
RazorResources.FormatTagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag(
|
||||||
tagName,
|
tagName,
|
||||||
invalidDescriptor.TypeName,
|
invalidDescriptor.TypeName,
|
||||||
invalidDescriptor.TagStructure),
|
invalidDescriptor.TagStructure),
|
||||||
tagBlock.Length);
|
tagName.Length);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -233,8 +233,9 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
// Could not recover, the end tag helper has no corresponding start tag, create
|
// Could not recover, the end tag helper has no corresponding start tag, create
|
||||||
// an error based on the current childBlock.
|
// an error based on the current childBlock.
|
||||||
context.ErrorSink.OnError(
|
context.ErrorSink.OnError(
|
||||||
tagBlock.Start,
|
SourceLocation.Advance(tagBlock.Start, "</"),
|
||||||
RazorResources.FormatTagHelpersParseTreeRewriter_FoundMalformedTagHelper(tagName));
|
RazorResources.FormatTagHelpersParseTreeRewriter_FoundMalformedTagHelper(tagName),
|
||||||
|
tagName.Length);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -333,8 +334,9 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
tagName,
|
tagName,
|
||||||
tracker.Builder.TagName,
|
tracker.Builder.TagName,
|
||||||
allowedChildrenString);
|
allowedChildrenString);
|
||||||
|
var errorStart = GetTagDeclarationErrorStart(tagBlock);
|
||||||
|
|
||||||
errorSink.OnError(tagBlock.Start, errorMessage, tagBlock.Length);
|
errorSink.OnError(errorStart, errorMessage, tagName.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ValidateDescriptors(
|
private static void ValidateDescriptors(
|
||||||
|
|
@ -373,9 +375,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
// We assume an invalid syntax until we verify that the tag meets all of our "valid syntax" criteria.
|
// We assume an invalid syntax until we verify that the tag meets all of our "valid syntax" criteria.
|
||||||
if (IsPartialTag(tag))
|
if (IsPartialTag(tag))
|
||||||
{
|
{
|
||||||
|
var errorStart = GetTagDeclarationErrorStart(tag);
|
||||||
|
|
||||||
context.ErrorSink.OnError(
|
context.ErrorSink.OnError(
|
||||||
tag.Start,
|
errorStart,
|
||||||
RazorResources.FormatTagHelpersParseTreeRewriter_MissingCloseAngle(tagName));
|
RazorResources.FormatTagHelpersParseTreeRewriter_MissingCloseAngle(tagName),
|
||||||
|
tagName.Length);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -383,6 +388,13 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SourceLocation GetTagDeclarationErrorStart(Block tagBlock)
|
||||||
|
{
|
||||||
|
var advanceBy = IsEndTag(tagBlock) ? "</" : "<";
|
||||||
|
|
||||||
|
return SourceLocation.Advance(tagBlock.Start, advanceBy);
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsPartialTag(Block tagBlock)
|
private static bool IsPartialTag(Block tagBlock)
|
||||||
{
|
{
|
||||||
// No need to validate the tag end because in order to be a tag block it must start with '<'.
|
// No need to validate the tag end because in order to be a tag block it must start with '<'.
|
||||||
|
|
@ -501,9 +513,10 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
var malformedTagHelper = _trackerStack.Peek().Builder;
|
var malformedTagHelper = _trackerStack.Peek().Builder;
|
||||||
|
|
||||||
context.ErrorSink.OnError(
|
context.ErrorSink.OnError(
|
||||||
malformedTagHelper.Start,
|
SourceLocation.Advance(malformedTagHelper.Start, "<"),
|
||||||
RazorResources.FormatTagHelpersParseTreeRewriter_FoundMalformedTagHelper(
|
RazorResources.FormatTagHelpersParseTreeRewriter_FoundMalformedTagHelper(
|
||||||
malformedTagHelper.TagName));
|
malformedTagHelper.TagName),
|
||||||
|
malformedTagHelper.TagName.Length);
|
||||||
|
|
||||||
BuildCurrentlyTrackedTagHelperBlock(endTag: null);
|
BuildCurrentlyTrackedTagHelperBlock(endTag: null);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,10 +71,12 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
AcceptAndMoveNext();
|
AcceptAndMoveNext();
|
||||||
if (EndOfFile && ((mode & BalancingModes.NoErrorOnFailure) != BalancingModes.NoErrorOnFailure))
|
if (EndOfFile && ((mode & BalancingModes.NoErrorOnFailure) != BalancingModes.NoErrorOnFailure))
|
||||||
{
|
{
|
||||||
Context.OnError(start,
|
Context.OnError(
|
||||||
RazorResources.FormatParseError_Expected_CloseBracket_Before_EOF(
|
start,
|
||||||
Language.GetSample(left),
|
RazorResources.FormatParseError_Expected_CloseBracket_Before_EOF(
|
||||||
Language.GetSample(right)));
|
Language.GetSample(left),
|
||||||
|
Language.GetSample(right)),
|
||||||
|
length: 1 /* { OR } */);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Balance(mode, left, right, start);
|
return Balance(mode, left, right, start);
|
||||||
|
|
@ -119,10 +121,12 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
{
|
{
|
||||||
if ((mode & BalancingModes.NoErrorOnFailure) != BalancingModes.NoErrorOnFailure)
|
if ((mode & BalancingModes.NoErrorOnFailure) != BalancingModes.NoErrorOnFailure)
|
||||||
{
|
{
|
||||||
Context.OnError(start,
|
Context.OnError(
|
||||||
RazorResources.FormatParseError_Expected_CloseBracket_Before_EOF(
|
start,
|
||||||
Language.GetSample(left),
|
RazorResources.FormatParseError_Expected_CloseBracket_Before_EOF(
|
||||||
Language.GetSample(right)));
|
Language.GetSample(left),
|
||||||
|
Language.GetSample(right)),
|
||||||
|
length: 1 /* { OR } */);
|
||||||
}
|
}
|
||||||
if ((mode & BalancingModes.BacktrackOnFailure) == BalancingModes.BacktrackOnFailure)
|
if ((mode & BalancingModes.BacktrackOnFailure) == BalancingModes.BacktrackOnFailure)
|
||||||
{
|
{
|
||||||
|
|
@ -355,9 +359,17 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
error = RazorResources.FormatErrorComponent_Character(CurrentSymbol.Content);
|
error = RazorResources.FormatErrorComponent_Character(CurrentSymbol.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.OnError(
|
int errorLength;
|
||||||
CurrentLocation,
|
if (CurrentSymbol == null || CurrentSymbol.Content == null)
|
||||||
errorBase(error));
|
{
|
||||||
|
errorLength = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorLength = Math.Max(CurrentSymbol.Content.Length, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.OnError(CurrentLocation, errorBase(error), errorLength);
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +533,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
if (!Optional(KnownSymbolType.CommentStar))
|
if (!Optional(KnownSymbolType.CommentStar))
|
||||||
{
|
{
|
||||||
errorReported = true;
|
errorReported = true;
|
||||||
Context.OnError(start, RazorResources.ParseError_RazorComment_Not_Terminated);
|
Context.OnError(
|
||||||
|
start,
|
||||||
|
RazorResources.ParseError_RazorComment_Not_Terminated,
|
||||||
|
length: 2 /* @* */);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -533,7 +548,10 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
if (!errorReported)
|
if (!errorReported)
|
||||||
{
|
{
|
||||||
errorReported = true;
|
errorReported = true;
|
||||||
Context.OnError(start, RazorResources.ParseError_RazorComment_Not_Terminated);
|
Context.OnError(
|
||||||
|
start,
|
||||||
|
RazorResources.ParseError_RazorComment_Not_Terminated,
|
||||||
|
length: 2 /* @* */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -11,18 +11,16 @@ namespace Microsoft.AspNet.Razor
|
||||||
{
|
{
|
||||||
internal const int DefaultErrorLength = 1;
|
internal const int DefaultErrorLength = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used only for deserialization.
|
||||||
|
/// </summary>
|
||||||
public RazorError()
|
public RazorError()
|
||||||
: this(message: string.Empty, location: SourceLocation.Undefined)
|
: this(message: string.Empty, location: SourceLocation.Undefined, length: -1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public RazorError(string message, SourceLocation location)
|
public RazorError(string message, int absoluteIndex, int lineIndex, int columnIndex, int length)
|
||||||
: this(message, location, DefaultErrorLength)
|
: this(message, new SourceLocation(absoluteIndex, lineIndex, columnIndex), length)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public RazorError(string message, int absoluteIndex, int lineIndex, int columnIndex)
|
|
||||||
: this(message, new SourceLocation(absoluteIndex, lineIndex, columnIndex))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,11 +31,6 @@ namespace Microsoft.AspNet.Razor
|
||||||
Length = length;
|
Length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RazorError(string message, int absoluteIndex, int lineIndex, int columnIndex, int length)
|
|
||||||
: this(message, new SourceLocation(absoluteIndex, lineIndex, columnIndex), length)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets (or sets) the message describing the error.
|
/// Gets (or sets) the message describing the error.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,11 @@ namespace Microsoft.AspNet.Razor.Tokenizer
|
||||||
}
|
}
|
||||||
else if (EndOfFile)
|
else if (EndOfFile)
|
||||||
{
|
{
|
||||||
CurrentErrors.Add(new RazorError(RazorResources.ParseError_Unterminated_String_Literal, CurrentStart));
|
CurrentErrors.Add(
|
||||||
|
new RazorError(
|
||||||
|
RazorResources.ParseError_Unterminated_String_Literal,
|
||||||
|
CurrentStart,
|
||||||
|
length: 1 /* end of file */));
|
||||||
}
|
}
|
||||||
return Transition(EndSymbol(CSharpSymbolType.StringLiteral), Data);
|
return Transition(EndSymbol(CSharpSymbolType.StringLiteral), Data);
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +289,11 @@ namespace Microsoft.AspNet.Razor.Tokenizer
|
||||||
}
|
}
|
||||||
else if (EndOfFile || ParserHelpers.IsNewLine(CurrentCharacter))
|
else if (EndOfFile || ParserHelpers.IsNewLine(CurrentCharacter))
|
||||||
{
|
{
|
||||||
CurrentErrors.Add(new RazorError(RazorResources.ParseError_Unterminated_String_Literal, CurrentStart));
|
CurrentErrors.Add(
|
||||||
|
new RazorError(
|
||||||
|
RazorResources.ParseError_Unterminated_String_Literal,
|
||||||
|
CurrentStart,
|
||||||
|
length: 1 /* " */));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -300,7 +308,11 @@ namespace Microsoft.AspNet.Razor.Tokenizer
|
||||||
TakeUntil(c => c == '*');
|
TakeUntil(c => c == '*');
|
||||||
if (EndOfFile)
|
if (EndOfFile)
|
||||||
{
|
{
|
||||||
CurrentErrors.Add(new RazorError(RazorResources.ParseError_BlockComment_Not_Terminated, CurrentStart));
|
CurrentErrors.Add(
|
||||||
|
new RazorError(
|
||||||
|
RazorResources.ParseError_BlockComment_Not_Terminated,
|
||||||
|
CurrentStart,
|
||||||
|
length: 1 /* end of file */));
|
||||||
return Transition(EndSymbol(CSharpSymbolType.Comment), Data);
|
return Transition(EndSymbol(CSharpSymbolType.Comment), Data);
|
||||||
}
|
}
|
||||||
if (CurrentCharacter == '*')
|
if (CurrentCharacter == '*')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue