Addressed code review comments.

This commit is contained in:
N. Taylor Mullen 2015-05-28 15:15:02 -07:00
parent 6df8bc23f1
commit ed92b6992d
79 changed files with 366 additions and 212 deletions

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
#if NET45
@ -36,7 +36,11 @@ namespace Microsoft.AspNet.Razor
/// <summary>
/// Constructs a new instance of the chunk generator for this language with the specified settings
/// </summary>
public override RazorChunkGenerator CreateChunkGenerator(string className, string rootNamespaceName, string sourceFileName, RazorEngineHost host)
public override RazorChunkGenerator CreateChunkGenerator(
string className,
string rootNamespaceName,
string sourceFileName,
RazorEngineHost host)
{
return new RazorChunkGenerator(className, rootNamespaceName, sourceFileName, host);
}

View File

@ -8,13 +8,13 @@ namespace Microsoft.AspNet.Razor.Chunks
{
public class ChunkTreeBuilder
{
private readonly Stack<ParentChunk> _parentChain;
private readonly Stack<ParentChunk> _parentStack;
private Chunk _lastChunk;
public ChunkTreeBuilder()
{
ChunkTree = new ChunkTree();
_parentChain = new Stack<ParentChunk>();
_parentStack = new Stack<ParentChunk>();
}
public ChunkTree ChunkTree { get; private set; }
@ -27,13 +27,13 @@ namespace Microsoft.AspNet.Razor.Chunks
chunk.Association = association;
// If we're not in the middle of a chunk block
if (_parentChain.Count == 0 || topLevel == true)
if (_parentStack.Count == 0 || topLevel == true)
{
ChunkTree.Chunks.Add(chunk);
}
else
{
_parentChain.Peek().Children.Add(chunk);
_parentStack.Peek().Children.Add(chunk);
}
}
@ -164,14 +164,14 @@ namespace Microsoft.AspNet.Razor.Chunks
{
AddChunk(parentChunk, association, topLevel);
_parentChain.Push(parentChunk);
_parentStack.Push(parentChunk);
return parentChunk;
}
public void EndParentChunk()
{
_lastChunk = _parentChain.Pop();
_lastChunk = _parentStack.Pop();
}
}
}

View File

@ -33,11 +33,11 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
public string SourceFile { get; internal set; }
public string RootNamespace { get; private set; }
public string RootNamespace { get; }
public string ClassName { get; private set; }
public string ClassName { get; }
public RazorEngineHost Host { get; private set; }
public RazorEngineHost Host { get; }
public ChunkTreeBuilder ChunkTreeBuilder { get; set; }
}

View File

