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

Commit

Permalink
Changes to show intellisense for @Inject directive
Browse files Browse the repository at this point in the history
  • Loading branch information
pranavkm committed Sep 17, 2014
1 parent 7f34709 commit bc7241d
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 17 deletions.
8 changes: 4 additions & 4 deletions src/Microsoft.AspNet.Mvc.Razor.Host/InjectChunkVisitor.cs
Expand Up @@ -38,10 +38,10 @@ protected override void Visit([NotNull] InjectChunk chunk)
if (Context.Host.DesignTimeMode && chunk.Association != null)
{
Writer.WriteLine("public");
var code = string.Format(CultureInfo.InvariantCulture,
"{0} {1}",
chunk.TypeName,
chunk.MemberName);

var code = string.IsNullOrEmpty(chunk.MemberName) ?
chunk.TypeName :
chunk.TypeName + ' ' + chunk.MemberName;
var csharpVisitor = new CSharpCodeVisitor(Writer, Context);
csharpVisitor.CreateExpressionCodeMapping(code, chunk);
Writer.WriteLine("{ get; private set; }");
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs
Expand Up @@ -107,7 +107,7 @@ protected virtual void InjectDirective()
var propertyStartLocation = CurrentLocation;
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true));

if (!hasTypeError && At(CSharpSymbolType.NewLine))
if (!hasTypeError && (EndOfFile || At(CSharpSymbolType.NewLine)))
{
// Add an error for the property name only if we successfully read the type name
Context.OnError(propertyStartLocation,
Expand All @@ -131,6 +131,7 @@ protected virtual void InjectDirective()
propertyName.Trim());

// Output the span and finish the block
CompleteBlock();
Output(SpanKind.Code);
}

Expand Down
58 changes: 47 additions & 11 deletions test/Microsoft.AspNet.Mvc.Razor.Host.Test/InjectChunkVisitorTest.cs
@@ -1,6 +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;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNet.Razor;
Expand Down Expand Up @@ -71,18 +72,54 @@ public void Visit_GeneratesProperties_ForInjectChunks()
public void Visit_WithDesignTimeHost_GeneratesPropertiesAndLinePragmas_ForInjectChunks()
{
// Arrange
var expected = @"[Microsoft.AspNet.Mvc.ActivateAttribute]
public
#line 1 """"
MyType1 MyPropertyName1
var expected = string.Join(Environment.NewLine,
@"[Microsoft.AspNet.Mvc.ActivateAttribute]",
@"public",
@"#line 1 """"",
@"MyType1 MyPropertyName1",
"",
@"#line default",
@"#line hidden",
@"{ get; private set; }",
@"[Microsoft.AspNet.Mvc.ActivateAttribute]",
@"public",
@"#line 1 """"",
@"MyType2 @MyPropertyName2",
"",
@"#line default",
@"#line hidden",
@"{ get; private set; }",
"");
var writer = new CSharpCodeWriter();
var context = CreateContext();
context.Host.DesignTimeMode = true;

#line default
#line hidden
{ get; private set; }
[Microsoft.AspNet.Mvc.ActivateAttribute]
var visitor = new InjectChunkVisitor(writer, context, "Microsoft.AspNet.Mvc.ActivateAttribute");
var factory = SpanFactory.CreateCsHtml();
var node = (Span)factory.Code("Some code")
.As(new InjectParameterGenerator("MyType", "MyPropertyName"));

// Act
visitor.Accept(new Chunk[]
{
new LiteralChunk(),
new InjectChunk("MyType1", "MyPropertyName1") { Association = node },
new InjectChunk("MyType2", "@MyPropertyName2") { Association = node }
});
var code = writer.GenerateCode();

// Assert
Assert.Equal(expected, code);
}

[Fact]
public void Visit_WithDesignTimeHost_GeneratesPropertiesAndLinePragmas_ForPartialInjectChunks()
{
// Arrange
var expected = @"[Microsoft.AspNet.Mvc.ActivateAttribute]
public
#line 1 """"
MyType2 @MyPropertyName2
MyType1
#line default
#line hidden
Expand All @@ -101,8 +138,7 @@ MyType2 @MyPropertyName2
visitor.Accept(new Chunk[]
{
new LiteralChunk(),
new InjectChunk("MyType1", "MyPropertyName1") { Association = node },
new InjectChunk("MyType2", "@MyPropertyName2") { Association = node }
new InjectChunk("MyType1", string.Empty) { Association = node },
});
var code = writer.GenerateCode();

Expand Down
Expand Up @@ -309,7 +309,7 @@ public void ParseInjectKeyword_ErrorOnMissingTypeName()
{
// Arrange
var errors = new List<RazorError>();
var documentContent = "@inject \r\nBar";
var documentContent = "@inject " + Environment.NewLine + "Bar";
var factory = SpanFactory.CreateCsHtml();
var expectedSpans = new Span[]
{
Expand Down Expand Up @@ -337,6 +337,37 @@ public void ParseInjectKeyword_ErrorOnMissingTypeName()
Assert.Equal(expectedErrors, errors);
}

[Fact]
public void ParseInjectKeyword_ErrorOnMissingTypeName_WhenTypeNameEndsWithEOF()
{
// Arrange
var errors = new List<RazorError>();
var documentContent = "@inject ";
var factory = SpanFactory.CreateCsHtml();
var expectedSpans = new Span[]
{
factory.EmptyHtml(),
factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
factory.MetaCode("inject ")
.Accepts(AcceptedCharacters.None),
factory.Code(" ")
.As(new InjectParameterGenerator(string.Empty, string.Empty)),
};
var expectedErrors = new[]
{
new RazorError("The 'inject' keyword must be followed by a type name on the same line.",
new SourceLocation(11, 0, 11), 1)
};

// Act
var spans = ParseDocument(documentContent, errors);

// Assert
Assert.Equal(expectedSpans, spans);
Assert.Equal(expectedErrors, errors);
}

[Fact]
public void ParseInjectKeyword_ErrorOnMissingPropertyName()
{
Expand Down Expand Up @@ -371,6 +402,38 @@ public void ParseInjectKeyword_ErrorOnMissingPropertyName()
Assert.Equal(expectedErrors, errors);
}

[Fact]
public void ParseInjectKeyword_ErrorOnMissingPropertyName_WhenTypeNameEndsWithEOF()
{
// Arrange
var errors = new List<RazorError>();
var documentContent = "@inject IMyServi";
var factory = SpanFactory.CreateCsHtml();
var expectedSpans = new Span[]
{
factory.EmptyHtml(),
factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
factory.MetaCode("inject ")
.Accepts(AcceptedCharacters.None),
factory.Code(" IMyServi")
.As(new InjectParameterGenerator("IMyServi", string.Empty)),
};
var expectedErrors = new[]
{
new RazorError("A property name must be specified when using the 'inject' statement. " +
"Format for a 'inject' statement is '@inject <Type Name> <Property Name>'.",
new SourceLocation(19, 0, 19), 1)
};

// Act
var spans = ParseDocument(documentContent, errors);

// Assert
Assert.Equal(expectedSpans, spans);
Assert.Equal(expectedErrors, errors);
}

private static List<Span> ParseDocument(string documentContents,
List<RazorError> errors = null,
List<LineMapping> lineMappings = null)
Expand Down

0 comments on commit bc7241d

Please sign in to comment.