Fixes https://github.com/aspnet/Razor/issues/2612
This commit is contained in:
Pranav K 2018-11-09 17:32:58 -08:00
Родитель fe7881d5f7
Коммит fc3f45bf4e
258 изменённых файлов: 18247 добавлений и 67 удалений

Просмотреть файл

@ -97,6 +97,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib", "test\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj", "{72E89155-86C7-454E-BDD9-39F497F2F61B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X", "src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj", "{0693CA32-BB75-401E-BC08-72D6DEEB4C99}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test", "test\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj", "{495A006C-D2B9-4AD0-9D33-60820BA501D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X", "test\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj", "{D87E5501-B832-46B6-ACD3-EC989E3D14ED}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -391,6 +397,30 @@ Global
{72E89155-86C7-454E-BDD9-39F497F2F61B}.Release|Any CPU.Build.0 = Release|Any CPU
{72E89155-86C7-454E-BDD9-39F497F2F61B}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{72E89155-86C7-454E-BDD9-39F497F2F61B}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.Release|Any CPU.Build.0 = Release|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{0693CA32-BB75-401E-BC08-72D6DEEB4C99}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.Release|Any CPU.Build.0 = Release|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{495A006C-D2B9-4AD0-9D33-60820BA501D8}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.Release|Any CPU.Build.0 = Release|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{D87E5501-B832-46B6-ACD3-EC989E3D14ED}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -432,6 +462,9 @@ Global
{7D9ECCEE-71D1-4A42-ABEE-876AFA1B4FC9} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{6EA56B2B-89EC-4C38-A384-97D203375B06} = {92463391-81BE-462B-AC3C-78C6C760741F}
{72E89155-86C7-454E-BDD9-39F497F2F61B} = {92463391-81BE-462B-AC3C-78C6C760741F}
{0693CA32-BB75-401E-BC08-72D6DEEB4C99} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{495A006C-D2B9-4AD0-9D33-60820BA501D8} = {92463391-81BE-462B-AC3C-78C6C760741F}
{D87E5501-B832-46B6-ACD3-EC989E3D14ED} = {92463391-81BE-462B-AC3C-78C6C760741F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0035341D-175A-4D05-95E6-F1C2785A1E26}

Просмотреть файл

@ -73,6 +73,7 @@
<ItemGroup>
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X\bin\$(Configuration)\net46\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.dll" />
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X\bin\$(Configuration)\net46\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.dll" />
<LanguageServiceExtensionAssembly Include="$(RepositoryRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\bin\$(Configuration)\net46\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll" />
<LanguageServiceAssembly Include="$(LanguageServiceOutputPath)%(LanguageServiceAssemblyNames.Identity)" Condition="Exists('$(LanguageServiceOutputPath)%(LanguageServiceAssemblyNames.Identity)')" />
<LanguageServiceAssembly Include="%(LanguageServiceExtensionAssembly.Identity)" />

Просмотреть файл

@ -0,0 +1,102 @@
// 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 System.Diagnostics;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class AssemblyAttributeInjectionPass : IntermediateNodePassBase, IRazorOptimizationPass
{
private const string RazorViewAttribute = "global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute";
private const string RazorPageAttribute = "global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute";
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (documentNode.Options.DesignTime)
{
return;
}
var @namespace = documentNode.FindPrimaryNamespace();
if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
{
// No namespace node or it's incomplete. Skip.
return;
}
var @class = documentNode.FindPrimaryClass();
if (@class == null || string.IsNullOrEmpty(@class.ClassName))
{
// No class node or it's incomplete. Skip.
return;
}
var generatedTypeName = $"{@namespace.Content}.{@class.ClassName}";
// The MVC attributes require a relative path to be specified so that we can make a view engine path.
// We can't use a rooted path because we don't know what the project root is.
//
// If we can't sanitize the path, we'll just set it to null and let is blow up at runtime - we don't
// want to create noise if this code has to run in some unanticipated scenario.
var escapedPath = MakeVerbatimStringLiteral(ConvertToViewEnginePath(codeDocument.Source.RelativePath));
string attribute;
if (documentNode.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind)
{
attribute = $"[assembly:{RazorViewAttribute}({escapedPath}, typeof({generatedTypeName}))]";
}
else if (documentNode.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
PageDirective.TryGetPageDirective(documentNode, out var pageDirective))
{
var escapedRoutePrefix = MakeVerbatimStringLiteral(pageDirective.RouteTemplate);
attribute = $"[assembly:{RazorPageAttribute}({escapedPath}, typeof({generatedTypeName}), {escapedRoutePrefix})]";
}
else
{
return;
}
var index = documentNode.Children.IndexOf(@namespace);
Debug.Assert(index >= 0);
var pageAttribute = new CSharpCodeIntermediateNode();
pageAttribute.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = attribute,
});
documentNode.Children.Insert(index, pageAttribute);
}
private static string MakeVerbatimStringLiteral(string value)
{
if (value == null)
{
return "null";
}
value = value.Replace("\"", "\"\"");
return $"@\"{value}\"";
}
private static string ConvertToViewEnginePath(string relativePath)
{
if (string.IsNullOrEmpty(relativePath))
{
return null;
}
// Checking for both / and \ because a \ will become a /.
if (!relativePath.StartsWith("/") && !relativePath.StartsWith("\\"))
{
relativePath = "/" + relativePath;
}
relativePath = relativePath.Replace('\\', '/');
return relativePath;
}
}
}

Просмотреть файл

@ -0,0 +1,71 @@
// 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 System;
using System.Globalization;
using System.Text;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal static class CSharpIdentifier
{
private const string CshtmlExtension = ".cshtml";
public static string GetClassNameFromPath(string path)
{
if (string.IsNullOrEmpty(path))
{
return path;
}
if (path.EndsWith(CshtmlExtension, StringComparison.OrdinalIgnoreCase))
{
path = path.Substring(0, path.Length - CshtmlExtension.Length);
}
return SanitizeClassName(path);
}
// CSharp Spec §2.4.2
private static bool IsIdentifierStart(char character)
{
return char.IsLetter(character) ||
character == '_' ||
CharUnicodeInfo.GetUnicodeCategory(character) == UnicodeCategory.LetterNumber;
}
public static bool IsIdentifierPart(char character)
{
return char.IsDigit(character) ||
IsIdentifierStart(character) ||
IsIdentifierPartByUnicodeCategory(character);
}
private static bool IsIdentifierPartByUnicodeCategory(char character)
{
var category = CharUnicodeInfo.GetUnicodeCategory(character);
return category == UnicodeCategory.NonSpacingMark || // Mn
category == UnicodeCategory.SpacingCombiningMark || // Mc
category == UnicodeCategory.ConnectorPunctuation || // Pc
category == UnicodeCategory.Format; // Cf
}
public static string SanitizeClassName(string inputName)
{
if (!IsIdentifierStart(inputName[0]) && IsIdentifierPart(inputName[0]))
{
inputName = "_" + inputName;
}
var builder = new StringBuilder(inputName.Length);
for (var i = 0; i < inputName.Length; i++)
{
var ch = inputName[i];
builder.Append(IsIdentifierPart(ch) ? ch : '_');
}
return builder.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,15 @@
// 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.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal class ExtensionInitializer : RazorExtensionInitializer
{
public override void Initialize(RazorProjectEngineBuilder builder)
{
RazorExtensions.Register(builder);
}
}
}

Просмотреть файл

@ -0,0 +1,12 @@
// 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.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public interface IInjectTargetExtension : ICodeTargetExtension
{
void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node);
}
}

Просмотреть файл

@ -0,0 +1,12 @@
// 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.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public interface IViewComponentTagHelperTargetExtension : ICodeTargetExtension
{
void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node);
}
}

Просмотреть файл

@ -0,0 +1,124 @@
// 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 System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class InjectDirective
{
public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective(
"inject",
DirectiveKind.SingleLine,
builder =>
{
builder
.AddTypeToken(Resources.InjectDirective_TypeToken_Name, Resources.InjectDirective_TypeToken_Description)
.AddMemberToken(Resources.InjectDirective_MemberToken_Name, Resources.InjectDirective_MemberToken_Description);
builder.Usage = DirectiveUsage.FileScopedMultipleOccurring;
builder.Description = Resources.InjectDirective_Description;
});
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass());
builder.AddTargetExtension(new InjectTargetExtension());
return builder;
}
internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass
{
// Runs after the @model and @namespace directives
public override int Order => 10;
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
var visitor = new Visitor();
visitor.Visit(documentNode);
var modelType = ModelDirective.GetModelType(documentNode);
var properties = new HashSet<string>(StringComparer.Ordinal);
for (var i = visitor.Directives.Count - 1; i >= 0; i--)
{
var directive = visitor.Directives[i];
var tokens = directive.Tokens.ToArray();
if (tokens.Length < 2)
{
continue;
}
var typeName = tokens[0].Content;
var memberName = tokens[1].Content;
if (!properties.Add(memberName))
{
continue;
}
typeName = typeName.Replace("<TModel>", "<" + modelType + ">");
var injectNode = new InjectIntermediateNode()
{
TypeName = typeName,
MemberName = memberName,
};
visitor.Class.Children.Add(injectNode);
}
}
}
private class Visitor : IntermediateNodeWalker
{
public ClassDeclarationIntermediateNode Class { get; private set; }
public IList<DirectiveIntermediateNode> Directives { get; } = new List<DirectiveIntermediateNode>();
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
if (Class == null)
{
Class = node;
}
base.VisitClassDeclaration(node);
}
public override void VisitDirective(DirectiveIntermediateNode node)
{
if (node.Directive == Directive)
{
Directives.Add(node);
}
}
}
#region Obsolete
[Obsolete("This method is obsolete and will be removed in a future version.")]
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass());
builder.AddTargetExtension(new InjectTargetExtension());
return builder;
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,58 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class InjectIntermediateNode : ExtensionIntermediateNode
{
public string TypeName { get; set; }
public string MemberName { get; set; }
public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<InjectIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IInjectTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IInjectTargetExtension>(context);
return;
}
extension.WriteInjectProperty(context, this);
}
public override void FormatNode(IntermediateNodeFormatter formatter)
{
formatter.WriteContent(MemberName);
formatter.WriteProperty(nameof(MemberName), MemberName);
formatter.WriteProperty(nameof(TypeName), TypeName);
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class InjectTargetExtension : IInjectTargetExtension
{
private const string RazorInjectAttribute = "[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]";
public void WriteInjectProperty(CodeRenderingContext context, InjectIntermediateNode node)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (node == null)
{
throw new ArgumentNullException(nameof(node));
}
var property = $"public {node.TypeName} {node.MemberName} {{ get; private set; }}";
if (node.Source.HasValue)
{
using (context.CodeWriter.BuildLinePragma(node.Source.Value))
{
context.CodeWriter
.WriteLine(RazorInjectAttribute)
.WriteLine(property);
}
}
else
{
context.CodeWriter
.WriteLine(RazorInjectAttribute)
.WriteLine(property);
}
}
}
}

Просмотреть файл

@ -0,0 +1,125 @@
// 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 System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class InstrumentationPass : IntermediateNodePassBase, IRazorOptimizationPass
{
public override int Order => DefaultFeatureOrder;
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (documentNode.Options.DesignTime)
{
return;
}
var walker = new Visitor();
walker.VisitDocument(documentNode);
for (var i = 0; i < walker.Items.Count; i++)
{
var node = walker.Items[i];
AddInstrumentation(node);
}
}
private static void AddInstrumentation(InstrumentationItem item)
{
var beginContextMethodName = "BeginContext"; // ORIGINAL: BeginContextMethodName
var endContextMethodName = "EndContext"; // ORIGINAL: EndContextMethodName
var beginNode = new CSharpCodeIntermediateNode();
beginNode.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = string.Format("{0}({1}, {2}, {3});",
beginContextMethodName,
item.Source.AbsoluteIndex.ToString(CultureInfo.InvariantCulture),
item.Source.Length.ToString(CultureInfo.InvariantCulture),
item.IsLiteral ? "true" : "false")
});
var endNode = new CSharpCodeIntermediateNode();
endNode.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = string.Format("{0}();", endContextMethodName)
});
var nodeIndex = item.Parent.Children.IndexOf(item.Node);
item.Parent.Children.Insert(nodeIndex, beginNode);
item.Parent.Children.Insert(nodeIndex + 2, endNode);
}
private struct InstrumentationItem
{
public InstrumentationItem(IntermediateNode node, IntermediateNode parent, bool isLiteral, SourceSpan source)
{
Node = node;
Parent = parent;
IsLiteral = isLiteral;
Source = source;
}
public IntermediateNode Node { get; }
public IntermediateNode Parent { get; }
public bool IsLiteral { get; }
public SourceSpan Source { get; }
}
private class Visitor : IntermediateNodeWalker
{
public List<InstrumentationItem> Items { get; } = new List<InstrumentationItem>();
public override void VisitHtml(HtmlContentIntermediateNode node)
{
if (node.Source != null)
{
Items.Add(new InstrumentationItem(node, Parent, isLiteral: true, source: node.Source.Value));
}
VisitDefault(node);
}
public override void VisitCSharpExpression(CSharpExpressionIntermediateNode node)
{
if (node.Source != null)
{
Items.Add(new InstrumentationItem(node, Parent, isLiteral: false, source: node.Source.Value));
}
VisitDefault(node);
}
public override void VisitTagHelper(TagHelperIntermediateNode node)
{
if (node.Source != null)
{
Items.Add(new InstrumentationItem(node, Parent, isLiteral: false, source: node.Source.Value));
}
// Inside a tag helper we only want to visit inside of the body (skip all of the attributes and properties).
for (var i = 0; i < node.Children.Count; i++)
{
var child = node.Children[i];
if (child is TagHelperBodyIntermediateNode ||
child is DefaultTagHelperBodyIntermediateNode)
{
VisitDefault(child);
}
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>ASP.NET Core design time hosting infrastructure for the Razor view engine.</Description>
<TargetFrameworks>net46;netstandard2.0</TargetFrameworks>
<PackageTags>$(PackageTags);aspnetcoremvc</PackageTags>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CodeGeneration\CodeWriterExtensions.cs">
<Link>Shared\CodeWriterExtensions.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Microsoft.AspNetCore.Razor.Language/Microsoft.AspNetCore.Razor.Language.csproj" />
<ProjectReference Include="../Microsoft.CodeAnalysis.Razor/Microsoft.CodeAnalysis.Razor.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,152 @@
// 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 System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class ModelDirective
{
public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective(
"model",
DirectiveKind.SingleLine,
builder =>
{
builder.AddTypeToken(Resources.ModelDirective_TypeToken_Name, Resources.ModelDirective_TypeToken_Description);
builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
builder.Description = Resources.ModelDirective_Description;
});
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass());
return builder;
}
public static string GetModelType(DocumentIntermediateNode document)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
var visitor = new Visitor();
return GetModelType(document, visitor);
}
private static string GetModelType(DocumentIntermediateNode document, Visitor visitor)
{
visitor.Visit(document);
for (var i = visitor.ModelDirectives.Count - 1; i >= 0; i--)
{
var directive = visitor.ModelDirectives[i];
var tokens = directive.Tokens.ToArray();
if (tokens.Length >= 1)
{
return tokens[0].Content;
}
}
if (document.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind)
{
return visitor.Class.ClassName;
}
else
{
return "dynamic";
}
}
internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass
{
// Runs after the @inherits directive
public override int Order => 5;
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
var visitor = new Visitor();
var modelType = GetModelType(documentNode, visitor);
if (documentNode.Options.DesignTime)
{
// Alias the TModel token to a known type.
// This allows design time compilation to succeed for Razor files where the token isn't replaced.
var typeName = $"global::{typeof(object).FullName}";
var usingNode = new UsingDirectiveIntermediateNode()
{
Content = $"TModel = {typeName}"
};
visitor.Namespace?.Children.Insert(0, usingNode);
}
var baseType = visitor.Class?.BaseType?.Replace("<TModel>", "<" + modelType + ">");
visitor.Class.BaseType = baseType;
}
}
private class Visitor : IntermediateNodeWalker
{
public NamespaceDeclarationIntermediateNode Namespace { get; private set; }
public ClassDeclarationIntermediateNode Class { get; private set; }
public IList<DirectiveIntermediateNode> ModelDirectives { get; } = new List<DirectiveIntermediateNode>();
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
{
if (Namespace == null)
{
Namespace = node;
}
base.VisitNamespaceDeclaration(node);
}
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
if (Class == null)
{
Class = node;
}
base.VisitClassDeclaration(node);
}
public override void VisitDirective(DirectiveIntermediateNode node)
{
if (node.Directive == Directive)
{
ModelDirectives.Add(node);
}
}
}
#region Obsolete
[Obsolete("This method is obsolete and will be removed in a future version.")]
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass());
return builder;
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,85 @@
// 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 System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class ModelExpressionPass : IntermediateNodePassBase, IRazorOptimizationPass
{
private const string ModelExpressionTypeName = "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression";
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
var visitor = new Visitor();
visitor.Visit(documentNode);
}
private class Visitor : IntermediateNodeWalker
{
public List<TagHelperIntermediateNode> TagHelpers { get; } = new List<TagHelperIntermediateNode>();
public override void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node)
{
if (string.Equals(node.BoundAttribute.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) ||
(node.IsIndexerNameMatch &&
string.Equals(node.BoundAttribute.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal)))
{
var expression = new CSharpExpressionIntermediateNode();
expression.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = "ModelExpressionProvider.CreateModelExpression(ViewData, __model => ",
});
if (node.Children.Count == 1 && node.Children[0] is IntermediateToken token && token.IsCSharp)
{
// A 'simple' expression will look like __model => __model.Foo
expression.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = "__model."
});
expression.Children.Add(token);
}
else
{
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is CSharpExpressionIntermediateNode nestedExpression)
{
for (var j = 0; j < nestedExpression.Children.Count; j++)
{
if (nestedExpression.Children[j] is IntermediateToken cSharpToken &&
cSharpToken.IsCSharp)
{
expression.Children.Add(cSharpToken);
}
}
continue;
}
}
}
expression.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = ")",
});
node.Children.Clear();
node.Children.Add(expression);
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,91 @@
// 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 System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal class MvcImportProjectFeature : RazorProjectEngineFeatureBase, IImportProjectFeature
{
private const string ImportsFileName = "_ViewImports.cshtml";
public IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem)
{
if (projectItem == null)
{
throw new ArgumentNullException(nameof(projectItem));
}
var imports = new List<RazorProjectItem>();
AddDefaultDirectivesImport(imports);
// We add hierarchical imports second so any default directive imports can be overridden.
AddHierarchicalImports(projectItem, imports);
return imports;
}
// Internal for testing
internal static void AddDefaultDirectivesImport(List<RazorProjectItem> imports)
{
imports.Add(DefaultDirectivesProjectItem.Instance);
}
// Internal for testing
internal void AddHierarchicalImports(RazorProjectItem projectItem, List<RazorProjectItem> imports)
{
// We want items in descending order. FindHierarchicalItems returns items in ascending order.
var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(projectItem.FilePath, ImportsFileName).Reverse();
imports.AddRange(importProjectItems);
}
private class DefaultDirectivesProjectItem : RazorProjectItem
{
private readonly byte[] _defaultImportBytes;
private DefaultDirectivesProjectItem()
{
var preamble = Encoding.UTF8.GetPreamble();
var content = @"
@using System
@using System.Collections.Generic
@using System.Linq
@using System.Threading.Tasks
@using Microsoft.AspNetCore.Mvc
@using Microsoft.AspNetCore.Mvc.Rendering
@using Microsoft.AspNetCore.Mvc.ViewFeatures
@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel> Html
@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json
@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component
@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url
@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider
@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
";
var contentBytes = Encoding.UTF8.GetBytes(content);
_defaultImportBytes = new byte[preamble.Length + contentBytes.Length];
preamble.CopyTo(_defaultImportBytes, 0);
contentBytes.CopyTo(_defaultImportBytes, preamble.Length);
}
public override string BasePath => null;
public override string FilePath => null;
public override string PhysicalPath => null;
public override bool Exists => true;
public static DefaultDirectivesProjectItem Instance { get; } = new DefaultDirectivesProjectItem();
public override Stream Read() => new MemoryStream(_defaultImportBytes);
}
}
}

Просмотреть файл

