This commit is contained in:
Ajay Bhargav Baaskaran 2015-05-14 17:15:56 -07:00
parent d0927bdc75
commit 47bfba11b9
3 changed files with 25 additions and 19 deletions

View File

@ -50,17 +50,18 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
// Verify we're on the right keyword and accept // Verify we're on the right keyword and accept
AssertDirective(ModelKeyword); AssertDirective(ModelKeyword);
var startModelLocation = CurrentLocation;
AcceptAndMoveNext(); AcceptAndMoveNext();
var endModelLocation = CurrentLocation;
BaseTypeDirective(Resources.FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(ModelKeyword), BaseTypeDirective(Resources.FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(ModelKeyword),
CreateModelCodeGenerator); CreateModelCodeGenerator);
if (_modelStatementFound) if (_modelStatementFound)
{ {
Context.OnError(endModelLocation, Context.OnError(startModelLocation,
Resources.FormatMvcRazorCodeParser_OnlyOneModelStatementIsAllowed(ModelKeyword)); Resources.FormatMvcRazorCodeParser_OnlyOneModelStatementIsAllowed(ModelKeyword),
ModelKeyword.Length);
} }
_modelStatementFound = true; _modelStatementFound = true;
@ -72,22 +73,25 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
// @inject MyApp.MyService MyServicePropertyName // @inject MyApp.MyService MyServicePropertyName
AssertDirective(InjectKeyword); AssertDirective(InjectKeyword);
var startLocation = CurrentLocation;
AcceptAndMoveNext(); AcceptAndMoveNext();
Context.CurrentBlock.Type = BlockType.Directive; Context.CurrentBlock.Type = BlockType.Directive;
// Accept whitespace // Accept whitespace
var remainingWs = AcceptSingleWhiteSpaceCharacter(); var remainingWhitespace = AcceptSingleWhiteSpaceCharacter();
var keywordwithSingleWhitespaceLength = Span.GetContent().Value.Length;
if (Span.Symbols.Count > 1) if (Span.Symbols.Count > 1)
{ {
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
} }
Output(SpanKind.MetaCode); Output(SpanKind.MetaCode);
if (remainingWs != null) if (remainingWhitespace != null)
{ {
Accept(remainingWs); Accept(remainingWhitespace);
} }
var remainingWhitespaceLength = Span.GetContent().Value.Length;
// Consume any other whitespace tokens. // Consume any other whitespace tokens.
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true));
@ -95,8 +99,10 @@ namespace Microsoft.AspNet.Mvc.Razor
var hasTypeError = !At(CSharpSymbolType.Identifier); var hasTypeError = !At(CSharpSymbolType.Identifier);
if (hasTypeError) if (hasTypeError)
{ {
Context.OnError(CurrentLocation, Context.OnError(
Resources.FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(InjectKeyword)); startLocation,
Resources.FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(InjectKeyword),
InjectKeyword.Length);
} }
// Accept 'MyApp.MyService' // Accept 'MyApp.MyService'
@ -105,14 +111,14 @@ namespace Microsoft.AspNet.Mvc.Razor
// typeName now contains the token 'MyApp.MyService' // typeName now contains the token 'MyApp.MyService'
var typeName = Span.GetContent().Value; var typeName = Span.GetContent().Value;
var propertyStartLocation = CurrentLocation;
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true));
if (!hasTypeError && (EndOfFile || At(CSharpSymbolType.NewLine))) if (!hasTypeError && (EndOfFile || At(CSharpSymbolType.NewLine)))
{ {
// Add an error for the property name only if we successfully read the type name // Add an error for the property name only if we successfully read the type name
Context.OnError(propertyStartLocation, Context.OnError(startLocation,
Resources.FormatMvcRazorCodeParser_InjectDirectivePropertyNameRequired(InjectKeyword)); Resources.FormatMvcRazorCodeParser_InjectDirectivePropertyNameRequired(InjectKeyword),
keywordwithSingleWhitespaceLength + remainingWhitespaceLength + typeName.Length);
} }
// Read until end of line. Span now contains 'MyApp.MyService MyServiceName'. // Read until end of line. Span now contains 'MyApp.MyService MyServiceName'.

