Add support for 2-phase compile
This commit is contained in:
parent
f9623c2c27
commit
8d629371bf
|
|
@ -20,7 +20,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
InjectDirective.Register(builder);
|
||||
ModelDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
|
||||
builder.Features.Add(new DefaultTagHelperDescriptorProvider());
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X
|
|||
NamespaceDirective.Register(builder);
|
||||
PageDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// 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.Components;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
|
||||
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
{
|
||||
if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
|
||||
documentNode.DocumentKind != MvcViewDocumentClassifierPass.MvcViewDocumentKind)
|
||||
{
|
||||
// Not a MVC file. Skip.
|
||||
return;
|
||||
}
|
||||
|
||||
var visitor = new Visitor();
|
||||
visitor.Visit(documentNode);
|
||||
var modelType = ModelDirective.GetModelType(documentNode);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CodeGeneration\CodeWriterExtensions.cs">
|
||||
<Link>Shared\CodeWriterExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CodeGeneration\CodeWriterExtensions.cs" Link="Shared\CodeWriterExtensions.cs" />
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\CSharpIdentifier.cs" Link="Shared\CSharpIdentifier.cs" />
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Language\Checksum.cs" Link="Shared\Checksum.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// 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;
|
||||
|
||||
|
|
@ -31,12 +30,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
{
|
||||
// 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());
|
||||
var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
|
||||
@class.ClassName = $"AspNetCore_{checksum}";
|
||||
}
|
||||
else
|
||||
{
|
||||
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
|
||||
@class.ClassName = GetClassNameFromPath(filePath);
|
||||
}
|
||||
|
||||
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
|
||||
|
|
@ -51,21 +50,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";
|
||||
}
|
||||
|
||||
private static string BytesToString(byte[] bytes)
|
||||
private static string GetClassNameFromPath(string path)
|
||||
{
|
||||
if (bytes == null)
|
||||
const string cshtmlExtension = ".cshtml";
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(bytes));
|
||||
return path;
|
||||
}
|
||||
|
||||
var result = new StringBuilder(bytes.Length);
|
||||
for (var i = 0; i < bytes.Length; i++)
|
||||
if (path.EndsWith(cshtmlExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// The x2 format means lowercase hex, where each byte is a 2-character string.
|
||||
result.Append(bytes[i].ToString("x2"));
|
||||
path = path.Substring(0, path.Length - cshtmlExtension.Length);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
return CSharpIdentifier.SanitizeIdentifier(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
for (var i = 0; i < segments.Length - 1; i++)
|
||||
{
|
||||
builder.Append('.');
|
||||
builder.Append(CSharpIdentifier.SanitizeClassName(segments[i]));
|
||||
builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[i]));
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
NamespaceDirective.Register(builder);
|
||||
PageDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
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;
|
||||
|
|
@ -58,12 +57,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
{
|
||||
// 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());
|
||||
var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
|
||||
@class.ClassName = $"AspNetCore_{checksum}";
|
||||
}
|
||||
else
|
||||
{
|
||||
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
|
||||
@class.ClassName = GetClassNameFromPath(filePath);
|
||||
}
|
||||
|
||||
@class.Modifiers.Clear();
|
||||
|
|
@ -144,21 +143,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
}
|
||||
}
|
||||
|
||||
private static string BytesToString(byte[] bytes)
|
||||
private static string GetClassNameFromPath(string path)
|
||||
{
|
||||
if (bytes == null)
|
||||
const string cshtmlExtension = ".cshtml";
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(bytes));
|
||||
return path;
|
||||
}
|
||||
|
||||
var result = new StringBuilder(bytes.Length);
|
||||
for (var i = 0; i < bytes.Length; i++)
|
||||
if (path.EndsWith(cshtmlExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// The x2 format means lowercase hex, where each byte is a 2-character string.
|
||||
result.Append(bytes[i].ToString("x2"));
|
||||
path = path.Substring(0, path.Length - cshtmlExtension.Length);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
return CSharpIdentifier.SanitizeIdentifier(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,13 @@
|
|||
// 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
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -51,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
category == UnicodeCategory.Format; // Cf
|
||||
}
|
||||
|
||||
public static string SanitizeClassName(string inputName)
|
||||
public static string SanitizeIdentifier(string inputName)
|
||||
{
|
||||
if (!IsIdentifierStart(inputName[0]) && IsIdentifierPart(inputName[0]))
|
||||
{
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.Razor.Language.Components
|
||||
{
|
||||
// Constants for method names used in code-generation
|
||||
// Keep these in sync with the actual definitions
|
||||
internal static class CodeGenerationConstants
|
||||
{
|
||||
public static class RazorComponent
|
||||
{
|
||||
public const string FullTypeName = "Microsoft.AspNetCore.Components.Component";
|
||||
public const string BuildRenderTree = "BuildRenderTree";
|
||||
public const string BuildRenderTreeParameter = "builder";
|
||||
}
|
||||
|
||||
public static class RenderTreeBuilder
|
||||
{
|
||||
public const string FullTypeName = "Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder";
|
||||
}
|
||||
|
||||
public static class InjectDirective
|
||||
{
|
||||
public const string FullTypeName = "Microsoft.AspNetCore.Razor.Components.InjectAttribute";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
// 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.Intermediate;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Components
|
||||
{
|
||||
internal class ComponentDocumentClassifierPass : DocumentClassifierPassBase
|
||||
{
|
||||
public static readonly string ComponentDocumentKind = "component.1.0";
|
||||
private static readonly object BuildRenderTreeBaseCallAnnotation = new object();
|
||||
private static readonly char[] PathSeparators = new char[] { '/', '\\' };
|
||||
private static readonly char[] NamespaceSeparators = new char[] { '.' };
|
||||
|
||||
protected override string DocumentKind => ComponentDocumentKind;
|
||||
|
||||
// Ensure this runs before the MVC classifiers which have Order = 0
|
||||
public override int Order => -100;
|
||||
|
||||
protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
{
|
||||
return codeDocument.GetInputDocumentKind() == InputDocumentKind.Component;
|
||||
}
|
||||
|
||||
protected override void OnDocumentStructureCreated(RazorCodeDocument codeDocument, NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, MethodDeclarationIntermediateNode method)
|
||||
{
|
||||
base.OnDocumentStructureCreated(codeDocument, @namespace, @class, method);
|
||||
|
||||
if (!TryComputeNamespaceAndClass(
|
||||
codeDocument.Source.FilePath,
|
||||
codeDocument.Source.RelativePath,
|
||||
out var computedNamespace,
|
||||
out var computedClass))
|
||||
{
|
||||
// If we can't compute a nice namespace (no relative path) then just generate something
|
||||
// mangled.
|
||||
computedNamespace = "AspNetCore";
|
||||
var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
|
||||
computedClass = $"AspNetCore_{checksum}";
|
||||
}
|
||||
|
||||
@namespace.Content = computedNamespace;
|
||||
|
||||
@class.ClassName = computedClass;
|
||||
@class.BaseType = $"global::{CodeGenerationConstants.RazorComponent.FullTypeName}";
|
||||
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 = Checksum.BytesToString(codeDocument.Source.GetChecksum());
|
||||
@class.ClassName = $"AspNetCore_{checksum}";
|
||||
}
|
||||
else
|
||||
{
|
||||
@class.ClassName = CSharpIdentifier.SanitizeIdentifier(Path.GetFileNameWithoutExtension(filePath));
|
||||
}
|
||||
|
||||
@class.Modifiers.Clear();
|
||||
@class.Modifiers.Add("public");
|
||||
@class.Modifiers.Add("sealed");
|
||||
|
||||
method.MethodName = CodeGenerationConstants.RazorComponent.BuildRenderTree;
|
||||
method.ReturnType = "void";
|
||||
method.Modifiers.Clear();
|
||||
method.Modifiers.Add("public");
|
||||
method.Modifiers.Add("override");
|
||||
|
||||
method.Parameters.Clear();
|
||||
method.Parameters.Add(new MethodParameter()
|
||||
{
|
||||
TypeName = CodeGenerationConstants.RenderTreeBuilder.FullTypeName,
|
||||
ParameterName = CodeGenerationConstants.RazorComponent.BuildRenderTreeParameter,
|
||||
});
|
||||
|
||||
// We need to call the 'base' method as the first statement.
|
||||
var callBase = new CSharpCodeIntermediateNode();
|
||||
callBase.Annotations.Add(BuildRenderTreeBaseCallAnnotation, true);
|
||||
callBase.Children.Add(new IntermediateToken
|
||||
{
|
||||
Kind = TokenKind.CSharp,
|
||||
Content = $"base.{CodeGenerationConstants.RazorComponent.BuildRenderTree}({CodeGenerationConstants.RazorComponent.BuildRenderTreeParameter});"
|
||||
});
|
||||
method.Children.Insert(0, callBase);
|
||||
}
|
||||
|
||||
private bool TryComputeNamespaceAndClass(string filePath, string relativePath, out string @namespace, out string @class)
|
||||
{
|
||||
if (filePath == null || relativePath == null || filePath.Length <= relativePath.Length)
|
||||
{
|
||||
@namespace = null;
|
||||
@class = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try and infer a namespace from the project directory. We don't yet have the ability to pass
|
||||
// the namespace through from the project.
|
||||
var trimLength = relativePath.Length + (relativePath.StartsWith("/") ? 0 : 1);
|
||||
var baseDirectory = filePath.Substring(0, filePath.Length - trimLength);
|
||||
|
||||
var lastSlash = baseDirectory.LastIndexOfAny(PathSeparators);
|
||||
var baseNamespace = lastSlash == -1 ? baseDirectory : baseDirectory.Substring(lastSlash + 1);
|
||||
if (string.IsNullOrEmpty(baseNamespace))
|
||||
{
|
||||
@namespace = null;
|
||||
@class = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
// Sanitize the base namespace, but leave the dots.
|
||||
var segments = baseNamespace.Split(NamespaceSeparators, StringSplitOptions.RemoveEmptyEntries);
|
||||
builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[0]));
|
||||
for (var i = 1; i < segments.Length; i++)
|
||||
{
|
||||
builder.Append('.');
|
||||
builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[i]));
|
||||
}
|
||||
|
||||
segments = relativePath.Split(PathSeparators, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// Skip the last segment because it's the FileName.
|
||||
for (var i = 0; i < segments.Length - 1; i++)
|
||||
{
|
||||
builder.Append('.');
|
||||
builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[i]));
|
||||
}
|
||||
|
||||
@namespace = builder.ToString();
|
||||
@class = CSharpIdentifier.SanitizeIdentifier(Path.GetFileNameWithoutExtension(relativePath));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// 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.Extensions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Components
|
||||
{
|
||||
public static class ComponentExtensions
|
||||
{
|
||||
public static void Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
builder.Features.Add(new ComponentDocumentClassifierPass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,13 +10,15 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
int indentSize,
|
||||
bool designTime,
|
||||
bool suppressChecksum,
|
||||
bool supressMetadataAttributes)
|
||||
bool supressMetadataAttributes,
|
||||
bool suppressPrimaryMethodBody)
|
||||
{
|
||||
IndentWithTabs = indentWithTabs;
|
||||
IndentSize = indentSize;
|
||||
DesignTime = designTime;
|
||||
SuppressChecksum = suppressChecksum;
|
||||
SuppressMetadataAttributes = supressMetadataAttributes;
|
||||
SuppressPrimaryMethodBody = suppressPrimaryMethodBody;
|
||||
}
|
||||
|
||||
public override bool DesignTime { get; }
|
||||
|
|
|
|||
|
|
@ -31,10 +31,16 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
public override bool IndentWithTabs { get; set; }
|
||||
|
||||
public override bool SuppressChecksum { get; set; }
|
||||
|
||||
|
||||
public override RazorCodeGenerationOptions Build()
|
||||
{
|
||||
return new DefaultRazorCodeGenerationOptions(IndentWithTabs, IndentSize, DesignTime, SuppressChecksum, SuppressMetadataAttributes);
|
||||
return new DefaultRazorCodeGenerationOptions(
|
||||
IndentWithTabs,
|
||||
IndentSize,
|
||||
DesignTime,
|
||||
SuppressChecksum,
|
||||
SuppressMetadataAttributes,
|
||||
SuppressPrimaryMethodBody);
|
||||
}
|
||||
|
||||
public override void SetDesignTime(bool designTime)
|
||||
|
|
|
|||
|
|
@ -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 Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
||||
{
|
||||
internal sealed class EliminateMethodBodyPass : IntermediateNodePassBase, IRazorOptimizationPass
|
||||
{
|
||||
// Run early in the optimization phase
|
||||
public override int Order => int.MinValue;
|
||||
|
||||
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
{
|
||||
if (codeDocument == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(codeDocument));
|
||||
}
|
||||
|
||||
if (documentNode == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(documentNode));
|
||||
}
|
||||
|
||||
var codeGenerationOptions = codeDocument.GetCodeGenerationOptions();
|
||||
if (codeGenerationOptions == null || !codeGenerationOptions.SuppressPrimaryMethodBody)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var method = documentNode.FindPrimaryMethod();
|
||||
if (method == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
method.Children.Clear();
|
||||
|
||||
// After we clear all of the method body there might be some unused fields, which can be
|
||||
// blocking if compiling with warnings as errors. Suppress this warning so that it doesn't
|
||||
// get annoying in VS.
|
||||
documentNode.Children.Insert(documentNode.Children.IndexOf(documentNode.FindPrimaryNamespace()), new CSharpCodeIntermediateNode()
|
||||
{
|
||||
Children =
|
||||
{
|
||||
// Field is assigned but never used
|
||||
new IntermediateToken()
|
||||
{
|
||||
Content = "#pragma warning disable 0414" + Environment.NewLine,
|
||||
Kind = TokenKind.CSharp,
|
||||
},
|
||||
|
||||
// Field is never assigned
|
||||
new IntermediateToken()
|
||||
{
|
||||
Content = "#pragma warning disable 0649" + Environment.NewLine,
|
||||
Kind = TokenKind.CSharp,
|
||||
},
|
||||
|
||||
// Field is never used
|
||||
new IntermediateToken()
|
||||
{
|
||||
Content = "#pragma warning disable 0169" + Environment.NewLine,
|
||||
Kind = TokenKind.CSharp,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
|
||||
{
|
||||
internal static class InputDocumentKind
|
||||
{
|
||||
public static readonly string Component = "component";
|
||||
|
||||
public static readonly string MvcFile = "mvc";
|
||||
}
|
||||
}
|
||||
|
|
@ -169,6 +169,26 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
document.Items[typeof(RazorCodeGenerationOptions)] = codeGenerationOptions;
|
||||
}
|
||||
|
||||
public static string GetInputDocumentKind(this RazorCodeDocument document)
|
||||
{
|
||||
if (document == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(document));
|
||||
}
|
||||
|
||||
return (string)document.Items[typeof(InputDocumentKind)];
|
||||
}
|
||||
|
||||
public static void SetInputDocumentKind(this RazorCodeDocument document, string kind)
|
||||
{
|
||||
if (document == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(document));
|
||||
}
|
||||
|
||||
document.Items[typeof(InputDocumentKind)] = kind;
|
||||
}
|
||||
|
||||
private class ImportSyntaxTreesHolder
|
||||
{
|
||||
public ImportSyntaxTreesHolder(IReadOnlyList<RazorSyntaxTree> syntaxTrees)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
indentSize: 4,
|
||||
designTime: false,
|
||||
suppressChecksum: false,
|
||||
supressMetadataAttributes: false);
|
||||
supressMetadataAttributes: false,
|
||||
suppressPrimaryMethodBody: false);
|
||||
}
|
||||
|
||||
public static RazorCodeGenerationOptions CreateDesignTimeDefault()
|
||||
|
|
@ -24,7 +25,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
indentSize: 4,
|
||||
designTime: true,
|
||||
suppressChecksum: false,
|
||||
supressMetadataAttributes: true);
|
||||
supressMetadataAttributes: true,
|
||||
suppressPrimaryMethodBody: false);
|
||||
}
|
||||
|
||||
public static RazorCodeGenerationOptions Create(Action<RazorCodeGenerationOptionsBuilder> configure)
|
||||
|
|
@ -93,5 +95,10 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public virtual bool SuppressMetadataAttributes { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines if an empty body is generated for the primary method.
|
||||
/// </summary>
|
||||
public virtual bool SuppressPrimaryMethodBody { get; protected set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
/// </remarks>
|
||||
public virtual bool SuppressMetadataAttributes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines if an empty body is generated for the primary method.
|
||||
/// </summary>
|
||||
public virtual bool SuppressPrimaryMethodBody { get; set; }
|
||||
|
||||
public abstract RazorCodeGenerationOptions Build();
|
||||
|
||||
public virtual void SetDesignTime(bool designTime)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language.Components;
|
||||
using Microsoft.AspNetCore.Razor.Language.Extensions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
|
|
@ -176,6 +176,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
features.Add(new DirectiveRemovalOptimizationPass());
|
||||
features.Add(new DefaultTagHelperOptimizationPass());
|
||||
features.Add(new PreallocatedTagHelperAttributeOptimizationPass());
|
||||
features.Add(new EliminateMethodBodyPass());
|
||||
|
||||
// Default Code Target Extensions
|
||||
var targetExtensionFeature = new DefaultRazorTargetExtensionFeature();
|
||||
|
|
@ -217,10 +218,15 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
// For now we only handle AssemblyExtension - which is not user-constructable. We're keeping a tight
|
||||
// lid on how things work until we add official support for extensibility everywhere. So, this is
|
||||
// intentionally inflexible for the time being.
|
||||
var extension = extensions[i] as AssemblyExtension;
|
||||
var initializer = extension?.CreateInitializer();
|
||||
initializer?.Initialize(builder);
|
||||
if (extensions[i] is AssemblyExtension extension)
|
||||
{
|
||||
var initializer = extension.CreateInitializer();
|
||||
initializer?.Initialize(builder);
|
||||
}
|
||||
}
|
||||
|
||||
// Default extensions.
|
||||
ComponentExtensions.Register(builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
public static class TagHelperConventions
|
||||
{
|
||||
public static readonly string DefaultKind = "ITagHelper";
|
||||
|
||||
public static readonly string ComponentKind = "IComponent";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
b.Features.Add(new DefaultMetadataReferenceFeature() { References = metadataReferences });
|
||||
b.Features.Add(new CompilationTagHelperFeature());
|
||||
b.Features.Add(new DefaultTagHelperDescriptorProvider());
|
||||
b.Features.Add(new ComponentTagHelperDescriptorProvider());
|
||||
});
|
||||
|
||||
var feature = engine.Engine.Features.OfType<ITagHelperFeature>().Single();
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Microsoft.VisualStudio.LanguageServices.Razor.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
|
@ -21,12 +23,14 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
Sources = Option("-s", ".cshtml files to compile", CommandOptionType.MultipleValue);
|
||||
Outputs = Option("-o", "Generated output file path", CommandOptionType.MultipleValue);
|
||||
RelativePaths = Option("-r", "Relative path", CommandOptionType.MultipleValue);
|
||||
DocumentKinds = Option("-k", "Document kind", CommandOptionType.MultipleValue);
|
||||
ProjectDirectory = Option("-p", "project root directory", CommandOptionType.SingleValue);
|
||||
TagHelperManifest = Option("-t", "tag helper manifest file", CommandOptionType.SingleValue);
|
||||
Version = Option("-v|--version", "Razor language version", CommandOptionType.SingleValue);
|
||||
Configuration = Option("-c", "Razor configuration name", CommandOptionType.SingleValue);
|
||||
ExtensionNames = Option("-n", "extension name", CommandOptionType.MultipleValue);
|
||||
ExtensionFilePaths = Option("-e", "extension file path", CommandOptionType.MultipleValue);
|
||||
GenerateDeclaration = Option("--generate-declaration", "Generate declaration", CommandOptionType.NoValue);
|
||||
}
|
||||
|
||||
public CommandOption Sources { get; }
|
||||
|
|
@ -35,6 +39,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
public CommandOption RelativePaths { get; }
|
||||
|
||||
public CommandOption DocumentKinds { get; }
|
||||
|
||||
public CommandOption ProjectDirectory { get; }
|
||||
|
||||
public CommandOption TagHelperManifest { get; }
|
||||
|
|
@ -47,6 +53,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
public CommandOption ExtensionFilePaths { get; }
|
||||
|
||||
public CommandOption GenerateDeclaration { get; }
|
||||
|
||||
protected override Task<int> ExecuteCoreAsync()
|
||||
{
|
||||
if (!Parent.Checker.Check(ExtensionFilePaths.Values))
|
||||
|
|
@ -66,13 +74,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
var version = RazorLanguageVersion.Parse(Version.Value());
|
||||
var configuration = RazorConfiguration.Create(version, Configuration.Value(), extensions);
|
||||
|
||||
var sourceItems = GetSourceItems(ProjectDirectory.Value(), Sources.Values, Outputs.Values, RelativePaths.Values, DocumentKinds.Values);
|
||||
|
||||
var result = ExecuteCore(
|
||||
configuration: configuration,
|
||||
projectDirectory: ProjectDirectory.Value(),
|
||||
tagHelperManifest: TagHelperManifest.Value(),
|
||||
sources: Sources.Values,
|
||||
outputs: Outputs.Values,
|
||||
relativePaths: RelativePaths.Values);
|
||||
sourceItems: sourceItems);
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
|
@ -88,11 +96,21 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
if (Outputs.Values.Count != Sources.Values.Count)
|
||||
{
|
||||
Error.WriteLine($"{Sources.Description} has {Sources.Values.Count}, but {Outputs.Description} has {Outputs.Values.Count} values.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RelativePaths.Values.Count != Sources.Values.Count)
|
||||
{
|
||||
Error.WriteLine($"{Sources.Description} has {Sources.Values.Count}, but {RelativePaths.Description} has {RelativePaths.Values.Count} values.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DocumentKinds.Values.Count != 0 && DocumentKinds.Values.Count != Sources.Values.Count)
|
||||
{
|
||||
// 2.x tasks do not specify DocumentKinds - in which case, no values will be present. If a kind for one document is specified, we expect as many kind entries
|
||||
// as sources.
|
||||
Error.WriteLine($"{Sources.Description} has {Sources.Values.Count}, but {DocumentKinds.Description} has {DocumentKinds.Values.Count} values.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ProjectDirectory.Value()))
|
||||
|
|
@ -138,26 +156,30 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
RazorConfiguration configuration,
|
||||
string projectDirectory,
|
||||
string tagHelperManifest,
|
||||
List<string> sources,
|
||||
List<string> outputs,
|
||||
List<string> relativePaths)
|
||||
SourceItem[] sourceItems)
|
||||
{
|
||||
tagHelperManifest = Path.Combine(projectDirectory, tagHelperManifest);
|
||||
|
||||
var tagHelpers = GetTagHelpers(tagHelperManifest);
|
||||
var inputItems = GetInputItems(projectDirectory, sources, outputs, relativePaths);
|
||||
|
||||
var compositeFileSystem = new CompositeRazorProjectFileSystem(new[]
|
||||
{
|
||||
GetVirtualRazorProjectSystem(inputItems),
|
||||
GetVirtualRazorProjectSystem(sourceItems),
|
||||
RazorProjectFileSystem.Create(projectDirectory),
|
||||
});
|
||||
|
||||
var engine = RazorProjectEngine.Create(configuration, compositeFileSystem, b =>
|
||||
{
|
||||
b.Features.Add(new StaticTagHelperFeature() { TagHelpers = tagHelpers, });
|
||||
b.Features.Add(new InputDocumentKindClassifierPass(sourceItems));
|
||||
|
||||
if (GenerateDeclaration.HasValue())
|
||||
{
|
||||
b.Features.Add(new SetSuppressPrimaryMethodBodyOptionFeature());
|
||||
}
|
||||
});
|
||||
|
||||
var results = GenerateCode(engine, inputItems);
|
||||
var results = GenerateCode(engine, sourceItems);
|
||||
|
||||
var success = true;
|
||||
|
||||
|
|
@ -229,13 +251,15 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
}
|
||||
}
|
||||
|
||||
private SourceItem[] GetInputItems(string projectDirectory, List<string> sources, List<string> outputs, List<string> relativePath)
|
||||
private SourceItem[] GetSourceItems(string projectDirectory, List<string> sources, List<string> outputs, List<string> relativePath, List<string> documentKinds)
|
||||
{
|
||||
var items = new SourceItem[sources.Count];
|
||||
for (var i = 0; i < items.Length; i++)
|
||||
{
|
||||
var outputPath = Path.Combine(projectDirectory, outputs[i]);
|
||||
items[i] = new SourceItem(sources[i], outputs[i], relativePath[i]);
|
||||
var documentKind = documentKinds.Count > 0 ? documentKinds[i] : "mvc";
|
||||
|
||||
items[i] = new SourceItem(sources[i], outputs[i], relativePath[i], documentKind);
|
||||
}
|
||||
|
||||
return items;
|
||||
|
|
@ -271,9 +295,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
public RazorCSharpDocument CSharpDocument { get; }
|
||||
}
|
||||
|
||||
private struct SourceItem
|
||||
private readonly struct SourceItem
|
||||
{
|
||||
public SourceItem(string sourcePath, string outputPath, string physicalRelativePath)
|
||||
public SourceItem(string sourcePath, string outputPath, string physicalRelativePath, string documentKind)
|
||||
{
|
||||
SourcePath = sourcePath;
|
||||
OutputPath = outputPath;
|
||||
|
|
@ -281,6 +305,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
FilePath = '/' + physicalRelativePath
|
||||
.Replace(Path.DirectorySeparatorChar, '/')
|
||||
.Replace("//", "/");
|
||||
DocumentKind = documentKind;
|
||||
}
|
||||
|
||||
public string SourcePath { get; }
|
||||
|
|
@ -290,6 +315,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
public string RelativePhysicalPath { get; }
|
||||
|
||||
public string FilePath { get; }
|
||||
|
||||
public string DocumentKind { get; }
|
||||
}
|
||||
|
||||
private class StaticTagHelperFeature : ITagHelperFeature
|
||||
|
|
@ -300,5 +327,46 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
public IReadOnlyList<TagHelperDescriptor> GetDescriptors() => TagHelpers;
|
||||
}
|
||||
|
||||
private class SetSuppressPrimaryMethodBodyOptionFeature : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature
|
||||
{
|
||||
public int Order { get; set; }
|
||||
|
||||
public void Configure(RazorCodeGenerationOptionsBuilder options)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
options.SuppressPrimaryMethodBody = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class InputDocumentKindClassifierPass : RazorEngineFeatureBase, IRazorDocumentClassifierPass
|
||||
{
|
||||
public InputDocumentKindClassifierPass(SourceItem[] sourceItems)
|
||||
{
|
||||
DocumentKinds = new Dictionary<string, string>(sourceItems.Length, StringComparer.OrdinalIgnoreCase);
|
||||
for (var i = 0; i < sourceItems.Length; i++)
|
||||
{
|
||||
var item = sourceItems[i];
|
||||
DocumentKinds[item.SourcePath] = item.DocumentKind;
|
||||
}
|
||||
}
|
||||
|
||||
// Run before other document classifiers
|
||||
public int Order => -1000;
|
||||
|
||||
public Dictionary<string, string> DocumentKinds { get; }
|
||||
|
||||
public void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
{
|
||||
if (DocumentKinds.TryGetValue(codeDocument.Source.FilePath, out var kind))
|
||||
{
|
||||
codeDocument.SetInputDocumentKind(kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Razor is a markup syntax for adding server-side logic to web pages. This assembly contains infrastructure supporting Razor MSBuild integration.</Description>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
/// Strings are encoded via a length prefix as a signed
|
||||
/// 32-bit integer, followed by an array of characters.
|
||||
/// </summary>
|
||||
internal struct RequestArgument
|
||||
internal readonly struct RequestArgument
|
||||
{
|
||||
public readonly ArgumentId Id;
|
||||
public readonly int ArgumentIndex;
|
||||
|
|
@ -63,5 +63,10 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
// The directory to use for temporary operations.
|
||||
TempDirectory,
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Id} {Value}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
public class ComponentTagHelperDescriptorProvider : 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 componentSymbol = compilation.GetTypeByMetadataName(TagHelperTypes.IComponent);
|
||||
if (componentSymbol == null || componentSymbol.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 ComponentTypeVisitor(componentSymbol, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < types.Count; i++)
|
||||
{
|
||||
var type = types[i];
|
||||
var descriptor = CreateDescriptor(type);
|
||||
|
||||
if (descriptor != null)
|
||||
{
|
||||
context.Results.Add(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static TagHelperDescriptor CreateDescriptor(INamedTypeSymbol type)
|
||||
{
|
||||
var typeName = type.ToDisplayString(DefaultTagHelperDescriptorFactory.FullNameTypeDisplayFormat);
|
||||
var assemblyName = type.ContainingAssembly.Identity.Name;
|
||||
|
||||
var descriptorBuilder = TagHelperDescriptorBuilder.Create(TagHelperConventions.ComponentKind, typeName, assemblyName);
|
||||
descriptorBuilder.SetTypeName(typeName);
|
||||
descriptorBuilder.Metadata[TagHelperMetadata.Runtime.Name] = TagHelperConventions.ComponentKind;
|
||||
|
||||
// Components have very simple matching rules. The type name (short) matches the tag name.
|
||||
descriptorBuilder.TagMatchingRule(r => r.TagName = type.Name);
|
||||
|
||||
var descriptor = descriptorBuilder.Build();
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private bool IsTagHelperAssembly(IAssemblySymbol assembly)
|
||||
{
|
||||
return assembly.Name != null && !assembly.Name.StartsWith("System.", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
// Visits top-level types and finds interface implementations.
|
||||
internal class ComponentTypeVisitor : SymbolVisitor
|
||||
{
|
||||
private readonly INamedTypeSymbol _componentSymbol;
|
||||
private readonly List<INamedTypeSymbol> _results;
|
||||
|
||||
public ComponentTypeVisitor(INamedTypeSymbol componentSymbol, List<INamedTypeSymbol> results)
|
||||
{
|
||||
_componentSymbol = componentSymbol;
|
||||
_results = results;
|
||||
}
|
||||
|
||||
public override void VisitNamedType(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (IsComponent(symbol))
|
||||
{
|
||||
_results.Add(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitNamespace(INamespaceSymbol symbol)
|
||||
{
|
||||
foreach (var member in symbol.GetMembers())
|
||||
{
|
||||
Visit(member);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitAssembly(IAssemblySymbol symbol)
|
||||
{
|
||||
// This as a simple yet high-value optimization that excludes the vast majority of
|
||||
// assemblies that (by definition) can't contain a component.
|
||||
if (symbol.Name != null && !symbol.Name.StartsWith("System.", StringComparison.Ordinal))
|
||||
{
|
||||
Visit(symbol.GlobalNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsComponent(INamedTypeSymbol symbol)
|
||||
{
|
||||
return
|
||||
symbol.DeclaredAccessibility == Accessibility.Public &&
|
||||
!symbol.IsAbstract &&
|
||||
symbol.AllInterfaces.Contains(_componentSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
private readonly INamedTypeSymbol _restrictChildrenAttributeSymbol;
|
||||
private readonly INamedTypeSymbol _editorBrowsableAttributeSymbol;
|
||||
|
||||
private static readonly SymbolDisplayFormat FullNameTypeDisplayFormat =
|
||||
internal static readonly SymbolDisplayFormat FullNameTypeDisplayFormat =
|
||||
SymbolDisplayFormat.FullyQualifiedFormat
|
||||
.WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted)
|
||||
.WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & (~SymbolDisplayMiscellaneousOptions.UseSpecialTypes));
|
||||
|
|
@ -434,6 +434,6 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
return false;
|
||||
}
|
||||
|
||||
private static string GetFullName(ITypeSymbol type) => type.ToDisplayString(FullNameTypeDisplayFormat);
|
||||
protected static string GetFullName(ITypeSymbol type) => type.ToDisplayString(FullNameTypeDisplayFormat);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,8 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
public const string ITagHelper = "Microsoft.AspNetCore.Razor.TagHelpers.ITagHelper";
|
||||
|
||||
public const string IComponent = "Microsoft.AspNetCore.Components.IComponent";
|
||||
|
||||
public const string IDictionary = "System.Collections.Generic.IDictionary`2";
|
||||
|
||||
public const string HtmlAttributeNameAttribute = "Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute";
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
|||
};
|
||||
|
||||
private const string GeneratedOutput = "GeneratedOutput";
|
||||
private const string DocumentKind = "DocumentKind";
|
||||
private const string TargetPath = "TargetPath";
|
||||
private const string FullPath = "FullPath";
|
||||
private const string Identity = "Identity";
|
||||
|
|
@ -41,6 +42,8 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
|||
[Required]
|
||||
public string TagHelperManifest { get; set; }
|
||||
|
||||
public bool GenerateDeclaration { get; set; }
|
||||
|
||||
internal override string Command => "generate";
|
||||
|
||||
protected override bool ValidateParameters()
|
||||
|
|
@ -99,6 +102,13 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
|||
builder.AppendLine("-o");
|
||||
var outputPath = Path.Combine(ProjectRoot, input.GetMetadata(GeneratedOutput));
|
||||
builder.AppendLine(outputPath);
|
||||
|
||||
var kind = input.GetMetadata(DocumentKind);
|
||||
if (!string.IsNullOrEmpty(kind))
|
||||
{
|
||||
builder.AppendLine("-k");
|
||||
builder.AppendLine(kind);
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine("-p");
|
||||
|
|
@ -113,6 +123,11 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
|||
builder.AppendLine("-c");
|
||||
builder.AppendLine(Configuration[0].GetMetadata(Identity));
|
||||
|
||||
if (GenerateDeclaration)
|
||||
{
|
||||
builder.AppendLine("--generate-declaration");
|
||||
}
|
||||
|
||||
for (var i = 0; i < Extensions.Length; i++)
|
||||
{
|
||||
builder.AppendLine("-n");
|
||||
|
|
|
|||
|
|
@ -70,10 +70,15 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target
|
||||
Name="_RazorEnsureCompiled"
|
||||
Condition="!Exists('$(_RazorGenerateTargetReferenceAssembly)')"
|
||||
DependsOnTargets="Compile" />
|
||||
|
||||
<Target
|
||||
Name="ResolveTagHelperRazorGenerateInputs"
|
||||
DependsOnTargets="_EnsureRazorTasksAssemblyDefined;Compile"
|
||||
Inputs="$(MSBuildAllProjects);@(RazorReferencePath)"
|
||||
Inputs="$(MSBuildAllProjects);@(RazorReferencePath);$(_RazorGenerateTargetReferenceAssembly)"
|
||||
DependsOnTargets="_RazorEnsureCompiled"
|
||||
Outputs="$(_RazorTagHelperInputCache)"
|
||||
Condition="'@(RazorGenerateWithTargetPath)' != ''">
|
||||
|
||||
|
|
@ -100,7 +105,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
Version="$(RazorLangVersion)"
|
||||
Configuration="@(ResolvedRazorConfiguration)"
|
||||
Extensions="@(ResolvedRazorExtension)"
|
||||
Assemblies="@(RazorReferencePath)"
|
||||
Assemblies="@(RazorReferencePath);$(_RazorGenerateTargetReferenceAssembly)"
|
||||
ProjectRoot="$(MSBuildProjectDirectory)"
|
||||
TagHelperManifest="$(_RazorTagHelperOutputCache)">
|
||||
<Output
|
||||
|
|
@ -121,7 +126,6 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
|
||||
<PropertyGroup>
|
||||
<RazorCoreGenerateDependsOn>
|
||||
_EnsureRazorTasksAssemblyDefined;
|
||||
_HashRazorGenerateInputs;
|
||||
_ResolveRazorGenerateOutputs;
|
||||
</RazorCoreGenerateDependsOn>
|
||||
|
|
@ -167,14 +171,10 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
|
||||
<Target Name="_ResolveGeneratedRazorCompileInputs">
|
||||
<ItemGroup>
|
||||
<RazorCompile Include="@(_RazorGenerateOutput)" />
|
||||
<RazorCompile
|
||||
Include="%(RazorGenerateWithTargetPath.GeneratedOutput)"
|
||||
Condition="'%(RazorGenerateWithTargetPath.DocumentKind)'=='mvc'" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_EnsureRazorTasksAssemblyDefined">
|
||||
<Error
|
||||
Text="Assembly location for Razor SDK Tasks was not specified. The most likely cause is an older incompatible version of Microsoft.NET.Sdk.Razor, or Microsoft.NET.Sdk.Web used by this project. Please target a newer version of the .NET Core SDK."
|
||||
Condition="'$(RazorSdkBuildTasksAssembly)' == ''" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
Inputs="$(MSBuildAllProjects);
|
||||
@(RazorCompile);
|
||||
$(AssemblyOriginatorKeyFile);
|
||||
$(_RazorCompileTargetReferenceAssembly);
|
||||
@(RazorReferencePath);
|
||||
@(CompiledLicenseFile);
|
||||
@(LinkResource);
|
||||
|
|
@ -147,7 +148,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
Prefer32Bit="$(Prefer32Bit)"
|
||||
PreferredUILang="$(PreferredUILang)"
|
||||
ProvideCommandLineArgs="$(ProvideCommandLineArgs)"
|
||||
References="@(RazorReferencePath)"
|
||||
References="@(RazorReferencePath);$(_RazorCompileTargetReferenceAssembly)"
|
||||
ReportAnalyzer="$(ReportAnalyzer)"
|
||||
Resources="@(_RazorCoreCompileResourceInputs);@(CompiledLicenseFile)"
|
||||
ResponseFiles="$(CompilerResponseFile)"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
<!--
|
||||
***********************************************************************************************
|
||||
Microsoft.NET.Sdk.Razor.Component.targets
|
||||
|
||||
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
|
||||
created a backup copy. Incorrect changes to this file will make it
|
||||
impossible to load or build your projects from the command-line or the IDE.
|
||||
|
||||
Copyright (c) .NET Foundation. All rights reserved.
|
||||
***********************************************************************************************
|
||||
-->
|
||||
|
||||
<Project ToolsVersion="14.0">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Used for tracking inputs to component generation -->
|
||||
<_RazorComponentInputHash></_RazorComponentInputHash>
|
||||
<_RazorComponentInputCacheFile>$(IntermediateOutputPath)$(MSBuildProjectName).RazorComponent.input.cache</_RazorComponentInputCacheFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Path used for the temporary compilation we produce for component discovery -->
|
||||
<_RazorComponentDeclarationAssembly Include="$(_RazorComponentDeclarationOutputPath)$(TargetName).dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="_HashRazorComponentInputs" Condition="'@(RazorComponentWithTargetPath->Count())'!='0'">
|
||||
<Hash ItemsToHash="@(RazorComponentWithTargetPath)">
|
||||
<Output TaskParameter="HashResult" PropertyName="_RazorComponentInputHash" />
|
||||
</Hash>
|
||||
|
||||
<MakeDir
|
||||
Directories="$(IntermediateOutputPath)"
|
||||
Condition="!Exists('$(IntermediateOutputPath)')" />
|
||||
|
||||
<WriteLinesToFile
|
||||
Lines="$(_RazorComponentInputHash)"
|
||||
File="$(_RazorComponentInputCacheFile)"
|
||||
Overwrite="True"
|
||||
WriteOnlyWhenDifferent="True" />
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="$(_RazorComponentInputCacheFile)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ResolveRazorComponentOutputs" Condition="'@(RazorComponentWithTargetPath->Count())'!='0'">
|
||||
<Error
|
||||
Text="RazorComponentWithTargetPath item '%(RazorComponentWithTargetPath.Identity)' does not specify required metadata 'GeneratedDeclaration'."
|
||||
Condition="'%(RazorComponentWithTargetPath.GeneratedDeclaration)' == ''" />
|
||||
|
||||
<ItemGroup>
|
||||
<_RazorComponentDeclaration Include="%(RazorComponentWithTargetPath.GeneratedDeclaration)" />
|
||||
<_RazorComponentDefinition Include="%(RazorComponentWithTargetPath.GeneratedOutput)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<RazorGenerateComponentDeclarationDependsOn>
|
||||
_HashRazorComponentInputs;
|
||||
_ResolveRazorComponentOutputs;
|
||||
</RazorGenerateComponentDeclarationDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
Generates 'declaration' files for each component, that only have that class and member declarations.
|
||||
These files participate in the design-time-build for intellisense, and are used at build-time
|
||||
when discovering components for a 'real' build.
|
||||
-->
|
||||
<Target
|
||||
Name="RazorGenerateComponentDeclaration"
|
||||
DependsOnTargets="$(RazorGenerateComponentDeclarationDependsOn)"
|
||||
Inputs="$(MSBuildAllProjects);@(RazorComponentWithTargetPath);$(_RazorComponentInputCacheFile)"
|
||||
Outputs="@(_RazorComponentDeclaration)"
|
||||
Condition="'@(RazorComponentWithTargetPath->Count())'!='0'">
|
||||
|
||||
<ItemGroup>
|
||||
<_RazorComponentDeclarationSources Include="@(RazorComponentWithTargetPath)">
|
||||
<GeneratedOutput>%(RazorComponentWithTargetPath.GeneratedDeclaration)</GeneratedOutput>
|
||||
</_RazorComponentDeclarationSources>
|
||||
</ItemGroup>
|
||||
|
||||
<MakeDir
|
||||
Directories="%(_RazorComponentDeclaration.RelativeDir)"
|
||||
Condition="!Exists('%(_RazorComponentDeclaration.RelativeDir)')" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- This file will not exist, but we need some value -->
|
||||
<_RazorComponentDeclarationManifest>$(IntermediateOutputPath)$(MSBuildProjectName).RazorComponents.declaration.json</_RazorComponentDeclarationManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<RazorGenerate
|
||||
Debug="$(_RazorDebugGenerateCodeTask)"
|
||||
DebugTool="$(_RazorDebugGenerateCodeTool)"
|
||||
ToolAssembly="$(_RazorToolAssembly)"
|
||||
UseServer="$(UseRazorBuildServer)"
|
||||
ForceServer="$(_RazorForceBuildServer)"
|
||||
PipeName="$(_RazorBuildServerPipeName)"
|
||||
Version="$(RazorLangVersion)"
|
||||
Configuration="@(ResolvedRazorConfiguration)"
|
||||
Extensions="@(ResolvedRazorExtension)"
|
||||
Sources="@(_RazorComponentDeclarationSources)"
|
||||
ProjectRoot="$(MSBuildProjectDirectory)"
|
||||
TagHelperManifest="$(_RazorComponentDeclarationManifest)"
|
||||
GenerateDeclaration="true" />
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="@(_RazorComponentDeclaration)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(DesignTimeBuild)'=='true'">
|
||||
<Compile Include="@(_RazorComponentDeclaration)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target
|
||||
Name="RazorCompileComponentDeclaration"
|
||||
Inputs="
|
||||
$(MSBuildAllProjects);
|
||||
@(_RazorComponentDeclaration);
|
||||
@(Compile);
|
||||
$(AssemblyOriginatorKeyFile);
|
||||
@(ReferencePathWithRefAssemblies);
|
||||
@(CompiledLicenseFile);
|
||||
@(LinkResource);
|
||||
$(ResolvedCodeAnalysisRuleSet);
|
||||
@(AdditionalFiles)"
|
||||
Outputs="@(_RazorComponentDeclarationAssembly);$(NonExistentFile)"
|
||||
Condition="'$(DesignTimeBuild)'!='true' AND '$(Language)'=='C#' AND '@(_RazorComponentDeclaration)' != ''">
|
||||
|
||||
<MakeDir Directories="%(_RazorComponentDeclarationAssembly.RelativeDir)" />
|
||||
|
||||
<!-- These two compiler warnings are raised when a reference is bound to a different version
|
||||
than specified in the assembly reference version number. MSBuild raises the same warning in this case,
|
||||
so the compiler warning would be redundant. -->
|
||||
<PropertyGroup Condition="('$(TargetFrameworkVersion)' != 'v1.0') and ('$(TargetFrameworkVersion)' != 'v1.1')">
|
||||
<NoWarn>$(NoWarn);1701;1702</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- To match historical behavior, when inside VS11+ disable the warning from csc.exe indicating that no sources were passed in-->
|
||||
<NoWarn Condition="'$(BuildingInsideVisualStudio)' == 'true' AND '$(VisualStudioVersion)' != '' AND '$(VisualStudioVersion)' > '10.0'">$(NoWarn);2008</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetingClr2Framework)' == 'true'">
|
||||
<ReferencePathWithRefAssemblies>
|
||||
<EmbedInteropTypes />
|
||||
</ReferencePathWithRefAssemblies>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- If the user has specified AppConfigForCompiler, we'll use it. If they have not, but they set UseAppConfigForCompiler,
|
||||
then we'll use AppConfig -->
|
||||
<AppConfigForCompiler Condition="'$(AppConfigForCompiler)' == '' AND '$(UseAppConfigForCompiler)' == 'true'">$(AppConfig)</AppConfigForCompiler>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Prefer32Bit was introduced in .NET 4.5. Set it to false if we are targeting 4.0 -->
|
||||
<PropertyGroup Condition="('$(TargetFrameworkVersion)' == 'v4.0')">
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- TODO: Remove this ItemGroup once it has been moved to "_GenerateCompileInputs" target in Microsoft.Common.CurrentVersion.targets.
|
||||
https://github.com/dotnet/roslyn/issues/12223 -->
|
||||
<ItemGroup Condition="('$(AdditionalFileItemNames)' != '')">
|
||||
<AdditionalFileItems Include="$(AdditionalFileItemNames)" />
|
||||
<AdditionalFiles Include="@(%(AdditionalFileItems.Identity))" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(UseSharedCompilation)' == ''">
|
||||
<UseSharedCompilation>true</UseSharedCompilation>
|
||||
</PropertyGroup>
|
||||
|
||||
<Csc
|
||||
AdditionalLibPaths="$(AdditionalLibPaths)"
|
||||
AddModules="@(AddModules)"
|
||||
AdditionalFiles="@(AdditionalFiles)"
|
||||
AllowUnsafeBlocks="$(AllowUnsafeBlocks)"
|
||||
Analyzers="@(Analyzer)"
|
||||
ApplicationConfiguration="$(AppConfigForCompiler)"
|
||||
BaseAddress="$(BaseAddress)"
|
||||
CheckForOverflowUnderflow="$(CheckForOverflowUnderflow)"
|
||||
ChecksumAlgorithm="$(ChecksumAlgorithm)"
|
||||
CodeAnalysisRuleSet="$(ResolvedCodeAnalysisRuleSet)"
|
||||
CodePage="$(CodePage)"
|
||||
DebugType="$(DebugType)"
|
||||
DefineConstants="$(DefineConstants)"
|
||||
DelaySign="$(DelaySign)"
|
||||
DisabledWarnings="$(NoWarn)"
|
||||
EmitDebugInformation="$(DebugSymbols)"
|
||||
EnvironmentVariables="$(CscEnvironment)"
|
||||
ErrorEndLocation="$(ErrorEndLocation)"
|
||||
ErrorLog="$(ErrorLog)"
|
||||
ErrorReport="$(ErrorReport)"
|
||||
Features="$(Features)"
|
||||
FileAlignment="$(FileAlignment)"
|
||||
GenerateFullPaths="$(GenerateFullPaths)"
|
||||
HighEntropyVA="$(HighEntropyVA)"
|
||||
Instrument="$(Instrument)"
|
||||
KeyContainer="$(KeyContainerName)"
|
||||
KeyFile="$(KeyOriginatorFile)"
|
||||
LangVersion="$(LangVersion)"
|
||||
LinkResources="@(LinkResource)"
|
||||
MainEntryPoint="$(StartupObject)"
|
||||
ModuleAssemblyName="$(ModuleAssemblyName)"
|
||||
NoConfig="true"
|
||||
NoLogo="$(NoLogo)"
|
||||
NoStandardLib="$(NoCompilerStandardLib)"
|
||||
NoWin32Manifest="$(NoWin32Manifest)"
|
||||
Optimize="$(Optimize)"
|
||||
Deterministic="$(Deterministic)"
|
||||
PublicSign="$(PublicSign)"
|
||||
OutputAssembly="@(_RazorComponentDeclarationAssembly)"
|
||||
Platform="$(PlatformTarget)"
|
||||
Prefer32Bit="$(Prefer32Bit)"
|
||||
PreferredUILang="$(PreferredUILang)"
|
||||
ProvideCommandLineArgs="$(ProvideCommandLineArgs)"
|
||||
References="@(ReferencePathWithRefAssemblies)"
|
||||
ReportAnalyzer="$(ReportAnalyzer)"
|
||||
Resources="@(CompiledLicenseFile)"
|
||||
ResponseFiles="$(CompilerResponseFile)"
|
||||
RuntimeMetadataVersion="$(RuntimeMetadataVersion)"
|
||||
SharedCompilationId="$(SharedCompilationId)"
|
||||
SkipCompilerExecution="$(SkipCompilerExecution)"
|
||||
Sources="@(_RazorComponentDeclaration);@(Compile)"
|
||||
SubsystemVersion="$(SubsystemVersion)"
|
||||
TargetType="$(OutputType)"
|
||||
ToolExe="$(CscToolExe)"
|
||||
ToolPath="$(CscToolPath)"
|
||||
TreatWarningsAsErrors="$(TreatWarningsAsErrors)"
|
||||
UseHostCompilerIfAvailable="$(UseHostCompilerIfAvailable)"
|
||||
UseSharedCompilation="$(UseSharedCompilation)"
|
||||
Utf8Output="$(Utf8Output)"
|
||||
VsSessionGuid="$(VsSessionGuid)"
|
||||
WarningLevel="$(WarningLevel)"
|
||||
WarningsAsErrors="$(WarningsAsErrors)"
|
||||
WarningsNotAsErrors="$(WarningsNotAsErrors)"
|
||||
PathMap="$(PathMap)"
|
||||
SourceLink="$(SourceLink)">
|
||||
<Output TaskParameter="CommandLineArgs" ItemName="CscCommandLineArgs" />
|
||||
</Csc>
|
||||
|
||||
<ItemGroup>
|
||||
<FileWrites Include="@(_RazorComponentDeclarationAssembly)" Condition="Exists('@(_RazorComponentDeclarationAssembly)')" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ResolveComponentRazorGenerateInputs">
|
||||
<ItemGroup>
|
||||
<!-- Add RazorComponent files to the set of files to be code-gened. -->
|
||||
<RazorGenerateWithTargetPath Include="@(RazorComponentWithTargetPath)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Point to the declaration assembly to perform taghelper discovery -->
|
||||
<PropertyGroup>
|
||||
<_RazorGenerateTargetReferenceAssembly>@(_RazorComponentDeclarationAssembly->Metadata('FullPath'))</_RazorGenerateTargetReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
Once RazorCompileComponentDeclaration is completed, we have all the inputs required for code generation of
|
||||
RazorComponents and RazorGenerate items. We'll initialize the inputs for RazorGenerate and invoke it.
|
||||
This should result in RazorGenerate \ RazorTagHelper targets no-oping when it get invoked as
|
||||
part of PrepareForRun \ PrepareForPublish for non-components (.cshtml) files.
|
||||
-->
|
||||
<Target
|
||||
Name="RazorGenerateComponentDefinition"
|
||||
DependsOnTargets="_ResolveComponentRazorGenerateInputs;RazorGenerate"
|
||||
Condition="'$(DesignTimeBuild)' != 'true' AND '@(_RazorComponentDefinition->Count())' != '0' AND Exists('@(_RazorComponentDeclarationAssembly)')">
|
||||
|
||||
<ItemGroup Condition="'$(DesignTimeBuild)' != 'true'">
|
||||
<Compile Include="@(_RazorComponentDefinition)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<RazorComponentGenerateCoreDependsOn>
|
||||
RazorGenerateComponentDeclaration;
|
||||
RazorCompileComponentDeclaration;
|
||||
RazorGenerateComponentDefinition;
|
||||
</RazorComponentGenerateCoreDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="RazorComponentGenerateCore" DependsOnTargets="$(RazorComponentGenerateCoreDependsOn)">
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -29,6 +29,11 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
-->
|
||||
<EnableDefaultRazorGenerateItems Condition="'$(EnableDefaultRazorGenerateItems)'==''">true</EnableDefaultRazorGenerateItems>
|
||||
|
||||
<!--
|
||||
Set to true to automatically include Razor (.razor) files in @(RazorComponent) from @(Content).
|
||||
-->
|
||||
<EnableDefaultRazorComponentItems Condition="'$(EnableDefaultRazorComponentItems)'==''">true</EnableDefaultRazorComponentItems>
|
||||
|
||||
<!--
|
||||
Set to true to copy RazorGenerate items (.cshtml) to the publish directory.
|
||||
|
||||
|
|
@ -61,14 +66,21 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<!--
|
||||
Configures the file extension used for generated C# files.
|
||||
-->
|
||||
<RazorGenerateOutputFileExtension>.g.cshtml.cs</RazorGenerateOutputFileExtension>
|
||||
<RazorGenerateOutputFileExtension>.g.cs</RazorGenerateOutputFileExtension>
|
||||
|
||||
<!--
|
||||
Configures the file extension used for the generated C# definition files.
|
||||
-->
|
||||
<RazorGenerateOutputDefinitionFileExtension>.g.i.cs</RazorGenerateOutputDefinitionFileExtension>
|
||||
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(EnableDefaultItems)' == 'true' And '$(EnableDefaultContentItems)' == 'true'">
|
||||
<Content Include="**\*.cshtml" CopyToPublishDirectory="PreserveNewest" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes)" />
|
||||
<Content Include="**\*.razor" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes)" />
|
||||
<None Remove="**\*.cshtml" />
|
||||
<None Remove="**\*.razor" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -50,12 +50,23 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
ResolveTagHelperRazorGenerateInputs
|
||||
</PrepareForRazorGenerateDependsOn>
|
||||
|
||||
<PrepareForRazorComponentGenerateDependsOn>
|
||||
ResolveRazorConfiguration;
|
||||
ResolveRazorComponentInputs;
|
||||
AssignRazorComponentTargetPaths;
|
||||
</PrepareForRazorComponentGenerateDependsOn>
|
||||
|
||||
<RazorGenerateDependsOn>
|
||||
PrepareForRazorGenerate;
|
||||
_CheckForMissingRazorCompiler;
|
||||
RazorCoreGenerate
|
||||
</RazorGenerateDependsOn>
|
||||
|
||||
|
||||
<RazorComponentGenerateDependsOn>
|
||||
PrepareForRazorComponentGenerate;
|
||||
RazorComponentGenerateCore
|
||||
</RazorComponentGenerateDependsOn>
|
||||
|
||||
<PrepareForRazorCompileDependsOn>
|
||||
RazorGenerate;
|
||||
ResolveRazorCompileInputs;
|
||||
|
|
@ -81,6 +92,11 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
_RazorAddDebugSymbolsProjectOutputGroupOutput
|
||||
</DebugSymbolsProjectOutputGroupDependsOn>
|
||||
|
||||
<CoreCompileDependsOn>
|
||||
RazorComponentGenerate;
|
||||
$(CoreCompileDependsOn)
|
||||
</CoreCompileDependsOn>
|
||||
|
||||
<PrepareForBuildDependsOn>
|
||||
$(PrepareForBuildDependsOn);
|
||||
ResolveRazorGenerateInputs
|
||||
|
|
@ -128,6 +144,8 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<!-- Output directory used for generated files -->
|
||||
<RazorGenerateIntermediateOutputPath Condition="'$(RazorGenerateIntermediateOutputPath)'==''">$(IntermediateOutputPath)Razor\</RazorGenerateIntermediateOutputPath>
|
||||
|
||||
<_RazorComponentDeclarationOutputPath Condition="'$(_RazorComponentDeclarationOutputPath)'==''">$(IntermediateOutputPath)RazorDeclaration\</_RazorComponentDeclarationOutputPath>
|
||||
|
||||
<!--
|
||||
Use the suffix .Views when producing compiled view assemblies. This matches the requirements for Mvc's ViewsFeatureProvider.
|
||||
-->
|
||||
|
|
@ -135,11 +153,11 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
|
||||
<!-- Suffix appended to $(TargetName) to produce $(RazorTargetName), the name of the assembly produced by Razor -->
|
||||
<RazorTargetNameSuffix Condition="'$(RazorTargetNameSuffix)' == ''">.Razor</RazorTargetNameSuffix>
|
||||
|
||||
|
||||
<!-- File name (without extension) of the assembly produced by Razor -->
|
||||
<RazorTargetName Condition="'$(RazorTargetName)'==''">$(TargetName)$(RazorTargetNameSuffix)</RazorTargetName>
|
||||
|
||||
<!--
|
||||
<!--
|
||||
The compatibility zone - these properties were provided by the MVC Precompilation tool and they
|
||||
map to supported settings in Razor SDK.
|
||||
|
||||
|
|
@ -210,7 +228,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<ItemGroup>
|
||||
<!-- Used to creating the final compiled Razor dll -->
|
||||
<RazorIntermediateAssembly Condition="'$(RazorIntermediateAssembly)'==''" Include="$(IntermediateOutputPath)$(RazorTargetName).dll" />
|
||||
<!-- Used in Compilation.targets -->
|
||||
<!-- Used in Compilation.targets -->
|
||||
<_RazorDebugSymbolsIntermediatePath Condition="'$(_RazorDebugSymbolsProduced)'=='true'" Include="$(IntermediateOutputPath)$(RazorTargetName).pdb" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
@ -246,6 +264,8 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<!-- For projects targeting 3.x and later, use the compiler that ships in the Sdk -->
|
||||
<Import Project="Microsoft.NET.Sdk.Razor.CodeGeneration.targets" Condition="'$(_EnableAllInclusiveRazorSdk)' == 'true'" />
|
||||
|
||||
<Import Project="Microsoft.NET.Sdk.Razor.Component.targets" />
|
||||
|
||||
<Import Project="Microsoft.NET.Sdk.Razor.GenerateAssemblyInfo.targets" />
|
||||
|
||||
<!--
|
||||
|
|
@ -258,9 +278,15 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<Target Name="PrepareForRazorGenerate" DependsOnTargets="$(PrepareForRazorGenerateDependsOn)">
|
||||
</Target>
|
||||
|
||||
<Target Name="PrepareForRazorComponentGenerate" DependsOnTargets="$(PrepareForRazorComponentGenerateDependsOn)">
|
||||
</Target>
|
||||
|
||||
<Target Name="RazorGenerate" DependsOnTargets="$(RazorGenerateDependsOn)">
|
||||
</Target>
|
||||
|
||||
<Target Name="RazorComponentGenerate" DependsOnTargets="$(RazorComponentGenerateDependsOn)">
|
||||
</Target>
|
||||
|
||||
<Target Name="PrepareForRazorCompile" DependsOnTargets="$(PrepareForRazorCompileDependsOn)">
|
||||
</Target>
|
||||
|
||||
|
|
@ -271,7 +297,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
Computes the applicable @(ResolvedRazorConfiguration) and @(ResolvedRazorExtension) items that match the project's
|
||||
configuration.
|
||||
-->
|
||||
<Target
|
||||
<Target
|
||||
Name="ResolveRazorConfiguration"
|
||||
Condition="'$(RazorDefaultConfiguration)'!=''">
|
||||
|
||||
|
|
@ -299,7 +325,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<_GenerateRazorAssemblyInfoDependsOn>RazorGetAssemblyAttributes;$(_GenerateRazorAssemblyInfoDependsOn)</_GenerateRazorAssemblyInfoDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target
|
||||
<Target
|
||||
Name="RazorGetAssemblyAttributes"
|
||||
Condition="'$(GenerateRazorHostingAssemblyInfo)'=='true' and '$(RazorDefaultConfiguration)'!=''"
|
||||
DependsOnTargets="ResolveRazorConfiguration">
|
||||
|
|
@ -354,7 +380,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
'$(CopyRazorGenerateFilesToPublishDirectory)'=='false' and
|
||||
'$(ResolvedRazorCompileToolset)'=='RazorSdk' and
|
||||
'$(RazorCompileOnPublish)'=='true'">
|
||||
|
||||
|
||||
<Content Condition="'%(Content.Extension)'=='.cshtml'" CopyToPublishDirectory="Never" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
@ -366,6 +392,40 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="ResolveRazorComponentInputs">
|
||||
<!--
|
||||
Gathers input source files for Razor component generation. This is a separate target so that we can avoid
|
||||
lots of work when there are no inputs for code generation.
|
||||
|
||||
NOTE: This target is called as part of an incremental build scenario in VS. Do not perform any work
|
||||
outside of calculating RazorComponent items in this target.
|
||||
-->
|
||||
|
||||
<ItemGroup Condition="'$(EnableDefaultRazorComponentItems)'=='true'">
|
||||
<RazorComponent Include="@(Content)" Condition="'%(Content.Extension)'=='.razor'" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="AssignRazorComponentTargetPaths" Condition="'@(RazorComponent)' != ''">
|
||||
<AssignTargetPath Files="@(RazorComponent)" RootFolder="$(MSBuildProjectDirectory)">
|
||||
<Output TaskParameter="AssignedFiles" ItemName="RazorComponentWithTargetPath" />
|
||||
</AssignTargetPath>
|
||||
|
||||
<ItemGroup>
|
||||
<RazorComponentWithTargetPath Condition="'%(RazorComponentWithTargetPath.GeneratedOutput)' == ''">
|
||||
<GeneratedOutput>$(RazorGenerateIntermediateOutputPath)%(RazorComponentWithTargetPath.TargetPath)$(RazorGenerateOutputFileExtension)</GeneratedOutput>
|
||||
</RazorComponentWithTargetPath>
|
||||
|
||||
<RazorComponentWithTargetPath Condition="'%(RazorComponentWithTargetPath.GeneratedDeclaration)' == ''">
|
||||
<GeneratedDeclaration>$(_RazorComponentDeclarationOutputPath)%(RazorComponentWithTargetPath.TargetPath)$(RazorGenerateOutputFileExtension)</GeneratedDeclaration>
|
||||
</RazorComponentWithTargetPath>
|
||||
|
||||
<RazorComponentWithTargetPath Condition="'%(RazorComponentWithTargetPath.DocumentKind)' == ''">
|
||||
<DocumentKind>component</DocumentKind>
|
||||
</RazorComponentWithTargetPath>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="AssignRazorGenerateTargetPaths" Condition="'@(RazorGenerate)' != ''">
|
||||
<AssignTargetPath Files="@(RazorGenerate)" RootFolder="$(MSBuildProjectDirectory)">
|
||||
<Output TaskParameter="AssignedFiles" ItemName="RazorGenerateWithTargetPath" />
|
||||
|
|
@ -373,7 +433,11 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
|
||||
<ItemGroup>
|
||||
<RazorGenerateWithTargetPath Condition="'%(RazorGenerateWithTargetPath.GeneratedOutput)' == ''">
|
||||
<GeneratedOutput>$(RazorGenerateIntermediateOutputPath)$([System.IO.Path]::ChangeExtension('%(RazorGenerateWithTargetPath.TargetPath)', '$(RazorGenerateOutputFileExtension)'))</GeneratedOutput>
|
||||
<GeneratedOutput>$(RazorGenerateIntermediateOutputPath)%(RazorGenerateWithTargetPath.TargetPath)$(RazorGenerateOutputFileExtension)</GeneratedOutput>
|
||||
</RazorGenerateWithTargetPath>
|
||||
|
||||
<RazorGenerateWithTargetPath Condition="'%(RazorGenerateWithTargetPath.DocumentKind)' == ''">
|
||||
<DocumentKind>mvc</DocumentKind>
|
||||
</RazorGenerateWithTargetPath>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
|
@ -386,8 +450,20 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
DependsOnTargets="ResolveReferences">
|
||||
<ItemGroup>
|
||||
<RazorReferencePath Include="@(ReferencePath)"/>
|
||||
<RazorReferencePath Include="$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)$(TargetName)$(TargetExt)'))"/>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Assembly of the project used as input in RazorGenerate. This property is overwritten to point to the definition assembly when components are present.
|
||||
-->
|
||||
<_RazorGenerateTargetReferenceAssembly Condition="'$(_RazorGenerateTargetReferenceAssembly)'==''">
|
||||
@(IntermediateAssembly->Metadata('FullPath'))
|
||||
</_RazorGenerateTargetReferenceAssembly>
|
||||
|
||||
<_RazorCompileTargetReferenceAssembly Condition="'$(_RazorCompileTargetReferenceAssembly)'==''">
|
||||
@(IntermediateAssembly->Metadata('FullPath'))
|
||||
</_RazorCompileTargetReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
|
|
@ -418,7 +494,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
This target just hooks up other targets since Publish and PrepareForPublish don't have a DependsOnTargets
|
||||
property we can use.
|
||||
-->
|
||||
<Target
|
||||
<Target
|
||||
Name="_RazorPrepareForPublish"
|
||||
AfterTargets="PrepareForPublish"
|
||||
DependsOnTargets="RazorCompile"
|
||||
|
|
@ -428,7 +504,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<!--
|
||||
This target adds the Razor assembly to the BuiltProjectOutputGroupOutput - which is used as input to the Pack target.
|
||||
-->
|
||||
<Target
|
||||
<Target
|
||||
Name="_RazorAddBuiltProjectOutputGroupOutput"
|
||||
DependsOnTargets="_ResolveRazorTargetPath;ResolveRazorGenerateInputs"
|
||||
Condition="'$(ResolvedRazorCompileToolset)'=='RazorSdk' and '$(RazorCompileOnBuild)'=='true'">
|
||||
|
|
@ -447,7 +523,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<ItemGroup Condition="Exists('@(_RazorDebugSymbolsIntermediatePath)')">
|
||||
<DebugSymbolsProjectOutputGroupOutput Include="%(_RazorDebugSymbolsIntermediatePath.FullPath)" FinalOutputPath="$(RazorTargetDir)$(RazorTargetName).pdb" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
|
|
@ -463,7 +539,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
Called as part of GetCopyToOutputDirectoryItems - this target populates the list of items that get
|
||||
copied to the output directory when building as a project reference.
|
||||
-->
|
||||
<Target
|
||||
<Target
|
||||
Name="_RazorGetCopyToOutputDirectoryItems"
|
||||
DependsOnTargets="ResolveRazorGenerateInputs"
|
||||
Condition="'$(ResolvedRazorCompileToolset)'=='RazorSdk' and '$(RazorCompileOnBuild)'=='true'">
|
||||
|
|
@ -519,8 +595,8 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
Called as part of CopyFilesToOutputDirectory - this target is called when building the project to copy
|
||||
files to the output directory.
|
||||
-->
|
||||
<Target
|
||||
Name="_RazorCopyFilesToOutputDirectory"
|
||||
<Target
|
||||
Name="_RazorCopyFilesToOutputDirectory"
|
||||
DependsOnTargets="_ResolveRazorTargetPath;RazorCompile"
|
||||
AfterTargets="CopyFilesToOutputDirectory"
|
||||
Condition="'$(ResolvedRazorCompileToolset)'=='RazorSdk' and '$(RazorCompileOnBuild)'=='true'">
|
||||
|
|
@ -541,9 +617,9 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
</Copy>
|
||||
|
||||
<Message
|
||||
Importance="High"
|
||||
Text="$(MSBuildProjectName) -> @(_RazorAssembly->'%(FullPath)')"
|
||||
<Message
|
||||
Importance="High"
|
||||
Text="$(MSBuildProjectName) -> @(_RazorAssembly->'%(FullPath)')"
|
||||
Condition="Exists('@(RazorIntermediateAssembly)') and '$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)'!='true'" />
|
||||
|
||||
<!-- Copy the Razor debug information file (.pdb), if any -->
|
||||
|
|
@ -569,7 +645,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<Touch Files="@(CopyUpToDateMarker)" AlwaysCreate="true" Condition="'@(_RazorAssembly)' != ''">
|
||||
<Output TaskParameter="TouchedFiles" ItemName="FileWrites" />
|
||||
</Touch>
|
||||
|
||||
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
|
|
@ -609,7 +685,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
most usages of Razor. There's no setting that excludes just the ref assemblies, so we do it ourselves.
|
||||
-->
|
||||
<ItemGroup>
|
||||
<ResolvedFileToPublish
|
||||
<ResolvedFileToPublish
|
||||
Remove="%(ResolvedFileToPublish.Identity)"
|
||||
Condition="'%(ResolvedFileToPublish.RelativePath)'=='$(RefAssembliesFolderName)\%(Filename)%(Extension)'"/>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ Examples:
|
|||
@class.Modifiers.Add("internal");
|
||||
});
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
|
||||
|
|
|
|||
|
|
@ -194,22 +194,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
var irDocument = codeDocument.GetDocumentIntermediateNode();
|
||||
irDocument.DocumentKind = MvcViewDocumentClassifierPass.MvcViewDocumentKind;
|
||||
return irDocument;
|
||||
}
|
||||
|
||||
private class ClassNodeVisitor : IntermediateNodeWalker
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
#pragma checksum "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "78993008d95836bec2b9175d4294bf7bd5f5f109"
|
||||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Razor.Template), @"default", @"/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml")]
|
||||
namespace Razor
|
||||
{
|
||||
#line hidden
|
||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"78993008d95836bec2b9175d4294bf7bd5f5f109", @"/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml")]
|
||||
public class Template
|
||||
{
|
||||
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("value", "Hello", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
|
||||
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("text"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
|
||||
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("unbound", new global::Microsoft.AspNetCore.Html.HtmlString("foo"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
|
||||
#line hidden
|
||||
#pragma warning disable 0169
|
||||
private string __tagHelperStringValueBuffer;
|
||||
#pragma warning restore 0169
|
||||
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
|
||||
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
|
||||
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
|
||||
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (__backed__tagHelperScopeManager == null)
|
||||
{
|
||||
__backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
|
||||
}
|
||||
return __backed__tagHelperScopeManager;
|
||||
}
|
||||
}
|
||||
private global::FormTagHelper __FormTagHelper;
|
||||
private global::InputTagHelper __InputTagHelper;
|
||||
#pragma warning disable 1998
|
||||
public async override global::System.Threading.Tasks.Task ExecuteAsync()
|
||||
{
|
||||
BeginContext(31, 28, true);
|
||||
WriteLiteral("<span someattr>Hola</span>\r\n");
|
||||
EndContext();
|
||||
BeginContext(61, 7, false);
|
||||
#line 3 "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml"
|
||||
Write("Hello");
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndContext();
|
||||
BeginContext(69, 2, true);
|
||||
WriteLiteral("\r\n");
|
||||
EndContext();
|
||||
BeginContext(71, 87, false);
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("form", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
|
||||
BeginContext(91, 6, true);
|
||||
WriteLiteral("\r\n ");
|
||||
EndContext();
|
||||
BeginContext(97, 52, false);
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
|
||||
}
|
||||
);
|
||||
__InputTagHelper = CreateTagHelper<global::InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper.FooProp = (string)__tagHelperAttribute_0.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
|
||||
#line 5 "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml"
|
||||
__InputTagHelper.BarProp = DateTime.Now;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("date", __InputTagHelper.BarProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
|
||||
__tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
|
||||
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
|
||||
if (!__tagHelperExecutionContext.Output.IsContentModified)
|
||||
{
|
||||
await __tagHelperExecutionContext.SetOutputContentAsync();
|
||||
}
|
||||
Write(__tagHelperExecutionContext.Output);
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
EndContext();
|
||||
BeginContext(149, 2, true);
|
||||
WriteLiteral("\r\n");
|
||||
EndContext();
|
||||
}
|
||||
);
|
||||
__FormTagHelper = CreateTagHelper<global::FormTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__FormTagHelper);
|
||||
__tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
|
||||
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
|
||||
if (!__tagHelperExecutionContext.Output.IsContentModified)
|
||||
{
|
||||
await __tagHelperExecutionContext.SetOutputContentAsync();
|
||||
}
|
||||
Write(__tagHelperExecutionContext.Output);
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
EndContext();
|
||||
BeginContext(158, 31, true);
|
||||
WriteLiteral("\r\n\r\n<span>Here is some content ");
|
||||
EndContext();
|
||||
BeginContext(207, 9, true);
|
||||
WriteLiteral("</span>\r\n");
|
||||
EndContext();
|
||||
BeginContext(217, 29, false);
|
||||
#line 9 "TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.cshtml"
|
||||
Write(Foo(item => new Template(async(__razor_template_writer) => {
|
||||
PushWriter(__razor_template_writer);
|
||||
BeginContext(222, 24, true);
|
||||
WriteLiteral("<span>Hello world</span>");
|
||||
EndContext();
|
||||
PopWriter();
|
||||
}
|
||||
)));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndContext();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
@addTagHelper *, TestAssembly
|
||||
<span someattr>Hola</span>
|
||||
@("Hello")
|
||||
<form unbound="foo">
|
||||
<input value=Hello date=@DateTime.Now type='text' />
|
||||
</form>
|
||||
|
||||
<span>Here is some content @*with a comment*@</span>
|
||||
@Foo(@<span>Hello world</span>)
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
Document -
|
||||
RazorCompiledItemAttribute -
|
||||
NamespaceDeclaration - - Razor
|
||||
RazorSourceChecksumAttribute -
|
||||
ClassDeclaration - - public - Template - -
|
||||
PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.DoubleQuotes
|
||||
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes
|
||||
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - unbound - foo - HtmlAttributeValueStyle.DoubleQuotes
|
||||
DefaultTagHelperRuntime -
|
||||
FieldDeclaration - - private - global::FormTagHelper - __FormTagHelper
|
||||
FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
|
||||
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(31, 28, true);
|
||||
HtmlContent - (31:1,0 [28] BasicTest.cshtml)
|
||||
IntermediateToken - (31:1,0 [5] BasicTest.cshtml) - Html - <span
|
||||
IntermediateToken - (36:1,5 [9] BasicTest.cshtml) - Html - someattr
|
||||
IntermediateToken - (45:1,14 [1] BasicTest.cshtml) - Html - >
|
||||
IntermediateToken - (46:1,15 [4] BasicTest.cshtml) - Html - Hola
|
||||
IntermediateToken - (50:1,19 [7] BasicTest.cshtml) - Html - </span>
|
||||
IntermediateToken - (57:1,26 [2] BasicTest.cshtml) - Html - \n
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(61, 7, false);
|
||||
CSharpExpression - (61:2,2 [7] BasicTest.cshtml)
|
||||
IntermediateToken - (61:2,2 [7] BasicTest.cshtml) - CSharp - "Hello"
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(69, 2, true);
|
||||
HtmlContent - (69:2,10 [2] BasicTest.cshtml)
|
||||
IntermediateToken - (69:2,10 [2] BasicTest.cshtml) - Html - \n
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(71, 87, false);
|
||||
TagHelper - (71:3,0 [87] BasicTest.cshtml) - form - TagMode.StartTagAndEndTag
|
||||
DefaultTagHelperBody -
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(91, 6, true);
|
||||
HtmlContent - (91:3,20 [6] BasicTest.cshtml)
|
||||
IntermediateToken - (91:3,20 [6] BasicTest.cshtml) - Html - \n
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(97, 52, false);
|
||||
TagHelper - (97:4,4 [52] BasicTest.cshtml) - input - TagMode.SelfClosing
|
||||
DefaultTagHelperBody -
|
||||
DefaultTagHelperCreate - - InputTagHelper
|
||||
PreallocatedTagHelperProperty - (110:4,17 [5] BasicTest.cshtml) - __tagHelperAttribute_0 - value - FooProp
|
||||
DefaultTagHelperProperty - (121:4,28 [13] BasicTest.cshtml) - date - System.DateTime InputTagHelper.BarProp - HtmlAttributeValueStyle.DoubleQuotes
|
||||
CSharpExpression - (122:4,29 [12] BasicTest.cshtml)
|
||||
IntermediateToken - (122:4,29 [12] BasicTest.cshtml) - CSharp - DateTime.Now
|
||||
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
|
||||
DefaultTagHelperExecute -
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(149, 2, true);
|
||||
HtmlContent - (149:4,56 [2] BasicTest.cshtml)
|
||||
IntermediateToken - (149:4,56 [2] BasicTest.cshtml) - Html - \n
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
DefaultTagHelperCreate - - FormTagHelper
|
||||
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
|
||||
DefaultTagHelperExecute -
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(158, 31, true);
|
||||
HtmlContent - (158:5,7 [31] BasicTest.cshtml)
|
||||
IntermediateToken - (158:5,7 [4] BasicTest.cshtml) - Html - \n\n
|
||||
IntermediateToken - (162:7,0 [6] BasicTest.cshtml) - Html - <span>
|
||||
IntermediateToken - (168:7,6 [21] BasicTest.cshtml) - Html - Here is some content
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(207, 9, true);
|
||||
HtmlContent - (207:7,45 [9] BasicTest.cshtml)
|
||||
IntermediateToken - (207:7,45 [7] BasicTest.cshtml) - Html - </span>
|
||||
IntermediateToken - (214:7,52 [2] BasicTest.cshtml) - Html - \n
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(217, 29, false);
|
||||
CSharpExpression - (217:8,1 [29] BasicTest.cshtml)
|
||||
IntermediateToken - (217:8,1 [4] BasicTest.cshtml) - CSharp - Foo(
|
||||
Template - (222:8,6 [24] BasicTest.cshtml)
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - BeginContext(222, 24, true);
|
||||
HtmlContent - (222:8,6 [24] BasicTest.cshtml)
|
||||
IntermediateToken - (222:8,6 [6] BasicTest.cshtml) - Html - <span>
|
||||
IntermediateToken - (228:8,12 [11] BasicTest.cshtml) - Html - Hello world
|
||||
IntermediateToken - (239:8,23 [7] BasicTest.cshtml) - Html - </span>
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
IntermediateToken - (246:8,30 [1] BasicTest.cshtml) - CSharp - )
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - EndContext();
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
// 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.Intermediate;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Components
|
||||
{
|
||||
public class ComponentDocumentClassifierPassTest
|
||||
{
|
||||
[Fact]
|
||||
public void Execute_SetsDocumentKind()
|
||||
{
|
||||
// Arrange
|
||||
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.razor"));
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var irDocument = CreateIRDocument(projectEngine, codeDocument);
|
||||
var pass = new ComponentDocumentClassifierPass
|
||||
{
|
||||
Engine = projectEngine.Engine
|
||||
};
|
||||
|
||||
// Act
|
||||
pass.Execute(codeDocument, irDocument);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(ComponentDocumentClassifierPass.ComponentDocumentKind, irDocument.DocumentKind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComponentDocumentClassifierPass_SetsNamespace()
|
||||
{
|
||||
// Arrange
|
||||
var properties = new RazorSourceDocumentProperties(filePath: "/MyApp/Test.razor", relativePath: "Test.razor");
|
||||
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var irDocument = CreateIRDocument(projectEngine, codeDocument);
|
||||
var pass = new ComponentDocumentClassifierPass
|
||||
{
|
||||
Engine = projectEngine.Engine
|
||||
};
|
||||
|
||||
// Act
|
||||
pass.Execute(codeDocument, irDocument);
|
||||
var visitor = new Visitor();
|
||||
visitor.Visit(irDocument);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("MyApp", visitor.Namespace.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComponentDocumentClassifierPass_SetsClass()
|
||||
{
|
||||
// Arrange
|
||||
var properties = new RazorSourceDocumentProperties(filePath: "/MyApp/Test.razor", relativePath: "Test.razor");
|
||||
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var irDocument = CreateIRDocument(projectEngine, codeDocument);
|
||||
var pass = new ComponentDocumentClassifierPass
|
||||
{
|
||||
Engine = projectEngine.Engine
|
||||
};
|
||||
|
||||
// Act
|
||||
pass.Execute(codeDocument, irDocument);
|
||||
var visitor = new Visitor();
|
||||
visitor.Visit(irDocument);
|
||||
|
||||
// Assert
|
||||
Assert.Equal($"global::{CodeGenerationConstants.RazorComponent.FullTypeName}", visitor.Class.BaseType);
|
||||
Assert.Equal(new[] { "public", "sealed" }, visitor.Class.Modifiers);
|
||||
Assert.Equal("Test", visitor.Class.ClassName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComponentDocumentClassifierPass_UsesRelativePathToGenerateTypeNameAndNamespace()
|
||||
{
|
||||
// Arrange
|
||||
var relativePath = "/Pages/Announcements/Banner.razor";
|
||||
var properties = new RazorSourceDocumentProperties(filePath: $"/MyApp{relativePath}", relativePath: relativePath);
|
||||
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var irDocument = CreateIRDocument(projectEngine, codeDocument);
|
||||
var pass = new ComponentDocumentClassifierPass
|
||||
{
|
||||
Engine = projectEngine.Engine
|
||||
};
|
||||
|
||||
// Act
|
||||
pass.Execute(codeDocument, irDocument);
|
||||
var visitor = new Visitor();
|
||||
visitor.Visit(irDocument);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Banner", visitor.Class.ClassName);
|
||||
Assert.Equal("MyApp.Pages.Announcements", visitor.Namespace.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComponentDocumentClassifierPass_SanitizesClassName()
|
||||
{
|
||||
// Arrange
|
||||
var properties = new RazorSourceDocumentProperties(filePath: @"x:\path.with+invalid-chars.razor", relativePath: "path.with+invalid-chars.razor");
|
||||
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var irDocument = CreateIRDocument(projectEngine, codeDocument);
|
||||
var pass = new ComponentDocumentClassifierPass
|
||||
{
|
||||
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 ComponentDocumentClassifierPass_SetsUpMainMethod()
|
||||
{
|
||||
// Arrange
|
||||
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.razor"));
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
|
||||
var projectEngine = CreateProjectEngine();
|
||||
var irDocument = CreateIRDocument(projectEngine, codeDocument);
|
||||
var pass = new ComponentDocumentClassifierPass
|
||||
{
|
||||
Engine = projectEngine.Engine
|
||||
};
|
||||
|
||||
// Act
|
||||
pass.Execute(codeDocument, irDocument);
|
||||
var visitor = new Visitor();
|
||||
visitor.Visit(irDocument);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CodeGenerationConstants.RazorComponent.BuildRenderTree, visitor.Method.MethodName);
|
||||
Assert.Equal("void", visitor.Method.ReturnType);
|
||||
Assert.Equal(new[] { "public", "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);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestComponentDocumentClassifierPass : ComponentDocumentClassifierPass
|
||||
{
|
||||
public new bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
=> base.IsMatch(codeDocument, documentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -465,7 +465,6 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
{
|
||||
builder?.Invoke(b);
|
||||
|
||||
FunctionsDirective.Register(b);
|
||||
SectionDirective.Register(b);
|
||||
b.AddTagHelpers(tagHelpers);
|
||||
|
||||
|
|
|
|||
|
|
@ -76,10 +76,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
|
||||
private static RazorProjectEngine CreateProjectEngine()
|
||||
{
|
||||
return RazorProjectEngine.Create(b =>
|
||||
{
|
||||
FunctionsDirective.Register(b);
|
||||
});
|
||||
return RazorProjectEngine.Create();
|
||||
}
|
||||
|
||||
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorProjectEngine projectEngine)
|
||||
|
|
|
|||
|
|
@ -884,7 +884,6 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
// Some of these tests use templates
|
||||
builder.AddTargetExtension(new TemplateTargetExtension());
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
|
@ -909,8 +908,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
|
||||
// Some of these tests use templates
|
||||
builder.AddTargetExtension(new TemplateTargetExtension());
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
|
@ -935,7 +933,6 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
// Some of these tests use templates
|
||||
builder.AddTargetExtension(new TemplateTargetExtension());
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
|
@ -961,7 +958,6 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
// Some of these tests use templates
|
||||
builder.AddTargetExtension(new TemplateTargetExtension());
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// 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.Components;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
||||
{
|
||||
public class ComponentIntegrationTest : IntegrationTestBase
|
||||
{
|
||||
public ComponentIntegrationTest()
|
||||
: base(generateBaselines: null)
|
||||
{
|
||||
Configuration = RazorConfiguration.Default;
|
||||
FileExtension = ".razor";
|
||||
}
|
||||
|
||||
protected override RazorConfiguration Configuration { get; }
|
||||
|
||||
[Fact]
|
||||
public void BasicTest()
|
||||
{
|
||||
var projectEngine = CreateProjectEngine(engine =>
|
||||
{
|
||||
engine.Features.Add(new InputDocumentKindClassifierPass());
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = projectEngine.Process(projectItem);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
|
||||
AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument());
|
||||
}
|
||||
|
||||
private class InputDocumentKindClassifierPass : RazorEngineFeatureBase, IRazorDocumentClassifierPass
|
||||
{
|
||||
// Run before other document classifiers
|
||||
public int Order => -1000;
|
||||
|
||||
public void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
{
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// 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.Components;
|
||||
using Microsoft.AspNetCore.Razor.Language.IntegrationTests;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
public class SuppressPrimaryMethodBodyIntegrationTest : IntegrationTestBase
|
||||
{
|
||||
public SuppressPrimaryMethodBodyIntegrationTest()
|
||||
: base(generateBaselines: null)
|
||||
{
|
||||
Configuration = RazorConfiguration.Default;
|
||||
FileExtension = ".razor";
|
||||
}
|
||||
|
||||
protected override RazorConfiguration Configuration { get; }
|
||||
|
||||
[Fact]
|
||||
public void BasicTest()
|
||||
{
|
||||
var engine = CreateProjectEngine(e =>
|
||||
{
|
||||
e.Features.Add(new SetSuppressPrimaryMethodBodyFeature());
|
||||
e.Features.Add(new InputDocumentKindClassifierPass());
|
||||
});
|
||||
|
||||
var projectItem = CreateProjectItemFromFile();
|
||||
|
||||
// Act
|
||||
var codeDocument = engine.Process(projectItem);
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
|
||||
|
||||
var csharpDocument = codeDocument.GetCSharpDocument();
|
||||
AssertCSharpDocumentMatchesBaseline(csharpDocument);
|
||||
Assert.Empty(csharpDocument.Diagnostics);
|
||||
}
|
||||
|
||||
private class SetSuppressPrimaryMethodBodyFeature : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature
|
||||
{
|
||||
public int Order { get; set; }
|
||||
|
||||
public void Configure(RazorCodeGenerationOptionsBuilder options)
|
||||
{
|
||||
options.SuppressPrimaryMethodBody = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class InputDocumentKindClassifierPass : RazorEngineFeatureBase, IRazorDocumentClassifierPass
|
||||
{
|
||||
// Run before other document classifiers
|
||||
public int Order => -1000;
|
||||
|
||||
public void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||
{
|
||||
codeDocument.SetInputDocumentKind(InputDocumentKind.Component);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
// 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.AspNetCore.Razor.Language.Components;
|
||||
using Microsoft.AspNetCore.Razor.Language.Extensions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -45,6 +45,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test
|
|||
var features = engine.EngineFeatures.OrderBy(f => f.GetType().Name).ToArray();
|
||||
Assert.Collection(
|
||||
features,
|
||||
feature => Assert.IsType<ComponentDocumentClassifierPass>(feature),
|
||||
feature => Assert.IsType<DefaultDirectiveSyntaxTreePass>(feature),
|
||||
feature => Assert.IsType<DefaultDocumentClassifierPass>(feature),
|
||||
feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
|
||||
|
|
@ -56,6 +57,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Test
|
|||
feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
|
||||
feature => Assert.IsType<DesignTimeDirectivePass>(feature),
|
||||
feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
|
||||
feature => Assert.IsType<EliminateMethodBodyPass>(feature),
|
||||
feature => Assert.IsType<FunctionsDirectivePass>(feature),
|
||||
feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
|
||||
feature => Assert.IsType<MetadataAttributePass>(feature),
|
||||
feature => Assert.IsType<PreallocatedTagHelperAttributeOptimizationPass>(feature));
|
||||
|
|
@ -65,7 +68,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Test
|
|||
{
|
||||
var feature = engine.EngineFeatures.OfType<IRazorDirectiveFeature>().FirstOrDefault();
|
||||
Assert.NotNull(feature);
|
||||
Assert.Empty(feature.Directives);
|
||||
Assert.Collection(
|
||||
feature.Directives,
|
||||
directive => Assert.Same(FunctionsDirective.Directive, directive));
|
||||
}
|
||||
|
||||
private static void AssertDefaultTargetExtensions(RazorProjectEngine engine)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
#pragma checksum "TestFiles/IntegrationTests/ComponentIntegrationTest/BasicTest.razor" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "47f616cdc7ec75674c74246619b0e6118ef227e4"
|
||||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.BasicTest), @"component.1.0", @"/TestFiles/IntegrationTests/ComponentIntegrationTest/BasicTest.razor")]
|
||||
namespace AspNetCore
|
||||
{
|
||||
#line hidden
|
||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"47f616cdc7ec75674c74246619b0e6118ef227e4", @"/TestFiles/IntegrationTests/ComponentIntegrationTest/BasicTest.razor")]
|
||||
public sealed class BasicTest : global::Microsoft.AspNetCore.Components.Component
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
public override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)
|
||||
{
|
||||
base.BuildRenderTree(builder);
|
||||
WriteLiteral("Hello world\r\n<span class=\"content\"></span>\r\n\r\n");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
#line 4 "TestFiles/IntegrationTests/ComponentIntegrationTest/BasicTest.razor"
|
||||
|
||||
string SomeProperty { get; set; }
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
Document -
|
||||
RazorCompiledItemAttribute -
|
||||
NamespaceDeclaration - - AspNetCore
|
||||
RazorSourceChecksumAttribute -
|
||||
ClassDeclaration - - public sealed - BasicTest - global::Microsoft.AspNetCore.Components.Component -
|
||||
MethodDeclaration - - public override - void - BuildRenderTree
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - base.BuildRenderTree(builder);
|
||||
HtmlContent - (0:0,0 [46] BasicTest.razor)
|
||||
IntermediateToken - (0:0,0 [13] BasicTest.razor) - Html - Hello world\n
|
||||
IntermediateToken - (13:1,0 [5] BasicTest.razor) - Html - <span
|
||||
IntermediateToken - (18:1,5 [16] BasicTest.razor) - Html - class="content"
|
||||
IntermediateToken - (34:1,21 [1] BasicTest.razor) - Html - >
|
||||
IntermediateToken - (35:1,22 [7] BasicTest.razor) - Html - </span>
|
||||
IntermediateToken - (42:1,29 [4] BasicTest.razor) - Html - \n\n
|
||||
CSharpCode - (58:3,12 [41] BasicTest.razor)
|
||||
IntermediateToken - (58:3,12 [41] BasicTest.razor) - CSharp - \n string SomeProperty { get; set; }\n
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Hello world
|
||||
<span class="content"></span>
|
||||
|
||||
@functions {
|
||||
string SomeProperty { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#pragma checksum "TestFiles/IntegrationTests/SuppressPrimaryMethodBodyIntegrationTest/BasicTest.razor" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "47f616cdc7ec75674c74246619b0e6118ef227e4"
|
||||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCore.BasicTest), @"component.1.0", @"/TestFiles/IntegrationTests/SuppressPrimaryMethodBodyIntegrationTest/BasicTest.razor")]
|
||||
#pragma warning disable 0414
|
||||
#pragma warning disable 0649
|
||||
#pragma warning disable 0169
|
||||
|
||||
namespace AspNetCore
|
||||
{
|
||||
#line hidden
|
||||
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"47f616cdc7ec75674c74246619b0e6118ef227e4", @"/TestFiles/IntegrationTests/SuppressPrimaryMethodBodyIntegrationTest/BasicTest.razor")]
|
||||
public sealed class BasicTest : global::Microsoft.AspNetCore.Components.Component
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
public override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)
|
||||
{
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
#line 4 "TestFiles/IntegrationTests/SuppressPrimaryMethodBodyIntegrationTest/BasicTest.razor"
|
||||
|
||||
string SomeProperty { get; set; }
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
Document -
|
||||
RazorCompiledItemAttribute -
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - #pragma warning disable 0414\n
|
||||
IntermediateToken - - CSharp - #pragma warning disable 0649\n
|
||||
IntermediateToken - - CSharp - #pragma warning disable 0169\n
|
||||
NamespaceDeclaration - - AspNetCore
|
||||
RazorSourceChecksumAttribute -
|
||||
ClassDeclaration - - public sealed - BasicTest - global::Microsoft.AspNetCore.Components.Component -
|
||||
MethodDeclaration - - public override - void - BuildRenderTree
|
||||
CSharpCode - (58:3,12 [41] BasicTest.razor)
|
||||
IntermediateToken - (58:3,12 [41] BasicTest.razor) - CSharp - \n string SomeProperty { get; set; }\n
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Hello world
|
||||
<span class="content"></span>
|
||||
|
||||
@functions {
|
||||
string SomeProperty { get; set; }
|
||||
}
|
||||
|
|
@ -132,6 +132,8 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
#endif
|
||||
}
|
||||
|
||||
public string FileExtension { get; set; } = ".cshtml";
|
||||
|
||||
protected virtual void ConfigureProjectEngine(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
}
|
||||
|
|
@ -193,7 +195,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
|
||||
var suffixIndex = FileName.LastIndexOf("_");
|
||||
var normalizedFileName = suffixIndex == -1 ? FileName : FileName.Substring(0, suffixIndex);
|
||||
var sourceFileName = Path.ChangeExtension(normalizedFileName, ".cshtml");
|
||||
var sourceFileName = Path.ChangeExtension(normalizedFileName, FileExtension);
|
||||
var testFile = TestFile.Create(sourceFileName, GetType().GetTypeInfo().Assembly);
|
||||
if (!testFile.Exists())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Test.MvcShim\Microsoft.AspNetCore.Mvc*\**\*.cs" />
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Test.MvcShim\Microsoft.*\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// 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.Components.RenderTree;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components
|
||||
{
|
||||
public abstract class Component : IComponent
|
||||
{
|
||||
public virtual void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
}
|
||||
|
||||
protected void WriteLiteral(string literal) { }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// 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.Components
|
||||
{
|
||||
public interface IComponent
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// 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.Components.RenderTree
|
||||
{
|
||||
public abstract class RenderTreeBuilder
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);TestFiles\**</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -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.Razor.Tools
|
||||
{
|
||||
internal static class MvcShim
|
||||
{
|
||||
public static readonly string AssemblyName = "Microsoft.AspNetCore.Razor.Test.MvcShim";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,9 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
|
@ -373,6 +376,28 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
}
|
||||
}
|
||||
|
||||
public static void AssemblyContainsType(MSBuildResult result, string assemblyPath, string fullTypeName)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(result));
|
||||
}
|
||||
|
||||
assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath));
|
||||
using (var file = File.OpenRead(assemblyPath))
|
||||
{
|
||||
var peReader = new PEReader(file);
|
||||
var metadataReader = peReader.GetMetadataReader();
|
||||
var typeNames = metadataReader.TypeDefinitions.Where(t => !t.IsNil).Select(t =>
|
||||
{
|
||||
var type = metadataReader.GetTypeDefinition(t);
|
||||
return metadataReader.GetString(type.Namespace) + "." + metadataReader.GetString(type.Name);
|
||||
});
|
||||
|
||||
Assert.Contains(fullTypeName, typeNames);
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class MSBuildXunitException : Xunit.Sdk.XunitException
|
||||
{
|
||||
protected MSBuildXunitException(MSBuildResult result)
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
var result = await DotnetMSBuild("Build");
|
||||
var file = Path.Combine(Project.DirectoryPath, "SimpleTagHelper.cs");
|
||||
var tagHelperOutputCache = Path.Combine(IntermediateOutputPath, "SimpleMvc.TagHelpers.output.cache");
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.g.cshtml.cs");
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
Assert.BuildPassed(result);
|
||||
|
|
@ -133,6 +133,152 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("MvcWithComponents")]
|
||||
public async Task BuildComponents_ErrorInGeneratedCode_ReportsMSBuildError_OnIncrementalBuild()
|
||||
{
|
||||
// Introducing a Razor semantic error
|
||||
ReplaceContent("@{ // Unterminated code block", "Views", "Shared", "NavMenu.razor");
|
||||
|
||||
// Regular build
|
||||
await VerifyError();
|
||||
|
||||
// Incremental build
|
||||
await VerifyError();
|
||||
|
||||
async Task VerifyError()
|
||||
{
|
||||
var result = await DotnetMSBuild("Build");
|
||||
|
||||
Assert.BuildFailed(result);
|
||||
|
||||
// This needs to be relative path. Tracked by https://github.com/aspnet/Razor/issues/2187.
|
||||
var filePath = Path.Combine(Project.DirectoryPath, "Views", "Shared", "NavMenu.razor");
|
||||
var location = filePath + "(1,2)";
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
// Absolute paths on OSX don't work well.
|
||||
location = null;
|
||||
}
|
||||
|
||||
Assert.BuildError(result, "RZ1006", location: location);
|
||||
|
||||
// Compilation failed without creating the views assembly
|
||||
Assert.FileDoesNotExist(result, IntermediateOutputPath, "MvcWithComponents.dll");
|
||||
Assert.FileDoesNotExist(result, IntermediateOutputPath, "MvcWithComponents.Views.dll");
|
||||
|
||||
// File with error does not get written to disk.
|
||||
Assert.FileDoesNotExist(result, IntermediateOutputPath, "RazorComponents", "Views", "Shared", "NavMenu.razor.g.cs");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("MvcWithComponents")]
|
||||
public async Task BuildComponents_RegeneratesComponentDefinition_WhenFilesChange()
|
||||
{
|
||||
// Act - 1
|
||||
var tagHelperOutputCache = Path.Combine(IntermediateOutputPath, "MvcWithComponents.TagHelpers.output.cache");
|
||||
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
|
||||
var generatedDefinitionFile = Path.Combine(RazorComponentIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
var result = await DotnetMSBuild("Build");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
var outputFile = Path.Combine(OutputPath, "MvcWithComponents.dll");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
|
||||
var outputAssemblyThumbprint = GetThumbPrint(outputFile);
|
||||
|
||||
Assert.FileExists(result, generatedDefinitionFile);
|
||||
var generatedDefinitionThumbprint = GetThumbPrint(generatedDefinitionFile);
|
||||
Assert.FileExists(result, generatedFile);
|
||||
var generatedFileThumbprint = GetThumbPrint(generatedFile);
|
||||
|
||||
Assert.FileExists(result, tagHelperOutputCache);
|
||||
Assert.FileContains(
|
||||
result,
|
||||
tagHelperOutputCache,
|
||||
@"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
|
||||
|
||||
var definitionThumbprint = GetThumbPrint(tagHelperOutputCache);
|
||||
|
||||
// Act - 2
|
||||
ReplaceContent("Different things", "Views", "Shared", "NavMenu.razor");
|
||||
result = await DotnetMSBuild("Build");
|
||||
|
||||
// Assert - 2
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
|
||||
Assert.NotEqual(outputAssemblyThumbprint, GetThumbPrint(outputFile));
|
||||
|
||||
Assert.FileExists(result, generatedDefinitionFile);
|
||||
Assert.NotEqual(generatedDefinitionThumbprint, GetThumbPrint(generatedDefinitionFile));
|
||||
Assert.FileExists(result, generatedFile);
|
||||
Assert.NotEqual(generatedFileThumbprint, GetThumbPrint(generatedFile));
|
||||
|
||||
Assert.FileExists(result, tagHelperOutputCache);
|
||||
Assert.FileContains(
|
||||
result,
|
||||
tagHelperOutputCache,
|
||||
@"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
|
||||
|
||||
// TODO:
|
||||
Assert.Equal(definitionThumbprint, GetThumbPrint(tagHelperOutputCache));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("MvcWithComponents")]
|
||||
public async Task BuildComponents_DoesNotModifyFiles_IfFilesDoNotChange()
|
||||
{
|
||||
// Act - 1
|
||||
var tagHelperOutputCache = Path.Combine(IntermediateOutputPath, "MvcWithComponents.TagHelpers.output.cache");
|
||||
|
||||
var file = Path.Combine(Project.DirectoryPath, "Views", "Shared", "NavMenu.razor.g.cs");
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
|
||||
var generatedDefinitionFile = Path.Combine(RazorComponentIntermediateOutputPath, "Views", "Shared", "NavMenu.razor.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
var result = await DotnetMSBuild("Build");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
var outputFile = Path.Combine(OutputPath, "MvcWithComponents.dll");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
|
||||
var outputAssemblyThumbprint = GetThumbPrint(outputFile);
|
||||
|
||||
Assert.FileExists(result, generatedDefinitionFile);
|
||||
var generatedDefinitionThumbprint = GetThumbPrint(generatedDefinitionFile);
|
||||
Assert.FileExists(result, generatedFile);
|
||||
var generatedFileThumbprint = GetThumbPrint(generatedFile);
|
||||
|
||||
Assert.FileExists(result, tagHelperOutputCache);
|
||||
Assert.FileContains(
|
||||
result,
|
||||
tagHelperOutputCache,
|
||||
@"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
|
||||
|
||||
var definitionThumbprint = GetThumbPrint(tagHelperOutputCache);
|
||||
|
||||
// Act - 2
|
||||
result = await DotnetMSBuild("Build");
|
||||
|
||||
// Assert - 2
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
|
||||
Assert.Equal(outputAssemblyThumbprint, GetThumbPrint(outputFile));
|
||||
|
||||
Assert.FileExists(result, generatedDefinitionFile);
|
||||
Assert.Equal(generatedDefinitionThumbprint, GetThumbPrint(generatedDefinitionFile));
|
||||
Assert.FileExists(result, generatedFile);
|
||||
Assert.Equal(generatedFileThumbprint, GetThumbPrint(generatedFile));
|
||||
|
||||
Assert.FileExists(result, tagHelperOutputCache);
|
||||
Assert.FileContains(
|
||||
result,
|
||||
tagHelperOutputCache,
|
||||
@"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
|
||||
|
||||
Assert.Equal(definitionThumbprint, GetThumbPrint(tagHelperOutputCache));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("AppWithP2PReference", additionalProjects: "ClassLibrary")]
|
||||
public async Task IncrementalBuild_WithP2P_WorksWhenBuildProjectReferencesIsDisabled()
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
var result = await DotnetMSBuild("Build", "/t:_IntrospectRazorCompileItems");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
Assert.BuildOutputContainsLine(result, $"RazorCompile: {Path.Combine(IntermediateOutputPath, "Razor", "Views", "Home", "Index.g.cshtml.cs")}");
|
||||
Assert.BuildOutputContainsLine(result, $"RazorCompile: {Path.Combine(IntermediateOutputPath, "Razor", "Views", "Home", "Index.cshtml.g.cs")}");
|
||||
Assert.BuildOutputContainsLine(result, $"RazorCompile: {Path.Combine(IntermediateOutputPath, "SimpleMvc.RazorTargetAssemblyInfo.cs")}");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
// 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 System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||
{
|
||||
public class BuildPerformanceTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
|
||||
{
|
||||
public BuildPerformanceTest(BuildServerTestFixture buildServer)
|
||||
: base(buildServer)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("SimpleMvc")]
|
||||
public async Task BuildMvcApp()
|
||||
{
|
||||
var result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
var summary = ParseTaskPerformanceSummary(result.Output);
|
||||
|
||||
Assert.Equal(1, summary.First(f => f.Name == "RazorGenerate").Calls);
|
||||
Assert.Equal(1, summary.First(f => f.Name == "RazorTagHelper").Calls);
|
||||
|
||||
// Incremental builds
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
summary = ParseTaskPerformanceSummary(result.Output);
|
||||
|
||||
Assert.DoesNotContain(summary, item => item.Name == "RazorGenerate");
|
||||
Assert.DoesNotContain(summary, item => item.Name == "RazorTagHelper");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("MvcWithComponents")]
|
||||
public async Task BuildMvcAppWithComponents()
|
||||
{
|
||||
var result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
var summary = ParseTaskPerformanceSummary(result.Output);
|
||||
|
||||
// One for declaration build, one for the "real" code gen
|
||||
Assert.Equal(2, summary.First(f => f.Name == "RazorGenerate").Calls);
|
||||
Assert.Equal(1, summary.First(f => f.Name == "RazorTagHelper").Calls);
|
||||
|
||||
// Incremental builds
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
result = await DotnetMSBuild(target: default, args: "/clp:PerformanceSummary");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
summary = ParseTaskPerformanceSummary(result.Output);
|
||||
|
||||
Assert.DoesNotContain(summary, item => item.Name == "RazorGenerate");
|
||||
Assert.DoesNotContain(summary, item => item.Name == "RazorTagHelper");
|
||||
}
|
||||
}
|
||||
|
||||
private List<PerformanceSummaryEntry> ParseTaskPerformanceSummary(string output)
|
||||
{
|
||||
const string Header = "Task Performance Summary:";
|
||||
var lines = output.Split(Environment.NewLine);
|
||||
var taskSection = Array.LastIndexOf(lines, Header);
|
||||
Assert.True(taskSection != -1, $"Could not find line ${Header} in {output}");
|
||||
|
||||
var entries = new List<PerformanceSummaryEntry>();
|
||||
// 6 ms FindAppConfigFile 4 calls
|
||||
var matcher = new Regex(@"\s+(?<time>\w+) ms\s+(?<name>\w+)\s+(?<calls>\d+) calls");
|
||||
for (var i = taskSection + 1; i < lines.Length; i++)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(lines[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var match = matcher.Match(lines[i]);
|
||||
Assert.True(match.Success, $"Line {lines[i]} did not match.");
|
||||
|
||||
var entry = new PerformanceSummaryEntry
|
||||
{
|
||||
Name = match.Groups["name"].Value,
|
||||
Calls = int.Parse(match.Groups["calls"].Value),
|
||||
};
|
||||
entries.Add(entry);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
private class PerformanceSummaryEntry
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Calls { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,14 +3,10 @@
|
|||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Tools;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||
|
|
@ -92,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
|
||||
Assert.FileExists(result, IntermediateOutputPath, "Whitespace in name.Views.dll");
|
||||
Assert.FileExists(result, IntermediateOutputPath, "Whitespace in name.RazorCoreGenerate.cache");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Index.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -230,6 +226,35 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("MvcWithComponents")]
|
||||
public async Task Build_MvcWithComponents()
|
||||
{
|
||||
var tagHelperOutputCacheFile = Path.Combine(IntermediateOutputPath, "MvcWithComponents.TagHelpers.output.cache");
|
||||
|
||||
var result = await DotnetMSBuild(
|
||||
"Build",
|
||||
"/p:_RazorForceBuildServer=true");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.pdb");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.Views.dll");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.Views.pdb");
|
||||
|
||||
// Verify tag helper discovery from components work
|
||||
Assert.FileExists(result, tagHelperOutputCacheFile);
|
||||
Assert.FileContains(
|
||||
result,
|
||||
tagHelperOutputCacheFile,
|
||||
@"""Name"":""MvcWithComponents.TestComponent""");
|
||||
|
||||
Assert.FileContains(
|
||||
result,
|
||||
tagHelperOutputCacheFile,
|
||||
@"""Name"":""MvcWithComponents.Views.Shared.NavMenu""");
|
||||
}
|
||||
|
||||
private class TestProjectDirectory : ProjectDirectory
|
||||
{
|
||||
public TestProjectDirectory(string solutionPath, string directoryPath, string projectFilePath)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
// 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.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||
{
|
||||
public class BuildWithComponentsIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
|
||||
{
|
||||
public BuildWithComponentsIntegrationTest(BuildServerTestFixture buildServer)
|
||||
: base(buildServer)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitializeTestProject("MvcWithComponents")]
|
||||
public Task Build_Components_WithDotNetCoreMSBuild_Works() => Build_ComponentsWorks(MSBuildProcessKind.Dotnet);
|
||||
|
||||
[ConditionalFact]
|
||||
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
||||
[InitializeTestProject("MvcWithComponents")]
|
||||
public Task Build_Components_WithDesktopMSBuild_Works() => Build_ComponentsWorks(MSBuildProcessKind.Desktop);
|
||||
|
||||
private async Task Build_ComponentsWorks(MSBuildProcessKind msBuildProcessKind)
|
||||
{
|
||||
var result = await DotnetMSBuild("Build", msBuildProcessKind: msBuildProcessKind);
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.dll");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.pdb");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.Views.dll");
|
||||
Assert.FileExists(result, OutputPath, "MvcWithComponents.Views.pdb");
|
||||
|
||||
Assert.AssemblyContainsType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "MvcWithComponents.TestComponent");
|
||||
Assert.AssemblyContainsType(result, Path.Combine(OutputPath, "MvcWithComponents.dll"), "MvcWithComponents.Views.Shared.NavMenu");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
{
|
||||
Assert.BuildOutputContainsLine(
|
||||
result,
|
||||
$@"RazorGenerateWithTargetPath: {filePath} {filePath} {Path.Combine(RazorIntermediateOutputPath, Path.ChangeExtension(filePath, ".g.cshtml.cs"))}");
|
||||
$@"RazorGenerateWithTargetPath: {filePath} {filePath} {Path.Combine(RazorIntermediateOutputPath, filePath + ".g.cs")}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
|
||||
protected string RazorIntermediateOutputPath => Path.Combine(IntermediateOutputPath, "Razor");
|
||||
|
||||
protected string RazorComponentIntermediateOutputPath => Path.Combine(IntermediateOutputPath, "RazorDeclaration");
|
||||
|
||||
internal static string TargetFramework
|
||||
{
|
||||
get => _projectTfm.Value;
|
||||
|
|
|
|||
|
|
@ -38,15 +38,15 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
Path.Combine(IntermediateOutputPath, "SimpleMvc.TagHelpers.output.cache"),
|
||||
@"""Name"":""SimpleMvc.SimpleTagHelper""");
|
||||
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewImports.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewStart.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Contact.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Index.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_Layout.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_ValidationScriptsPartial.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "Error.g.cshtml.cs");
|
||||
Assert.FileCountEquals(result, 8, RazorIntermediateOutputPath, "*.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewImports.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewStart.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Contact.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_Layout.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_ValidationScriptsPartial.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "Error.cshtml.g.cs");
|
||||
Assert.FileCountEquals(result, 8, RazorIntermediateOutputPath, "*.cshtml.g.cs");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
Assert.FileDoesNotExist(result, IntermediateOutputPath, "SimpleMvc.Views.dll");
|
||||
|
||||
// If there's a parser error, the generated file contents is likely incorrect. The file should not be written to disk.
|
||||
Assert.FileDoesNotExist(result, RazorIntermediateOutputPath, "Views", "Home", "Index.g.cshtml.cs");
|
||||
Assert.FileDoesNotExist(result, RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -96,7 +96,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
{
|
||||
// Act - 1
|
||||
var result = await DotnetMSBuild(RazorGenerateTarget);
|
||||
var generatedFile = Path.Combine(Project.DirectoryPath, RazorIntermediateOutputPath, "Views", "Home", "About.g.cshtml.cs");
|
||||
var generatedFile = Path.Combine(Project.DirectoryPath, RazorIntermediateOutputPath, "Views", "Home", "About.cshtml.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
Assert.BuildPassed(result);
|
||||
|
|
@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
// Act - 1
|
||||
var result = await DotnetMSBuild(RazorGenerateTarget);
|
||||
var file = Path.Combine(Project.DirectoryPath, "Views", "Home", "Contact.cshtml");
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Contact.g.cshtml.cs");
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Contact.cshtml.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
Assert.BuildPassed(result);
|
||||
|
|
@ -146,7 +146,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
{
|
||||
// Act - 1
|
||||
var result = await DotnetMSBuild(RazorGenerateTarget);
|
||||
var file = Path.Combine(Project.DirectoryPath, RazorIntermediateOutputPath, "Views", "Home", "About.g.cshtml.cs");
|
||||
var file = Path.Combine(Project.DirectoryPath, RazorIntermediateOutputPath, "Views", "Home", "About.cshtml.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
Assert.BuildPassed(result);
|
||||
|
|
@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
var result = await DotnetMSBuild(RazorGenerateTarget);
|
||||
var file = Path.Combine(Project.DirectoryPath, "Views", "Home", "Index.cshtml");
|
||||
var renamed = Path.Combine(Project.DirectoryPath, "Views", "Home", "NewIndex.cshtml");
|
||||
var generated = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.g.cshtml.cs");
|
||||
var generated = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
Assert.BuildPassed(result);
|
||||
|
|
@ -182,7 +182,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
|
||||
// Assert - 2
|
||||
Assert.BuildPassed(result);
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "NewIndex.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "NewIndex.cshtml.g.cs");
|
||||
Assert.FileDoesNotExist(result, generated);
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
// Act - 1
|
||||
var result = await DotnetMSBuild(RazorGenerateTarget);
|
||||
var file = Path.Combine(Project.DirectoryPath, "Views", "Home", "Index.cshtml");
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.g.cshtml.cs");
|
||||
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
|
||||
|
||||
// Assert - 1
|
||||
Assert.BuildPassed(result);
|
||||
|
|
@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
// We shouldn't need to hash the files
|
||||
Assert.FileDoesNotExist(result, Path.Combine(IntermediateOutputPath, "SimpleMvc.RazorCoreGenerate.cache"));
|
||||
|
||||
Assert.FileCountEquals(result, 0, RazorIntermediateOutputPath, "*.g.cshtml.cs");
|
||||
Assert.FileCountEquals(result, 0, RazorIntermediateOutputPath, "*.cshtml.g.cs");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -243,8 +243,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.g.cshtml.cs");
|
||||
Assert.FileCountEquals(result, 1, RazorIntermediateOutputPath, "*.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.cshtml.g.cs");
|
||||
Assert.FileCountEquals(result, 1, RazorIntermediateOutputPath, "*.cshtml.g.cs");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -265,8 +265,8 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.g.cshtml.cs");
|
||||
Assert.FileCountEquals(result, 1, RazorIntermediateOutputPath, "*.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.cshtml.g.cs");
|
||||
Assert.FileCountEquals(result, 1, RazorIntermediateOutputPath, "*.cshtml.g.cs");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -287,13 +287,13 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFile.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFile2.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFileWithRename.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFile.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFile2.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFileWithRename.cshtml.g.cs");
|
||||
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile.cshtml")} LinkedFile.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFile.g.cshtml.cs")}");
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile2.cshtml")} LinkedFileOut\LinkedFile2.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFile2.g.cshtml.cs")}");
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile3.cshtml")} LinkedFileOut\LinkedFileWithRename.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFileWithRename.g.cshtml.cs")}");
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile.cshtml")} LinkedFile.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFile.cshtml.g.cs")}");
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile2.cshtml")} LinkedFileOut\LinkedFile2.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFile2.cshtml.g.cs")}");
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {Path.Combine("..", "LinkedDir", "LinkedFile3.cshtml")} LinkedFileOut\LinkedFileWithRename.cshtml {Path.Combine(RazorIntermediateOutputPath, "LinkedFileOut", "LinkedFileWithRename.cshtml.g.cs")}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -342,17 +342,17 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.dll");
|
||||
Assert.FileDoesNotExist(result, IntermediateOutputPath, "SimpleMvc.Views.dll");
|
||||
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewImports.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewStart.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Contact.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Index.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_Layout.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_ValidationScriptsPartial.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "Error.g.cshtml.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "temp.g.cshtml.cs");
|
||||
Assert.FileCountEquals(result, 9, RazorIntermediateOutputPath, "*.g.cshtml.cs");
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {filePath} temp.cshtml {Path.Combine(RazorIntermediateOutputPath, "temp.g.cshtml.cs")}");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewImports.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "_ViewStart.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Contact.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "Index.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_Layout.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "_ValidationScriptsPartial.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Shared", "Error.cshtml.g.cs");
|
||||
Assert.FileExists(result, RazorIntermediateOutputPath, "temp.cshtml.g.cs");
|
||||
Assert.FileCountEquals(result, 9, RazorIntermediateOutputPath, "*.cshtml.g.cs");
|
||||
Assert.BuildOutputContainsLine(result, $@"RazorGenerateWithTargetPath: {filePath} temp.cshtml {Path.Combine(RazorIntermediateOutputPath, "temp.cshtml.g.cs")}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||
<ProjectReference Include="..\..\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Design\Microsoft.AspNetCore.Razor.Design.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'!=''">
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||
<ProjectReference Include="..\..\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Design\Microsoft.AspNetCore.Razor.Design.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'!=''">
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||
<ProjectReference Include="..\..\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Design\Microsoft.AspNetCore.Razor.Design.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'!=''">
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||
<ProjectReference Include="..\..\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Design\Microsoft.AspNetCore.Razor.Design.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'!=''">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace MvcWithComponents.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<RazorSdkDirectoryRoot>$(RazorSdkProjectDirectory)bin\$(Configuration)\sdk-output\</RazorSdkDirectoryRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(RunningAsTest)' == ''">
|
||||
<!-- We don't want to run build server when not running as tests. -->
|
||||
<UseRazorBuildServer>false</UseRazorBuildServer>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'==''">
|
||||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||
<ProjectReference Include="..\..\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'!=''">
|
||||
<Reference Include="$(BinariesRoot)\Microsoft.AspNetCore.Html.Abstractions.dll"/>
|
||||
<Reference Include="$(BinariesRoot)\Microsoft.AspNetCore.Razor.dll"/>
|
||||
<Reference Include="$(BinariesRoot)\Microsoft.AspNetCore.Razor.Runtime.dll"/>
|
||||
<Reference Include="$(BinariesRoot)\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.dll"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Test Placeholder -->
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
namespace MvcWithComponents
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Just make sure we have a reference to the MvcShim
|
||||
var t = typeof(Microsoft.AspNetCore.Mvc.IActionResult);
|
||||
System.Console.WriteLine(t.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Hello from component
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
Hello world!
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
NavMenu content
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@using MvcWithComponents
|
||||
@using MvcWithComponents.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
|
|
@ -22,7 +22,6 @@
|
|||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||
<ProjectReference Include="..\..\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Design\Microsoft.AspNetCore.Razor.Design.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'!=''">
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||
<ProjectReference Include="..\..\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Runtime\Microsoft.AspNetCore.Razor.Runtime.csproj"/>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Razor.Design\Microsoft.AspNetCore.Razor.Design.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BinariesRoot)'!=''">
|
||||
|
|
|
|||
Loading…
Reference in New Issue