@ -0,0 +1,71 @@
// 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 System;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class MvcViewDocumentClassifierPass : DocumentClassifierPassBase
{
public static readonly string MvcViewDocumentKind = "mvc.1.0.view";
protected override string DocumentKind => MvcViewDocumentKind;
protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode) => true;
protected override void OnDocumentStructureCreated(
RazorCodeDocument codeDocument,
NamespaceDeclarationIntermediateNode @namespace,
ClassDeclarationIntermediateNode @class,
MethodDeclarationIntermediateNode method)
{
base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);
@namespace.Content = "AspNetCore";
var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;
if (string.IsNullOrEmpty(filePath))
{
// It's possible for a Razor document to not have a file path.
// Eg. When we try to generate code for an in memory document like default imports.
var checksum = BytesToString(codeDocument.Source.GetChecksum());
@class.ClassName = $"AspNetCore_{checksum}";
}
else
{
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
}
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
@class.Modifiers.Clear();
@class.Modifiers.Add("public");
method.MethodName = "ExecuteAsync";
method.Modifiers.Clear();
method.Modifiers.Add("public");
method.Modifiers.Add("async");
method.Modifiers.Add("override");
method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";
}
private static string BytesToString(byte[] bytes)
{
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes));
}
var result = new StringBuilder(bytes.Length);
for (var i = 0; i < bytes.Length; i++)
{
// The x2 format means lowercase hex, where each byte is a 2-character string.
result.Append(bytes[i].ToString("x2"));
}
return result.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,204 @@
// 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 System;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class NamespaceDirective
{
private static readonly char[] Separators = new char[] { '\\', '/' };
public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective(
"namespace",
DirectiveKind.SingleLine,
builder =>
{
builder.AddNamespaceToken(
Resources.NamespaceDirective_NamespaceToken_Name,
Resources.NamespaceDirective_NamespaceToken_Description);
builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
builder.Description = Resources.NamespaceDirective_Description;
});
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException();
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass());
}
// internal for testing
internal class Pass : IntermediateNodePassBase, IRazorDirectiveClassifierPass
{
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
documentNode.DocumentKind != MvcViewDocumentClassifierPass.MvcViewDocumentKind)
{
// Not a page. Skip.
return;
}
var visitor = new Visitor();
visitor.Visit(documentNode);
var directive = visitor.LastNamespaceDirective;
if (directive == null)
{
// No namespace set. Skip.
return;
}
var @namespace = visitor.FirstNamespace;
if (@namespace == null)
{
// No namespace node. Skip.
return;
}
@namespace.Content = GetNamespace(codeDocument.Source.FilePath, directive);
}
}
// internal for testing.
//
// This code does a best-effort attempt to compute a namespace 'suffix' - the path difference between
// where the @namespace directive appears and where the current document is on disk.
//
// In the event that these two source either don't have FileNames set or don't follow a coherent hierarchy,
// we will just use the namespace verbatim.
internal static string GetNamespace(string source, DirectiveIntermediateNode directive)
{
var directiveSource = NormalizeDirectory(directive.Source?.FilePath);
var baseNamespace = directive.Tokens.FirstOrDefault()?.Content;
if (string.IsNullOrEmpty(baseNamespace))
{
// The namespace directive was incomplete.
return string.Empty;
}
if (string.IsNullOrEmpty(source) || directiveSource == null)
{
// No sources, can't compute a suffix.
return baseNamespace;
}
// We're specifically using OrdinalIgnoreCase here because Razor treats all paths as case-insensitive.
if (!source.StartsWith(directiveSource, StringComparison.OrdinalIgnoreCase) ||
source.Length <= directiveSource.Length)
{
// The imports are not from the directory hierarchy, can't compute a suffix.
return baseNamespace;
}
// OK so that this point we know that the 'imports' file containing this directive is in the directory
// hierarchy of this soure file. This is the case where we can append a suffix to the baseNamespace.
//
// Everything so far has just been defensiveness on our part.
var builder = new StringBuilder(baseNamespace);
var segments = source.Substring(directiveSource.Length).Split(Separators);
// Skip the last segment because it's the FileName.
for (var i = 0; i < segments.Length - 1; i++)
{
builder.Append('.');
builder.Append(CSharpIdentifier.SanitizeClassName(segments[i]));
}
return builder.ToString();
}
// We want to normalize the path of the file containing the '@namespace' directive to just the containing
// directory with a trailing separator.
//
// Not using Path.GetDirectoryName here because it doesn't meet these requirements, and we want to handle
// both 'view engine' style paths and absolute paths.
//
// We also don't normalize the separators here. We expect that all documents are using a consistent style of path.
//
// If we can't normalize the path, we just return null so it will be ignored.
private static string NormalizeDirectory(string path)
{
if (string.IsNullOrEmpty(path))
{
return null;
}
var lastSeparator = path.LastIndexOfAny(Separators);
if (lastSeparator == -1)
{
return null;
}
// Includes the separator
return path.Substring(0, lastSeparator + 1);
}
private class Visitor : IntermediateNodeWalker
{
public ClassDeclarationIntermediateNode FirstClass { get; private set; }
public NamespaceDeclarationIntermediateNode FirstNamespace { get; private set; }
// We want the last one, so get them all and then .
public DirectiveIntermediateNode LastNamespaceDirective { get; private set; }
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
{
if (FirstNamespace == null)
{
FirstNamespace = node;
}
base.VisitNamespaceDeclaration(node);
}
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
if (FirstClass == null)
{
FirstClass = node;
}
base.VisitClassDeclaration(node);
}
public override void VisitDirective(DirectiveIntermediateNode node)
{
if (node.Directive == Directive)
{
LastNamespaceDirective = node;
}
base.VisitDirective(node);
}
}
#region Obsolete
[Obsolete("This method is obsolete and will be removed in a future version.")]
public static void Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException();
}
builder.AddDirective(Directive);
builder.Features.Add(new Pass());
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,121 @@
// 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 System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class PageDirective
{
public static readonly DirectiveDescriptor Directive = DirectiveDescriptor.CreateDirective(
"page",
DirectiveKind.SingleLine,
builder =>
{
builder.AddOptionalStringToken(Resources.PageDirective_RouteToken_Name, Resources.PageDirective_RouteToken_Description);
builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
builder.Description = Resources.PageDirective_Description;
});
private PageDirective(string routeTemplate, IntermediateNode directiveNode)
{
RouteTemplate = routeTemplate;
DirectiveNode = directiveNode;
}
public string RouteTemplate { get; }
public IntermediateNode DirectiveNode { get; }
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
return builder;
}
public static bool TryGetPageDirective(DocumentIntermediateNode documentNode, out PageDirective pageDirective)
{
var visitor = new Visitor();
for (var i = 0; i < documentNode.Children.Count; i++)
{
visitor.Visit(documentNode.Children[i]);
}
if (visitor.DirectiveTokens == null)
{
pageDirective = null;
return false;
}
var tokens = visitor.DirectiveTokens.ToList();
string routeTemplate = null;
if (tokens.Count > 0)
{
routeTemplate = TrimQuotes(tokens[0].Content);
}
pageDirective = new PageDirective(routeTemplate, visitor.DirectiveNode);
return true;
}
private static string TrimQuotes(string content)
{
// Tokens aren't captured if they're malformed. Therefore, this method will
// always be called with a valid token content.
Debug.Assert(content.Length >= 2);
Debug.Assert(content.StartsWith("\"", StringComparison.Ordinal));
Debug.Assert(content.EndsWith("\"", StringComparison.Ordinal));
return content.Substring(1, content.Length - 2);
}
private class Visitor : IntermediateNodeWalker
{
public IntermediateNode DirectiveNode { get; private set; }
public IEnumerable<DirectiveTokenIntermediateNode> DirectiveTokens { get; private set; }
public override void VisitDirective(DirectiveIntermediateNode node)
{
if (node.Directive == Directive)
{
DirectiveNode = node;
DirectiveTokens = node.Tokens;
}
}
public override void VisitMalformedDirective(MalformedDirectiveIntermediateNode node)
{
if (DirectiveTokens == null && node.Directive == Directive)
{
DirectiveNode = node;
DirectiveTokens = node.Tokens;
}
}
}
#region Obsolete
[Obsolete("This method is obsolete and will be removed in a future version.")]
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddDirective(Directive);
return builder;
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,57 @@
// 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.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class PagesPropertyInjectionPass : IntermediateNodePassBase, IRazorOptimizationPass
{
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind)
{
return;
}
var modelType = ModelDirective.GetModelType(documentNode);
var visitor = new Visitor();
visitor.Visit(documentNode);
var @class = visitor.Class;
var viewDataType = $"global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<{modelType}>";
var vddProperty = new CSharpCodeIntermediateNode();
vddProperty.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = $"public {viewDataType} ViewData => ({viewDataType})PageContext?.ViewData;",
});
@class.Children.Add(vddProperty);
var modelProperty = new CSharpCodeIntermediateNode();
modelProperty.Children.Add(new IntermediateToken()
{
Kind = TokenKind.CSharp,
Content = $"public {modelType} Model => ViewData.Model;",
});
@class.Children.Add(modelProperty);
}
private class Visitor : IntermediateNodeWalker
{
public ClassDeclarationIntermediateNode Class { get; private set; }
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
if (Class == null)
{
Class = node;
}
base.VisitClassDeclaration(node);
}
}
}
}

Просмотреть файл

@ -0,0 +1,12 @@
// 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 System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X;
using Microsoft.AspNetCore.Razor.Language;
[assembly: ProvideRazorExtensionInitializer("MVC-2.0", typeof(ExtensionInitializer))]
[assembly: ProvideRazorExtensionInitializer("MVC-2.1", typeof(ExtensionInitializer))]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

Просмотреть файл

@ -0,0 +1,338 @@
// <auto-generated />
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
using System.Globalization;
using System.Reflection;
using System.Resources;
internal static class Resources
{
private static readonly ResourceManager _resourceManager
= new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Resources", typeof(Resources).GetTypeInfo().Assembly);
/// <summary>
/// Value cannot be null or empty.
/// </summary>
internal static string ArgumentCannotBeNullOrEmpty
{
get => GetString("ArgumentCannotBeNullOrEmpty");
}
/// <summary>
/// Value cannot be null or empty.
/// </summary>
internal static string FormatArgumentCannotBeNullOrEmpty()
=> GetString("ArgumentCannotBeNullOrEmpty");
/// <summary>
/// Inject a service from the application's service container into a property.
/// </summary>
internal static string InjectDirective_Description
{
get => GetString("InjectDirective_Description");
}
/// <summary>
/// Inject a service from the application's service container into a property.
/// </summary>
internal static string FormatInjectDirective_Description()
=> GetString("InjectDirective_Description");
/// <summary>
/// The name of the property.
/// </summary>
internal static string InjectDirective_MemberToken_Description
{
get => GetString("InjectDirective_MemberToken_Description");
}
/// <summary>
/// The name of the property.
/// </summary>
internal static string FormatInjectDirective_MemberToken_Description()
=> GetString("InjectDirective_MemberToken_Description");
/// <summary>
/// PropertyName
/// </summary>
internal static string InjectDirective_MemberToken_Name
{
get => GetString("InjectDirective_MemberToken_Name");
}
/// <summary>
/// PropertyName
/// </summary>
internal static string FormatInjectDirective_MemberToken_Name()
=> GetString("InjectDirective_MemberToken_Name");
/// <summary>
/// The type of the service to inject.
/// </summary>
internal static string InjectDirective_TypeToken_Description
{
get => GetString("InjectDirective_TypeToken_Description");
}
/// <summary>
/// The type of the service to inject.
/// </summary>
internal static string FormatInjectDirective_TypeToken_Description()
=> GetString("InjectDirective_TypeToken_Description");
/// <summary>
/// TypeName
/// </summary>
internal static string InjectDirective_TypeToken_Name
{
get => GetString("InjectDirective_TypeToken_Name");
}
/// <summary>
/// TypeName
/// </summary>
internal static string FormatInjectDirective_TypeToken_Name()
=> GetString("InjectDirective_TypeToken_Name");
/// <summary>
/// Specify the view or page model for the page.
/// </summary>
internal static string ModelDirective_Description
{
get => GetString("ModelDirective_Description");
}
/// <summary>
/// Specify the view or page model for the page.
/// </summary>
internal static string FormatModelDirective_Description()
=> GetString("ModelDirective_Description");
/// <summary>
/// The model type.
/// </summary>
internal static string ModelDirective_TypeToken_Description
{
get => GetString("ModelDirective_TypeToken_Description");
}
/// <summary>
/// The model type.
/// </summary>
internal static string FormatModelDirective_TypeToken_Description()
=> GetString("ModelDirective_TypeToken_Description");
/// <summary>
/// TypeName
/// </summary>
internal static string ModelDirective_TypeToken_Name
{
get => GetString("ModelDirective_TypeToken_Name");
}
/// <summary>
/// TypeName
/// </summary>
internal static string FormatModelDirective_TypeToken_Name()
=> GetString("ModelDirective_TypeToken_Name");
/// <summary>
/// The 'inherits' keyword is not allowed when a '{0}' keyword is used.
/// </summary>
internal static string MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword
{
get => GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword");
}
/// <summary>
/// The 'inherits' keyword is not allowed when a '{0}' keyword is used.
/// </summary>
internal static string FormatMvcRazorCodeParser_CannotHaveModelAndInheritsKeyword(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword"), p0);
/// <summary>
/// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} &lt;Type Name&gt; &lt;Property Name&gt;'.
/// </summary>
internal static string MvcRazorCodeParser_InjectDirectivePropertyNameRequired
{
get => GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired");
}
/// <summary>
/// A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} &lt;Type Name&gt; &lt;Property Name&gt;'.
/// </summary>
internal static string FormatMvcRazorCodeParser_InjectDirectivePropertyNameRequired(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_InjectDirectivePropertyNameRequired"), p0);
/// <summary>
/// The '{0}' keyword must be followed by a type name on the same line.
/// </summary>
internal static string MvcRazorCodeParser_KeywordMustBeFollowedByTypeName
{
get => GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName");
}
/// <summary>
/// The '{0}' keyword must be followed by a type name on the same line.
/// </summary>
internal static string FormatMvcRazorCodeParser_KeywordMustBeFollowedByTypeName(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_KeywordMustBeFollowedByTypeName"), p0);
/// <summary>
/// Only one '{0}' statement is allowed in a file.
/// </summary>
internal static string MvcRazorCodeParser_OnlyOneModelStatementIsAllowed
{
get => GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed");
}
/// <summary>
/// Only one '{0}' statement is allowed in a file.
/// </summary>
internal static string FormatMvcRazorCodeParser_OnlyOneModelStatementIsAllowed(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed"), p0);
/// <summary>
/// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'.
/// </summary>
internal static string MvcRazorParser_InvalidPropertyType
{
get => GetString("MvcRazorParser_InvalidPropertyType");
}
/// <summary>
/// Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'.
/// </summary>
internal static string FormatMvcRazorParser_InvalidPropertyType(object p0, object p1, object p2)
=> string.Format(CultureInfo.CurrentCulture, GetString("MvcRazorParser_InvalidPropertyType"), p0, p1, p2);
/// <summary>
/// Specify the base namespace for the page.
/// </summary>
internal static string NamespaceDirective_Description
{
get => GetString("NamespaceDirective_Description");
}
/// <summary>
/// Specify the base namespace for the page.
/// </summary>
internal static string FormatNamespaceDirective_Description()
=> GetString("NamespaceDirective_Description");
/// <summary>
/// The namespace for the page.
/// </summary>
internal static string NamespaceDirective_NamespaceToken_Description
{
get => GetString("NamespaceDirective_NamespaceToken_Description");
}
/// <summary>
/// The namespace for the page.
/// </summary>
internal static string FormatNamespaceDirective_NamespaceToken_Description()
=> GetString("NamespaceDirective_NamespaceToken_Description");
/// <summary>
/// Namespace
/// </summary>
internal static string NamespaceDirective_NamespaceToken_Name
{
get => GetString("NamespaceDirective_NamespaceToken_Name");
}
/// <summary>
/// Namespace
/// </summary>
internal static string FormatNamespaceDirective_NamespaceToken_Name()
=> GetString("NamespaceDirective_NamespaceToken_Name");
/// <summary>
/// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.
/// </summary>
internal static string PageDirectiveCannotBeImported
{
get => GetString("PageDirectiveCannotBeImported");
}
/// <summary>
/// The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.
/// </summary>
internal static string FormatPageDirectiveCannotBeImported(object p0, object p1)
=> string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveCannotBeImported"), p0, p1);
/// <summary>
/// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive.
/// </summary>
internal static string PageDirectiveMustExistAtTheTopOfFile
{
get => GetString("PageDirectiveMustExistAtTheTopOfFile");
}
/// <summary>
/// The '@{0}' directive must exist at the top of the file. Only comments and whitespace are allowed before the '@{0}' directive.
/// </summary>
internal static string FormatPageDirectiveMustExistAtTheTopOfFile(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("PageDirectiveMustExistAtTheTopOfFile"), p0);
/// <summary>
/// Mark the page as a Razor Page.
/// </summary>
internal static string PageDirective_Description
{
get => GetString("PageDirective_Description");
}
/// <summary>
/// Mark the page as a Razor Page.
/// </summary>
internal static string FormatPageDirective_Description()
=> GetString("PageDirective_Description");
/// <summary>
/// An optional route template for the page.
/// </summary>
internal static string PageDirective_RouteToken_Description
{
get => GetString("PageDirective_RouteToken_Description");
}
/// <summary>
/// An optional route template for the page.
/// </summary>
internal static string FormatPageDirective_RouteToken_Description()
=> GetString("PageDirective_RouteToken_Description");
/// <summary>
/// RouteTemplate
/// </summary>
internal static string PageDirective_RouteToken_Name
{
get => GetString("PageDirective_RouteToken_Name");
}
/// <summary>
/// RouteTemplate
/// </summary>
internal static string FormatPageDirective_RouteToken_Name()
=> GetString("PageDirective_RouteToken_Name");
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
System.Diagnostics.Debug.Assert(value != null);
if (formatterNames != null)
{
for (var i = 0; i < formatterNames.Length; i++)
{
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
}
}
return value;
}
}
}

Просмотреть файл

@ -0,0 +1,100 @@
// <auto-generated />
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
using System.Globalization;
using System.Reflection;
using System.Resources;
internal static class ViewComponentResources
{
private static readonly ResourceManager _resourceManager
= new ResourceManager("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentResources", typeof(ViewComponentResources).GetTypeInfo().Assembly);
/// <summary>
/// View component '{0}' must have exactly one public method named '{1}' or '{2}'.
/// </summary>
internal static string ViewComponent_AmbiguousMethods
{
get => GetString("ViewComponent_AmbiguousMethods");
}
/// <summary>
/// View component '{0}' must have exactly one public method named '{1}' or '{2}'.
/// </summary>
internal static string FormatViewComponent_AmbiguousMethods(object p0, object p1, object p2)
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AmbiguousMethods"), p0, p1, p2);
/// <summary>
/// Method '{0}' of view component '{1}' should be declared to return {2}&amp;lt;T&amp;gt;.
/// </summary>
internal static string ViewComponent_AsyncMethod_ShouldReturnTask
{
get => GetString("ViewComponent_AsyncMethod_ShouldReturnTask");
}
/// <summary>
/// Method '{0}' of view component '{1}' should be declared to return {2}&amp;lt;T&amp;gt;.
/// </summary>
internal static string FormatViewComponent_AsyncMethod_ShouldReturnTask(object p0, object p1, object p2)
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_AsyncMethod_ShouldReturnTask"), p0, p1, p2);
/// <summary>
/// Could not find an '{0}' or '{1}' method for the view component '{2}'.
/// </summary>
internal static string ViewComponent_CannotFindMethod
{
get => GetString("ViewComponent_CannotFindMethod");
}
/// <summary>
/// Could not find an '{0}' or '{1}' method for the view component '{2}'.
/// </summary>
internal static string FormatViewComponent_CannotFindMethod(object p0, object p1, object p2)
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_CannotFindMethod"), p0, p1, p2);
/// <summary>
/// Method '{0}' of view component '{1}' cannot return a {2}.
/// </summary>
internal static string ViewComponent_SyncMethod_CannotReturnTask
{
get => GetString("ViewComponent_SyncMethod_CannotReturnTask");
}
/// <summary>
/// Method '{0}' of view component '{1}' cannot return a {2}.
/// </summary>
internal static string FormatViewComponent_SyncMethod_CannotReturnTask(object p0, object p1, object p2)
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_CannotReturnTask"), p0, p1, p2);
/// <summary>
/// Method '{0}' of view component '{1}' should be declared to return a value.
/// </summary>
internal static string ViewComponent_SyncMethod_ShouldReturnValue
{
get => GetString("ViewComponent_SyncMethod_ShouldReturnValue");
}
/// <summary>
/// Method '{0}' of view component '{1}' should be declared to return a value.
/// </summary>
internal static string FormatViewComponent_SyncMethod_ShouldReturnValue(object p0, object p1)
=> string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_ShouldReturnValue"), p0, p1);
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
System.Diagnostics.Debug.Assert(value != null);
if (formatterNames != null)
{
for (var i = 0; i < formatterNames.Length; i++)
{
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
}
}
return value;
}
}
}

Просмотреть файл

@ -0,0 +1,49 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class RazorExtensions
{
public static void Register(RazorProjectEngineBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
InjectDirective.Register(builder);
ModelDirective.Register(builder);
NamespaceDirective.Register(builder);
PageDirective.Register(builder);
FunctionsDirective.Register(builder);
InheritsDirective.Register(builder);
SectionDirective.Register(builder);
builder.Features.Add(new DefaultTagHelperDescriptorProvider());
builder.Features.Add(new ViewComponentTagHelperDescriptorProvider());
builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension());
builder.AddTargetExtension(new TemplateTargetExtension()
{
TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult",
});
builder.Features.Add(new ModelExpressionPass());
builder.Features.Add(new PagesPropertyInjectionPass());
builder.Features.Add(new ViewComponentTagHelperPass());
builder.Features.Add(new RazorPageDocumentClassifierPass());
builder.Features.Add(new MvcViewDocumentClassifierPass());
builder.Features.Add(new AssemblyAttributeInjectionPass());
builder.Features.Add(new InstrumentationPass());
builder.SetImportFeature(new MvcImportProjectFeature());
}
}
}

Просмотреть файл

@ -0,0 +1,131 @@
// 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 System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal class RazorExtensionsDiagnosticFactory
{
private const string DiagnosticPrefix = "RZ";
internal static readonly RazorDiagnosticDescriptor ViewComponent_CannotFindMethod =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3900",
() => ViewComponentResources.ViewComponent_CannotFindMethod,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateViewComponent_CannotFindMethod(string tagHelperType)
{
var diagnostic = RazorDiagnostic.Create(
ViewComponent_CannotFindMethod,
new SourceSpan(SourceLocation.Undefined, contentLength: 0),
ViewComponentTypes.SyncMethodName,
ViewComponentTypes.AsyncMethodName,
tagHelperType);
return diagnostic;
}
internal static readonly RazorDiagnosticDescriptor ViewComponent_AmbiguousMethods =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3901",
() => ViewComponentResources.ViewComponent_AmbiguousMethods,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateViewComponent_AmbiguousMethods(string tagHelperType)
{
var diagnostic = RazorDiagnostic.Create(
ViewComponent_AmbiguousMethods,
new SourceSpan(SourceLocation.Undefined, contentLength: 0),
tagHelperType,
ViewComponentTypes.SyncMethodName,
ViewComponentTypes.AsyncMethodName);
return diagnostic;
}
internal static readonly RazorDiagnosticDescriptor ViewComponent_AsyncMethod_ShouldReturnTask =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3902",
() => ViewComponentResources.ViewComponent_AsyncMethod_ShouldReturnTask,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateViewComponent_AsyncMethod_ShouldReturnTask(string tagHelperType)
{
var diagnostic = RazorDiagnostic.Create(
ViewComponent_AsyncMethod_ShouldReturnTask,
new SourceSpan(SourceLocation.Undefined, contentLength: 0),
ViewComponentTypes.AsyncMethodName,
tagHelperType,
nameof(Task));
return diagnostic;
}
internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_ShouldReturnValue =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3903",
() => ViewComponentResources.ViewComponent_SyncMethod_ShouldReturnValue,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateViewComponent_SyncMethod_ShouldReturnValue(string tagHelperType)
{
var diagnostic = RazorDiagnostic.Create(
ViewComponent_SyncMethod_ShouldReturnValue,
new SourceSpan(SourceLocation.Undefined, contentLength: 0),
ViewComponentTypes.SyncMethodName,
tagHelperType);
return diagnostic;
}
internal static readonly RazorDiagnosticDescriptor ViewComponent_SyncMethod_CannotReturnTask =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3904",
() => ViewComponentResources.ViewComponent_SyncMethod_CannotReturnTask,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateViewComponent_SyncMethod_CannotReturnTask(string tagHelperType)
{
var diagnostic = RazorDiagnostic.Create(
ViewComponent_SyncMethod_CannotReturnTask,
new SourceSpan(SourceLocation.Undefined, contentLength: 0),
ViewComponentTypes.SyncMethodName,
tagHelperType,
nameof(Task));
return diagnostic;
}
internal static readonly RazorDiagnosticDescriptor PageDirective_CannotBeImported =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3905",
() => Resources.PageDirectiveCannotBeImported,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreatePageDirective_CannotBeImported(SourceSpan source)
{
var fileName = Path.GetFileName(source.FilePath);
var diagnostic = RazorDiagnostic.Create(PageDirective_CannotBeImported, source, PageDirective.Directive.Directive, fileName);
return diagnostic;
}
internal static readonly RazorDiagnosticDescriptor PageDirective_MustExistAtTheTopOfFile =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3906",
() => Resources.PageDirectiveMustExistAtTheTopOfFile,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreatePageDirective_MustExistAtTheTopOfFile(SourceSpan source)
{
var fileName = Path.GetFileName(source.FilePath);
var diagnostic = RazorDiagnostic.Create(PageDirective_MustExistAtTheTopOfFile, source, PageDirective.Directive.Directive);
return diagnostic;
}
}
}

