diff --git a/Mvc.sln b/Mvc.sln
index 01b51cf2ce..4ff2f92df8 100644
--- a/Mvc.sln
+++ b/Mvc.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.22303.1
+VisualStudioVersion = 14.0.22512.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
EndProject
@@ -122,6 +122,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CustomRouteWebSite", "test\
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ResponseCacheWebSite", "test\WebSites\ResponseCacheWebSite\ResponseCacheWebSite.kproj", "{BDEEBE09-C0C4-433C-B0B8-8478C9776996}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Common.Test", "test\Microsoft.AspNet.Mvc.Common.Test\Microsoft.AspNet.Mvc.Common.Test.kproj", "{0449D6D2-BE1B-4E29-8E1B-444420802C03}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -682,6 +684,18 @@ Global
{BDEEBE09-C0C4-433C-B0B8-8478C9776996}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{BDEEBE09-C0C4-433C-B0B8-8478C9776996}.Release|x86.ActiveCfg = Release|Any CPU
{BDEEBE09-C0C4-433C-B0B8-8478C9776996}.Release|x86.Build.0 = Release|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|x86.Build.0 = Debug|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Release|x86.ActiveCfg = Release|Any CPU
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -741,5 +755,6 @@ Global
{AF210F69-9D31-43AF-AC3A-CD366E252218} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{364EC3C6-C9DB-45E0-A0F2-1EE61E4B429B} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{BDEEBE09-C0C4-433C-B0B8-8478C9776996} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
+ {0449D6D2-BE1B-4E29-8E1B-444420802C03} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
EndGlobalSection
EndGlobal
diff --git a/src/Microsoft.AspNet.Mvc.Common/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Mvc.Common/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..1f3fdbe409
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Common/Properties/AssemblyInfo.cs
@@ -0,0 +1,7 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("Microsoft.AspNet.Mvc.Common.Test")]
+[assembly: InternalsVisibleTo("Microsoft.AspNet.Mvc.Razor.Host")]
diff --git a/src/Microsoft.AspNet.Mvc.Common/StringHelper.cs b/src/Microsoft.AspNet.Mvc.Common/StringHelper.cs
new file mode 100644
index 0000000000..8f3333692b
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Common/StringHelper.cs
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+
+namespace Microsoft.AspNet.Mvc
+{
+ internal static class StringHelper
+ {
+ public static string TrimSpacesAndChars(string value, params char[] chars)
+ {
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ return string.Empty;
+ }
+
+ if (chars == null || chars.Length == 0)
+ {
+ return value.Trim();
+ }
+
+ var firstIndex = 0;
+ for (; firstIndex < value.Length; firstIndex++)
+ {
+ var currentChar = value[firstIndex];
+ if (!char.IsWhiteSpace(currentChar) && !chars.Any(compareChar => compareChar == currentChar))
+ {
+ break;
+ }
+ }
+
+ // We trimmed all the way
+ if (firstIndex == value.Length)
+ {
+ return string.Empty;
+ }
+
+ var lastIndex = value.Length - 1;
+ for (; lastIndex > firstIndex; lastIndex--)
+ {
+ var currentChar = value[lastIndex];
+ if (!char.IsWhiteSpace(currentChar) && !chars.Any(compareChar => compareChar == currentChar))
+ {
+ break;
+ }
+ }
+
+ if (firstIndex == 0 && lastIndex == value.Length - 1)
+ {
+ return value;
+ }
+ else
+ {
+ return value.Substring(firstIndex, lastIndex - firstIndex + 1);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs
index ff40c3b42f..84be0bc674 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs
@@ -127,8 +127,9 @@ namespace Microsoft.AspNet.Mvc.Razor
.Value
.Substring(typeName.Length);
- Span.CodeGenerator = new InjectParameterGenerator(typeName.Trim(),
- propertyName.Trim());
+ // ';' is optional
+ propertyName = StringHelper.TrimSpacesAndChars(propertyName, ';');
+ Span.CodeGenerator = new InjectParameterGenerator(typeName.Trim(), propertyName);
// Output the span and finish the block
CompleteBlock();
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/CopyOnWriteDictionaryTest.cs b/test/Microsoft.AspNet.Mvc.Common.Test/CopyOnWriteDictionaryTest.cs
similarity index 98%
rename from test/Microsoft.AspNet.Mvc.Core.Test/CopyOnWriteDictionaryTest.cs
rename to test/Microsoft.AspNet.Mvc.Common.Test/CopyOnWriteDictionaryTest.cs
index f1d7263235..ba6edf507f 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/CopyOnWriteDictionaryTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Common.Test/CopyOnWriteDictionaryTest.cs
@@ -3,13 +3,16 @@
using System;
using System.Collections.Generic;
+#if !ASPNETCORE50
using Moq;
+#endif
using Xunit;
-namespace Microsoft.AspNet.Mvc.Core
+namespace Microsoft.AspNet.Mvc
{
public class CopyOnWriteDictionaryTest
{
+#if !ASPNETCORE50
[Fact]
public void ReadOperation_DelegatesToSourceDictionary_IfNoMutationsArePerformed()
{
@@ -49,6 +52,7 @@ namespace Microsoft.AspNet.Mvc.Core
Assert.False(copyOnWriteDictionary.TryGetValue("different-key", out value));
sourceDictionary.Verify();
}
+#endif
[Fact]
public void ReadOperation_DoesNotDelegateToSourceDictionary_OnceAValueIsChanged()
diff --git a/test/Microsoft.AspNet.Mvc.Common.Test/Microsoft.AspNet.Mvc.Common.Test.kproj b/test/Microsoft.AspNet.Mvc.Common.Test/Microsoft.AspNet.Mvc.Common.Test.kproj
new file mode 100644
index 0000000000..fdf5b55d84
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Common.Test/Microsoft.AspNet.Mvc.Common.Test.kproj
@@ -0,0 +1,17 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 0449d6d2-be1b-4e29-8e1b-444420802c03
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/PropertyHelperTest.cs b/test/Microsoft.AspNet.Mvc.Common.Test/PropertyHelperTest.cs
similarity index 96%
rename from test/Microsoft.AspNet.Mvc.Core.Test/PropertyHelperTest.cs
rename to test/Microsoft.AspNet.Mvc.Common.Test/PropertyHelperTest.cs
index d52bc1e54d..3c47b7a3b3 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/PropertyHelperTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Common.Test/PropertyHelperTest.cs
@@ -16,10 +16,10 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var anonymous = new { foo = "bar" };
- PropertyInfo property = anonymous.GetType().GetProperties().First();
+ var property = PropertyHelper.GetProperties(anonymous.GetType()).First().Property;
// Act
- PropertyHelper helper = new PropertyHelper(property);
+ var helper = new PropertyHelper(property);
// Assert
Assert.Equal("foo", property.Name);
@@ -31,10 +31,10 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var anonymous = new { bar = "baz" };
- PropertyInfo property = anonymous.GetType().GetProperties().First();
+ var property = PropertyHelper.GetProperties(anonymous.GetType()).First().Property;
// Act
- PropertyHelper helper = new PropertyHelper(property);
+ var helper = new PropertyHelper(property);
// Assert
Assert.Equal("bar", helper.Name);
@@ -46,7 +46,7 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var anonymous = new { foo = 32 };
- var property = anonymous.GetType().GetProperties().First();
+ var property = PropertyHelper.GetProperties(anonymous.GetType()).First().Property;
// Act
var helper = new PropertyHelper(property);
diff --git a/test/Microsoft.AspNet.Mvc.Common.Test/StringHelperTest.cs b/test/Microsoft.AspNet.Mvc.Common.Test/StringHelperTest.cs
new file mode 100644
index 0000000000..9657f99606
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Common.Test/StringHelperTest.cs
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc
+{
+ public class StringHelperTest
+ {
+ public static TheoryData TrimSpacesAndCharsData
+ {
+ get
+ {
+ // input, trimCharacters, expectedOutput
+ return new TheoryData
+ {
+ { "abcd", new char[] { }, "abcd" },
+ { " /.", new char[] { '/', '.' }, string.Empty },
+ { string.Empty, new char[] { }, string.Empty },
+ { " ", new char[] { }, string.Empty },
+ { " ", new char[] { }, string.Empty },
+ { " / ", new char[] { '/' }, string.Empty },
+ { " \t ", new char[] { '/' }, string.Empty },
+ { " ", new char[] { '/' }, string.Empty },
+ { " ", new char[] { '/' }, string.Empty },
+ { "/", new char[] { '/' }, string.Empty },
+ { "//", new char[] { '/' }, string.Empty },
+ { "// ", new char[] { '/' }, string.Empty },
+ { "/ ", new char[] { '/' }, string.Empty },
+ { " a ", new char[] { }, "a" },
+ { " a", new char[] { }, "a" },
+ { "a ", new char[] { }, "a" },
+ { " a ", new char[] { }, "a" },
+ { " a \n\r", new char[] { }, "a" },
+ { "\t\r a ", new char[] { }, "a" },
+ { "\ta ", new char[] { }, "a" },
+ { " a a ", new char[] { }, "a a" },
+ { " a ", new char[] { '/' }, "a" },
+ { " a", new char[] { '/' }, "a" },
+ { "a ", new char[] { '/' }, "a" },
+ { " a ", new char[] { '/' }, "a" },
+ { " a \n\r", new char[] { '/' }, "a" },
+ { "\t\r a ", new char[] { '/' }, "a" },
+ { "\ta ", new char[] { '/' }, "a" },
+ { " a a ", new char[] { '/' }, "a a" },
+ { " a ", new char[] { '/', ' ' }, "a" },
+ { " a", new char[] { '/', ' ' }, "a" },
+ { "a ", new char[] { '/', ' ' }, "a" },
+ { " a ", new char[] { '/', ' ' }, "a" },
+ { " a \n\r", new char[] { '/', ' ' }, "a" },
+ { "\t\r a ", new char[] { '/', ' ' }, "a" },
+ { "\ta ", new char[] { '/', ' ' }, "a" },
+ { " a a ", new char[] { '/', ' ' }, "a a" },
+ { "/ a ", new char[] { '/' }, "a" },
+ { " / a", new char[] { '/' }, "a" },
+ { "a / /", new char[] { '/' }, "a" },
+ { " a // //", new char[] { '/' }, "a" },
+ { " a \n\r//", new char[] { '/' }, "a" },
+ { "////\t\r a ", new char[] { '/' }, "a" },
+ { "\ta /", new char[] { '/' }, "a" },
+ { " a/ a ", new char[] { '/' }, "a/ a" },
+ { "/ a ", new char[] { '/', ' ' }, "a" },
+ { " / a", new char[] { '/', ' ' }, "a" },
+ { "a / /", new char[] { '/', ' ' }, "a" },
+ { " a // //", new char[] { '/', ' ' }, "a" },
+ { " a \n\r//", new char[] { '/', ' ' }, "a" },
+ { "////\t\r a ", new char[] { '/', ' ' }, "a" },
+ { "\ta /", new char[] { '/', ' ' }, "a" },
+ { " a/ a ", new char[] { '/', ' ' }, "a/ a" },
+ { " a /.", new char[] { '/', '.' }, "a" },
+ { " a", new char[] { '/', '.' }, "a" },
+ { "/. ./a ", new char[] { '/', '.' }, "a" },
+ { " a ", new char[] { '/', '.' }, "a" },
+ { " a \n\r", new char[] { '/', '.' }, "a" },
+ { "\t\r a ", new char[] { '/', '.' }, "a" },
+ { "\ta ", new char[] { '/', '.' }, "a" },
+ { "///..a/./a /. ./....", new char[] { '/', '.' }, "a/./a" },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(TrimSpacesAndCharsData))]
+ public void TrimSpacesAndChars_GeneratesExpectedOutput(
+ string input,
+ char[] trimCharacters,
+ string expectedOutput)
+ {
+ // Arrange & Act
+ var output = StringHelper.TrimSpacesAndChars(input, trimCharacters);
+
+ // Assert
+ Assert.Equal(expectedOutput, output, StringComparer.Ordinal);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Internal/TaskHelperTest.cs b/test/Microsoft.AspNet.Mvc.Common.Test/TaskHelperTest.cs
similarity index 97%
rename from test/Microsoft.AspNet.Mvc.Core.Test/Internal/TaskHelperTest.cs
rename to test/Microsoft.AspNet.Mvc.Common.Test/TaskHelperTest.cs
index 346d3dd8e7..d3d3b752a5 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Internal/TaskHelperTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Common.Test/TaskHelperTest.cs
@@ -5,7 +5,7 @@ using System;
using System.Threading.Tasks;
using Xunit;
-namespace Microsoft.AspNet.Mvc.Internal
+namespace Microsoft.AspNet.Mvc
{
public class TaskHelperTest
{
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Internal/TypeExtensionTests.cs b/test/Microsoft.AspNet.Mvc.Common.Test/TypeExtensionsTest.cs
similarity index 98%
rename from test/Microsoft.AspNet.Mvc.ModelBinding.Test/Internal/TypeExtensionTests.cs
rename to test/Microsoft.AspNet.Mvc.Common.Test/TypeExtensionsTest.cs
index fd366867ed..ab81f6bf8c 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Internal/TypeExtensionTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Common.Test/TypeExtensionsTest.cs
@@ -7,7 +7,7 @@ using Xunit;
namespace Microsoft.AspNet.Mvc
{
- public class TypeExtensionTests
+ public class TypeExtensionsTest
{
[Theory]
[InlineData(typeof(decimal))]
diff --git a/test/Microsoft.AspNet.Mvc.Common.Test/project.json b/test/Microsoft.AspNet.Mvc.Common.Test/project.json
new file mode 100644
index 0000000000..8e005b0732
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Common.Test/project.json
@@ -0,0 +1,21 @@
+{
+ "compilationOptions": {
+ "warningsAsErrors": "true"
+ },
+ "dependencies": {
+ "Microsoft.AspNet.Mvc.Common": "6.0.0-*",
+ "xunit.runner.kre": "1.0.0-*",
+ "Microsoft.AspNet.Testing": "1.0.0-*"
+ },
+ "commands": {
+ "test": "xunit.runner.kre"
+ },
+ "frameworks": {
+ "aspnet50": {
+ "dependencies": {
+ "Moq": "4.2.1312.1622"
+ }
+ },
+ "aspnetcore50": { }
+ }
+}
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcCSharpRazorCodeParserTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcCSharpRazorCodeParserTest.cs
index b1182cae34..7697e2cc56 100644
--- a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcCSharpRazorCodeParserTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcCSharpRazorCodeParserTest.cs
@@ -272,6 +272,50 @@ namespace Microsoft.AspNet.Mvc.Razor
Assert.Empty(errors);
}
+ [Theory]
+ [InlineData("IMyService Service;", "IMyService", "Service")]
+ [InlineData("IMyService Service;;", "IMyService", "Service")]
+ [InlineData(" Microsoft.AspNet.Mvc.IHtmlHelper MyHelper; ",
+ "Microsoft.AspNet.Mvc.IHtmlHelper", "MyHelper")]
+ [InlineData(" Microsoft.AspNet.Mvc.IHtmlHelper MyHelper; ; ",
+ "Microsoft.AspNet.Mvc.IHtmlHelper", "MyHelper")]
+ [InlineData(" TestService @class; ; ", "TestService", "@class")]
+ [InlineData("IMyService Service ;", "IMyService", "Service")]
+ [InlineData("IMyService Service ; ;", "IMyService", "Service")]
+ [InlineData(" Microsoft.AspNet.Mvc.IHtmlHelper MyHelper ; ",
+ "Microsoft.AspNet.Mvc.IHtmlHelper", "MyHelper")]
+ [InlineData(" Microsoft.AspNet.Mvc.IHtmlHelper MyHelper ; ; ",
+ "Microsoft.AspNet.Mvc.IHtmlHelper", "MyHelper")]
+ [InlineData(" TestService @class ; ", "TestService", "@class")]
+ [InlineData(" TestService @class ; ; ", "TestService", "@class")]
+ public void ParseInjectKeyword_AllowsOptionalTrailingSemicolon(
+ string injectStatement,
+ string expectedService,
+ string expectedPropertyName)
+ {
+ // Arrange
+ var documentContent = "@inject " + injectStatement;
+ var factory = SpanFactory.CreateCsHtml();
+ var errors = new List();
+ var expectedSpans = new Span[]
+ {
+ factory.EmptyHtml(),
+ factory.CodeTransition(SyntaxConstants.TransitionString)
+ .Accepts(AcceptedCharacters.None),
+ factory.MetaCode("inject ")
+ .Accepts(AcceptedCharacters.None),
+ factory.Code(injectStatement)
+ .As(new InjectParameterGenerator(expectedService, expectedPropertyName))
+ };
+
+ // Act
+ var spans = ParseDocument(documentContent, errors);
+
+ // Assert
+ Assert.Equal(expectedSpans, spans);
+ Assert.Empty(errors);
+ }
+
[Theory]
[InlineData("IMyService Service ", "IMyService", "Service")]
[InlineData(" TestService @namespace ", "TestService", "@namespace")]
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcRazorHostTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcRazorHostTest.cs
index 792c50083e..ef6972ceb4 100644
--- a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcRazorHostTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/MvcRazorHostTest.cs
@@ -79,6 +79,7 @@ namespace Microsoft.AspNet.Mvc.Razor
[InlineData("Basic")]
[InlineData("Inject")]
[InlineData("InjectWithModel")]
+ [InlineData("InjectWithSemicolon")]
[InlineData("Model")]
[InlineData("ModelExpressionTagHelper")]
public void MvcRazorHost_ParsesAndGeneratesCodeForBasicScenarios(string scenarioName)
@@ -129,6 +130,28 @@ namespace Microsoft.AspNet.Mvc.Razor
RunDesignTimeTest(host, "InjectWithModel", expectedLineMappings);
}
+ [Fact]
+ public void InjectVisitorWithSemicolon_GeneratesCorrectLineMappings()
+ {
+ // Arrange
+ var host = new MvcRazorHost(new TestFileProvider())
+ {
+ DesignTimeMode = true
+ };
+ host.NamespaceImports.Clear();
+ var expectedLineMappings = new[]
+ {
+ BuildLineMapping(7, 0, 7, 222, 6, 7, 7),
+ BuildLineMapping(24, 1, 8, 729, 26, 8, 20),
+ BuildLineMapping(58, 2, 8, 941, 34, 8, 23),
+ BuildLineMapping(93, 3, 8, 1156, 42, 8, 21),
+ BuildLineMapping(129, 4, 8, 1369, 50, 8, 24),
+ };
+
+ // Act and Assert
+ RunDesignTimeTest(host, "InjectWithSemicolon", expectedLineMappings);
+ }
+
[Fact]
public void ModelVisitor_GeneratesCorrectLineMappings()
{
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Input/InjectWithSemicolon.cshtml b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Input/InjectWithSemicolon.cshtml
new file mode 100644
index 0000000000..d840486787
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Input/InjectWithSemicolon.cshtml
@@ -0,0 +1,5 @@
+@model MyModel
+@inject MyApp MyPropertyName;
+@inject MyService Html;
+@inject MyApp MyPropertyName2 ;
+@inject MyService Html2 ;
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithSemicolon.cs b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithSemicolon.cs
new file mode 100644
index 0000000000..76df5b3879
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithSemicolon.cs
@@ -0,0 +1,69 @@
+namespace Asp
+{
+ using System.Threading.Tasks;
+
+ public class ASPV_TestFiles_Input_InjectWithSemicolon_cshtml : Microsoft.AspNet.Mvc.Razor.RazorPage<
+#line 1 "TestFiles/Input/InjectWithSemicolon.cshtml"
+ MyModel
+
+#line default
+#line hidden
+ >
+ {
+ private static object @__o;
+ private void @__RazorDesignTimeHelpers__()
+ {
+ #pragma warning disable 219
+ #pragma warning restore 219
+ }
+ #line hidden
+ public ASPV_TestFiles_Input_InjectWithSemicolon_cshtml()
+ {
+ }
+ #line hidden
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public
+#line 2 "TestFiles/Input/InjectWithSemicolon.cshtml"
+ MyApp MyPropertyName
+
+#line default
+#line hidden
+ { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public
+#line 3 "TestFiles/Input/InjectWithSemicolon.cshtml"
+ MyService Html
+
+#line default
+#line hidden
+ { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public
+#line 4 "TestFiles/Input/InjectWithSemicolon.cshtml"
+ MyApp MyPropertyName2
+
+#line default
+#line hidden
+ { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public
+#line 5 "TestFiles/Input/InjectWithSemicolon.cshtml"
+ MyService Html2
+
+#line default
+#line hidden
+ { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
+
+ #line hidden
+
+ #pragma warning disable 1998
+ public override async Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithSemicolon.cs b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithSemicolon.cs
new file mode 100644
index 0000000000..651cc1140f
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithSemicolon.cs
@@ -0,0 +1,45 @@
+#pragma checksum "TestFiles/Input/InjectWithSemicolon.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "b753615982659a9805e6213ceced76ba06782038"
+namespace Asp
+{
+ using System;
+ using System.Linq;
+ using System.Collections.Generic;
+ using Microsoft.AspNet.Mvc;
+ using Microsoft.AspNet.Mvc.Rendering;
+ using System.Threading.Tasks;
+
+ public class ASPV_TestFiles_Input_InjectWithSemicolon_cshtml : Microsoft.AspNet.Mvc.Razor.RazorPage<
+#line 1 "TestFiles/Input/InjectWithSemicolon.cshtml"
+ MyModel
+
+#line default
+#line hidden
+ >
+ {
+ #line hidden
+ public ASPV_TestFiles_Input_InjectWithSemicolon_cshtml()
+ {
+ }
+ #line hidden
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public MyApp MyPropertyName { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public MyService Html { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public MyApp MyPropertyName2 { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public MyService Html2 { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
+ [Microsoft.AspNet.Mvc.ActivateAttribute]
+ public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
+
+ #line hidden
+
+ #pragma warning disable 1998
+ public override async Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}