@ -5,21 +5,21 @@ using Microsoft.AspNet.Razor.Parser.SyntaxTree;
namespace Microsoft.AspNet.Razor.Chunks.Generators
{
public class ExpressionChunkGenerator : HybridChunkGenerator
public class ExpressionChunkGenerator : ISpanChunkGenerator, IParentChunkGenerator
{
private static readonly int TypeHashCode = typeof(ExpressionChunkGenerator).GetHashCode();
public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
public void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
{
context.ChunkTreeBuilder.StartParentChunk<ExpressionBlockChunk>(target);
}
public override void GenerateChunk(Span target, ChunkGeneratorContext context)
public void GenerateChunk(Span target, ChunkGeneratorContext context)
{
context.ChunkTreeBuilder.AddExpressionChunk(target.Content, target);
}
public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context)
public void GenerateEndParentChunk(Block target, ChunkGeneratorContext context)
{
context.ChunkTreeBuilder.EndParentChunk();
}

View File

@ -1,22 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
namespace Microsoft.AspNet.Razor.Chunks.Generators
{
public abstract class HybridChunkGenerator : ISpanChunkGenerator, IParentChunkGenerator
{
public virtual void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
{
}
public virtual void GenerateEndParentChunk(Block target, ChunkGeneratorContext context)
{
}
public virtual void GenerateChunk(Span target, ChunkGeneratorContext context)
{
}
}
}

View File

@ -10,7 +10,9 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
{
public class LiteralAttributeChunkGenerator : SpanChunkGenerator
{
public LiteralAttributeChunkGenerator(LocationTagged<string> prefix, LocationTagged<SpanChunkGenerator> valueGenerator)
public LiteralAttributeChunkGenerator(
LocationTagged<string> prefix,
LocationTagged<SpanChunkGenerator> valueGenerator)
{
Prefix = prefix;
ValueGenerator = valueGenerator;

View File

@ -10,7 +10,10 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
{
private static readonly int TypeHashCode = typeof(ParentChunkGenerator).GetHashCode();
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "This class has no instance state")]
[SuppressMessage(
"Microsoft.Security",
"CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
Justification = "This class has no instance state")]
public static readonly IParentChunkGenerator Null = new NullParentChunkGenerator();
public virtual void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)

View File

@ -10,7 +10,10 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
{
private static readonly int TypeHashCode = typeof(SpanChunkGenerator).GetHashCode();
[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "This class has no instance state")]
[SuppressMessage(
"Microsoft.Security",
"CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
Justification = "This class has no instance state")]
public static readonly ISpanChunkGenerator Null = new NullSpanChunkGenerator();
public virtual void GenerateChunk(Span target, ChunkGeneratorContext context)

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Parser.TagHelpers;
@ -40,11 +41,9 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
{
var tagHelperBlock = target as TagHelperBlock;
if (tagHelperBlock == null)
{
throw new ArgumentException(
RazorResources.TagHelpers_TagHelperCodeGeneartorMustBeAssociatedWithATagHelperBlock);
}
Debug.Assert(
tagHelperBlock != null,
$"A {nameof(TagHelperChunkGenerator)} must only be used with {nameof(TagHelperBlock)}s.");
var attributes = new List<KeyValuePair<string, Chunk>>();
@ -60,7 +59,7 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
if (attribute.Value != null)
{
// Populates the code tree with chunks associated with attributes
// Populates the chunk tree with chunks associated with attributes
attribute.Value.Accept(chunkGenerator);
var chunks = chunkGenerator.Context.ChunkTreeBuilder.ChunkTree.Chunks;
@ -76,7 +75,7 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
attributes.Add(new KeyValuePair<string, Chunk>(attribute.Key, attributeChunkValue));
// Reset the code tree builder so we can build a new one for the next attribute
// Reset the chunk tree builder so we can build a new one for the next attribute
chunkGenerator.Context.ChunkTreeBuilder = new ChunkTreeBuilder();
}

View File

@ -5,10 +5,10 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.CodeGeneration.Visitors;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CSharpCodeGenerator : CodeGenerator
{

View File

@ -10,7 +10,7 @@ using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Text;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CSharpCodeWriter : CodeWriter
{
@ -464,7 +464,10 @@ namespace Microsoft.AspNet.Razor.CodeGeneration
Write("\"");
}
public void WriteStartInstrumentationContext(ChunkGeneratorContext context, SyntaxTreeNode syntaxNode, bool isLiteral)
public void WriteStartInstrumentationContext(
ChunkGeneratorContext context,
SyntaxTreeNode syntaxNode,
bool isLiteral)
{
WriteStartMethodInvocation(context.Host.GeneratedClassContext.BeginContextMethodName);
Write(syntaxNode.Start.AbsoluteIndex.ToString(CultureInfo.InvariantCulture));

View File

@ -4,7 +4,7 @@
using System;
using System.Linq;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public struct CSharpCodeWritingScope : IDisposable
{

View File

@ -3,7 +3,7 @@
using System;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public struct CSharpDisableWarningScope : IDisposable
{

View File

@ -4,7 +4,7 @@
using System;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CSharpLineMappingWriter : IDisposable
{

View File

@ -6,7 +6,7 @@ using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CSharpPaddingBuilder
{

View File

@ -6,11 +6,11 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.CodeGeneration.Visitors;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
/// <summary>
/// Renders tag helper rendering code.

View File

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public abstract class CodeGenerator
{

View File

@ -3,7 +3,7 @@
using Microsoft.AspNet.Razor.Chunks.Generators;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
/// <summary>
/// Context object with information used to generate a Razor page.
@ -26,12 +26,13 @@ namespace Microsoft.AspNet.Razor.CodeGeneration
}
// Internal for testing.
internal CodeGeneratorContext(RazorEngineHost host,
string className,
string rootNamespace,
string sourceFile,
bool shouldGenerateLinePragmas,
ErrorSink errorSink)
internal CodeGeneratorContext(
RazorEngineHost host,
string className,
string rootNamespace,
string sourceFile,
bool shouldGenerateLinePragmas,
ErrorSink errorSink)
: base(host, className, rootNamespace, sourceFile, shouldGenerateLinePragmas)
{
ErrorSink = errorSink;

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CodeGeneratorResult
{

View File

@ -4,7 +4,7 @@
using System;
using System.IO;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CodeWriter : IDisposable
{

View File

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public enum ExpressionRenderingMode
{

View File

@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis;
using Microsoft.Framework.Internal;
using Microsoft.Internal.Web.Utils;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public struct GeneratedClassContext
{

View File

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
/// <summary>
/// Contains necessary information for the tag helper code generation process.

View File

@ -3,12 +3,11 @@
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor
namespace Microsoft.AspNet.Razor.CodeGenerators
{
/// <summary>
/// The results of parsing and generating code for a Razor document.

View File

@ -4,7 +4,7 @@
using System.Globalization;
using Microsoft.Internal.Web.Utils;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class LineMapping
{

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class LineMappingManager
{

View File

@ -4,7 +4,7 @@
using System.Globalization;
using Microsoft.Internal.Web.Utils;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class MappingLocation
{

View File

@ -5,7 +5,7 @@ using System;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
/// <summary>
/// Renders code for tag helper property initialization.
@ -20,8 +20,8 @@ namespace Microsoft.AspNet.Razor.CodeGeneration
/// The <see cref="TagHelperAttributeDescriptor"/> to generate code for.
/// </param>
/// <param name="writer">The <see cref="CSharpCodeWriter"/> that's used to write code.</param>
/// <param name="context">A <see cref="Chunks.Generators.ChunkGeneratorContext"/> instance that contains information about
/// the current code generation process.</param>
/// <param name="context">A <see cref="Chunks.Generators.ChunkGeneratorContext"/> instance that contains
/// information about the current code generation process.</param>
/// <param name="renderAttributeValue">
/// <see cref="Action"/> that renders the raw value of the HTML attribute.
/// </param>

View File

@ -4,7 +4,7 @@
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public class CSharpBaseTypeVisitor : CodeVisitor<CSharpCodeWriter>
{

View File

@ -7,7 +7,7 @@ using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public class CSharpCodeVisitor : CodeVisitor<CSharpCodeWriter>
{

View File

@ -6,7 +6,7 @@ using System.Globalization;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public class CSharpDesignTimeHelpersVisitor : CodeVisitor<CSharpCodeWriter>
{

View File

@ -6,7 +6,7 @@ using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
/// <summary>
/// <see cref="CodeVisitor{CSharpCodeWriter}"/> that writes code for a non-<see langword="string"/> tag helper
@ -98,7 +98,7 @@ namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
/// <param name="chunk">The <see cref="ResolveUrlChunk"/> to render.</param>
/// <remarks>
/// Allowed to support future C# extensions. Likely "~/..." will lead to a C# compilation error but that is up
/// to the .
/// to the compiler.
/// </remarks>
protected override void Visit(ResolveUrlChunk chunk)
{

View File

@ -6,7 +6,7 @@ using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public class CSharpTagHelperFieldDeclarationVisitor : CodeVisitor<CSharpCodeWriter>
{

View File

@ -4,7 +4,7 @@
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
/// <summary>
/// The <see cref="CodeVisitor{T}"/> that generates the code to initialize the TagHelperRunner.

View File

@ -4,7 +4,7 @@
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public class CSharpTypeMemberVisitor : CodeVisitor<CSharpCodeWriter>
{

View File

@ -7,7 +7,7 @@ using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public class CSharpUsingVisitor : CodeVisitor<CSharpCodeWriter>
{

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public abstract class ChunkVisitor<TWriter> : IChunkVisitor
where TWriter : CodeWriter

View File

@ -4,7 +4,7 @@
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public class CodeVisitor<TWriter> : ChunkVisitor<TWriter>
where TWriter : CodeWriter

View File

@ -4,7 +4,7 @@
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks;
namespace Microsoft.AspNet.Razor.CodeGeneration.Visitors
namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
{
public interface IChunkVisitor
{

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Text;
namespace Microsoft.AspNet.Razor

View File

@ -9,6 +9,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Text;
using Microsoft.AspNet.Razor.Utils;

View File

@ -222,7 +222,9 @@ namespace Microsoft.AspNet.Razor.Parser
protected void InheritsDirectiveCore()
{
BaseTypeDirective(RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, baseType => new SetBaseTypeChunkGenerator(baseType));
BaseTypeDirective(
RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName,
baseType => new SetBaseTypeChunkGenerator(baseType));
}
protected void BaseTypeDirective(string noTypeNameError, Func<string, SpanChunkGenerator> createChunkGenerator)

View File

@ -334,7 +334,10 @@ namespace Microsoft.AspNet.Razor.Parser
using (PushSpanConfig(span =>
{
span.EditHandler = new ImplicitExpressionEditHandler(Language.TokenizeString, Keywords, acceptTrailingDot: IsNested);
span.EditHandler = new ImplicitExpressionEditHandler(
Language.TokenizeString,
Keywords,
acceptTrailingDot: IsNested);
span.EditHandler.AcceptedCharacters = acceptedCharacters;
span.ChunkGenerator = new ExpressionChunkGenerator();
}))

View File

@ -635,17 +635,20 @@ namespace Microsoft.AspNet.Razor.Parser
Accept(prefix);
// Literal value
// 'quote' should be "Unknown" if not quoted and symbols coming from the tokenizer should never have "Unknown" type.
// 'quote' should be "Unknown" if not quoted and symbols coming from the tokenizer should never have
// "Unknown" type.
var value = ReadWhile(sym =>
// These three conditions find separators which break the attribute value into portions
sym.Type != HtmlSymbolType.WhiteSpace &&
sym.Type != HtmlSymbolType.NewLine &&
sym.Type != HtmlSymbolType.Transition &&
// This condition checks for the end of the attribute value (it repeats some of the checks above
// but for now that's ok)
!IsEndOfAttributeValue(quote, sym));
// These three conditions find separators which break the attribute value into portions
sym.Type != HtmlSymbolType.WhiteSpace &&
sym.Type != HtmlSymbolType.NewLine &&
sym.Type != HtmlSymbolType.Transition &&
// This condition checks for the end of the attribute value (it repeats some of the checks above
// but for now that's ok)
!IsEndOfAttributeValue(quote, sym));
Accept(value);
Span.ChunkGenerator = new LiteralAttributeChunkGenerator(prefix.GetContent(prefixStart), value.GetContent(prefixStart));
Span.ChunkGenerator = new LiteralAttributeChunkGenerator(
prefix.GetContent(prefixStart),
value.GetContent(prefixStart));
}
Output(SpanKind.Markup);
}

View File

@ -45,7 +45,11 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
Children = contents;
}
[SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "Type is the most appropriate name for this property and there is little chance of confusion with GetType")]
[SuppressMessage(
"Microsoft.Naming",
"CA1721:PropertyNamesShouldNotMatchGetMethods",
Justification = "Type is the most appropriate name for this property and there is little chance of " +
"confusion with GetType")]
public BlockType Type { get; }
public IEnumerable<SyntaxTreeNode> Children { get; }
@ -105,7 +109,13 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
public override string ToString()
{
return string.Format(CultureInfo.CurrentCulture, "{0} Block at {1}::{2} (Gen:{3})", Type, Start, Length, ChunkGenerator);
return string.Format(
CultureInfo.CurrentCulture,
"{0} Block at {1}::{2} (Gen:{3})",
Type,
Start,
Length,
ChunkGenerator);
}
public override bool Equals(object obj)

View File

@ -21,7 +21,11 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
ChunkGenerator = original.ChunkGenerator;
}
[SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "Type is the most appropriate name for this property and there is little chance of confusion with GetType")]
[SuppressMessage(
"Microsoft.Naming",
"CA1721:PropertyNamesShouldNotMatchGetMethods",
Justification = "Type is the most appropriate name for this property and there is little chance of " +
"confusion with GetType")]
public BlockType? Type { get; set; }
public IList<SyntaxTreeNode> Children { get; private set; }
public IParentChunkGenerator ChunkGenerator { get; set; }

View File

@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
namespace Microsoft.AspNet.Razor
@ -14,7 +14,8 @@ namespace Microsoft.AspNet.Razor
/// </summary>
public abstract class RazorCodeLanguage
{
private static IDictionary<string, RazorCodeLanguage> _services = new Dictionary<string, RazorCodeLanguage>(StringComparer.OrdinalIgnoreCase)
private static IDictionary<string, RazorCodeLanguage> _services =
new Dictionary<string, RazorCodeLanguage>(StringComparer.OrdinalIgnoreCase)
{
{ "cshtml", new CSharpRazorCodeLanguage() }
};
@ -52,7 +53,11 @@ namespace Microsoft.AspNet.Razor
/// <summary>
/// Constructs the chunk generator. Must return a new instance on EVERY call to ensure thread-safety
/// </summary>
public abstract RazorChunkGenerator CreateChunkGenerator(string className, string rootNamespaceName, string sourceFileName, RazorEngineHost host);
public abstract RazorChunkGenerator CreateChunkGenerator(
string className,
string rootNamespaceName,
string sourceFileName,
RazorEngineHost host);
public abstract CodeGenerator CreateCodeGenerator(CodeGeneratorContext chunkGeneratorContext);
}

View File

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Framework.Internal;
@ -36,7 +36,10 @@ namespace Microsoft.AspNet.Razor
private int _tabSize = 4;
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The code path is safe, it is a property setter and not dependent on other state")]
[SuppressMessage(
"Microsoft.Usage",
"CA2214:DoNotCallOverridableMethodsInConstructors",
Justification = "The code path is safe, it is a property setter and not dependent on other state")]
protected RazorEngineHost()
{
GeneratedClassContext = GeneratedClassContext.Default;

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
@ -375,9 +375,6 @@ Instead, wrap the contents of the block in "{{}}":
<data name="TagHelpers_CannotHaveCSharpInTagDeclaration" xml:space="preserve">
<value>The tag helper '{0}' must not have C# in the element's attribute declaration area.</value>
</data>
<data name="TagHelpers_TagHelperCodeGeneartorMustBeAssociatedWithATagHelperBlock" xml:space="preserve">
<value>A TagHelperChunkGenerator must only be used with TagHelperBlocks.</value>
</data>
<data name="ParseError_DirectiveMustHaveValue" xml:space="preserve">
<value>Directive '{0}' must have a value.</value>
</data>

View File

@ -8,7 +8,7 @@ using System.Security.Cryptography;
using System.Text;
using System.Threading;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Text;
using Microsoft.Framework.Internal;

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
using Xunit;

View File

@ -7,7 +7,7 @@ using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Test.Framework;
using Xunit;
namespace Microsoft.AspNet.Razor.Chunks
namespace Microsoft.AspNet.Razor.Chunks.Generators
{
public class ChunkTreeBuilderTest
{

View File

@ -2,13 +2,13 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if !DNXCORE50
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGeneration.Visitors;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Moq;
using Moq.Protected;
using Xunit;
namespace Microsoft.AspNet.Razor.Chunks
namespace Microsoft.AspNet.Razor.Chunks.Generators
{
public class ChunkVisitorTests
{

View File

@ -9,7 +9,7 @@ using Microsoft.AspNet.Razor.Test.Utils;
using Moq;
using Xunit;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CSharpCodeGeneratorTest
{

View File

@ -3,7 +3,7 @@
using Xunit;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CSharpCodeWriterTest
{

View File

@ -4,7 +4,7 @@
using System;
using Xunit;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CSharpLineMappingWriterTest
{

View File

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Xunit;

View File

@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Xunit;
@ -33,13 +33,17 @@ namespace Microsoft.AspNet.Razor.Test.Generator
[Fact]
public void ConstructorRequiresNonNullClassName()
{
Assert.Throws<ArgumentException>("className", () => new RazorChunkGenerator(null, TestRootNamespaceName, TestPhysicalPath, CreateHost()));
Assert.Throws<ArgumentException>(
"className",
() => new RazorChunkGenerator(null, TestRootNamespaceName, TestPhysicalPath, CreateHost()));
}
[Fact]
public void ConstructorRequiresNonEmptyClassName()
{
Assert.Throws<ArgumentException>("className", () => new RazorChunkGenerator(string.Empty, TestRootNamespaceName, TestPhysicalPath, CreateHost()));
Assert.Throws<ArgumentException>(
"className",
() => new RazorChunkGenerator(string.Empty, TestRootNamespaceName, TestPhysicalPath, CreateHost()));
}
[Fact]

View File

@ -6,7 +6,7 @@ using System.Linq;
#if DNXCORE50
using System.Reflection;
#endif
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;

View File

@ -1,8 +1,8 @@
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGeneration.Visitors;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;

View File

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
namespace Microsoft.AspNet.Razor.Test.Generator
{

View File

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
namespace Microsoft.AspNet.Razor.Test.Generator
{

View File

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using Xunit;
namespace Microsoft.AspNet.Razor.CodeGeneration
namespace Microsoft.AspNet.Razor.CodeGenerators
{
public class CodeWriterTest
{

View File

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Xunit;
namespace Microsoft.AspNet.Razor.Test.Generator

View File

@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Test.Utils;
using Microsoft.AspNet.Testing;
using Xunit;
@ -127,7 +127,9 @@ namespace Microsoft.AspNet.Razor.Test.Generator
}
var sourceLocation = string.Format("TestFiles/CodeGenerator/Source/{0}.{1}", name, FileExtension);
var expectedOutput = TestFile.Create(string.Format("TestFiles/CodeGenerator/Output/{0}.{1}", baselineName, BaselineExtension)).ReadAllText();
var expectedOutput = TestFile
.Create(string.Format("TestFiles/CodeGenerator/Output/{0}.{1}", baselineName, BaselineExtension))
.ReadAllText();
// Set up the host and engine
var host = CreateHost();
@ -171,10 +173,19 @@ namespace Microsoft.AspNet.Razor.Test.Generator
{
var sourceFile = NormalizeNewLines(source);
var sourceFileName = generatePragmas ? string.Format("{0}.{1}", name, FileExtension) : null;
results = engine.GenerateCode(sourceFile, className: name, rootNamespace: TestRootNamespaceName, sourceFileName: sourceFileName);
results = engine.GenerateCode(
sourceFile,
className: name,
rootNamespace: TestRootNamespaceName,
sourceFileName: sourceFileName);
}
// Only called if GENERATE_BASELINES is set, otherwise compiled out.
BaselineWriter.WriteBaseline(string.Format(@"test\Microsoft.AspNet.Razor.Test\TestFiles\ChunkGenerator\Output\{0}.{1}", baselineName, BaselineExtension), results.GeneratedCode);
BaselineWriter.WriteBaseline(
string.Format(
@"test\Microsoft.AspNet.Razor.Test\TestFiles\ChunkGenerator\Output\{0}.{1}",
baselineName,
BaselineExtension),
results.GeneratedCode);
#if !GENERATE_BASELINES
var textOutput = results.GeneratedCode;

View File

@ -5,8 +5,8 @@ using System;
#if DNXCORE50
using System.Reflection;
#endif
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGeneration.Visitors;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;
@ -58,7 +58,9 @@ namespace Microsoft.AspNet.Razor.Test.Generator
GeneratedClassContext = originalHost.GeneratedClassContext;
}
public override CodeGenerator DecorateCodeGenerator(CodeGenerator incomingBuilder, CodeGeneratorContext context)
public override CodeGenerator DecorateCodeGenerator(
CodeGenerator incomingBuilder,
CodeGeneratorContext context)
{
return new AttributeChunkGeneratorReplacingCodeGenerator(context);
}

View File

@ -4,8 +4,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGeneration.Visitors;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.TagHelpers;
@ -100,7 +100,9 @@ namespace Microsoft.AspNet.Razor.Test.Generator
}
protected override CSharpCodeVisitor CreateCSharpCodeVisitor(CSharpCodeWriter writer, CodeGeneratorContext context)
protected override CSharpCodeVisitor CreateCSharpCodeVisitor(
CSharpCodeWriter writer,
CodeGeneratorContext context)
{
var visitor = base.CreateCSharpCodeVisitor(writer, context);
visitor.TagHelperRenderer = new NoUniqueIdsTagHelperCodeRenderer(visitor, writer, context);

View File

@ -124,7 +124,10 @@ namespace Microsoft.AspNet.Razor.Test.Framework
{
private const BlockType ThisBlockType = BlockType.Markup;
public MarkupBlock(BlockType blockType, IParentChunkGenerator chunkGenerator, IEnumerable<SyntaxTreeNode> children)
public MarkupBlock(
BlockType blockType,
IParentChunkGenerator chunkGenerator,
IEnumerable<SyntaxTreeNode> children)
: base(blockType, children, chunkGenerator)
{
}

View File

@ -19,12 +19,17 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public static UnclassifiedCodeSpanConstructor EmptyCSharp(this SpanFactory self)
{
return new UnclassifiedCodeSpanConstructor(
self.Span(SpanKind.Code, new CSharpSymbol(self.LocationTracker.CurrentLocation, string.Empty, CSharpSymbolType.Unknown)));
self.Span(
SpanKind.Code,
new CSharpSymbol(self.LocationTracker.CurrentLocation, string.Empty, CSharpSymbolType.Unknown)));
}
public static SpanConstructor EmptyHtml(this SpanFactory self)
{
return self.Span(SpanKind.Markup, new HtmlSymbol(self.LocationTracker.CurrentLocation, string.Empty, HtmlSymbolType.Unknown))
return self
.Span(
SpanKind.Markup,
new HtmlSymbol(self.LocationTracker.CurrentLocation, string.Empty, HtmlSymbolType.Unknown))
.With(new MarkupChunkGenerator());
}
@ -36,7 +41,9 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public static SpanConstructor CodeTransition(this SpanFactory self)
{
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, markup: false).Accepts(AcceptedCharacters.None);
return self
.Span(SpanKind.Transition, SyntaxConstants.TransitionString, markup: false)
.Accepts(AcceptedCharacters.None);
}
public static SpanConstructor CodeTransition(this SpanFactory self, string content)
@ -46,7 +53,9 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public static SpanConstructor CodeTransition(this SpanFactory self, CSharpSymbolType type)
{
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, type).Accepts(AcceptedCharacters.None);
return self
.Span(SpanKind.Transition, SyntaxConstants.TransitionString, type)
.Accepts(AcceptedCharacters.None);
}
public static SpanConstructor CodeTransition(this SpanFactory self, string content, CSharpSymbolType type)
@ -56,7 +65,9 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public static SpanConstructor MarkupTransition(this SpanFactory self)
{
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, markup: true).Accepts(AcceptedCharacters.None);
return self
.Span(SpanKind.Transition, SyntaxConstants.TransitionString, markup: true)
.Accepts(AcceptedCharacters.None);
}
public static SpanConstructor MarkupTransition(this SpanFactory self, string content)
@ -66,7 +77,9 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public static SpanConstructor MarkupTransition(this SpanFactory self, HtmlSymbolType type)
{
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, type).Accepts(AcceptedCharacters.None);
return self
.Span(SpanKind.Transition, SyntaxConstants.TransitionString, type)
.Accepts(AcceptedCharacters.None);
}
public static SpanConstructor MarkupTransition(this SpanFactory self, string content, HtmlSymbolType type)
@ -241,7 +254,10 @@ namespace Microsoft.AspNet.Razor.Test.Framework
return AutoCompleteWith(self, autoCompleteString, atEndOfSpan: false);
}
public static SpanConstructor AutoCompleteWith(this SpanConstructor self, string autoCompleteString, bool atEndOfSpan)
public static SpanConstructor AutoCompleteWith(
this SpanConstructor self,
string autoCompleteString,
bool atEndOfSpan)
{
return self.With(new AutoCompleteEditHandler(
SpanConstructor.TestTokenizer,
@ -289,7 +305,8 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public SpanConstructor AsImplicitExpression(ISet<string> keywords, bool acceptTrailingDot)
{
return _self.With(new ImplicitExpressionEditHandler(SpanConstructor.TestTokenizer, keywords, acceptTrailingDot))
return _self
.With(new ImplicitExpressionEditHandler(SpanConstructor.TestTokenizer, keywords, acceptTrailingDot))
.With(new ExpressionChunkGenerator());
}

View File

@ -61,37 +61,58 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
[Fact]
public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsForKeyword()
{
SingleSpanBlockTest("for(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"for(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsForeachKeyword()
{
SingleSpanBlockTest("foreach(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"foreach(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsWhileKeyword()
{
SingleSpanBlockTest("while(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"while(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsUsingKeywordFollowedByParen()
{
SingleSpanBlockTest("using(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"using(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
BlockType.Statement,
SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSupportsUsingsNestedWithinOtherBlocks()
{
SingleSpanBlockTest("if(foo) { using(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); } }", BlockType.Statement, SpanKind.Code);
SingleSpanBlockTest(
"if(foo) { using(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); } }",
BlockType.Statement,
SpanKind.Code);
}
[Fact]
public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsIfKeywordWithNoElseBranches()
{
SingleSpanBlockTest("if(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }", BlockType.Statement, SpanKind.Code);
SingleSpanBlockTest(
"if(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
BlockType.Statement,
SpanKind.Code);
}
[Fact]
@ -113,31 +134,46 @@ namespace Microsoft.AspNet.Razor.Test.Parser.CSharp
[Fact]
public void ParseBlockSupportsBlockCommentBetweenIfAndElseClause()
{
SingleSpanBlockTest("if(foo) { bar(); } /* Foo */ /* Bar */ else { baz(); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"if(foo) { bar(); } /* Foo */ /* Bar */ else { baz(); }",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSupportsRazorCommentBetweenIfAndElseClause()
{
RunRazorCommentBetweenClausesTest("if(foo) { bar(); } ", " else { baz(); }", acceptedCharacters: AcceptedCharacters.None);
RunRazorCommentBetweenClausesTest(
"if(foo) { bar(); } ", " else { baz(); }",
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSupportsBlockCommentBetweenElseIfAndElseClause()
{
SingleSpanBlockTest("if(foo) { bar(); } else if(bar) { baz(); } /* Foo */ /* Bar */ else { biz(); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"if(foo) { bar(); } else if(bar) { baz(); } /* Foo */ /* Bar */ else { biz(); }",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSupportsRazorCommentBetweenElseIfAndElseClause()
{
RunRazorCommentBetweenClausesTest("if(foo) { bar(); } else if(bar) { baz(); } ", " else { baz(); }", acceptedCharacters: AcceptedCharacters.None);
RunRazorCommentBetweenClausesTest(
"if(foo) { bar(); } else if(bar) { baz(); } ", " else { baz(); }",
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSupportsBlockCommentBetweenIfAndElseIfClause()
{
SingleSpanBlockTest("if(foo) { bar(); } /* Foo */ /* Bar */ else if(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
SingleSpanBlockTest(
"if(foo) { bar(); } /* Foo */ /* Bar */ else if(bar) { baz(); }",
BlockType.Statement,
SpanKind.Code);
}
[Fact]
@ -228,7 +264,9 @@ else if(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
const string document = ifStatement + elseIfBranch + elseBranch + elseIfBranch;
const string expected = ifStatement + elseIfBranch + elseBranch;
ParseBlockTest(document, new StatementBlock(Factory.Code(expected).AsStatement().Accepts(AcceptedCharacters.None)));
ParseBlockTest(
document,
new StatementBlock(Factory.Code(expected).AsStatement().Accepts(AcceptedCharacters.None)));
}
[Fact]
@ -244,7 +282,8 @@ else if(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
[Fact]
public void ParseBlockAcceptsElseIfWithNoCondition()
{
// We don't want to be a full C# parser - If the else if is missing it's condition, the C# compiler can handle that, we have all the info we need to keep parsing
// We don't want to be a full C# parser - If the else if is missing it's condition, the C# compiler
// can handle that, we have all the info we need to keep parsing
const string ifBranch = @"if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
Debug.WriteLine(@""foo } bar"");
}";
@ -257,7 +296,11 @@ else if(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
[Fact]
public void ParseBlockCorrectlyParsesDoWhileBlock()
{
SingleSpanBlockTest("do { var foo = bar; } while(foo != bar);", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"do { var foo = bar; } while(foo != bar);",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
@ -275,7 +318,11 @@ else if(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
[Fact]
public void ParseBlockCorrectlyParsesDoWhileBlockMissingWhileConditionWithSemicolon()
{
SingleSpanBlockTest("do { var foo = bar; } while;", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"do { var foo = bar; } while;",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
@ -287,7 +334,11 @@ else if(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
[Fact]
public void ParseBlockSupportsBlockCommentBetweenDoAndWhileClause()
{
SingleSpanBlockTest("do { var foo = bar; } /* Foo */ /* Bar */ while(true);", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"do { var foo = bar; } /* Foo */ /* Bar */ while(true);",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
@ -302,7 +353,9 @@ while(true);", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedC
[Fact]
public void ParseBlockSupportsRazorCommentBetweenDoAndWhileClause()
{
RunRazorCommentBetweenClausesTest("do { var foo = bar; } ", " while(true);", acceptedCharacters: AcceptedCharacters.None);
RunRazorCommentBetweenClausesTest(
"do { var foo = bar; } ", " while(true);",
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
@ -343,25 +396,40 @@ while(true);", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedC
[Fact]
public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsLockKeyword()
{
SingleSpanBlockTest("lock(foo) { Debug.WriteLine(@\"foo } bar\"); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"lock(foo) { Debug.WriteLine(@\"foo } bar\"); }",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockHasErrorsIfNamespaceImportMissingSemicolon()
{
NamespaceImportTest("using Foo.Bar.Baz", " Foo.Bar.Baz", acceptedCharacters: AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace, location: new SourceLocation(17, 0, 17));
NamespaceImportTest(
"using Foo.Bar.Baz",
" Foo.Bar.Baz",
acceptedCharacters: AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace,
location: new SourceLocation(17, 0, 17));
}
[Fact]
public void ParseBlockHasErrorsIfNamespaceAliasMissingSemicolon()
{
NamespaceImportTest("using Foo.Bar.Baz = FooBarBaz", " Foo.Bar.Baz = FooBarBaz", acceptedCharacters: AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace, location: new SourceLocation(29, 0, 29));
NamespaceImportTest(
"using Foo.Bar.Baz = FooBarBaz",
" Foo.Bar.Baz = FooBarBaz",
acceptedCharacters: AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace,
location: new SourceLocation(29, 0, 29));
}
[Fact]
public void ParseBlockParsesNamespaceImportWithSemicolonForUsingKeywordIfIsInValidFormat()
{
NamespaceImportTest("using Foo.Bar.Baz;", " Foo.Bar.Baz", AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace);
NamespaceImportTest(
"using Foo.Bar.Baz;",
" Foo.Bar.Baz",
AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace);
}
[Fact]
@ -377,7 +445,10 @@ while(true);", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedC
[Fact]
public void ParseBlockParsesNamespaceAliasWithSemicolonForUsingKeywordIfIsInValidFormat()
{
NamespaceImportTest("using FooBarBaz = FooBarBaz;", " FooBarBaz = FooBarBaz", AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace);
NamespaceImportTest(
"using FooBarBaz = FooBarBaz;",
" FooBarBaz = FooBarBaz",
AcceptedCharacters.NonWhiteSpace | AcceptedCharacters.WhiteSpace);
}
[Fact]
@ -390,17 +461,29 @@ while(true);", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedC
public void ParseBlockTerminatesSingleLineCommentAtEndOfFile()
{
const string document = "foreach(var f in Foo) { // foo bar baz";
SingleSpanBlockTest(document, document, BlockType.Statement, SpanKind.Code,
new RazorError(RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("foreach", '}', '{'), SourceLocation.Zero));
SingleSpanBlockTest(
document,
document,
BlockType.Statement,
SpanKind.Code,
new RazorError(
RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("foreach", '}', '{'),
SourceLocation.Zero));
}
[Fact]
public void ParseBlockTerminatesBlockCommentAtEndOfFile()
{
const string document = "foreach(var f in Foo) { /* foo bar baz";
SingleSpanBlockTest(document, document, BlockType.Statement, SpanKind.Code,
new RazorError(RazorResources.ParseError_BlockComment_Not_Terminated, 24, 0, 24),
new RazorError(RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("foreach", '}', '{'), SourceLocation.Zero));
SingleSpanBlockTest(
document,
document,
BlockType.Statement,
SpanKind.Code,
new RazorError(RazorResources.ParseError_BlockComment_Not_Terminated, 24, 0, 24),
new RazorError(
RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF("foreach", '}', '{'),
SourceLocation.Zero));
}
[Fact]
@ -426,13 +509,19 @@ while(true);", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedC
[Fact]
public void ParseBlockSupportsBlockCommentBetweenCatchAndFinallyClause()
{
SingleSpanBlockTest("try { bar(); } catch(bar) { baz(); } /* Foo */ /* Bar */ finally { biz(); }", BlockType.Statement, SpanKind.Code, acceptedCharacters: AcceptedCharacters.None);
SingleSpanBlockTest(
"try { bar(); } catch(bar) { baz(); } /* Foo */ /* Bar */ finally { biz(); }",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSupportsRazorCommentBetweenCatchAndFinallyClause()
{
RunRazorCommentBetweenClausesTest("try { bar(); } catch(bar) { baz(); } ", " finally { biz(); }", acceptedCharacters: AcceptedCharacters.None);
RunRazorCommentBetweenClausesTest(
"try { bar(); } catch(bar) { baz(); } ", " finally { biz(); }",
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
@ -519,7 +608,11 @@ catch(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
[Fact]
public void ParseBlockSupportsTryStatementWithMultipleCatchClause()
{
SingleSpanBlockTest("try { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } }", BlockType.Statement, SpanKind.Code);
SingleSpanBlockTest(
"try { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) " +
"{ var foo = new { } } catch(Foo Bar Baz) { var foo = new { } }",
BlockType.Statement,
SpanKind.Code);
}
[Fact]
@ -532,7 +625,8 @@ catch(bar) { baz(); }", BlockType.Statement, SpanKind.Code);
public void ParseBlockSupportsMarkupWithinAdditionalCatchClauses()
{
RunSimpleWrappedMarkupTest(
prefix: "try { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) {",
prefix: "try { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) " +
"{ var foo = new { } } catch(Foo Bar Baz) {",
markup: " <p>Foo</p> ",
suffix: "}",
expectedMarkup: new MarkupBlock(

View File

@ -4,7 +4,7 @@
using System;
using System.Threading;
using System.Web.WebPages.TestUtils;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Test.Framework;
using Microsoft.AspNet.Razor.Test.Utils;

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
using Xunit;

View File

@ -8,7 +8,7 @@ using System.Text;
using System.Threading;
using System.Web.WebPages.TestUtils;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.CodeGeneration;
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Text;
using Moq;