Просмотреть файл

@ -0,0 +1,164 @@
// 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 System;
using System.Diagnostics;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class RazorPageDocumentClassifierPass : DocumentClassifierPassBase
{
public static readonly string RazorPageDocumentKind = "mvc.1.0.razor-page";
public static readonly string RouteTemplateKey = "RouteTemplate";
private static readonly RazorProjectEngine LeadingDirectiveParsingEngine = RazorProjectEngine.Create(
RazorConfiguration.Default,
RazorProjectFileSystem.Create("/"),
builder =>
{
for (var i = builder.Phases.Count - 1; i >= 0; i--)
{
var phase = builder.Phases[i];
builder.Phases.RemoveAt(i);
if (phase is IRazorDocumentClassifierPhase)
{
break;
}
}
RazorExtensions.Register(builder);
builder.Features.Add(new LeadingDirectiveParserOptionsFeature());
});
protected override string DocumentKind => RazorPageDocumentKind;
protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
return PageDirective.TryGetPageDirective(documentNode, out var pageDirective);
}
protected override void OnDocumentStructureCreated(
RazorCodeDocument codeDocument,
NamespaceDeclarationIntermediateNode @namespace,
ClassDeclarationIntermediateNode @class,
MethodDeclarationIntermediateNode method)
{
base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);
@namespace.Content = "AspNetCore";
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.RazorPages.Page";
var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;
if (string.IsNullOrEmpty(filePath))
{
// It's possible for a Razor document to not have a file path.
// Eg. When we try to generate code for an in memory document like default imports.
var checksum = BytesToString(codeDocument.Source.GetChecksum());
@class.ClassName = $"AspNetCore_{checksum}";
}
else
{
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
}
@class.Modifiers.Clear();
@class.Modifiers.Add("public");
method.MethodName = "ExecuteAsync";
method.Modifiers.Clear();
method.Modifiers.Add("public");
method.Modifiers.Add("async");
method.Modifiers.Add("override");
method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";
var document = codeDocument.GetDocumentIntermediateNode();
PageDirective.TryGetPageDirective(document, out var pageDirective);
EnsureValidPageDirective(codeDocument, pageDirective);
AddRouteTemplateMetadataAttribute(@namespace, @class, pageDirective);
}
private static void AddRouteTemplateMetadataAttribute(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, PageDirective pageDirective)
{
if (string.IsNullOrEmpty(pageDirective.RouteTemplate))
{
return;
}
var classIndex = @namespace.Children.IndexOf(@class);
if (classIndex == -1)
{
return;
}
var metadataAttributeNode = new RazorCompiledItemMetadataAttributeIntermediateNode
{
Key = RouteTemplateKey,
Value = pageDirective.RouteTemplate,
};
// Metadata attributes need to be inserted right before the class declaration.
@namespace.Children.Insert(classIndex, metadataAttributeNode);
}
private void EnsureValidPageDirective(RazorCodeDocument codeDocument, PageDirective pageDirective)
{
Debug.Assert(pageDirective != null);
if (pageDirective.DirectiveNode.IsImported())
{
pageDirective.DirectiveNode.Diagnostics.Add(
RazorExtensionsDiagnosticFactory.CreatePageDirective_CannotBeImported(pageDirective.DirectiveNode.Source.Value));
}
else
{
// The document contains a page directive and it is not imported.
// We now want to make sure this page directive exists at the top of the file.
// We are going to do that by re-parsing the document until the very first line that is not Razor comment
// or whitespace. We then make sure the page directive still exists in the re-parsed IR tree.
var leadingDirectiveCodeDocument = RazorCodeDocument.Create(codeDocument.Source);
LeadingDirectiveParsingEngine.Engine.Process(leadingDirectiveCodeDocument);
var leadingDirectiveDocumentNode = leadingDirectiveCodeDocument.GetDocumentIntermediateNode();
if (!PageDirective.TryGetPageDirective(leadingDirectiveDocumentNode, out var _))
{
// The page directive is not the leading directive. Add an error.
pageDirective.DirectiveNode.Diagnostics.Add(
RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(pageDirective.DirectiveNode.Source.Value));
}
}
}
private class LeadingDirectiveParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorParserOptionsFeature
{
public int Order { get; }
public void Configure(RazorParserOptionsBuilder options)
{
options.ParseLeadingDirectives = true;
}
}
private static string BytesToString(byte[] bytes)
{
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes));
}
var result = new StringBuilder(bytes.Length);
for (var i = 0; i < bytes.Length; i++)
{
// The x2 format means lowercase hex, where each byte is a 2-character string.
result.Append(bytes[i].ToString("x2"));
}
return result.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
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
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<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
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
mimetype set.
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
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
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
: 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
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
<value>Value cannot be null or empty.</value>
</data>
<data name="InjectDirective_Description" xml:space="preserve">
<value>Inject a service from the application's service container into a property.</value>
</data>
<data name="InjectDirective_MemberToken_Description" xml:space="preserve">
<value>The name of the property.</value>
</data>
<data name="InjectDirective_MemberToken_Name" xml:space="preserve">
<value>PropertyName</value>
</data>
<data name="InjectDirective_TypeToken_Description" xml:space="preserve">
<value>The type of the service to inject.</value>
</data>
<data name="InjectDirective_TypeToken_Name" xml:space="preserve">
<value>TypeName</value>
</data>
<data name="ModelDirective_Description" xml:space="preserve">
<value>Specify the view or page model for the page.</value>
</data>
<data name="ModelDirective_TypeToken_Description" xml:space="preserve">
<value>The model type.</value>
</data>
<data name="ModelDirective_TypeToken_Name" xml:space="preserve">
<value>TypeName</value>
</data>
<data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve">
<value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value>
</data>
<data name="MvcRazorCodeParser_InjectDirectivePropertyNameRequired" xml:space="preserve">
<value>A property name must be specified when using the '{0}' statement. Format for a '{0}' statement is '@{0} &lt;Type Name&gt; &lt;Property Name&gt;'.</value>
</data>
<data name="MvcRazorCodeParser_KeywordMustBeFollowedByTypeName" xml:space="preserve">
<value>The '{0}' keyword must be followed by a type name on the same line.</value>
</data>
<data name="MvcRazorCodeParser_OnlyOneModelStatementIsAllowed" xml:space="preserve">
<value>Only one '{0}' statement is allowed in a file.</value>
</data>
<data name="MvcRazorParser_InvalidPropertyType" xml:space="preserve">
<value>Invalid tag helper property '{0}.{1}'. Dictionary values must not be of type '{2}'.</value>
</data>
<data name="NamespaceDirective_Description" xml:space="preserve">
<value>Specify the base namespace for the page.</value>
</data>
<data name="NamespaceDirective_NamespaceToken_Description" xml:space="preserve">
<value>The namespace for the page.</value>
</data>
<data name="NamespaceDirective_NamespaceToken_Name" xml:space="preserve">
<value>Namespace</value>
</data>
<data name="PageDirectiveCannotBeImported" xml:space="preserve">
<value>The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.</value>
</data>
<data name="PageDirectiveMustExistAtTheTopOfFile" xml:space="preserve">
<value>The '@{0}' directive must precede all other elements defined in a Razor file.</value>
</data>
<data name="PageDirective_Description" xml:space="preserve">
<value>Mark the page as a Razor Page.</value>
</data>
<data name="PageDirective_RouteToken_Description" xml:space="preserve">
<value>An optional route template for the page.</value>
</data>
<data name="PageDirective_RouteToken_Name" xml:space="preserve">
<value>RouteTemplate</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,37 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class TagHelperDescriptorExtensions
{
/// <summary>
/// Indicates whether a <see cref="TagHelperDescriptor"/> represents a view component.
/// </summary>
/// <param name="tagHelper">The <see cref="TagHelperDescriptor"/> to check.</param>
/// <returns>Whether a <see cref="TagHelperDescriptor"/> represents a view component.</returns>
public static bool IsViewComponentKind(this TagHelperDescriptor tagHelper)
{
if (tagHelper == null)
{
throw new ArgumentNullException(nameof(tagHelper));
}
return string.Equals(ViewComponentTagHelperConventions.Kind, tagHelper.Kind, StringComparison.Ordinal);
}
public static string GetViewComponentName(this TagHelperDescriptor tagHelper)
{
if (tagHelper == null)
{
throw new ArgumentNullException(nameof(tagHelper));
}
tagHelper.Metadata.TryGetValue(ViewComponentTagHelperMetadata.Name, out var result);
return result;
}
}
}

Просмотреть файл

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
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
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<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
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
mimetype set.
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
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
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
: 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
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ViewComponent_AmbiguousMethods" xml:space="preserve">
<value>View component '{0}' must have exactly one public method named '{1}' or '{2}'.</value>
</data>
<data name="ViewComponent_AsyncMethod_ShouldReturnTask" xml:space="preserve">
<value>Method '{0}' of view component '{1}' should be declared to return {2}&amp;lt;T&amp;gt;.</value>
</data>
<data name="ViewComponent_CannotFindMethod" xml:space="preserve">
<value>Could not find an '{0}' or '{1}' method for the view component '{2}'.</value>
</data>
<data name="ViewComponent_SyncMethod_CannotReturnTask" xml:space="preserve">
<value>Method '{0}' of view component '{1}' cannot return a {2}.</value>
</data>
<data name="ViewComponent_SyncMethod_ShouldReturnValue" xml:space="preserve">
<value>Method '{0}' of view component '{1}' should be declared to return a value.</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,10 @@
// 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.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class ViewComponentTagHelperConventions
{
public static readonly string Kind = "MVC.ViewComponent";
}
}

Просмотреть файл

@ -0,0 +1,284 @@
// 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 System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal class ViewComponentTagHelperDescriptorFactory
{
private readonly INamedTypeSymbol _viewComponentAttributeSymbol;
private readonly INamedTypeSymbol _genericTaskSymbol;
private readonly INamedTypeSymbol _taskSymbol;
private readonly INamedTypeSymbol _iDictionarySymbol;
private static readonly SymbolDisplayFormat FullNameTypeDisplayFormat =
SymbolDisplayFormat.FullyQualifiedFormat
.WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted)
.WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & (~SymbolDisplayMiscellaneousOptions.UseSpecialTypes));
private static readonly IReadOnlyDictionary<string, string> PrimitiveDisplayTypeNameLookups = new Dictionary<string, string>(StringComparer.Ordinal)
{
[typeof(byte).FullName] = "byte",
[typeof(sbyte).FullName] = "sbyte",
[typeof(int).FullName] = "int",
[typeof(uint).FullName] = "uint",
[typeof(short).FullName] = "short",
[typeof(ushort).FullName] = "ushort",
[typeof(long).FullName] = "long",
[typeof(ulong).FullName] = "ulong",
[typeof(float).FullName] = "float",
[typeof(double).FullName] = "double",
[typeof(char).FullName] = "char",
[typeof(bool).FullName] = "bool",
[typeof(object).FullName] = "object",
[typeof(string).FullName] = "string",
[typeof(decimal).FullName] = "decimal",
};
public ViewComponentTagHelperDescriptorFactory(Compilation compilation)
{
_viewComponentAttributeSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute);
_genericTaskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.GenericTask);
_taskSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.Task);
_iDictionarySymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.IDictionary);
}
public virtual TagHelperDescriptor CreateDescriptor(INamedTypeSymbol type)
{
var assemblyName = type.ContainingAssembly.Name;
var shortName = GetShortName(type);
var tagName = $"vc:{HtmlConventions.ToHtmlCase(shortName)}";
var typeName = $"__Generated__{shortName}ViewComponentTagHelper";
var displayName = shortName + "ViewComponentTagHelper";
var descriptorBuilder = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, typeName, assemblyName);
descriptorBuilder.SetTypeName(typeName);
descriptorBuilder.DisplayName = displayName;
if (TryFindInvokeMethod(type, out var method, out var diagnostic))
{
var methodParameters = method.Parameters;
descriptorBuilder.TagMatchingRule(ruleBuilder =>
{
ruleBuilder.TagName = tagName;
AddRequiredAttributes(methodParameters, ruleBuilder);
});
AddBoundAttributes(methodParameters, displayName, descriptorBuilder);
}
else
{
descriptorBuilder.Diagnostics.Add(diagnostic);
}
descriptorBuilder.Metadata[ViewComponentTagHelperMetadata.Name] = shortName;
var descriptor = descriptorBuilder.Build();
return descriptor;
}
private bool TryFindInvokeMethod(INamedTypeSymbol type, out IMethodSymbol method, out RazorDiagnostic diagnostic)
{
var methods = GetInvokeMethods(type);
if (methods.Count == 0)
{
diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_CannotFindMethod(type.ToDisplayString(FullNameTypeDisplayFormat));
method = null;
return false;
}
else if (methods.Count > 1)
{
diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AmbiguousMethods(type.ToDisplayString(FullNameTypeDisplayFormat));
method = null;
return false;
}
var selectedMethod = methods[0];
var returnType = selectedMethod.ReturnType as INamedTypeSymbol;
if (string.Equals(selectedMethod.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal))
{
// Will invoke asynchronously. Method must not return Task or Task<T>.
if (returnType == _taskSymbol)
{
// This is ok.
}
else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol)
{
// This is ok.
}
else
{
diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_AsyncMethod_ShouldReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat));
method = null;
return false;
}
}
else
{
// Will invoke synchronously. Method must not return void, Task or Task<T>.
if (returnType.SpecialType == SpecialType.System_Void)
{
diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_ShouldReturnValue(type.ToDisplayString(FullNameTypeDisplayFormat));
method = null;
return false;
}
else if (returnType == _taskSymbol)
{
diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat));
method = null;
return false;
}
else if (returnType.IsGenericType && returnType.ConstructedFrom == _genericTaskSymbol)
{
diagnostic = RazorExtensionsDiagnosticFactory.CreateViewComponent_SyncMethod_CannotReturnTask(type.ToDisplayString(FullNameTypeDisplayFormat));
method = null;
return false;
}
}
method = selectedMethod;
diagnostic = null;
return true;
}
private static IReadOnlyList<IMethodSymbol> GetInvokeMethods(INamedTypeSymbol type)
{
var methods = new List<IMethodSymbol>();
while (type != null)
{
var currentTypeMethods = type.GetMembers()
.OfType<IMethodSymbol>()
.Where(m =>
m.DeclaredAccessibility == Accessibility.Public &&
!m.IsStatic &&
(string.Equals(m.Name, ViewComponentTypes.AsyncMethodName, StringComparison.Ordinal) ||
string.Equals(m.Name, ViewComponentTypes.SyncMethodName, StringComparison.Ordinal)));
methods.AddRange(currentTypeMethods);
type = type.BaseType;
}
return methods;
}
private void AddRequiredAttributes(ImmutableArray<IParameterSymbol> methodParameters, TagMatchingRuleDescriptorBuilder builder)
{
foreach (var parameter in methodParameters)
{
if (GetIndexerValueTypeName(parameter) == null)
{
// Set required attributes only for non-indexer attributes. Indexer attributes can't be required attributes
// because there are two ways of setting values for the attribute.
builder.Attribute(attributeBuilder =>
{
var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name);
attributeBuilder.Name = lowerKebabName;
});
}
}
}
private void AddBoundAttributes(ImmutableArray<IParameterSymbol> methodParameters, string containingDisplayName, TagHelperDescriptorBuilder builder)
{
foreach (var parameter in methodParameters)
{
var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name);
var typeName = parameter.Type.ToDisplayString(FullNameTypeDisplayFormat);
if (!PrimitiveDisplayTypeNameLookups.TryGetValue(typeName, out var simpleName))
{
simpleName = typeName;
}
builder.BindAttribute(attributeBuilder =>
{
attributeBuilder.Name = lowerKebabName;
attributeBuilder.TypeName = typeName;
attributeBuilder.DisplayName = $"{simpleName} {containingDisplayName}.{parameter.Name}";
attributeBuilder.SetPropertyName(parameter.Name);
if (parameter.Type.TypeKind == TypeKind.Enum)
{
attributeBuilder.IsEnum = true;
}
else
{
var dictionaryValueType = GetIndexerValueTypeName(parameter);
if (dictionaryValueType != null)
{
attributeBuilder.AsDictionary(lowerKebabName + "-", dictionaryValueType);
}
}
});
}
}
private string GetIndexerValueTypeName(IParameterSymbol parameter)
{
INamedTypeSymbol dictionaryType;
if ((parameter.Type as INamedTypeSymbol)?.ConstructedFrom == _iDictionarySymbol)
{
dictionaryType = (INamedTypeSymbol)parameter.Type;
}
else if (parameter.Type.AllInterfaces.Any(s => s.ConstructedFrom == _iDictionarySymbol))
{
dictionaryType = parameter.Type.AllInterfaces.First(s => s.ConstructedFrom == _iDictionarySymbol);
}
else
{
dictionaryType = null;
}
if (dictionaryType == null || dictionaryType.TypeArguments[0].SpecialType != SpecialType.System_String)
{
return null;
}
var type = dictionaryType.TypeArguments[1];
var typeName = type.ToDisplayString(FullNameTypeDisplayFormat);
return typeName;
}
private string GetShortName(INamedTypeSymbol componentType)
{
var viewComponentAttribute = componentType.GetAttributes().Where(a => a.AttributeClass == _viewComponentAttributeSymbol).FirstOrDefault();
var name = viewComponentAttribute
?.NamedArguments
.Where(namedArgument => string.Equals(namedArgument.Key, ViewComponentTypes.ViewComponent.Name, StringComparison.Ordinal))
.FirstOrDefault()
.Value
.Value as string;
if (!string.IsNullOrEmpty(name))
{
var separatorIndex = name.LastIndexOf('.');
if (separatorIndex >= 0)
{
return name.Substring(separatorIndex + 1);
}
else
{
return name;
}
}
// Get name by convention
if (componentType.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix, StringComparison.OrdinalIgnoreCase))
{
return componentType.Name.Substring(0, componentType.Name.Length - ViewComponentTypes.ViewComponentSuffix.Length);
}
else
{
return componentType.Name;
}
}
}
}

Просмотреть файл

@ -0,0 +1,72 @@
// 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 System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public sealed class ViewComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider
{
public int Order { get; set; }
public void Execute(TagHelperDescriptorProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var compilation = context.GetCompilation();
if (compilation == null)
{
// No compilation, nothing to do.
return;
}
var vcAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute);
var nonVCAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute);
if (vcAttribute == null || vcAttribute.TypeKind == TypeKind.Error)
{
// Could not find attributes we care about in the compilation. Nothing to do.
return;
}
var types = new List<INamedTypeSymbol>();
var visitor = new ViewComponentTypeVisitor(vcAttribute, nonVCAttribute, types);
// We always visit the global namespace.
visitor.Visit(compilation.Assembly.GlobalNamespace);
foreach (var reference in compilation.References)
{
if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
{
if (IsTagHelperAssembly(assembly))
{
visitor.Visit(assembly.GlobalNamespace);
}
}
}
var factory = new ViewComponentTagHelperDescriptorFactory(compilation);
for (var i = 0; i < types.Count; i++)
{
var descriptor = factory.CreateDescriptor(types[i]);
if (descriptor != null)
{
context.Results.Add(descriptor);
}
}
}
private bool IsTagHelperAssembly(IAssemblySymbol assembly)
{
return assembly.Name != null && !assembly.Name.StartsWith("System.", StringComparison.Ordinal);
}
}
}

Просмотреть файл

@ -0,0 +1,59 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public sealed class ViewComponentTagHelperIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children { get; } = IntermediateNodeCollection.ReadOnly;
public string ClassName { get; set; }
public TagHelperDescriptor TagHelper { get; set; }
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<ViewComponentTagHelperIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IViewComponentTagHelperTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IViewComponentTagHelperTargetExtension>(context);
return;
}
extension.WriteViewComponentTagHelper(context, this);
}
public override void FormatNode(IntermediateNodeFormatter formatter)
{
formatter.WriteContent(ClassName);
formatter.WriteProperty(nameof(ClassName), ClassName);
formatter.WriteProperty(nameof(TagHelper), TagHelper?.DisplayName);
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
// 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.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class ViewComponentTagHelperMetadata
{
/// <summary>
/// The key in a <see cref="Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor.Metadata"/> containing
/// the short name of a view component.
/// </summary>
public static readonly string Name = "MVC.ViewComponent.Name";
}
}

Просмотреть файл