View File

@ -117,7 +117,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var expectedErrors = new[] var expectedErrors = new[]
{ {
new RazorError("The 'model' keyword must be followed by a type name on the same line.", new RazorError("The 'model' keyword must be followed by a type name on the same line.",
new SourceLocation(9, 0, 9), 1) new SourceLocation(1, 0, 1), 5)
}; };
Assert.Equal(expectedSpans, spans); Assert.Equal(expectedSpans, spans);
Assert.Equal(expectedErrors, errors); Assert.Equal(expectedErrors, errors);
@ -157,7 +157,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var expectedErrors = new[] var expectedErrors = new[]
{ {
new RazorError("Only one 'model' statement is allowed in a file.", new RazorError("Only one 'model' statement is allowed in a file.",
new SourceLocation(18, 1, 6), 1) new SourceLocation(13, 1, 1), 5)
}; };
// Act // Act
@ -394,7 +394,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var expectedErrors = new[] var expectedErrors = new[]
{ {
new RazorError("The 'inject' keyword must be followed by a type name on the same line.", new RazorError("The 'inject' keyword must be followed by a type name on the same line.",
new SourceLocation(11, 0, 11), 1) new SourceLocation(1, 0, 1), 6)
}; };
// Act // Act
@ -427,7 +427,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var expectedErrors = new[] var expectedErrors = new[]
{ {
new RazorError("The 'inject' keyword must be followed by a type name on the same line.", new RazorError("The 'inject' keyword must be followed by a type name on the same line.",
new SourceLocation(11, 0, 11), 1) new SourceLocation(1, 0, 1), 6)
}; };
// Act // Act
@ -462,7 +462,7 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
new RazorError("A property name must be specified when using the 'inject' statement. " + new RazorError("A property name must be specified when using the 'inject' statement. " +
"Format for a 'inject' statement is '@inject <Type Name> <Property Name>'.", "Format for a 'inject' statement is '@inject <Type Name> <Property Name>'.",
new SourceLocation(20, 0, 20), 1) new SourceLocation(1, 0, 1), 21)
}; };
// Act // Act
@ -496,7 +496,7 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
new RazorError("A property name must be specified when using the 'inject' statement. " + new RazorError("A property name must be specified when using the 'inject' statement. " +
"Format for a 'inject' statement is '@inject <Type Name> <Property Name>'.", "Format for a 'inject' statement is '@inject <Type Name> <Property Name>'.",
new SourceLocation(19, 0, 19), 1) new SourceLocation(1, 0, 1), 21)
}; };
// Act // Act

View File

@ -147,7 +147,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Host.Test
}; };
var expectedErrors = new[] var expectedErrors = new[]
{ {
new RazorError("The 'model' keyword must be followed by a type name on the same line.", new SourceLocation(9, 0, 9), 1) new RazorError("The 'model' keyword must be followed by a type name on the same line.", new SourceLocation(1, 0, 1), 5)
}; };
Assert.Equal(expectedSpans, spans.ToArray()); Assert.Equal(expectedSpans, spans.ToArray());
Assert.Equal(expectedErrors, errors.ToArray()); Assert.Equal(expectedErrors, errors.ToArray());
@ -188,7 +188,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Host.Test
var expectedErrors = new[] var expectedErrors = new[]
{ {
new RazorError("Only one 'model' statement is allowed in a file.", new SourceLocation(18, 1, 6), 1) new RazorError("Only one 'model' statement is allowed in a file.", new SourceLocation(13, 1, 1), 5)
}; };
expectedSpans.Zip(spans, (exp, span) => new { expected = exp, span = span }).ToList().ForEach(i => Assert.Equal(i.expected, i.span)); expectedSpans.Zip(spans, (exp, span) => new { expected = exp, span = span }).ToList().ForEach(i => Assert.Equal(i.expected, i.span));
Assert.Equal(expectedSpans, spans.ToArray()); Assert.Equal(expectedSpans, spans.ToArray());