@ -0,0 +1,203 @@
// 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 System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class ViewComponentTagHelperPass : IntermediateNodePassBase, IRazorOptimizationPass
{
// Run after the default taghelper pass
public override int Order => IntermediateNodePassBase.DefaultFeatureOrder + 2000;
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
var @namespace = documentNode.FindPrimaryNamespace();
var @class = documentNode.FindPrimaryClass();
if (@namespace == null || @class == null)
{
// Nothing to do, bail. We can't function without the standard structure.
return;
}
var context = new Context(@namespace, @class);
// For each VCTH *usage* we need to rewrite the tag helper node to use the tag helper runtime to construct
// and set properties on the the correct field, and using the name of the type we will generate.
var nodes = documentNode.FindDescendantNodes<TagHelperIntermediateNode>();
for (var i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
foreach (var tagHelper in node.TagHelpers)
{
RewriteUsage(context, node, tagHelper);
}
}
// Then for each VCTH *definition* that we've seen we need to generate the class that implements
// ITagHelper and the field that will hold it.
foreach (var tagHelper in context.TagHelpers)
{
AddField(context, tagHelper);
AddTagHelperClass(context, tagHelper);
}
}
private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper)
{
if (!tagHelper.IsViewComponentKind())
{
return;
}
context.Add(tagHelper);
// Now we need to insert a create node using the default tag helper runtime. This is similar to
// code in DefaultTagHelperOptimizationPass.
//
// Find the body node.
var i = 0;
while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode)
{
i++;
}
while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode)
{
i++;
}
// Now find the last create node.
while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode)
{
i++;
}
// Now i has the right insertion point.
node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode()
{
FieldName = context.GetFieldName(tagHelper),
TagHelper = tagHelper,
TypeName = context.GetFullyQualifiedName(tagHelper),
});
// Now we need to rewrite any set property nodes to use the default runtime.
for (i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode &&
propertyNode.TagHelper == tagHelper)
{
// This is a set property for this VCTH - we need to replace it with a node
// that will use our field and property name.
node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode)
{
FieldName = context.GetFieldName(tagHelper),
PropertyName = propertyNode.BoundAttribute.GetPropertyName(),
};
}
}
}
private void AddField(Context context, TagHelperDescriptor tagHelper)
{
// We need to insert a node for the field that will hold the tag helper. We've already generated a field name
// at this time and use it for all uses of the same tag helper type.
//
// We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing
// field nodes.
var i = 0;
while (i < context.Class.Children.Count && context.Class.Children[i] is DefaultTagHelperRuntimeIntermediateNode)
{
i++;
}
while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode)
{
i++;
}
context.Class.Children.Insert(i, new FieldDeclarationIntermediateNode()
{
Annotations =
{
{ CommonAnnotations.DefaultTagHelperExtension.TagHelperField, bool.TrueString },
},
Modifiers =
{
"private",
},
FieldName = context.GetFieldName(tagHelper),
FieldType = "global::" + context.GetFullyQualifiedName(tagHelper),
});
}
private void AddTagHelperClass(Context context, TagHelperDescriptor tagHelper)
{
var node = new ViewComponentTagHelperIntermediateNode()
{
ClassName = context.GetClassName(tagHelper),
TagHelper = tagHelper
};
context.Class.Children.Add(node);
}
private struct Context
{
private Dictionary<TagHelperDescriptor, (string className, string fullyQualifiedName, string fieldName)> _tagHelpers;
public Context(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class)
{
Namespace = @namespace;
Class = @class;
_tagHelpers = new Dictionary<TagHelperDescriptor, (string, string, string)>();
}
public ClassDeclarationIntermediateNode Class { get; }
public NamespaceDeclarationIntermediateNode Namespace { get; }
public IEnumerable<TagHelperDescriptor> TagHelpers => _tagHelpers.Keys;
public bool Add(TagHelperDescriptor tagHelper)
{
if (_tagHelpers.ContainsKey(tagHelper))
{
return false;
}
var className = $"__Generated__{tagHelper.GetViewComponentName()}ViewComponentTagHelper";
var fullyQualifiedName = $"{Namespace.Content}.{Class.ClassName}.{className}";
var fieldName = GenerateFieldName(tagHelper);
_tagHelpers.Add(tagHelper, (className, fullyQualifiedName, fieldName));
return true;
}
public string GetClassName(TagHelperDescriptor taghelper)
{
return _tagHelpers[taghelper].className;
}
public string GetFullyQualifiedName(TagHelperDescriptor taghelper)
{
return _tagHelpers[taghelper].fullyQualifiedName;
}
public string GetFieldName(TagHelperDescriptor taghelper)
{
return _tagHelpers[taghelper].fieldName;
}
private static string GenerateFieldName(TagHelperDescriptor tagHelper)
{
return $"__{tagHelper.GetViewComponentName()}ViewComponentTagHelper";
}
}
}
}

Просмотреть файл

@ -0,0 +1,183 @@
// 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 System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal class ViewComponentTagHelperTargetExtension : IViewComponentTagHelperTargetExtension
{
private static readonly string[] PublicModifiers = new[] { "public" };
public string TagHelperTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelper";
public string ViewComponentHelperTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.IViewComponentHelper";
public string ViewComponentHelperVariableName { get; set; } = "_helper";
public string ViewComponentInvokeMethodName { get; set; } = "InvokeAsync";
public string HtmlAttributeNotBoundAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute";
public string ViewContextAttributeTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute";
public string ViewContextTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext";
public string ViewContextPropertyName { get; set; } = "ViewContext";
public string HtmlTargetElementAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute";
public string TagHelperProcessMethodName { get; set; } = "ProcessAsync";
public string TagHelperContextTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext";
public string TagHelperContextVariableName { get; set; } = "context";
public string TagHelperOutputTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput";
public string TagHelperOutputVariableName { get; set; } = "output";
public string TagHelperOutputTagNamePropertyName { get; set; } = "TagName";
public string TagHelperOutputContentPropertyName { get; set; } = "Content";
public string TagHelperContentSetMethodName { get; set; } = "SetHtmlContent";
public string TagHelperContentVariableName { get; set; } = "content";
public string IViewContextAwareTypeName { get; set; } = "global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware";
public string IViewContextAwareContextualizeMethodName { get; set; } = "Contextualize";
public void WriteViewComponentTagHelper(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node)
{
// Add target element.
WriteTargetElementString(context.CodeWriter, node.TagHelper);
// Initialize declaration.
using (context.CodeWriter.BuildClassDeclaration(
PublicModifiers,
node.ClassName,
TagHelperTypeName,
interfaces: null,
typeParameters: null))
{
// Add view component helper.
context.CodeWriter.WriteVariableDeclaration(
$"private readonly {ViewComponentHelperTypeName}",
ViewComponentHelperVariableName,
value: null);
// Add constructor.
WriteConstructorString(context.CodeWriter, node.ClassName);
// Add attributes.
WriteAttributeDeclarations(context.CodeWriter, node.TagHelper);
// Add process method.
WriteProcessMethodString(context.CodeWriter, node.TagHelper);
}
}
private void WriteConstructorString(CodeWriter writer, string className)
{
writer.Write("public ")
.Write(className)
.Write("(")
.Write($"{ViewComponentHelperTypeName} helper")
.WriteLine(")");
using (writer.BuildScope())
{
writer.WriteStartAssignment(ViewComponentHelperVariableName)
.Write("helper")
.WriteLine(";");
}
}
private void WriteAttributeDeclarations(CodeWriter writer, TagHelperDescriptor tagHelper)
{
writer.Write("[")
.Write(HtmlAttributeNotBoundAttributeTypeName)
.WriteParameterSeparator()
.Write(ViewContextAttributeTypeName)
.WriteLine("]");
writer.WriteAutoPropertyDeclaration(
PublicModifiers,
ViewContextTypeName,
ViewContextPropertyName);
foreach (var attribute in tagHelper.BoundAttributes)
{
writer.WriteAutoPropertyDeclaration(
PublicModifiers,
attribute.TypeName,
attribute.GetPropertyName());
if (attribute.IndexerTypeName != null)
{
writer.Write(" = ")
.WriteStartNewObject(attribute.TypeName)
.WriteEndMethodInvocation();
}
}
}
private void WriteProcessMethodString(CodeWriter writer, TagHelperDescriptor tagHelper)
{
using (writer.BuildMethodDeclaration(
$"public override async",
$"global::{typeof(Task).FullName}",
TagHelperProcessMethodName,
new Dictionary<string, string>()
{
{ TagHelperContextTypeName, TagHelperContextVariableName },
{ TagHelperOutputTypeName, TagHelperOutputVariableName }
}))
{
writer.WriteInstanceMethodInvocation(
$"({ViewComponentHelperVariableName} as {IViewContextAwareTypeName})?",
IViewContextAwareContextualizeMethodName,
new[] { ViewContextPropertyName });
var methodParameters = GetMethodParameters(tagHelper);
writer.Write("var ")
.WriteStartAssignment(TagHelperContentVariableName)
.WriteInstanceMethodInvocation($"await {ViewComponentHelperVariableName}", ViewComponentInvokeMethodName, methodParameters);
writer.WriteStartAssignment($"{TagHelperOutputVariableName}.{TagHelperOutputTagNamePropertyName}")
.WriteLine("null;");
writer.WriteInstanceMethodInvocation(
$"{TagHelperOutputVariableName}.{TagHelperOutputContentPropertyName}",
TagHelperContentSetMethodName,
new[] { TagHelperContentVariableName });
}
}
private string[] GetMethodParameters(TagHelperDescriptor tagHelper)
{
var propertyNames = tagHelper.BoundAttributes.Select(attribute => attribute.GetPropertyName());
var joinedPropertyNames = string.Join(", ", propertyNames);
var parametersString = $"new {{ { joinedPropertyNames } }}";
var viewComponentName = tagHelper.GetViewComponentName();
var methodParameters = new[] { $"\"{viewComponentName}\"", parametersString };
return methodParameters;
}
private void WriteTargetElementString(CodeWriter writer, TagHelperDescriptor tagHelper)
{
Debug.Assert(tagHelper.TagMatchingRules.Count() == 1);
var rule = tagHelper.TagMatchingRules.First();
writer.Write("[")
.WriteStartMethodInvocation(HtmlTargetElementAttributeTypeName)
.WriteStringLiteral(rule.TagName)
.WriteLine(")]");
}
}
}

Просмотреть файл

@ -0,0 +1,88 @@
// 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 System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal class ViewComponentTypeVisitor : SymbolVisitor
{
private readonly INamedTypeSymbol _viewComponentAttribute;
private readonly INamedTypeSymbol _nonViewComponentAttribute;
private readonly List<INamedTypeSymbol> _results;
public ViewComponentTypeVisitor(
INamedTypeSymbol viewComponentAttribute,
INamedTypeSymbol nonViewComponentAttribute,
List<INamedTypeSymbol> results)
{
_viewComponentAttribute = viewComponentAttribute;
_nonViewComponentAttribute = nonViewComponentAttribute;
_results = results;
}
public override void VisitNamedType(INamedTypeSymbol symbol)
{
if (IsViewComponent(symbol))
{
_results.Add(symbol);
}
if (symbol.DeclaredAccessibility != Accessibility.Public)
{
return;
}
foreach (var member in symbol.GetTypeMembers())
{
Visit(member);
}
}
public override void VisitNamespace(INamespaceSymbol symbol)
{
foreach (var member in symbol.GetMembers())
{
Visit(member);
}
}
internal bool IsViewComponent(INamedTypeSymbol symbol)
{
if (_viewComponentAttribute == null)
{
return false;
}
if (symbol.DeclaredAccessibility != Accessibility.Public ||
symbol.IsAbstract ||
symbol.IsGenericType ||
AttributeIsDefined(symbol, _nonViewComponentAttribute))
{
return false;
}
return symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix) ||
AttributeIsDefined(symbol, _viewComponentAttribute);
}
private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute)
{
if (type == null || queryAttribute == null)
{
return false;
}
var attribute = type.GetAttributes().Where(a => a.AttributeClass == queryAttribute).FirstOrDefault();
if (attribute != null)
{
return true;
}
return AttributeIsDefined(type.BaseType, queryAttribute);
}
}
}

Просмотреть файл

@ -0,0 +1,35 @@
// 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 System;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal static class ViewComponentTypes
{
public const string Assembly = "Microsoft.AspNetCore.Mvc.ViewFeatures";
public static readonly Version AssemblyVersion = new Version(1, 1, 0, 0);
public const string ViewComponentSuffix = "ViewComponent";
public const string ViewComponentAttribute = "Microsoft.AspNetCore.Mvc.ViewComponentAttribute";
public const string NonViewComponentAttribute = "Microsoft.AspNetCore.Mvc.NonViewComponentAttribute";
public const string GenericTask = "System.Threading.Tasks.Task`1";
public const string Task = "System.Threading.Tasks.Task";
public const string IDictionary = "System.Collections.Generic.IDictionary`2";
public const string AsyncMethodName = "InvokeAsync";
public const string SyncMethodName = "Invoke";
public static class ViewComponent
{
public const string Name = "Name";
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,982 @@
{
"AssemblyIdentity": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.AssemblyAttributeInjectionPass",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase",
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass"
],
"Members": [
{
"Kind": "Method",
"Name": "ExecuteCore",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Razor.Language.CodeGeneration.ICodeTargetExtension"
],
"Members": [
{
"Kind": "Method",
"Name": "WriteInjectProperty",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext"
},
{
"Name": "node",
"Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode"
}
],
"ReturnType": "System.Void",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectDirective",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Register",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "Directive",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.Intermediate.ExtensionIntermediateNode",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_TypeName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_TypeName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_MemberName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_MemberName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Children",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeCollection",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Accept",
"Parameters": [
{
"Name": "visitor",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeVisitor"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "WriteNode",
"Parameters": [
{
"Name": "target",
"Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeTarget"
},
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectTargetExtension",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension"
],
"Members": [
{
"Kind": "Method",
"Name": "WriteInjectProperty",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeRenderingContext"
},
{
"Name": "node",
"Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InjectIntermediateNode"
}
],
"ReturnType": "System.Void",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IInjectTargetExtension",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.InstrumentationPass",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase",
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass"
],
"Members": [
{
"Kind": "Method",
"Name": "get_Order",
"Parameters": [],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "ExecuteCore",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ModelDirective",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Register",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "GetModelType",
"Parameters": [
{
"Name": "document",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "Directive",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ModelExpressionPass",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase",
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass"
],
"Members": [
{
"Kind": "Method",
"Name": "ExecuteCore",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.MvcViewDocumentClassifierPass",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_DocumentKind",
"Parameters": [],
"ReturnType": "System.String",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "IsMatch",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "OnDocumentStructureCreated",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "namespace",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode"
},
{
"Name": "class",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode"
},
{
"Name": "method",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "MvcViewDocumentKind",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.NamespaceDirective",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Register",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder"
}
],
"ReturnType": "System.Void",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "Directive",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PageDirective",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_RouteTemplate",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_DirectiveNode",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNode",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Register",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.IRazorEngineBuilder",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "TryGetPageDirective",
"Parameters": [
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
},
{
"Name": "pageDirective",
"Type": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PageDirective",
"Direction": "Out"
}
],
"ReturnType": "System.Boolean",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "Directive",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Razor.Language.DirectiveDescriptor",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.PagesPropertyInjectionPass",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase",
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass"
],
"Members": [
{
"Kind": "Method",
"Name": "ExecuteCore",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.RazorExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Register",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilder"
}
],
"ReturnType": "System.Void",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.RazorPageDocumentClassifierPass",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.DocumentClassifierPassBase",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_DocumentKind",
"Parameters": [],
"ReturnType": "System.String",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "IsMatch",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.Boolean",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "OnDocumentStructureCreated",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "namespace",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.NamespaceDeclarationIntermediateNode"
},
{
"Name": "class",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.ClassDeclarationIntermediateNode"
},
{
"Name": "method",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.MethodDeclarationIntermediateNode"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Field",
"Name": "RazorPageDocumentKind",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.TagHelperDescriptorExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "IsViewComponentKind",
"Parameters": [
{
"Name": "tagHelper",
"Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor"
}
],
"ReturnType": "System.Boolean",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "GetViewComponentName",
"Parameters": [
{
"Name": "tagHelper",
"Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptor"
}
],
"ReturnType": "System.String",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperConventions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "Kind",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperDescriptorProvider",
"Visibility": "Public",
"Kind": "Class",
"Sealed": true,
"BaseType": "Microsoft.AspNetCore.Razor.Language.RazorEngineFeatureBase",
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider"
],
"Members": [
{
"Kind": "Method",
"Name": "get_Order",
"Parameters": [],
"ReturnType": "System.Int32",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_Order",
"Parameters": [
{
"Name": "value",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Execute",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext"
}
],
"ReturnType": "System.Void",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.ITagHelperDescriptorProvider",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperMetadata",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "Name",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"ReadOnly": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTagHelperPass",
"Visibility": "Public",
"Kind": "Class",
"BaseType": "Microsoft.AspNetCore.Razor.Language.IntermediateNodePassBase",
"ImplementedInterfaces": [
"Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass"
],
"Members": [
{
"Kind": "Method",
"Name": "get_Order",
"Parameters": [],
"ReturnType": "System.Int32",
"Virtual": true,
"Override": true,
"ImplementedInterface": "Microsoft.AspNetCore.Razor.Language.IRazorOptimizationPass",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "ExecuteCore",
"Parameters": [
{
"Name": "codeDocument",
"Type": "Microsoft.AspNetCore.Razor.Language.RazorCodeDocument"
},
{
"Name": "documentNode",
"Type": "Microsoft.AspNetCore.Razor.Language.Intermediate.DocumentIntermediateNode"
}
],
"ReturnType": "System.Void",
"Virtual": true,
"Override": true,
"Visibility": "Protected",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriterExtensions+CSharpCodeWritingScope",
"Visibility": "Public",
"Kind": "Struct",
"Sealed": true,
"ImplementedInterfaces": [
"System.IDisposable"
],
"Members": [
{
"Kind": "Method",
"Name": "Dispose",
"Parameters": [],
"ReturnType": "System.Void",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "System.IDisposable",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "writer",
"Type": "Microsoft.AspNetCore.Razor.Language.CodeGeneration.CodeWriter"
},
{
"Name": "tabSize",
"Type": "System.Int32",
"DefaultValue": "4"
},
{
"Name": "autoSpace",
"Type": "System.Boolean",
"DefaultValue": "True"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.ViewComponentTypes+ViewComponent",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "Name",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": [],
"Constant": true,
"Literal": "\"Name\""
}
],
"GenericParameters": []
}
]
}

Просмотреть файл

@ -12,11 +12,6 @@
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="build\**\*.props" PackagePath="build\" />
<Content Include="build\**\*.targets" PackagePath="build\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Microsoft.AspNetCore.Razor.Language/Microsoft.AspNetCore.Razor.Language.csproj" />
<ProjectReference Include="../Microsoft.CodeAnalysis.Razor/Microsoft.CodeAnalysis.Razor.csproj" />

Просмотреть файл

@ -5,8 +5,7 @@ using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
using Microsoft.AspNetCore.Razor.Language;
[assembly: ProvideRazorExtensionInitializer("MVC-2.0", typeof(ExtensionInitializer))]
[assembly: ProvideRazorExtensionInitializer("MVC-2.1", typeof(ExtensionInitializer))]
[assembly: ProvideRazorExtensionInitializer("MVC-3.0", typeof(ExtensionInitializer))]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

Просмотреть файл

@ -3,25 +3,28 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("rzls, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Performance, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.GenerateTool, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Language.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.TagHelperTool, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Test.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Tools.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("rzc, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.GenerateTool, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.TagHelperTool, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Remote.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor.Test.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.RazorExtension, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Language.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Test.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Tools.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor.Test.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Performance, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

Просмотреть файл

@ -17,7 +17,9 @@ namespace Microsoft.AspNetCore.Razor.Language
public static readonly RazorLanguageVersion Version_2_1 = new RazorLanguageVersion(2, 1);
public static readonly RazorLanguageVersion Latest = Version_2_1;
public static readonly RazorLanguageVersion Version_3_0 = new RazorLanguageVersion(3, 0);
public static readonly RazorLanguageVersion Latest = Version_3_0;
public static readonly RazorLanguageVersion Experimental = new RazorLanguageVersion(1337, 1337);
@ -30,7 +32,7 @@ namespace Microsoft.AspNetCore.Razor.Language
if (string.Equals(languageVersion, "latest", StringComparison.OrdinalIgnoreCase))
{
version = Version_2_1;
version = Latest;
return true;
}
else if (string.Equals(languageVersion, "experimental", StringComparison.OrdinalIgnoreCase))
@ -38,6 +40,11 @@ namespace Microsoft.AspNetCore.Razor.Language
version = Experimental;
return true;
}
else if (languageVersion == "3.0")
{
version = Version_3_0;
return true;
}
else if (languageVersion == "2.1")
{
version = Version_2_1;

Просмотреть файл

@ -45,7 +45,7 @@
<MvcRazorExtenionOutput Include="..\Microsoft.AspNetCore.Mvc.Razor.Extensions\bin\$(Configuration)\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll" />
</ItemGroup>
<Copy SourceFiles="@(MvcRazorExtenionOutput)" DestinationFolder="$(SdkOutputPath)extensions\mvc-2-1\" />
<Copy SourceFiles="@(MvcRazorExtenionOutput)" DestinationFolder="$(SdkOutputPath)extensions\mvc-3-0\" />
<ItemGroup>
<ProjectOutput Include="..\Microsoft.NET.Sdk.Razor\bin\$(Configuration)\net46*\Microsoft.NET.Sdk.Razor.Tasks.*" />

Просмотреть файл

@ -49,31 +49,31 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>
<PropertyGroup Condition="'$(RazorLangVersion)'==''">
<RazorLangVersion Condition="'$(_TargetingNETCoreApp30OrLater)' == 'true'">2.1</RazorLangVersion>
<RazorLangVersion Condition="'$(_TargetingNETCoreApp30OrLater)' == 'true'">3.0</RazorLangVersion>
</PropertyGroup>
<!--
Set the primary configuration supported by this SDK as the default configuration for Razor.
-->
<PropertyGroup Condition="'$(RazorDefaultConfiguration)'==''">
<RazorDefaultConfiguration Condition="'$(_TargetingNETCoreApp30OrLater)' == 'true'">MVC-2.1</RazorDefaultConfiguration>
<RazorDefaultConfiguration Condition="'$(_TargetingNETCoreApp30OrLater)' == 'true'">MVC-3.0</RazorDefaultConfiguration>
</PropertyGroup>
<ItemGroup>
<!--
While technically the assembly in this package can provide support for the MVC-2.0 configuration, don't declare
While technically the assembly in this package can provide support for the MVC-2.X, don't declare
it here. The IDE is hardcoded to inject 2.0 support when needed. The settings flowing through MSBuild should reflect
the project's runtime.
-->
<RazorConfiguration Include="MVC-2.1">
<Extensions>MVC-2.1;$(CustomRazorExtension)</Extensions>
<RazorConfiguration Include="MVC-3.0">
<Extensions>MVC-3.0;$(CustomRazorExtension)</Extensions>
</RazorConfiguration>
</ItemGroup>
<ItemGroup>
<RazorExtension Include="MVC-2.1">
<RazorExtension Include="MVC-3.0">
<AssemblyName>Microsoft.AspNetCore.Mvc.Razor.Extensions</AssemblyName>
<AssemblyFilePath>$(RazorSdkDirectoryRoot)extensions\mvc-2-1\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll</AssemblyFilePath>
<AssemblyFilePath>$(RazorSdkDirectoryRoot)extensions\mvc-3-0\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll</AssemblyFilePath>
</RazorExtension>
</ItemGroup>

Просмотреть файл

@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
[ExportCustomProjectEngineFactory("MVC-2.0", SupportsSerialization = true)]
internal class LegacyProjectEngineFactory_2_0 : IProjectEngineFactory
{
private const string AssemblyName = "Microsoft.AspNetCore.Mvc.Razor.Extensions";
private const string AssemblyName = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X";
public RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action<RazorProjectEngineBuilder> configure)
{
// Rewrite the assembly name into a full name just like this one, but with the name of the MVC design time assembly.

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
[ExportCustomProjectEngineFactory("MVC-2.1", SupportsSerialization = true)]
internal class LegacyProjectEngineFactory_2_1 : IProjectEngineFactory
{
private const string AssemblyName = "Microsoft.AspNetCore.Mvc.Razor.Extensions";
private const string AssemblyName = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X";
public RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action<RazorProjectEngineBuilder> configure)
{
// Rewrite the assembly name into a full name just like this one, but with the name of the MVC design time assembly.

Просмотреть файл

@ -0,0 +1,31 @@
// 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 System;
using System.Reflection;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.Editor.Razor
{
[ExportCustomProjectEngineFactory("MVC-3.0", SupportsSerialization = true)]
internal class LegacyProjectEngineFactory_3_0 : IProjectEngineFactory
{
private const string AssemblyName = "Microsoft.AspNetCore.Mvc.Razor.Extensions";
public RazorProjectEngine Create(RazorConfiguration configuration, RazorProjectFileSystem fileSystem, Action<RazorProjectEngineBuilder> configure)
{
// Rewrite the assembly name into a full name just like this one, but with the name of the MVC design time assembly.
var assemblyName = new AssemblyName(typeof(LegacyProjectEngineFactory_3_0).Assembly.FullName);
assemblyName.Name = AssemblyName;
var extension = new AssemblyExtension(configuration.ConfigurationName, Assembly.Load(assemblyName));
var initializer = extension.CreateInitializer();
return RazorProjectEngine.Create(configuration, fileSystem, b =>
{
initializer.Initialize(b);
configure?.Invoke(b);
});
}
}
}

Просмотреть файл

@ -19,9 +19,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.IntegrationTests
: base(generateBaselines: null)
{
Configuration = RazorConfiguration.Create(
RazorLanguageVersion.Version_2_0,
"MVC-2.1",
new[] { new AssemblyExtension("MVC-2.1", typeof(ExtensionInitializer).Assembly) });
RazorLanguageVersion.Version_3_0,
"MVC-3.0",
new[] { new AssemblyExtension("MVC-3.0", typeof(ExtensionInitializer).Assembly) });
}
protected override CSharpCompilation BaseCompilation => DefaultBaseCompilation;

Просмотреть файл

@ -41,11 +41,11 @@
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourcePackageVersion)" />
</ItemGroup>
<ItemGroup>
<MvcShim Condition="$(TargetFramework) != ''" Include="..\Microsoft.AspNetCore.Razor.Test.MvcShim\bin\$(Configuration)\$(TargetFramework)\Microsoft.AspNetCore.Razor.Test.MvcShim.deps.json" />
</ItemGroup>
<Target Name="CopyDepsFromShims" AfterTargets="Build">
<ItemGroup>
<MvcShim Condition="$(TargetFramework) != ''" Include="..\Microsoft.AspNetCore.Razor.Test.MvcShim\bin\$(Configuration)\$(TargetFramework)\Microsoft.AspNetCore.Razor.Test.MvcShim.deps.json" />
</ItemGroup>
<Copy SourceFiles="@(MvcShim)" DestinationFolder="$(OutputPath)" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,444 @@
// 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.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class AssemblyAttributeInjectionPassTest
{
[Fact]
public void Execute_NoOps_IfNamespaceNodeIsMissing()
{
// Arrange
var irDocument = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument);
// Assert
Assert.Empty(irDocument.Children);
}
[Fact]
public void Execute_NoOps_IfNamespaceNodeHasEmptyContent()
{
// Arrange
var irDocument = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = string.Empty };
@namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace;
builder.Push(@namespace);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument);
// Assert
Assert.Collection(irDocument.Children,
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_NoOps_IfClassNameNodeIsMissing()
{
// Arrange
var irDocument = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "SomeNamespace" };
builder.Push(@namespace);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument);
// Assert
Assert.Collection(
irDocument.Children,
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_NoOps_IfClassNameIsEmpty()
{
// Arrange
var irDocument = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode
{
Content = "SomeNamespace",
Annotations =
{
[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
},
};
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode
{
Annotations =
{
[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
},
};
builder.Add(@class);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument);
// Assert
Assert.Collection(irDocument.Children,
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_NoOps_IfDocumentIsNotViewOrPage()
{
// Arrange
var irDocument = new DocumentIntermediateNode
{
DocumentKind = "Default",
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "SomeNamespace" };
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode
{
ClassName = "SomeName",
Annotations =
{
[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
},
};
builder.Add(@class);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument);
// Assert
Assert.Collection(
irDocument.Children,
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_NoOps_ForDesignTime()
{
// Arrange
var irDocument = new DocumentIntermediateNode
{
DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind,
Options = RazorCodeGenerationOptions.CreateDesignTimeDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode
{
Content = "SomeNamespace",
Annotations =
{
[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
},
};
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode
{
ClassName = "SomeName",
Annotations =
{
[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
},
};
builder.Add(@class);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml"));
var document = RazorCodeDocument.Create(source);
// Act
pass.Execute(document, irDocument);
// Assert
Assert.Collection(
irDocument.Children,
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_AddsRazorViewAttribute_ToViews()
{
// Arrange
var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName))]";
var irDocument = new DocumentIntermediateNode
{
DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind,
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode
{
Content = "SomeNamespace",
Annotations =
{
[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
},
};
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode
{
ClassName = "SomeName",
Annotations =
{
[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
},
};
builder.Add(@class);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml"));
var document = RazorCodeDocument.Create(source);
// Act
pass.Execute(document, irDocument);
// Assert
Assert.Collection(irDocument.Children,
node =>
{
var csharpCode = Assert.IsType<CSharpCodeIntermediateNode>(node);
var token = Assert.IsType<IntermediateToken>(Assert.Single(csharpCode.Children));
Assert.Equal(TokenKind.CSharp, token.Kind);
Assert.Equal(expectedAttribute, token.Content);
},
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_EscapesViewPathWhenAddingAttributeToViews()
{
// Arrange
var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/test/\"\"Index.cshtml\", typeof(SomeNamespace.SomeName))]";
var irDocument = new DocumentIntermediateNode
{
DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind,
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode
{
Content = "SomeNamespace",
Annotations =
{
[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
},
};
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode
{
ClassName = "SomeName",
Annotations =
{
[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
},
};
builder.Add(@class);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "\\test\\\"Index.cshtml"));
var document = RazorCodeDocument.Create(source);
// Act
pass.Execute(document, irDocument);
// Assert
Assert.Collection(irDocument.Children,
node =>
{
var csharpCode = Assert.IsType<CSharpCodeIntermediateNode>(node);
var token = Assert.IsType<IntermediateToken>(Assert.Single(csharpCode.Children));
Assert.Equal(TokenKind.CSharp, token.Kind);
Assert.Equal(expectedAttribute, token.Content);
},
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_AddsRazorPagettribute_ToPage()
{
// Arrange
var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@\"/Views/Index.cshtml\", typeof(SomeNamespace.SomeName), null)]";
var irDocument = new DocumentIntermediateNode
{
DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind,
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var pageDirective = new DirectiveIntermediateNode
{
Directive = PageDirective.Directive,
};
builder.Add(pageDirective);
var @namespace = new NamespaceDeclarationIntermediateNode
{
Content = "SomeNamespace",
Annotations =
{
[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
},
};
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode
{
ClassName = "SomeName",
Annotations =
{
[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
},
};
builder.Add(@class);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "/Views/Index.cshtml"));
var document = RazorCodeDocument.Create(source);
// Act
pass.Execute(document, irDocument);
// Assert
Assert.Collection(irDocument.Children,
node => Assert.Same(pageDirective, node),
node =>
{
var csharpCode = Assert.IsType<CSharpCodeIntermediateNode>(node);
var token = Assert.IsType<IntermediateToken>(Assert.Single(csharpCode.Children));
Assert.Equal(TokenKind.CSharp, token.Kind);
Assert.Equal(expectedAttribute, token.Content);
},
node => Assert.Same(@namespace, node));
}
[Fact]
public void Execute_EscapesViewPathAndRouteWhenAddingAttributeToPage()
{
// Arrange
var expectedAttribute = "[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@\"/test/\"\"Index.cshtml\", typeof(SomeNamespace.SomeName))]";
var irDocument = new DocumentIntermediateNode
{
DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind,
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(irDocument);
var @namespace = new NamespaceDeclarationIntermediateNode
{
Content = "SomeNamespace",
Annotations =
{
[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace
},
};
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode
{
ClassName = "SomeName",
Annotations =
{
[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
},
};
builder.Add(@class);
var pass = new AssemblyAttributeInjectionPass
{
Engine = RazorProjectEngine.Create().Engine,
};
var source = TestRazorSourceDocument.Create("test", new RazorSourceDocumentProperties(filePath: null, relativePath: "test\\\"Index.cshtml"));
var document = RazorCodeDocument.Create(source);
// Act
pass.Execute(document, irDocument);
// Assert
Assert.Collection(irDocument.Children,
node =>
{
var csharpCode = Assert.IsType<CSharpCodeIntermediateNode>(node);
var token = Assert.IsType<IntermediateToken>(Assert.Single(csharpCode.Children));
Assert.Equal(TokenKind.CSharp, token.Kind);
Assert.Equal(expectedAttribute, token.Content);
},
node => Assert.Same(@namespace, node));
}
private DocumentIntermediateNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorDocumentClassifierPhase)
{
break;
}
}
return codeDocument.GetDocumentIntermediateNode();
}
}
}

Просмотреть файл

@ -0,0 +1,225 @@
// 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 System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class InjectDirectiveTest
{
[Fact]
public void InjectDirectivePass_Execute_DefinesProperty()
{
// Arrange
var codeDocument = CreateDocument(@"
@inject PropertyType PropertyName
");
var engine = CreateEngine();
var pass = new InjectDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal(2, @class.Children.Count);
var node = Assert.IsType<InjectIntermediateNode>(@class.Children[1]);
Assert.Equal("PropertyType", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
}
[Fact]
public void InjectDirectivePass_Execute_DedupesPropertiesByName()
{
// Arrange
var codeDocument = CreateDocument(@"
@inject PropertyType PropertyName
@inject PropertyType2 PropertyName
");
var engine = CreateEngine();
var pass = new InjectDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal(2, @class.Children.Count);
var node = Assert.IsType<InjectIntermediateNode>(@class.Children[1]);
Assert.Equal("PropertyType2", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
}
[Fact]
public void InjectDirectivePass_Execute_ExpandsTModel_WithDynamic()
{
// Arrange
var codeDocument = CreateDocument(@"
@inject PropertyType<TModel> PropertyName
");
var engine = CreateEngine();
var pass = new InjectDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal(2, @class.Children.Count);
var node = Assert.IsType<InjectIntermediateNode>(@class.Children[1]);
Assert.Equal("PropertyType<dynamic>", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
}
[Fact]
public void InjectDirectivePass_Execute_ExpandsTModel_WithModelTypeFirst()
{
// Arrange
var codeDocument = CreateDocument(@"
@model ModelType
@inject PropertyType<TModel> PropertyName
");
var engine = CreateEngine();
var pass = new InjectDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal(2, @class.Children.Count);
var node = Assert.IsType<InjectIntermediateNode>(@class.Children[1]);
Assert.Equal("PropertyType<ModelType>", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
}
[Fact]
public void InjectDirectivePass_Execute_ExpandsTModel_WithModelType()
{
// Arrange
var codeDocument = CreateDocument(@"
@inject PropertyType<TModel> PropertyName
@model ModelType
");
var engine = CreateEngine();
var pass = new InjectDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal(2, @class.Children.Count);
var node = Assert.IsType<InjectIntermediateNode>(@class.Children[1]);
Assert.Equal("PropertyType<ModelType>", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
}
private RazorCodeDocument CreateDocument(string content)
{
var source = RazorSourceDocument.Create(content, "test.cshtml");
return RazorCodeDocument.Create(source);
}
private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node)
{
var visitor = new ClassNodeVisitor();
visitor.Visit(node);
return visitor.Node;
}
private RazorEngine CreateEngine()
{
return RazorProjectEngine.Create(b =>
{
// Notice we're not registering the InjectDirective.Pass here so we can run it on demand.
b.AddDirective(InjectDirective.Directive);
b.AddDirective(ModelDirective.Directive);
}).Engine;
}
private DocumentIntermediateNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorDocumentClassifierPhase)
{
break;
}
}
return codeDocument.GetDocumentIntermediateNode();
}
private string GetCSharpContent(IntermediateNode node)
{
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
var child = node.Children[i] as IntermediateToken;
if (child.Kind == TokenKind.CSharp)
{
builder.Append(child.Content);
}
}
return builder.ToString();
}
private class ClassNodeVisitor : IntermediateNodeWalker
{
public ClassDeclarationIntermediateNode Node { get; set; }
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
Node = node;
}
}
}
}

Просмотреть файл

@ -0,0 +1,68 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class InjectTargetExtensionTest
{
[Fact]
public void InjectDirectiveTargetExtension_WritesProperty()
{
// Arrange
var context = TestCodeRenderingContext.CreateRuntime();
var target = new InjectTargetExtension();
var node = new InjectIntermediateNode()
{
TypeName = "PropertyType",
MemberName = "PropertyName",
};
// Act
target.WriteInjectProperty(context, node);
// Assert
Assert.Equal(
"[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
"public PropertyType PropertyName { get; private set; }" + Environment.NewLine,
context.CodeWriter.GenerateCode());
}
[Fact]
public void InjectDirectiveTargetExtension_WritesPropertyWithLinePragma_WhenSourceIsSet()
{
// Arrange
var context = TestCodeRenderingContext.CreateRuntime();
var target = new InjectTargetExtension();
var node = new InjectIntermediateNode()
{
TypeName = "PropertyType<ModelType>",
MemberName = "PropertyName",
Source = new SourceSpan(
filePath: "test-path",
absoluteIndex: 0,
lineIndex: 1,
characterIndex: 1,
length: 10)
};
// Act
target.WriteInjectProperty(context, node);
// Assert
Assert.Equal(
"#line 2 \"test-path\"" + Environment.NewLine +
"[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]" + Environment.NewLine +
"public PropertyType<ModelType> PropertyName { get; private set; }" + Environment.NewLine + Environment.NewLine +
"#line default" + Environment.NewLine +
"#line hidden" + Environment.NewLine,
context.CodeWriter.GenerateCode());
}
}
}

Просмотреть файл

@ -0,0 +1,348 @@
// 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.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class InstrumentationPassTest
{
[Fact]
public void InstrumentationPass_NoOps_ForDesignTime()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDesignTimeDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new HtmlContentIntermediateNode());
builder.Add(new IntermediateToken()
{
Content = "Hi",
Kind = TokenKind.Html,
});
builder.Pop();
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n => IntermediateNodeAssert.Html("Hi", n));
}
[Fact]
public void InstrumentationPass_InstrumentsHtml()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new HtmlContentIntermediateNode()
{
Source = CreateSource(1),
});
builder.Add(new IntermediateToken()
{
Content = "Hi",
Kind = TokenKind.Html,
Source = CreateSource(1)
});
builder.Pop();
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n => BeginInstrumentation("1, 1, true", n),
n => IntermediateNodeAssert.Html("Hi", n),
n => EndInstrumentation(n));
}
[Fact]
public void InstrumentationPass_SkipsHtml_WithoutLocation()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new HtmlContentIntermediateNode());
builder.Add(new IntermediateToken()
{
Content = "Hi",
Kind = TokenKind.Html,
});
builder.Pop();
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n => IntermediateNodeAssert.Html("Hi", n));
}
[Fact]
public void InstrumentationPass_InstrumentsCSharpExpression()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new CSharpExpressionIntermediateNode()
{
Source = CreateSource(2),
});
builder.Add(new IntermediateToken()
{
Content = "Hi",
Kind = TokenKind.CSharp,
});
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n => BeginInstrumentation("2, 2, false", n),
n => CSharpExpression("Hi", n),
n => EndInstrumentation(n));
}
[Fact]
public void InstrumentationPass_SkipsCSharpExpression_WithoutLocation()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new CSharpExpressionIntermediateNode());
builder.Add(new IntermediateToken()
{
Content = "Hi",
Kind = TokenKind.CSharp,
});
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n => CSharpExpression("Hi", n));
}
[Fact]
public void InstrumentationPass_SkipsCSharpExpression_InsideTagHelperAttribute()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new TagHelperIntermediateNode());
builder.Push(new TagHelperHtmlAttributeIntermediateNode());
builder.Push(new CSharpExpressionIntermediateNode()
{
Source = CreateSource(5)
});
builder.Add(new IntermediateToken()
{
Content = "Hi",
Kind = TokenKind.CSharp,
});
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n =>
{
Assert.IsType<TagHelperIntermediateNode>(n);
Children(
n,
c =>
{
Assert.IsType<TagHelperHtmlAttributeIntermediateNode>(c);
Children(
c,
s => CSharpExpression("Hi", s));
});
});
}
[Fact]
public void InstrumentationPass_SkipsCSharpExpression_InsideTagHelperProperty()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new TagHelperIntermediateNode());
builder.Push(new TagHelperPropertyIntermediateNode());
builder.Push(new CSharpExpressionIntermediateNode()
{
Source = CreateSource(5)
});
builder.Add(new IntermediateToken()
{
Content = "Hi",
Kind = TokenKind.CSharp,
});
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n =>
{
Assert.IsType<TagHelperIntermediateNode>(n);
Children(
n,
c =>
{
Assert.IsType<TagHelperPropertyIntermediateNode>(c);
Children(
c,
s => CSharpExpression("Hi", s));
});
});
}
[Fact]
public void InstrumentationPass_InstrumentsTagHelper()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Add(new TagHelperIntermediateNode()
{
Source = CreateSource(3),
});
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n => BeginInstrumentation("3, 3, false", n),
n => Assert.IsType<TagHelperIntermediateNode>(n),
n => EndInstrumentation(n));
}
[Fact]
public void InstrumentationPass_SkipsTagHelper_WithoutLocation()
{
// Arrange
var document = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new TagHelperIntermediateNode());
var pass = new InstrumentationPass()
{
Engine = RazorProjectEngine.CreateEmpty().Engine,
};
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);
// Assert
Children(
document,
n => Assert.IsType<TagHelperIntermediateNode>(n));
}
private SourceSpan CreateSource(int number)
{
// The actual source span doesn't really matter, we just want to see the values used.
return new SourceSpan(new SourceLocation(number, number, number), number);
}
}
}

Просмотреть файл

@ -0,0 +1,961 @@
// 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 System.Linq;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.IntegrationTests;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IntegrationTests
{
public class CodeGenerationIntegrationTest : IntegrationTestBase
{
private readonly static CSharpCompilation DefaultBaseCompilation = MvcShim.BaseCompilation.WithAssemblyName("AppCode");
public CodeGenerationIntegrationTest()
: base(generateBaselines: null)
{
Configuration = RazorConfiguration.Create(
RazorLanguageVersion.Version_2_0,
"MVC-2.1",
new[] { new AssemblyExtension("MVC-2.1", typeof(ExtensionInitializer).Assembly) });
}
protected override CSharpCompilation BaseCompilation => DefaultBaseCompilation;
protected override RazorConfiguration Configuration { get; }
#region Runtime
[Fact]
public void UsingDirectives_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false, throwOnFailure: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
var diagnostics = compiled.Compilation.GetDiagnostics().Where(d => d.Severity >= DiagnosticSeverity.Warning);
Assert.Equal("The using directive for 'System' appeared previously in this namespace", Assert.Single(diagnostics).GetMessage());
}
[Fact]
public void InvalidNamespaceAtEOF_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ1014", Assert.Single(diagnotics).Id);
}
[Fact]
public void IncompleteDirectives_Runtime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyService<TModel>
{
public string Html { get; set; }
}");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
// We expect this test to generate a bunch of errors.
Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0);
}
[Fact]
public void InheritsViewModel_Runtime()
{
// Arrange
AddCSharpSyntaxTree(@"
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Razor;
public class MyBasePageForViews<TModel> : RazorPage
{
public override Task ExecuteAsync()
{
throw new System.NotImplementedException();
}
}
public class MyModel
{
}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void InheritsWithViewImports_Runtime()
{
// Arrange
AddCSharpSyntaxTree(@"
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
public abstract class MyPageModel<T> : Page
{
public override Task ExecuteAsync()
{
throw new System.NotImplementedException();
}
}
public class MyModel
{
}");
AddProjectItemFromText(@"@inherits MyPageModel<TModel>");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void MalformedPageDirective_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ1016", Assert.Single(diagnotics).Id);
}
[Fact]
public void Basic_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void Sections_Runtime()
{
// Arrange
AddCSharpSyntaxTree($@"
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class InputTestTagHelper : {typeof(TagHelper).FullName}
{{
public ModelExpression For {{ get; set; }}
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void _ViewImports_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void Inject_Runtime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyApp
{
public string MyProperty { get; set; }
}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void InjectWithModel_Runtime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyModel
{
}
public class MyService<TModel>
{
public string Html { get; set; }
}
public class MyApp
{
public string MyProperty { get; set; }
}");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void InjectWithSemicolon_Runtime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyModel
{
}
public class MyApp
{
public string MyProperty { get; set; }
}
public class MyService<TModel>
{
public string Html { get; set; }
}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void Model_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void ModelExpressionTagHelper_Runtime()
{
// Arrange
AddCSharpSyntaxTree($@"
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class InputTestTagHelper : {typeof(TagHelper).FullName}
{{
public ModelExpression For {{ get; set; }}
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void RazorPages_Runtime()
{
// Arrange
AddCSharpSyntaxTree($@"
public class DivTagHelper : {typeof(TagHelper).FullName}
{{
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void RazorPagesWithRouteTemplate_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void RazorPagesWithoutModel_Runtime()
{
// Arrange
AddCSharpSyntaxTree($@"
public class DivTagHelper : {typeof(TagHelper).FullName}
{{
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void PageWithNamespace_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void ViewWithNamespace_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void ViewComponentTagHelper_Runtime()
{
// Arrange
AddCSharpSyntaxTree($@"
public class TestViewComponent
{{
public string Invoke(string firstName)
{{
return firstName;
}}
}}
[{typeof(HtmlTargetElementAttribute).FullName}]
public class AllTagHelper : {typeof(TagHelper).FullName}
{{
public string Bar {{ get; set; }}
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
}
[Fact]
public void RazorPageWithNoLeadingPageDirective_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ3906", Assert.Single(diagnotics).Id);
}
#endregion
#region DesignTime
[Fact]
public void UsingDirectives_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true, throwOnFailure: false);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
var diagnostics = compiled.Compilation.GetDiagnostics().Where(d => d.Severity >= DiagnosticSeverity.Warning);
Assert.Equal("The using directive for 'System' appeared previously in this namespace", Assert.Single(diagnostics).GetMessage());
}
[Fact]
public void InvalidNamespaceAtEOF_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ1014", Assert.Single(diagnotics).Id);
}
[Fact]
public void IncompleteDirectives_DesignTime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyService<TModel>
{
public string Html { get; set; }
}");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
// We expect this test to generate a bunch of errors.
Assert.True(compiled.CodeDocument.GetCSharpDocument().Diagnostics.Count > 0);
}
[Fact]
public void InheritsViewModel_DesignTime()
{
// Arrange
AddCSharpSyntaxTree(@"
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Razor;
public class MyBasePageForViews<TModel> : RazorPage
{
public override Task ExecuteAsync()
{
throw new System.NotImplementedException();
}
}
public class MyModel
{
}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void InheritsWithViewImports_DesignTime()
{
// Arrange
AddCSharpSyntaxTree(@"
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
public abstract class MyPageModel<T> : Page
{
public override Task ExecuteAsync()
{
throw new System.NotImplementedException();
}
}
public class MyModel
{
}");
AddProjectItemFromText(@"@inherits MyPageModel<TModel>");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void MalformedPageDirective_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ1016", Assert.Single(diagnotics).Id);
}
[Fact]
public void Basic_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void Sections_DesignTime()
{
// Arrange
AddCSharpSyntaxTree($@"
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class InputTestTagHelper : {typeof(TagHelper).FullName}
{{
public ModelExpression For {{ get; set; }}
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void _ViewImports_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void Inject_DesignTime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyApp
{
public string MyProperty { get; set; }
}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void InjectWithModel_DesignTime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyModel
{
}
public class MyService<TModel>
{
public string Html { get; set; }
}
public class MyApp
{
public string MyProperty { get; set; }
}");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void InjectWithSemicolon_DesignTime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class MyModel
{
}
public class MyApp
{
public string MyProperty { get; set; }
}
public class MyService<TModel>
{
public string Html { get; set; }
}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void Model_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void MultipleModels_DesignTime()
{
// Arrange
AddCSharpSyntaxTree(@"
public class ThisShouldBeGenerated
{
}");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ2001", Assert.Single(diagnotics).Id);
}
[Fact]
public void ModelExpressionTagHelper_DesignTime()
{
// Arrange
AddCSharpSyntaxTree($@"
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class InputTestTagHelper : {typeof(TagHelper).FullName}
{{
public ModelExpression For {{ get; set; }}
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void RazorPages_DesignTime()
{
// Arrange
AddCSharpSyntaxTree($@"
public class DivTagHelper : {typeof(TagHelper).FullName}
{{
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void RazorPagesWithRouteTemplate_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void RazorPagesWithoutModel_DesignTime()
{
// Arrange
AddCSharpSyntaxTree($@"
public class DivTagHelper : {typeof(TagHelper).FullName}
{{
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void PageWithNamespace_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void ViewWithNamespace_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void ViewComponentTagHelper_DesignTime()
{
// Arrange
AddCSharpSyntaxTree($@"
public class TestViewComponent
{{
public string Invoke(string firstName)
{{
return firstName;
}}
}}
[{typeof(HtmlTargetElementAttribute).FullName}]
public class AllTagHelper : {typeof(TagHelper).FullName}
{{
public string Bar {{ get; set; }}
}}
");
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToAssembly(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void RazorPageWithNoLeadingPageDirective_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();
// Act
var compiled = CompileToCSharp(projectItem, designTime: true);
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ3906", Assert.Single(diagnotics).Id);
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,92 @@
// 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 System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.IntegrationTests;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.IntegrationTests
{
public class InstrumentationPassIntegrationTest : IntegrationTestBase
{
[Fact]
public void BasicTest()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "p",
typeName: "PTagHelper",
assemblyName: "TestAssembly"),
CreateTagHelperDescriptor(
tagName: "form",
typeName: "FormTagHelper",
assemblyName: "TestAssembly"),
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("value")
.PropertyName("FooProp")
.TypeName("System.String"), // Gets preallocated
builder => builder
.Name("date")
.PropertyName("BarProp")
.TypeName("System.DateTime"), // Doesn't get preallocated
})
};
var engine = CreateProjectEngine(b =>
{
b.AddTagHelpers(descriptors);
b.Features.Add(new InstrumentationPass());
// This test includes templates
b.AddTargetExtension(new TemplateTargetExtension());
});
var projectItem = CreateProjectItemFromFile();
// Act
var document = engine.Process(projectItem);
// Assert
AssertDocumentNodeMatchesBaseline(document.GetDocumentIntermediateNode());
var csharpDocument = document.GetCSharpDocument();
AssertCSharpDocumentMatchesBaseline(csharpDocument);
Assert.Empty(csharpDocument.Diagnostics);
}
private static TagHelperDescriptor CreateTagHelperDescriptor(
string tagName,
string typeName,
string assemblyName,
IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null)
{
var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
builder.TypeName(typeName);
if (attributes != null)
{
foreach (var attributeBuilder in attributes)
{
builder.BoundAttributeDescriptor(attributeBuilder);
}
}
builder.TagMatchingRuleDescriptor(ruleBuilder => ruleBuilder.RequireTagName(tagName));
var descriptor = builder.Build();
return descriptor;
}
}
}

Просмотреть файл

@ -0,0 +1,52 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
<PreserveCompilationContext>true</PreserveCompilationContext>
<DefaultItemExcludes>$(DefaultItemExcludes);TestFiles\**</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\**" />
<None Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj" />
<ProjectReference Include="..\Microsoft.AspNetCore.Razor.Test.Common\Microsoft.AspNetCore.Razor.Test.Common.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj" />
<ProjectReference Include="..\..\src\Microsoft.CodeAnalysis.Razor\Microsoft.CodeAnalysis.Razor.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisCSharpPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="$(MicrosoftExtensionsDependencyModelPackageVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
<PackageReference Include="Moq" Version="$(MoqPackageVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
</ItemGroup>
<ItemGroup>
<!-- We need this to compile but don't want it referenced by the project. It is included dynamically in CodeGeneration tests. -->
<ProjectReference Include="..\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Targets>Build</Targets>
</ProjectReference>
<!-- Due to how DependencyContext.Load handles our special MvcShim reference above we need to also reference the MvcShim's DiagnosticSource dependency -->
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourcePackageVersion)" />
</ItemGroup>
<Target Name="CopyDepsFromShims" AfterTargets="Build">
<ItemGroup>
<MvcShim Condition="$(TargetFramework) != ''" Include="..\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X\bin\$(Configuration)\$(TargetFramework)\Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.deps.json" />
</ItemGroup>
<Copy SourceFiles="@(MvcShim)" DestinationFolder="$(OutputPath)" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,343 @@
// 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 System;
using System.IO;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class ModelDirectiveTest
{
[Fact]
public void ModelDirective_GetModelType_GetsTypeFromFirstWellFormedDirective()
{
// Arrange
var codeDocument = CreateDocument(@"
@model Type1
@model Type2
@model
");
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = ModelDirective.GetModelType(irDocument);
// Assert
Assert.Equal("Type1", result);
}
[Fact]
public void ModelDirective_GetModelType_DefaultsToDynamic()
{
// Arrange
var codeDocument = CreateDocument(@" ");
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = ModelDirective.GetModelType(irDocument);
// Assert
Assert.Equal("dynamic", result);
}
[Fact]
public void ModelDirectivePass_Execute_ReplacesTModelInBaseType()
{
// Arrange
var codeDocument = CreateDocument(@"
@inherits BaseType<TModel>
@model Type1
");
var engine = CreateEngine();
var pass = new ModelDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal("BaseType<Type1>", @class.BaseType);
}
[Fact]
public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DifferentOrdering()
{
// Arrange
var codeDocument = CreateDocument(@"
@model Type1
@inherits BaseType<TModel>
@model Type2
");
var engine = CreateEngine();
var pass = new ModelDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal("BaseType<Type1>", @class.BaseType);
}
[Fact]
public void ModelDirectivePass_Execute_NoOpWithoutTModel()
{
// Arrange
var codeDocument = CreateDocument(@"
@inherits BaseType
@model Type1
");
var engine = CreateEngine();
var pass = new ModelDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal("BaseType", @class.BaseType);
}
[Fact]
public void ModelDirectivePass_Execute_ReplacesTModelInBaseType_DefaultDynamic()
{
// Arrange
var codeDocument = CreateDocument(@"
@inherits BaseType<TModel>
");
var engine = CreateEngine();
var pass = new ModelDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal("BaseType<dynamic>", @class.BaseType);
}
[Fact]
public void ModelDirectivePass_DesignTime_AddsTModelUsingDirective()
{
// Arrange
var codeDocument = CreateDocument(@"
@inherits BaseType<TModel>
");
var engine = CreateDesignTimeEngine();
var pass = new ModelDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal("BaseType<dynamic>", @class.BaseType);
var @namespace = FindNamespaceNode(irDocument);
var usingNode = Assert.IsType<UsingDirectiveIntermediateNode>(@namespace.Children[0]);
Assert.Equal($"TModel = global::{typeof(object).FullName}", usingNode.Content);
}
[Fact]
public void ModelDirectivePass_DesignTime_WithModel_AddsTModelUsingDirective()
{
// Arrange
var codeDocument = CreateDocument(@"
@inherits BaseType<TModel>
@model SomeType
");
var engine = CreateDesignTimeEngine();
var pass = new ModelDirective.Pass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var @class = FindClassNode(irDocument);
Assert.NotNull(@class);
Assert.Equal("BaseType<SomeType>", @class.BaseType);
var @namespace = FindNamespaceNode(irDocument);
var usingNode = Assert.IsType<UsingDirectiveIntermediateNode>(@namespace.Children[0]);
Assert.Equal($"TModel = global::System.Object", usingNode.Content);
}
private RazorCodeDocument CreateDocument(string content)
{
var source = RazorSourceDocument.Create(content, "test.cshtml");
return RazorCodeDocument.Create(source);
}
private ClassDeclarationIntermediateNode FindClassNode(IntermediateNode node)
{
var visitor = new ClassNodeVisitor();
visitor.Visit(node);
return visitor.Node;
}
private NamespaceDeclarationIntermediateNode FindNamespaceNode(IntermediateNode node)
{
var visitor = new NamespaceNodeVisitor();
visitor.Visit(node);
return visitor.Node;
}
private RazorEngine CreateEngine()
{
return CreateEngineCore();
}
private RazorEngine CreateDesignTimeEngine()
{
return CreateEngineCore(designTime: true);
}
private RazorEngine CreateEngineCore(bool designTime = false)
{
return RazorProjectEngine.Create(b =>
{
// Notice we're not registering the ModelDirective.Pass here so we can run it on demand.
b.AddDirective(ModelDirective.Directive);
// There's some special interaction with the inherits directive
InheritsDirective.Register(b);
b.Features.Add(new DesignTimeOptionsFeature(designTime));
}).Engine;
}
private DocumentIntermediateNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorDocumentClassifierPhase)
{
break;
}
}
// InheritsDirectivePass needs to run before ModelDirective.
var pass = new InheritsDirectivePass()
{
Engine = engine
};
pass.Execute(codeDocument, codeDocument.GetDocumentIntermediateNode());
return codeDocument.GetDocumentIntermediateNode();
}
private string GetCSharpContent(IntermediateNode node)
{
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
var child = node.Children[i] as IntermediateToken;
if (child.Kind == TokenKind.CSharp)
{
builder.Append(child.Content);
}
}
return builder.ToString();
}
private class ClassNodeVisitor : IntermediateNodeWalker
{
public ClassDeclarationIntermediateNode Node { get; set; }
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
Node = node;
}
}
private class NamespaceNodeVisitor : IntermediateNodeWalker
{
public NamespaceDeclarationIntermediateNode Node { get; set; }
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
{
Node = node;
}
}
private class DesignTimeOptionsFeature : IConfigureRazorParserOptionsFeature, IConfigureRazorCodeGenerationOptionsFeature
{
private bool _designTime;
public DesignTimeOptionsFeature(bool designTime)
{
_designTime = designTime;
}
public int Order { get; }
public RazorEngine Engine { get; set; }
public void Configure(RazorParserOptionsBuilder options)
{
options.SetDesignTime(_designTime);
}
public void Configure(RazorCodeGenerationOptionsBuilder options)
{
options.SetDesignTime(_designTime);
}
}
}
}

Просмотреть файл

@ -0,0 +1,208 @@
// 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 System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class ModelExpressionPassTest
{
[Fact]
public void ModelExpressionPass_NonModelExpressionProperty_Ignored()
{
// Arrange
var codeDocument = CreateDocument(@"
@addTagHelper TestTagHelper, TestAssembly
<p foo=""17"">");
var tagHelpers = new[]
{
TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
.BoundAttributeDescriptor(attribute =>
attribute
.Name("Foo")
.TypeName("System.Int32"))
.TagMatchingRuleDescriptor(rule =>
rule.RequireTagName("p"))
.Build()
};
var engine = CreateEngine(tagHelpers);
var pass = new ModelExpressionPass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var tagHelper = FindTagHelperNode(irDocument);
var setProperty = tagHelper.Children.OfType<TagHelperPropertyIntermediateNode>().Single();
var token = Assert.IsType<IntermediateToken>(Assert.Single(setProperty.Children));
Assert.True(token.IsCSharp);
Assert.Equal("17", token.Content);
}
[Fact]
public void ModelExpressionPass_ModelExpressionProperty_SimpleExpression()
{
// Arrange
// Using \r\n here because we verify line mappings
var codeDocument = CreateDocument(
"@addTagHelper TestTagHelper, TestAssembly\r\n<p foo=\"Bar\">");
var tagHelpers = new[]
{
TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
.BoundAttributeDescriptor(attribute =>
attribute
.Name("Foo")
.TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"))
.TagMatchingRuleDescriptor(rule =>
rule.RequireTagName("p"))
.Build()
};
var engine = CreateEngine(tagHelpers);
var pass = new ModelExpressionPass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var tagHelper = FindTagHelperNode(irDocument);
var setProperty = tagHelper.Children.OfType<TagHelperPropertyIntermediateNode>().Single();
var expression = Assert.IsType<CSharpExpressionIntermediateNode>(Assert.Single(setProperty.Children));
Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Bar)", GetCSharpContent(expression));
var originalNode = Assert.IsType<IntermediateToken>(expression.Children[2]);
Assert.Equal(TokenKind.CSharp, originalNode.Kind);
Assert.Equal("Bar", originalNode.Content);
Assert.Equal(new SourceSpan("test.cshtml", 51, 1, 8, 3), originalNode.Source.Value);
}
[Fact]
public void ModelExpressionPass_ModelExpressionProperty_ComplexExpression()
{
// Arrange
// Using \r\n here because we verify line mappings
var codeDocument = CreateDocument(
"@addTagHelper TestTagHelper, TestAssembly\r\n<p foo=\"@Bar\">");
var tagHelpers = new[]
{
TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
.BoundAttributeDescriptor(attribute =>
attribute
.Name("Foo")
.TypeName("Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"))
.TagMatchingRuleDescriptor(rule =>
rule.RequireTagName("p"))
.Build()
};
var engine = CreateEngine(tagHelpers);
var pass = new ModelExpressionPass()
{
Engine = engine,
};
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var tagHelper = FindTagHelperNode(irDocument);
var setProperty = tagHelper.Children.OfType<TagHelperPropertyIntermediateNode>().Single();
var expression = Assert.IsType<CSharpExpressionIntermediateNode>(Assert.Single(setProperty.Children));
Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => Bar)", GetCSharpContent(expression));
var originalNode = Assert.IsType<IntermediateToken>(expression.Children[1]);
Assert.Equal(TokenKind.CSharp, originalNode.Kind);
Assert.Equal("Bar", originalNode.Content);
Assert.Equal(new SourceSpan("test.cshtml", 52, 1, 9, 3), originalNode.Source.Value);
}
private RazorCodeDocument CreateDocument(string content)
{
var source = RazorSourceDocument.Create(content, "test.cshtml");
return RazorCodeDocument.Create(source);
}
private RazorEngine CreateEngine(params TagHelperDescriptor[] tagHelpers)
{
return RazorProjectEngine.Create(b =>
{
b.Features.Add(new TestTagHelperFeature(tagHelpers));
}).Engine;
}
private DocumentIntermediateNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorDirectiveClassifierPhase)
{
break;
}
}
return codeDocument.GetDocumentIntermediateNode();
}
private TagHelperIntermediateNode FindTagHelperNode(IntermediateNode node)
{
var visitor = new TagHelperNodeVisitor();
visitor.Visit(node);
return visitor.Node;
}
private string GetCSharpContent(IntermediateNode node)
{
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
var child = node.Children[i] as IntermediateToken;
if (child.Kind == TokenKind.CSharp)
{
builder.Append(child.Content);
}
}
return builder.ToString();
}
private class TagHelperNodeVisitor : IntermediateNodeWalker
{
public TagHelperIntermediateNode Node { get; set; }
public override void VisitTagHelper(TagHelperIntermediateNode node)
{
Node = node;
}
}
}
}

Просмотреть файл

@ -0,0 +1,76 @@
// 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 System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Language;
using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class MvcImportProjectFeatureTest
{
[Fact]
public void AddDefaultDirectivesImport_AddsSingleDynamicImport()
{
// Arrange
var imports = new List<RazorProjectItem>();
// Act
MvcImportProjectFeature.AddDefaultDirectivesImport(imports);
// Assert
var import = Assert.Single(imports);
Assert.Null(import.FilePath);
}
[Fact]
public void AddHierarchicalImports_AddsViewImportSourceDocumentsOnDisk()
{
// Arrange
var imports = new List<RazorProjectItem>();
var projectItem = new TestRazorProjectItem("/Contact/Index.cshtml");
var testFileSystem = new TestRazorProjectFileSystem(new[]
{
new TestRazorProjectItem("/Index.cshtml"),
new TestRazorProjectItem("/_ViewImports.cshtml"),
new TestRazorProjectItem("/Contact/_ViewImports.cshtml"),
projectItem,
});
var mvcImportFeature = new MvcImportProjectFeature()
{
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
};
// Act
mvcImportFeature.AddHierarchicalImports(projectItem, imports);
// Assert
Assert.Collection(imports,
import => Assert.Equal("/_ViewImports.cshtml", import.FilePath),
import => Assert.Equal("/Contact/_ViewImports.cshtml", import.FilePath));
}
[Fact]
public void AddHierarchicalImports_AddsViewImportSourceDocumentsNotOnDisk()
{
// Arrange
var imports = new List<RazorProjectItem>();
var projectItem = new TestRazorProjectItem("/Pages/Contact/Index.cshtml");
var testFileSystem = new TestRazorProjectFileSystem(new[] { projectItem });
var mvcImportFeature = new MvcImportProjectFeature()
{
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
};
// Act
mvcImportFeature.AddHierarchicalImports(projectItem, imports);
// Assert
Assert.Collection(imports,
import => Assert.Equal("/_ViewImports.cshtml", import.FilePath),
import => Assert.Equal("/Pages/_ViewImports.cshtml", import.FilePath),
import => Assert.Equal("/Pages/Contact/_ViewImports.cshtml", import.FilePath));
}
}
}

Просмотреть файл

@ -0,0 +1,45 @@
// 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 System.IO;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
internal static class MvcShim
{
public static readonly string AssemblyName = "Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X";
private static Assembly _assembly;
private static CSharpCompilation _baseCompilation;
public static Assembly Assembly
{
get
{
if (_assembly == null)
{
var filePath = Path.Combine(Directory.GetCurrentDirectory(), AssemblyName + ".dll");
_assembly = Assembly.LoadFrom(filePath);
}
return _assembly;
}
}
public static CSharpCompilation BaseCompilation
{
get
{
if (_baseCompilation == null)
{
_baseCompilation = TestCompilation.Create(Assembly);
}
return _baseCompilation;
}
}
}
}

Просмотреть файл

@ -0,0 +1,264 @@
// 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.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class MvcViewDocumentClassifierPassTest
{
[Fact]
public void MvcViewDocumentClassifierPass_SetsDocumentKind()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml"));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
// Assert
Assert.Equal("mvc.1.0.view", irDocument.DocumentKind);
}
[Fact]
public void MvcViewDocumentClassifierPass_NoOpsIfDocumentKindIsAlreadySet()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml"));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
irDocument.DocumentKind = "some-value";
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
// Assert
Assert.Equal("some-value", irDocument.DocumentKind);
}
[Fact]
public void MvcViewDocumentClassifierPass_SetsNamespace()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml"));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("AspNetCore", visitor.Namespace.Content);
}
[Fact]
public void MvcViewDocumentClassifierPass_SetsClass()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml");
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>", visitor.Class.BaseType);
Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
Assert.Equal("Test", visitor.Class.ClassName);
}
[Fact]
public void MvcViewDocumentClassifierPass_NullFilePath_SetsClass()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>", visitor.Class.BaseType);
Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
Assert.Equal("AspNetCore_d9f877a857a7e9928eac04d09a59f25967624155", visitor.Class.ClassName);
}
[Theory]
[InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")]
[InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")]
public void MvcViewDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected)
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal(expected, visitor.Class.ClassName);
}
[Fact]
public void MvcViewDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName);
}
[Fact]
public void MvcViewDocumentClassifierPass_SanitizesClassName()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars");
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName);
}
[Fact]
public void MvcViewDocumentClassifierPass_SetsUpExecuteAsyncMethod()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml"));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("ExecuteAsync", visitor.Method.MethodName);
Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType);
Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers);
}
private static RazorProjectEngine CreateProjectEngine() => RazorProjectEngine.Create();
private static DocumentIntermediateNode CreateIRDocument(RazorProjectEngine projectEngine, RazorCodeDocument codeDocument)
{
for (var i = 0; i < projectEngine.Phases.Count; i++)
{
var phase = projectEngine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorIntermediateNodeLoweringPhase)
{
break;
}
}
return codeDocument.GetDocumentIntermediateNode();
}
private class Visitor : IntermediateNodeWalker
{
public NamespaceDeclarationIntermediateNode Namespace { get; private set; }
public ClassDeclarationIntermediateNode Class { get; private set; }
public MethodDeclarationIntermediateNode Method { get; private set; }
public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node)
{
Method = node;
}
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
{
Namespace = node;
base.VisitNamespaceDeclaration(node);
}
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
Class = node;
base.VisitClassDeclaration(node);
}
}
}
}

Просмотреть файл

@ -0,0 +1,352 @@
// 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.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class NamespaceDirectiveTest
{
[Fact]
public void GetNamespace_IncompleteDirective_UsesEmptyNamespace()
{
// Arrange
var source = "c:\\foo\\bar\\bleh.cshtml";
var imports = "c:\\foo\\baz\\bleh.cshtml";
var node = new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan(imports, 0, 0, 0, 0),
};
// Act
var @namespace = NamespaceDirective.GetNamespace(source, node);
// Assert
Assert.Equal(string.Empty, @namespace);
}
[Fact]
public void GetNamespace_EmptyDirective_UsesEmptyNamespace()
{
// Arrange
var source = "c:\\foo\\bar\\bleh.cshtml";
var imports = "c:\\foo\\baz\\bleh.cshtml";
var node = new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan(imports, 0, 0, 0, 0),
};
node.Children.Add(new DirectiveTokenIntermediateNode() { Content = string.Empty });
// Act
var @namespace = NamespaceDirective.GetNamespace(source, node);
// Assert
Assert.Equal(string.Empty, @namespace);
}
// When we don't have a relationship between the source file and the imports file
// we will just use the namespace on the node directly.
[Theory]
[InlineData((string)null, (string)null)]
[InlineData("", "")]
[InlineData(null, "/foo/bar")]
[InlineData("/foo/baz", "/foo/bar/bleh")]
[InlineData("/foo.cshtml", "/foo/bar.cshtml")]
[InlineData("c:\\foo.cshtml", "d:\\foo\\bar.cshtml")]
[InlineData("c:\\foo\\bar\\bleh.cshtml", "c:\\foo\\baz\\bleh.cshtml")]
public void GetNamespace_ForNonRelatedFiles_UsesNamespaceVerbatim(string source, string imports)
{
// Arrange
var node = new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan(imports, 0, 0, 0, 0),
};
node.Children.Add(new DirectiveTokenIntermediateNode() { Content = "Base" });
// Act
var @namespace = NamespaceDirective.GetNamespace(source, node);
// Assert
Assert.Equal("Base", @namespace);
}
[Theory]
[InlineData("/foo.cshtml", "/_ViewImports.cshtml", "Base")]
[InlineData("/foo/bar.cshtml", "/_ViewImports.cshtml", "Base.foo")]
[InlineData("/foo/bar/baz.cshtml", "/_ViewImports.cshtml", "Base.foo.bar")]
[InlineData("/foo/bar/baz.cshtml", "/foo/_ViewImports.cshtml", "Base.bar")]
[InlineData("/Foo/bar/baz.cshtml", "/foo/_ViewImports.cshtml", "Base.bar")]
[InlineData("c:\\foo.cshtml", "c:\\_ViewImports.cshtml", "Base")]
[InlineData("c:\\foo\\bar.cshtml", "c:\\_ViewImports.cshtml", "Base.foo")]
[InlineData("c:\\foo\\bar\\baz.cshtml", "c:\\_ViewImports.cshtml", "Base.foo.bar")]
[InlineData("c:\\foo\\bar\\baz.cshtml", "c:\\foo\\_ViewImports.cshtml", "Base.bar")]
[InlineData("c:\\Foo\\bar\\baz.cshtml", "c:\\foo\\_ViewImports.cshtml", "Base.bar")]
public void GetNamespace_ForRelatedFiles_ComputesNamespaceWithSuffix(string source, string imports, string expected)
{
// Arrange
var node = new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan(imports, 0, 0, 0, 0),
};
node.Children.Add(new DirectiveTokenIntermediateNode() { Content = "Base" });
// Act
var @namespace = NamespaceDirective.GetNamespace(source, node);
// Assert
Assert.Equal(expected, @namespace);
}
// This is the case where a _ViewImports sets the namespace.
[Fact]
public void Pass_SetsNamespace_ComputedFromImports()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" });
builder.Pop();
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" };
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" };
builder.Add(@class);
document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind;
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));
var pass = new NamespaceDirective.Pass();
pass.Engine = Mock.Of<RazorEngine>();
// Act
pass.Execute(codeDocument, document);
// Assert
Assert.Equal("WebApplication.Account.Manage", @namespace.Content);
Assert.Equal("default", @class.ClassName);
}
// This is the case where the source file sets the namespace.
[Fact]
public void Pass_SetsNamespace_ComputedFromSource()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
// This will be ignored.
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "ignored" });
builder.Pop();
// This will be used.
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan("/Account/Manage/AddUser.cshtml", 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account.Manage" });
builder.Pop();
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" };
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" };
builder.Add(@class);
document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind;
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));
var pass = new NamespaceDirective.Pass();
pass.Engine = Mock.Of<RazorEngine>();
// Act
pass.Execute(codeDocument, document);
// Assert
Assert.Equal("WebApplication.Account.Manage", @namespace.Content);
Assert.Equal("default", @class.ClassName);
}
// Handles cases where invalid characters appears in FileNames. Note that we don't sanitize the part of
// the namespace that you put in an import, just the file-based-suffix. Garbage in, garbage out.
[Fact]
public void Pass_SetsNamespace_SanitizesClassAndNamespace()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" });
builder.Pop();
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" };
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" };
builder.Add(@class);
document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind;
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage-Info/Add+User.cshtml"));
var pass = new NamespaceDirective.Pass();
pass.Engine = Mock.Of<RazorEngine>();
// Act
pass.Execute(codeDocument, document);
// Assert
Assert.Equal("WebApplication.Account.Manage_Info", @namespace.Content);
Assert.Equal("default", @class.ClassName);
}
// This is the case where the source file sets the namespace.
[Fact]
public void Pass_SetsNamespace_ComputedFromSource_ForView()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
// This will be ignored.
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "ignored" });
builder.Pop();
// This will be used.
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan("/Account/Manage/AddUser.cshtml", 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account.Manage" });
builder.Pop();
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" };
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" };
builder.Add(@class);
document.DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind;
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));
var pass = new NamespaceDirective.Pass();
pass.Engine = Mock.Of<RazorEngine>();
// Act
pass.Execute(codeDocument, document);
// Assert
Assert.Equal("WebApplication.Account.Manage", @namespace.Content);
Assert.Equal("default", @class.ClassName);
}
// This handles an error case where we can't determine the relationship between the
// imports and the source.
[Fact]
public void Pass_SetsNamespace_VerbatimFromImports()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan(null, 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" });
builder.Pop();
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" };
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" };
builder.Add(@class);
document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind;
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));
var pass = new NamespaceDirective.Pass();
pass.Engine = Mock.Of<RazorEngine>();
// Act
pass.Execute(codeDocument, document);
// Assert
Assert.Equal("WebApplication.Account", @namespace.Content);
Assert.Equal("default", @class.ClassName);
}
[Fact]
public void Pass_DoesNothing_ForUnknownDocumentKind()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new DirectiveIntermediateNode()
{
Directive = NamespaceDirective.Directive,
Source = new SourceSpan(null, 0, 0, 0, 0),
});
builder.Add(new DirectiveTokenIntermediateNode() { Content = "WebApplication.Account" });
builder.Pop();
var @namespace = new NamespaceDeclarationIntermediateNode() { Content = "default" };
builder.Push(@namespace);
var @class = new ClassDeclarationIntermediateNode() { ClassName = "default" };
builder.Add(@class);
document.DocumentKind = null;
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage/AddUser.cshtml"));
var pass = new NamespaceDirective.Pass();
pass.Engine = Mock.Of<RazorEngine>();
// Act
pass.Execute(codeDocument, document);
// Assert
Assert.Equal("default", @namespace.Content);
Assert.Equal("default", @class.ClassName);
}
}
}

Просмотреть файл

@ -0,0 +1,148 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class PageDirectiveTest
{
[Fact]
public void TryGetPageDirective_ReturnsTrue_IfPageIsMalformed()
{
// Arrange
var content = "@page \"some-route-template\" Invalid";
var sourceDocument = RazorSourceDocument.Create(content, "file");
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
// Assert
Assert.True(result);
Assert.Equal("some-route-template", pageDirective.RouteTemplate);
Assert.NotNull(pageDirective.DirectiveNode);
}
[Fact]
public void TryGetPageDirective_ReturnsTrue_IfPageIsImported()
{
// Arrange
var content = "Hello world";
var sourceDocument = RazorSourceDocument.Create(content, "file");
var importDocument = RazorSourceDocument.Create("@page", "imports.cshtml");
var codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { importDocument });
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
// Assert
Assert.True(result);
Assert.Null(pageDirective.RouteTemplate);
}
[Fact]
public void TryGetPageDirective_ReturnsFalse_IfPageDoesNotHaveDirective()
{
// Arrange
var content = "Hello world";
var sourceDocument = RazorSourceDocument.Create(content, "file");
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
// Assert
Assert.False(result);
Assert.Null(pageDirective);
}
[Fact]
public void TryGetPageDirective_ReturnsTrue_IfPageDoesStartWithDirective()
{
// Arrange
var content = "Hello @page";
var sourceDocument = RazorSourceDocument.Create(content, "file");
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
// Assert
Assert.True(result);
Assert.Null(pageDirective.RouteTemplate);
Assert.NotNull(pageDirective.DirectiveNode);
}
[Fact]
public void TryGetPageDirective_ReturnsTrue_IfContentHasDirective()
{
// Arrange
var content = "@page";
var sourceDocument = RazorSourceDocument.Create(content, "file");
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
// Assert
Assert.True(result);
Assert.Null(pageDirective.RouteTemplate);
}
[Fact]
public void TryGetPageDirective_ParsesRouteTemplate()
{
// Arrange
var content = "@page \"some-route-template\"";
var sourceDocument = RazorSourceDocument.Create(content, "file");
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
// Act
var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective);
// Assert
Assert.True(result);
Assert.Equal("some-route-template", pageDirective.RouteTemplate);
}
private RazorEngine CreateEngine()
{
return RazorProjectEngine.Create(b =>
{
PageDirective.Register(b);
}).Engine;
}
private DocumentIntermediateNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorDocumentClassifierPhase)
{
break;
}
}
return codeDocument.GetDocumentIntermediateNode();
}
}
}

Просмотреть файл

@ -0,0 +1,6 @@
// 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 System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

Просмотреть файл

@ -0,0 +1,417 @@
// 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 System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class RazorPageDocumentClassifierPassTest
{
[Fact]
public void RazorPageDocumentClassifierPass_LogsErrorForImportedPageDirectives()
{
// Arrange
var sourceSpan = new SourceSpan("import.cshtml", 0, 0, 0, 5);
var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_CannotBeImported(sourceSpan);
var importDocument = RazorSourceDocument.Create("@page", "import.cshtml");
var sourceDocument = RazorSourceDocument.Create("<p>Hello World</p>", "main.cshtml");
var codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { importDocument });
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive);
var directive = Assert.Single(pageDirectives);
var diagnostic = Assert.Single(directive.Node.Diagnostics);
Assert.Equal(expectedDiagnostic, diagnostic);
}
[Fact]
public void RazorPageDocumentClassifierPass_LogsErrorIfDirectiveNotAtTopOfFile()
{
// Arrange
var sourceSpan = new SourceSpan(
"Test.cshtml",
absoluteIndex: 14 + Environment.NewLine.Length * 2,
lineIndex: 2,
characterIndex: 0,
length: 5 + Environment.NewLine.Length);
var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(sourceSpan);
var content = @"
@somethingelse
@page
";
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml"));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive);
var directive = Assert.Single(pageDirectives);
var diagnostic = Assert.Single(directive.Node.Diagnostics);
Assert.Equal(expectedDiagnostic, diagnostic);
}
[Fact]
public void RazorPageDocumentClassifierPass_DoesNotLogErrorIfCommentAndWhitespaceBeforeDirective()
{
// Arrange
var content = @"
@* some comment *@
@page
";
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml"));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive);
var directive = Assert.Single(pageDirectives);
Assert.Empty(directive.Node.Diagnostics);
}
[Fact]
public void RazorPageDocumentClassifierPass_SetsDocumentKind()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml"));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
// Assert
Assert.Equal("mvc.1.0.razor-page", irDocument.DocumentKind);
}
[Fact]
public void RazorPageDocumentClassifierPass_NoOpsIfDocumentKindIsAlreadySet()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml"));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
irDocument.DocumentKind = "some-value";
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
// Assert
Assert.Equal("some-value", irDocument.DocumentKind);
}
[Fact]
public void RazorPageDocumentClassifierPass_NoOpsIfPageDirectiveIsMalformed()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page+1", "Test.cshtml"));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
irDocument.DocumentKind = "some-value";
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
// Assert
Assert.Equal("some-value", irDocument.DocumentKind);
}
[Fact]
public void RazorPageDocumentClassifierPass_SetsNamespace()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml"));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("AspNetCore", visitor.Namespace.Content);
}
[Fact]
public void RazorPageDocumentClassifierPass_SetsClass()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml");
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType);
Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
Assert.Equal("Test", visitor.Class.ClassName);
}
[Fact]
public void RazorPageDocumentClassifierPass_NullFilePath_SetsClass()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType);
Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
Assert.Equal("AspNetCore_74fbaab062bb228ed1ab09c5ff8d6ed2417320e2", visitor.Class.ClassName);
}
[Theory]
[InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")]
[InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")]
public void RazorPageDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected)
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal(expected, visitor.Class.ClassName);
}
[Fact]
public void RazorPageDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName);
}
[Fact]
public void RazorPageDocumentClassifierPass_SanitizesClassName()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars");
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName);
}
[Fact]
public void RazorPageDocumentClassifierPass_SetsUpExecuteAsyncMethod()
{
// Arrange
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", "Test.cshtml"));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("ExecuteAsync", visitor.Method.MethodName);
Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType);
Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers);
}
[Fact]
public void RazorPageDocumentClassifierPass_AddsRouteTemplateMetadata()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml");
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page \"some-route\"", properties));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
var attributeNode = Assert.IsType<RazorCompiledItemMetadataAttributeIntermediateNode>(visitor.ExtensionNode);
Assert.Equal("RouteTemplate", attributeNode.Key);
Assert.Equal("some-route", attributeNode.Value);
}
private static RazorEngine CreateEngine()
{
return RazorProjectEngine.Create(b =>
{
PageDirective.Register(b);
}).Engine;
}
private static DocumentIntermediateNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorIntermediateNodeLoweringPhase)
{
break;
}
}
return codeDocument.GetDocumentIntermediateNode();
}
private class Visitor : IntermediateNodeWalker
{
public NamespaceDeclarationIntermediateNode Namespace { get; private set; }
public ClassDeclarationIntermediateNode Class { get; private set; }
public MethodDeclarationIntermediateNode Method { get; private set; }
public ExtensionIntermediateNode ExtensionNode { get; private set; }
public override void VisitMethodDeclaration(MethodDeclarationIntermediateNode node)
{
Method = node;
}
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
{
Namespace = node;
base.VisitNamespaceDeclaration(node);
}
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
{
Class = node;
base.VisitClassDeclaration(node);
}
public override void VisitExtension(ExtensionIntermediateNode node)
{
ExtensionNode = node;
}
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
// 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 System;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public static class SourceMappingsSerializer
{
public static string Serialize(RazorCSharpDocument csharpDocument, RazorSourceDocument sourceDocument)
{
var builder = new StringBuilder();
var sourceFilePath = sourceDocument.FilePath;
var charBuffer = new char[sourceDocument.Length];
sourceDocument.CopyTo(0, charBuffer, 0, sourceDocument.Length);
var sourceContent = new string(charBuffer);
for (var i = 0; i < csharpDocument.SourceMappings.Count; i++)
{
var sourceMapping = csharpDocument.SourceMappings[i];
if (!string.Equals(sourceMapping.OriginalSpan.FilePath, sourceFilePath, StringComparison.Ordinal))
{
continue;
}
builder.Append("Source Location: ");
AppendMappingLocation(builder, sourceMapping.OriginalSpan, sourceContent);
builder.Append("Generated Location: ");
AppendMappingLocation(builder, sourceMapping.GeneratedSpan, csharpDocument.GeneratedCode);
builder.AppendLine();
}
return builder.ToString();
}
private static void AppendMappingLocation(StringBuilder builder, SourceSpan location, string content)
{
builder
.AppendLine(location.ToString())
.Append("|");
for (var i = 0; i < location.Length; i++)
{
builder.Append(content[location.AbsoluteIndex + i]);
}
builder.AppendLine("|");
}
}
}

Просмотреть файл

@ -0,0 +1,82 @@
// 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.AspNetCore.Razor.Language;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
{
public class TagHelperDescriptorExtensionsTest
{
[Fact]
public void IsViewComponentKind_ReturnsFalse_ForNonVCTHDescriptor()
{
// Arrange
var tagHelper = CreateTagHelperDescriptor();
// Act
var result = tagHelper.IsViewComponentKind();
// Assert
Assert.False(result);
}
[Fact]
public void IsViewComponentKind_ReturnsTrue_ForVCTHDescriptor()
{
// Arrange
var tagHelper = CreateViewComponentTagHelperDescriptor();
// Act
var result = tagHelper.IsViewComponentKind();
// Assert
Assert.True(result);
}
[Fact]
public void GetViewComponentName_ReturnsNull_ForNonVCTHDescriptor()
{
//Arrange
var tagHelper = CreateTagHelperDescriptor();
// Act
var result = tagHelper.GetViewComponentName();
// Assert
Assert.Null(result);
}
[Fact]
public void GetViewComponentName_ReturnsName_ForVCTHDescriptor()
{
// Arrange
var tagHelper = CreateViewComponentTagHelperDescriptor("ViewComponentName");
// Act
var result = tagHelper.GetViewComponentName();
// Assert
Assert.Equal("ViewComponentName", result);
}
private static TagHelperDescriptor CreateTagHelperDescriptor()
{
var tagHelper = TagHelperDescriptorBuilder.Create("TypeName", "AssemblyName")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name"))
.Build();
return tagHelper;
}
private static TagHelperDescriptor CreateViewComponentTagHelperDescriptor(string name = "ViewComponentName")
{
var tagHelper = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TypeName", "AssemblyName")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name"))
.AddMetadata(ViewComponentTagHelperMetadata.Name, name)
.Build();
return tagHelper;
}
}
}

Просмотреть файл

@ -0,0 +1,8 @@
<div class="@this.ToString()">
Hello world
@string.Format("{0}", "Hello")
</div>
@{
var cls = "foo";
}
<p class="@if(cls != null) { @cls }" />

Просмотреть файл

@ -0,0 +1,71 @@
// <auto-generated/>
#pragma warning disable 1591
namespace AspNetCore
{
#line hidden
using TModel = global::System.Object;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
}
#pragma warning restore 219
#pragma warning disable 0414
private static System.Object __o = null;
#pragma warning restore 0414
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
__o = this.ToString();
#line default
#line hidden
#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
__o = string.Format("{0}", "Hello");
#line default
#line hidden
#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
var cls = "foo";
#line default
#line hidden
#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
if(cls != null) {
#line default
#line hidden
#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
__o = cls;
#line default
#line hidden
#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
}
#line default
#line hidden
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,64 @@
Document -
NamespaceDeclaration - - AspNetCore
UsingDirective - - TModel = global::System.Object
UsingDirective - (1:0,1 [12] ) - System
UsingDirective - (16:1,1 [32] ) - System.Collections.Generic
UsingDirective - (51:2,1 [17] ) - System.Linq
UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
DirectiveToken - (363:8,63 [4] ) - Json
DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper
DirectiveToken - (431:9,62 [9] ) - Component
DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper
DirectiveToken - (494:10,52 [3] ) - Url
DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
CSharpCode -
IntermediateToken - - CSharp - #pragma warning disable 0414
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
CSharpCode -
IntermediateToken - - CSharp - #pragma warning restore 0414
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (0:0,0 [4] Basic.cshtml)
IntermediateToken - (0:0,0 [4] Basic.cshtml) - Html - <div
HtmlAttribute - (4:0,4 [25] Basic.cshtml) - class=" - "
CSharpExpressionAttributeValue - (12:0,12 [16] Basic.cshtml) -
IntermediateToken - (13:0,13 [15] Basic.cshtml) - CSharp - this.ToString()
HtmlContent - (29:0,29 [24] Basic.cshtml)
IntermediateToken - (29:0,29 [1] Basic.cshtml) - Html - >
IntermediateToken - (30:0,30 [23] Basic.cshtml) - Html - \n Hello world\n
CSharpExpression - (54:2,5 [29] Basic.cshtml)
IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello")
HtmlContent - (83:2,34 [10] Basic.cshtml)
IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n
IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html - </div>
IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n
CSharpCode - (95:4,2 [25] Basic.cshtml)
IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n
HtmlContent - (123:7,0 [2] Basic.cshtml)
IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html - <p
HtmlAttribute - (125:7,2 [34] Basic.cshtml) - class=" - "
CSharpCodeAttributeValue - (133:7,10 [25] Basic.cshtml) -
IntermediateToken - (134:7,11 [18] Basic.cshtml) - CSharp - if(cls != null) {
CSharpExpression - (153:7,30 [3] Basic.cshtml)
IntermediateToken - (153:7,30 [3] Basic.cshtml) - CSharp - cls
IntermediateToken - (156:7,33 [2] Basic.cshtml) - CSharp - }
HtmlContent - (159:7,36 [5] Basic.cshtml)
IntermediateToken - (159:7,36 [3] Basic.cshtml) - Html - />
IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n
Inject -
Inject -
Inject -
Inject -
Inject -

Просмотреть файл

@ -0,0 +1,34 @@
Source Location: (13:0,13 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml)
|this.ToString()|
Generated Location: (1030:26,13 [15] )
|this.ToString()|
Source Location: (54:2,5 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml)
|string.Format("{0}", "Hello")|
Generated Location: (1166:31,6 [29] )
|string.Format("{0}", "Hello")|
Source Location: (95:4,2 [25] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml)
|
var cls = "foo";
|
Generated Location: (1312:36,2 [25] )
|
var cls = "foo";
|
Source Location: (134:7,11 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml)
|if(cls != null) { |
Generated Location: (1460:42,11 [18] )
|if(cls != null) { |
Source Location: (153:7,30 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml)
|cls|
Generated Location: (1622:47,30 [3] )
|cls|
Source Location: (156:7,33 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml)
| }|
Generated Location: (1773:52,33 [2] )
| }|

Просмотреть файл

@ -0,0 +1,95 @@
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6d079dd6c39f39d17a2faff14404b37ab7e8b8fc"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml")]
[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic))]
namespace AspNetCore
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"6d079dd6c39f39d17a2faff14404b37ab7e8b8fc", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(0, 4, true);
WriteLiteral("<div");
EndContext();
BeginWriteAttribute("class", " class=\"", 4, "\"", 28, 1);
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
WriteAttributeValue("", 12, this.ToString(), 12, 16, false);
#line default
#line hidden
EndWriteAttribute();
BeginContext(29, 24, true);
WriteLiteral(">\r\n Hello world\r\n ");
EndContext();
BeginContext(54, 29, false);
#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
Write(string.Format("{0}", "Hello"));
#line default
#line hidden
EndContext();
BeginContext(83, 10, true);
WriteLiteral("\r\n</div>\r\n");
EndContext();
#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
var cls = "foo";
#line default
#line hidden
BeginContext(123, 2, true);
WriteLiteral("<p");
EndContext();
BeginWriteAttribute("class", " class=\"", 125, "\"", 158, 1);
WriteAttributeValue("", 133, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
PushWriter(__razor_attribute_value_writer);
#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
if(cls != null) {
#line default
#line hidden
BeginContext(153, 3, false);
#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
Write(cls);
#line default
#line hidden
EndContext();
#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml"
}
#line default
#line hidden
PopWriter();
}
), 133, 25, false);
EndWriteAttribute();
BeginContext(159, 5, true);
WriteLiteral(" />\r\n");
EndContext();
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; }
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,76 @@
Document -
RazorCompiledItemAttribute -
CSharpCode -
IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic))]
NamespaceDeclaration - - AspNetCore
UsingDirective - (1:0,1 [14] ) - System
UsingDirective - (16:1,1 [34] ) - System.Collections.Generic
UsingDirective - (51:2,1 [19] ) - System.Linq
UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
RazorSourceChecksumAttribute -
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpCode -
IntermediateToken - - CSharp - BeginContext(0, 4, true);
HtmlContent - (0:0,0 [4] Basic.cshtml)
IntermediateToken - (0:0,0 [4] Basic.cshtml) - Html - <div
CSharpCode -
IntermediateToken - - CSharp - EndContext();
HtmlAttribute - (4:0,4 [25] Basic.cshtml) - class=" - "
CSharpExpressionAttributeValue - (12:0,12 [16] Basic.cshtml) -
IntermediateToken - (13:0,13 [15] Basic.cshtml) - CSharp - this.ToString()
CSharpCode -
IntermediateToken - - CSharp - BeginContext(29, 24, true);
HtmlContent - (29:0,29 [24] Basic.cshtml)
IntermediateToken - (29:0,29 [1] Basic.cshtml) - Html - >
IntermediateToken - (30:0,30 [19] Basic.cshtml) - Html - \n Hello world\n
IntermediateToken - (49:2,0 [4] Basic.cshtml) - Html -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
IntermediateToken - - CSharp - BeginContext(54, 29, false);
CSharpExpression - (54:2,5 [29] Basic.cshtml)
IntermediateToken - (54:2,5 [29] Basic.cshtml) - CSharp - string.Format("{0}", "Hello")
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
IntermediateToken - - CSharp - BeginContext(83, 10, true);
HtmlContent - (83:2,34 [10] Basic.cshtml)
IntermediateToken - (83:2,34 [2] Basic.cshtml) - Html - \n
IntermediateToken - (85:3,0 [6] Basic.cshtml) - Html - </div>
IntermediateToken - (91:3,6 [2] Basic.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode - (95:4,2 [25] Basic.cshtml)
IntermediateToken - (95:4,2 [25] Basic.cshtml) - CSharp - \n var cls = "foo";\n
CSharpCode -
IntermediateToken - - CSharp - BeginContext(123, 2, true);
HtmlContent - (123:7,0 [2] Basic.cshtml)
IntermediateToken - (123:7,0 [2] Basic.cshtml) - Html - <p
CSharpCode -
IntermediateToken - - CSharp - EndContext();
HtmlAttribute - (125:7,2 [34] Basic.cshtml) - class=" - "
CSharpCodeAttributeValue - (133:7,10 [25] Basic.cshtml) -
IntermediateToken - (134:7,11 [18] Basic.cshtml) - CSharp - if(cls != null) {
CSharpCode -
IntermediateToken - - CSharp - BeginContext(153, 3, false);
CSharpExpression - (153:7,30 [3] Basic.cshtml)
IntermediateToken - (153:7,30 [3] Basic.cshtml) - CSharp - cls
CSharpCode -
IntermediateToken - - CSharp - EndContext();
IntermediateToken - (156:7,33 [2] Basic.cshtml) - CSharp - }
CSharpCode -
IntermediateToken - - CSharp - BeginContext(159, 5, true);
HtmlContent - (159:7,36 [5] Basic.cshtml)
IntermediateToken - (159:7,36 [3] Basic.cshtml) - Html - />
IntermediateToken - (162:7,39 [2] Basic.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
Inject -
Inject -
Inject -
Inject -
Inject -

Просмотреть файл

@ -0,0 +1,15 @@
@* These test files validate that end-to-end, incomplete directives don't throw. *@
@page
@page
@page "
@model
@model
@inject
@inject
@inject MyService<TModel>
@namespace
@namespace

Просмотреть файл

@ -0,0 +1,71 @@
// <auto-generated/>
#pragma warning disable 1591
namespace AspNetCore
{
#line hidden
using TModel = global::System.Object;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
}
))();
((System.Action)(() => {
}
))();
((System.Action)(() => {
}
))();
((System.Action)(() => {
}
))();
((System.Action)(() => {
#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml"
MyService<TModel> __typeHelper = default(MyService<TModel>);
#line default
#line hidden
}
))();
((System.Action)(() => {
}
))();
((System.Action)(() => {
}
))();
((System.Action)(() => {
}
))();
}
#pragma warning restore 219
#pragma warning disable 0414
private static System.Object __o = null;
#pragma warning restore 0414
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives> Html { get; private set; }
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives>)PageContext?.ViewData;
public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model;
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,12 @@
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ2001: The 'page' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ2001: The 'page' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ1013: The 'model' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ2001: The 'model' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ1013: The 'model' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ1013: The 'inject' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ1013: The 'inject' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ1015: The 'inject' directive expects an identifier.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ1014: The 'namespace' directive expects a namespace name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ2001: The 'namespace' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ1014: The 'namespace' directive expects a namespace name.

Просмотреть файл

@ -0,0 +1,84 @@
Document -
NamespaceDeclaration - - AspNetCore
UsingDirective - - TModel = global::System.Object
UsingDirective - (1:0,1 [12] ) - System
UsingDirective - (16:1,1 [32] ) - System.Collections.Generic
UsingDirective - (51:2,1 [17] ) - System.Linq
UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
DirectiveToken - (363:8,63 [4] ) - Json
DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper
DirectiveToken - (431:9,62 [9] ) - Component
DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper
DirectiveToken - (494:10,52 [3] ) - Url
DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) -
DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) -
DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) -
DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) -
DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService<TModel>
DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) -
DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) -
DirectiveToken - (203:14,11 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - #pragma warning disable 0414
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
CSharpCode -
IntermediateToken - - CSharp - #pragma warning restore 0414
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml)
IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n
MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page
MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page
HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml)
IntermediateToken - (108:4,6 [5] IncompleteDirectives.cshtml) - Html - "\n\n
MalformedDirective - (113:6,0 [6] IncompleteDirectives.cshtml) - model
DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) -
HtmlContent - (119:6,6 [2] IncompleteDirectives.cshtml)
IntermediateToken - (119:6,6 [2] IncompleteDirectives.cshtml) - Html - \n
MalformedDirective - (121:7,0 [7] IncompleteDirectives.cshtml) - model
DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) -
HtmlContent - (128:7,7 [4] IncompleteDirectives.cshtml)
IntermediateToken - (128:7,7 [4] IncompleteDirectives.cshtml) - Html - \n\n
MalformedDirective - (132:9,0 [7] IncompleteDirectives.cshtml) - inject
DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) -
HtmlContent - (139:9,7 [2] IncompleteDirectives.cshtml)
IntermediateToken - (139:9,7 [2] IncompleteDirectives.cshtml) - Html - \n
MalformedDirective - (141:10,0 [8] IncompleteDirectives.cshtml) - inject
DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) -
HtmlContent - (149:10,8 [2] IncompleteDirectives.cshtml)
IntermediateToken - (149:10,8 [2] IncompleteDirectives.cshtml) - Html - \n
MalformedDirective - (151:11,0 [25] IncompleteDirectives.cshtml) - inject
DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService<TModel>
DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) -
HtmlContent - (176:11,25 [4] IncompleteDirectives.cshtml)
IntermediateToken - (176:11,25 [4] IncompleteDirectives.cshtml) - Html - \n\n
MalformedDirective - (180:13,0 [10] IncompleteDirectives.cshtml) - namespace
DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) -
HtmlContent - (190:13,10 [2] IncompleteDirectives.cshtml)
IntermediateToken - (190:13,10 [2] IncompleteDirectives.cshtml) - Html - \n
MalformedDirective - (192:14,0 [11] IncompleteDirectives.cshtml) - namespace
DirectiveToken - (203:14,11 [0] IncompleteDirectives.cshtml) -
HtmlContent - (203:14,11 [2] IncompleteDirectives.cshtml)
IntermediateToken - (203:14,11 [2] IncompleteDirectives.cshtml) - Html - \n
Inject -
Inject -
Inject -
Inject -
Inject -
CSharpCode -
IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives>)PageContext?.ViewData;
CSharpCode -
IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model;

Просмотреть файл

@ -0,0 +1,40 @@
Source Location: (119:6,6 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
||
Generated Location: (671:18,0 [0] )
||
Source Location: (128:7,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
||
Generated Location: (724:21,0 [0] )
||
Source Location: (139:9,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
||
Generated Location: (777:24,0 [0] )
||
Source Location: (149:10,8 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
||
Generated Location: (830:27,0 [0] )
||
Source Location: (159:11,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
|MyService<TModel>|
Generated Location: (980:31,0 [17] )
|MyService<TModel>|
Source Location: (176:11,25 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
||
Generated Location: (1133:38,0 [0] )
||
Source Location: (190:13,10 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
||
Generated Location: (1186:41,0 [0] )
||
Source Location: (203:14,11 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
||
Generated Location: (1239:44,0 [0] )
||

Просмотреть файл

@ -0,0 +1,65 @@
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5add9dba0a182cd75498c5b24f64a2547e7f49b0"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")]
[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), null)]
namespace AspNetCore
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"5add9dba0a182cd75498c5b24f64a2547e7f49b0", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(83, 4, true);
WriteLiteral("\r\n\r\n");
EndContext();
BeginContext(108, 5, true);
WriteLiteral("\"\r\n\r\n");
EndContext();
BeginContext(119, 2, true);
WriteLiteral("\r\n");
EndContext();
BeginContext(128, 4, true);
WriteLiteral("\r\n\r\n");
EndContext();
BeginContext(139, 2, true);
WriteLiteral("\r\n");
EndContext();
BeginContext(149, 2, true);
WriteLiteral("\r\n");
EndContext();
BeginContext(176, 4, true);
WriteLiteral("\r\n\r\n");
EndContext();
BeginContext(190, 2, true);
WriteLiteral("\r\n");
EndContext();
BeginContext(203, 2, true);
WriteLiteral("\r\n");
EndContext();
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives> Html { get; private set; }
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives>)PageContext?.ViewData;
public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model;
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,12 @@
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,1): Error RZ2001: The 'page' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,1): Error RZ2001: The 'page' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,7): Error RZ1016: The 'page' directive expects a string surrounded by double quotes.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,7): Error RZ1013: The 'model' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,1): Error RZ2001: The 'model' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,8): Error RZ1013: The 'model' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(10,8): Error RZ1013: The 'inject' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,9): Error RZ1013: The 'inject' directive expects a type name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,26): Error RZ1015: The 'inject' directive expects an identifier.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(14,11): Error RZ1014: The 'namespace' directive expects a namespace name.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,1): Error RZ2001: The 'namespace' directive may only occur once per document.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,12): Error RZ1014: The 'namespace' directive expects a namespace name.

Просмотреть файл

@ -0,0 +1,95 @@
Document -
RazorCompiledItemAttribute -
CSharpCode -
IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives), null)]
NamespaceDeclaration - - AspNetCore
UsingDirective - (1:0,1 [14] ) - System
UsingDirective - (16:1,1 [34] ) - System.Collections.Generic
UsingDirective - (51:2,1 [19] ) - System.Linq
UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
RazorSourceChecksumAttribute -
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpCode -
IntermediateToken - - CSharp - BeginContext(83, 4, true);
HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml)
IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (94:3,0 [8] IncompleteDirectives.cshtml) - page
MalformedDirective - (102:4,0 [6] IncompleteDirectives.cshtml) - page
CSharpCode -
IntermediateToken - - CSharp - BeginContext(108, 5, true);
HtmlContent - (108:4,6 [5] IncompleteDirectives.cshtml)
IntermediateToken - (108:4,6 [5] IncompleteDirectives.cshtml) - Html - "\n\n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (113:6,0 [6] IncompleteDirectives.cshtml) - model
DirectiveToken - (119:6,6 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(119, 2, true);
HtmlContent - (119:6,6 [2] IncompleteDirectives.cshtml)
IntermediateToken - (119:6,6 [2] IncompleteDirectives.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (121:7,0 [7] IncompleteDirectives.cshtml) - model
DirectiveToken - (128:7,7 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(128, 4, true);
HtmlContent - (128:7,7 [4] IncompleteDirectives.cshtml)
IntermediateToken - (128:7,7 [4] IncompleteDirectives.cshtml) - Html - \n\n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (132:9,0 [7] IncompleteDirectives.cshtml) - inject
DirectiveToken - (139:9,7 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(139, 2, true);
HtmlContent - (139:9,7 [2] IncompleteDirectives.cshtml)
IntermediateToken - (139:9,7 [2] IncompleteDirectives.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (141:10,0 [8] IncompleteDirectives.cshtml) - inject
DirectiveToken - (149:10,8 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(149, 2, true);
HtmlContent - (149:10,8 [2] IncompleteDirectives.cshtml)
IntermediateToken - (149:10,8 [2] IncompleteDirectives.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (151:11,0 [25] IncompleteDirectives.cshtml) - inject
DirectiveToken - (159:11,8 [17] IncompleteDirectives.cshtml) - MyService<TModel>
DirectiveToken - (176:11,25 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(176, 4, true);
HtmlContent - (176:11,25 [4] IncompleteDirectives.cshtml)
IntermediateToken - (176:11,25 [4] IncompleteDirectives.cshtml) - Html - \n\n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (180:13,0 [10] IncompleteDirectives.cshtml) - namespace
DirectiveToken - (190:13,10 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(190, 2, true);
HtmlContent - (190:13,10 [2] IncompleteDirectives.cshtml)
IntermediateToken - (190:13,10 [2] IncompleteDirectives.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
MalformedDirective - (192:14,0 [11] IncompleteDirectives.cshtml) - namespace
DirectiveToken - (203:14,11 [0] IncompleteDirectives.cshtml) -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(203, 2, true);
HtmlContent - (203:14,11 [2] IncompleteDirectives.cshtml)
IntermediateToken - (203:14,11 [2] IncompleteDirectives.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
Inject -
Inject -
Inject -
Inject -
Inject -
CSharpCode -
IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives>)PageContext?.ViewData;
CSharpCode -
IntermediateToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives Model => ViewData.Model;

Просмотреть файл

@ -0,0 +1,2 @@
@inherits MyBasePageForViews<TModel>
@model MyModel

Просмотреть файл

@ -0,0 +1,56 @@
// <auto-generated/>
#pragma warning disable 1591
namespace AspNetCore
{
#line hidden
using TModel = global::System.Object;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel : MyBasePageForViews<MyModel>
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml"
MyBasePageForViews<TModel> __typeHelper = default(MyBasePageForViews<TModel>);
#line default
#line hidden
}
))();
((System.Action)(() => {
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml"
MyModel __typeHelper = default(MyModel);
#line default
#line hidden
}
))();
}
#pragma warning restore 219
#pragma warning disable 0414
private static System.Object __o = null;
#pragma warning restore 0414
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<MyModel> Html { get; private set; }
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,39 @@
Document -
NamespaceDeclaration - - AspNetCore
UsingDirective - - TModel = global::System.Object
UsingDirective - (1:0,1 [12] ) - System
UsingDirective - (16:1,1 [32] ) - System.Collections.Generic
UsingDirective - (51:2,1 [17] ) - System.Linq
UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel - MyBasePageForViews<MyModel> -
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
DirectiveToken - (363:8,63 [4] ) - Json
DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper
DirectiveToken - (431:9,62 [9] ) - Component
DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper
DirectiveToken - (494:10,52 [3] ) - Url
DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (10:0,10 [26] InheritsViewModel.cshtml) - MyBasePageForViews<TModel>
DirectiveToken - (45:1,7 [7] InheritsViewModel.cshtml) - MyModel
CSharpCode -
IntermediateToken - - CSharp - #pragma warning disable 0414
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
CSharpCode -
IntermediateToken - - CSharp - #pragma warning restore 0414
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
Inject -
Inject -
Inject -
Inject -
Inject -

Просмотреть файл

@ -0,0 +1,10 @@
Source Location: (10:0,10 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml)
|MyBasePageForViews<TModel>|
Generated Location: (740:19,0 [26] )
|MyBasePageForViews<TModel>|
Source Location: (45:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml)
|MyModel|
Generated Location: (1004:27,0 [7] )
|MyModel|

Просмотреть файл

@ -0,0 +1,36 @@
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3ff83e2f0d946feb387a8ea03a529c64350014f8"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml")]
[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel))]
namespace AspNetCore
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"3ff83e2f0d946feb387a8ea03a529c64350014f8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel : MyBasePageForViews<MyModel>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<MyModel> Html { get; private set; }
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,20 @@
Document -
RazorCompiledItemAttribute -
CSharpCode -
IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel))]
NamespaceDeclaration - - AspNetCore
UsingDirective - (1:0,1 [14] ) - System
UsingDirective - (16:1,1 [34] ) - System.Collections.Generic
UsingDirective - (51:2,1 [19] ) - System.Linq
UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
RazorSourceChecksumAttribute -
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel - MyBasePageForViews<MyModel> -
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
Inject -
Inject -
Inject -
Inject -
Inject -

Просмотреть файл

@ -0,0 +1,2 @@
@page
@model MyModel

Просмотреть файл

@ -0,0 +1,50 @@
// <auto-generated/>
#pragma warning disable 1591
namespace AspNetCore
{
#line hidden
using TModel = global::System.Object;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel<MyModel>
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml"
MyModel __typeHelper = default(MyModel);
#line default
#line hidden
}
))();
}
#pragma warning restore 219
#pragma warning disable 0414
private static System.Object __o = null;
#pragma warning restore 0414
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<MyModel> Html { get; private set; }
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel>)PageContext?.ViewData;
public MyModel Model => ViewData.Model;
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,43 @@
Document -
NamespaceDeclaration - - AspNetCore
UsingDirective - - TModel = global::System.Object
UsingDirective - (1:0,1 [12] ) - System
UsingDirective - (16:1,1 [32] ) - System.Collections.Generic
UsingDirective - (51:2,1 [17] ) - System.Linq
UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel<MyModel> -
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
DirectiveToken - (363:8,63 [4] ) - Json
DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper
DirectiveToken - (431:9,62 [9] ) - Component
DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper
DirectiveToken - (494:10,52 [3] ) - Url
DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (10:0,10 [19] TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml) - MyPageModel<TModel>
DirectiveToken - (14:1,7 [7] InheritsWithViewImports.cshtml) - MyModel
CSharpCode -
IntermediateToken - - CSharp - #pragma warning disable 0414
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
CSharpCode -
IntermediateToken - - CSharp - #pragma warning restore 0414
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
Inject -
Inject -
Inject -
Inject -
Inject -
CSharpCode -
IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel>)PageContext?.ViewData;
CSharpCode -
IntermediateToken - - CSharp - public MyModel Model => ViewData.Model;

Просмотреть файл

@ -0,0 +1,5 @@
Source Location: (14:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml)
|MyModel|
Generated Location: (745:19,0 [7] )
|MyModel|

Просмотреть файл

@ -0,0 +1,39 @@
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d196fc1c66d46d35e35af9b01c737e12bcce6782"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), @"mvc.1.0.razor-page", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")]
[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), null)]
namespace AspNetCore
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d196fc1c66d46d35e35af9b01c737e12bcce6782", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"f311ecbb5c4d63980a59c24af5ffe8baa1c3f99a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports : MyPageModel<MyModel>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<MyModel> Html { get; private set; }
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel>)PageContext?.ViewData;
public MyModel Model => ViewData.Model;
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,25 @@
Document -
RazorCompiledItemAttribute -
CSharpCode -
IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports), null)]
NamespaceDeclaration - - AspNetCore
UsingDirective - (1:0,1 [14] ) - System
UsingDirective - (16:1,1 [34] ) - System.Collections.Generic
UsingDirective - (51:2,1 [19] ) - System.Linq
UsingDirective - (71:3,1 [30] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
RazorSourceChecksumAttribute -
RazorSourceChecksumAttribute -
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports - MyPageModel<MyModel> -
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
Inject -
Inject -
Inject -
Inject -
Inject -
CSharpCode -
IntermediateToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<MyModel>)PageContext?.ViewData;
CSharpCode -
IntermediateToken - - CSharp - public MyModel Model => ViewData.Model;

Просмотреть файл

@ -0,0 +1 @@
@inject MyApp MyPropertyName

Просмотреть файл

@ -0,0 +1,3 @@
@model MyModel
@inject MyApp MyPropertyName
@inject MyService<TModel> Html

Просмотреть файл

@ -0,0 +1,82 @@
// <auto-generated/>
#pragma warning disable 1591
namespace AspNetCore
{
#line hidden
using TModel = global::System.Object;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<MyModel>
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml"
MyModel __typeHelper = default(MyModel);
#line default
#line hidden
}
))();
((System.Action)(() => {
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml"
MyApp __typeHelper = default(MyApp);
#line default
#line hidden
}
))();
((System.Action)(() => {
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml"
global::System.Object MyPropertyName = null;
#line default
#line hidden
}
))();
((System.Action)(() => {
#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml"
MyService<TModel> __typeHelper = default(MyService<TModel>);
#line default
#line hidden
}
))();
((System.Action)(() => {
#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml"
global::System.Object Html = null;
#line default
#line hidden
}
))();
}
#pragma warning restore 219
#pragma warning disable 0414
private static System.Object __o = null;
#pragma warning restore 0414
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public MyService<MyModel> Html { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public MyApp MyPropertyName { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,43 @@
Document -
NamespaceDeclaration - - AspNetCore
UsingDirective - - TModel = global::System.Object
UsingDirective - (1:0,1 [12] ) - System
UsingDirective - (16:1,1 [32] ) - System.Collections.Generic
UsingDirective - (51:2,1 [17] ) - System.Linq
UsingDirective - (71:3,1 [28] ) - System.Threading.Tasks
UsingDirective - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc
UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<MyModel> -
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
DirectiveToken - (363:8,63 [4] ) - Json
DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper
DirectiveToken - (431:9,62 [9] ) - Component
DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper
DirectiveToken - (494:10,52 [3] ) - Url
DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider
DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (7:0,7 [7] InjectWithModel.cshtml) - MyModel
DirectiveToken - (24:1,8 [5] InjectWithModel.cshtml) - MyApp
DirectiveToken - (30:1,14 [14] InjectWithModel.cshtml) - MyPropertyName
DirectiveToken - (54:2,8 [17] InjectWithModel.cshtml) - MyService<TModel>
DirectiveToken - (72:2,26 [4] InjectWithModel.cshtml) - Html
CSharpCode -
IntermediateToken - - CSharp - #pragma warning disable 0414
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
CSharpCode -
IntermediateToken - - CSharp - #pragma warning restore 0414
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
Inject -
Inject -
Inject -
Inject -
Inject -
Inject -

Просмотреть файл

@ -0,0 +1,25 @@
Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml)
|MyModel|
Generated Location: (766:19,0 [7] )
|MyModel|
Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml)
|MyApp|
Generated Location: (990:27,0 [5] )
|MyApp|
Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml)
|MyPropertyName|
Generated Location: (1232:35,22 [14] )
|MyPropertyName|
Source Location: (54:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml)
|MyService<TModel>|
Generated Location: (1438:43,0 [17] )
|MyService<TModel>|
Source Location: (72:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml)
|Html|
Generated Location: (1704:51,22 [4] )
|Html|

Просмотреть файл

@ -0,0 +1,38 @@
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2cafb599699b78d76f0355b6f528050b4720789d"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel), @"mvc.1.0.view", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml")]
[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(@"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml", typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel))]
namespace AspNetCore
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2cafb599699b78d76f0355b6f528050b4720789d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<MyModel>
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
}
#pragma warning restore 1998
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public MyService<MyModel> Html { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public MyApp MyPropertyName { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
}
}
#pragma warning restore 1591

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше