Flow RootNamespace from MSBuild (dotnet/aspnetcore-tooling#331)

- Flow Root namespace through in command line builds

- Flow Root namespace through in design time builds

- Feedback\n\nCommit migrated from 057d4f3570
This commit is contained in:
Ajay Bhargav Baaskaran 2019-03-13 14:18:07 -07:00 committed by GitHub
parent eeabe9ee71
commit 2c39457306
16 changed files with 106 additions and 27 deletions

View File

@ -1,6 +1,6 @@
// <auto-generated/>
#pragma warning disable 1591
namespace __BlazorGenerated
namespace __GeneratedComponent
{
#line hidden
using TModel = global::System.Object;

View File

@ -1,5 +1,5 @@
Document -
NamespaceDeclaration - - __BlazorGenerated
NamespaceDeclaration - - __GeneratedComponent
UsingDirective - - TModel = global::System.Object
UsingDirective - (1:0,1 [12] ) - System
UsingDirective - (16:1,1 [32] ) - System.Collections.Generic

View File

@ -1,23 +1,23 @@
Source Location: (12:0,12 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml)
|IDisposable|
Generated Location: (662:17,0 [11] )
Generated Location: (665:17,0 [11] )
|IDisposable|
Source Location: (38:1,13 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml)
|this.ToString()|
Generated Location: (1258:33,13 [15] )
Generated Location: (1261:33,13 [15] )
|this.ToString()|
Source Location: (79:3,5 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml)
|string.Format("{0}", "Hello")|
Generated Location: (1403:38,6 [29] )
Generated Location: (1406:38,6 [29] )
|string.Format("{0}", "Hello")|
Source Location: (132:6,12 [37] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml)
|
void IDisposable.Dispose(){ }
|
Generated Location: (1617:45,12 [37] )
Generated Location: (1620:45,12 [37] )
|
void IDisposable.Dispose(){ }
|

View File

@ -1,7 +1,7 @@
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicComponent.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d3c3d6059615673cb46fc4974164d61eabadb890"
// <auto-generated/>
#pragma warning disable 1591
namespace __BlazorGenerated
namespace __GeneratedComponent
{
#line hidden
using System;

View File

@ -1,5 +1,5 @@
Document -
NamespaceDeclaration - - __BlazorGenerated
NamespaceDeclaration - - __GeneratedComponent
UsingDirective - (1:0,1 [14] ) - System
UsingDirective - (16:1,1 [34] ) - System.Collections.Generic
UsingDirective - (51:2,1 [19] ) - System.Linq

View File

@ -18,11 +18,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
private static readonly char[] NamespaceSeparators = new char[] { '.' };
/// <summary>
/// The base namespace.
/// The fallback value of the root namespace. Only used if the fallback root namespace
/// was not passed in.
/// </summary>
// This is a fallback value and will only be used if we can't compute
// a reasonable namespace.
public string BaseNamespace { get; set; } = "__BlazorGenerated";
public string FallbackRootNamespace { get; set; } = "__GeneratedComponent";
/// <summary>
/// Gets or sets whether to mangle class names.
@ -58,7 +57,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
ClassDeclarationIntermediateNode @class,
MethodDeclarationIntermediateNode method)
{
var options = codeDocument.GetDocumentIntermediateNode().Options;
if (!TryComputeNamespaceAndClass(
options,
codeDocument.Source.FilePath,
codeDocument.Source.RelativePath,
out var computedNamespace,
@ -66,7 +67,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
// If we can't compute a nice namespace (no relative path) then just generate something
// mangled.
computedNamespace = BaseNamespace;
computedNamespace = FallbackRootNamespace;
var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
computedClass = $"AspNetCore_{checksum}";
}
@ -125,7 +126,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
//
// However all kinds of thing are possible in tools. We shouldn't barf here if the document isn't
// set up correctly.
private bool TryComputeNamespaceAndClass(string filePath, string relativePath, out string @namespace, out string @class)
private bool TryComputeNamespaceAndClass(
RazorCodeGenerationOptions options,
string filePath,
string relativePath,
out string @namespace,
out string @class)
{
if (filePath == null || relativePath == null || filePath.Length <= relativePath.Length)
{
@ -134,14 +140,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
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))
var rootNamespace = options.RootNamespace;
if (string.IsNullOrEmpty(rootNamespace))
{
@namespace = null;
@class = null;
@ -151,7 +151,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
var builder = new StringBuilder();
// Sanitize the base namespace, but leave the dots.
var segments = baseNamespace.Split(NamespaceSeparators, StringSplitOptions.RemoveEmptyEntries);
var segments = rootNamespace.Split(NamespaceSeparators, StringSplitOptions.RemoveEmptyEntries);
builder.Append(CSharpIdentifier.SanitizeIdentifier(segments[0]));
for (var i = 1; i < segments.Length; i++)
{

View File

@ -8,7 +8,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public DefaultRazorCodeGenerationOptions(
bool indentWithTabs,
int indentSize,
bool designTime,
bool designTime,
string rootNamespace,
bool suppressChecksum,
bool supressMetadataAttributes,
bool suppressPrimaryMethodBody)
@ -16,6 +17,7 @@ namespace Microsoft.AspNetCore.Razor.Language
IndentWithTabs = indentWithTabs;
IndentSize = indentSize;
DesignTime = designTime;
RootNamespace = rootNamespace;
SuppressChecksum = suppressChecksum;
SuppressMetadataAttributes = supressMetadataAttributes;
SuppressPrimaryMethodBody = suppressPrimaryMethodBody;
@ -27,6 +29,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public override int IndentSize { get; }
public override string RootNamespace { get; }
public override bool SuppressChecksum { get; }
}
}

View File

@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.Razor.Language
IndentWithTabs,
IndentSize,
DesignTime,
RootNamespace,
SuppressChecksum,
SuppressMetadataAttributes,
SuppressPrimaryMethodBody);

View File

@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Razor.Language
indentSize: 4,
designTime: false,
suppressChecksum: false,
rootNamespace: null,
supressMetadataAttributes: false,
suppressPrimaryMethodBody: false);
}
@ -24,6 +25,7 @@ namespace Microsoft.AspNetCore.Razor.Language
indentWithTabs: false,
indentSize: 4,
designTime: true,
rootNamespace: null,
suppressChecksum: false,
supressMetadataAttributes: true,
suppressPrimaryMethodBody: false);
@ -67,6 +69,11 @@ namespace Microsoft.AspNetCore.Razor.Language
public abstract int IndentSize { get; }
/// <summary>
/// Gets the root namespace for the generated code.
/// </summary>
public virtual string RootNamespace { get; }
/// <summary>
/// Gets a value that indicates whether to suppress the default <c>#pragma checksum</c> directive in the
/// generated C# code. If <c>false</c> the checkum directive will be included, otherwise it will not be

View File

@ -15,6 +15,11 @@ namespace Microsoft.AspNetCore.Razor.Language
public abstract bool IndentWithTabs { get; set; }
/// <summary>
/// Gets or sets the root namespace of the generated code.
/// </summary>
public virtual string RootNamespace { get; set; }
/// <summary>
/// Gets or sets a value that indicates whether to suppress the default <c>#pragma checksum</c> directive in the
/// generated C# code. If <c>false</c> the checkum directive will be included, otherwise it will not be

View File

@ -75,6 +75,23 @@ namespace Microsoft.AspNetCore.Razor.Language
return builder;
}
/// <summary>
/// Sets the root namespace for the generated code.
/// </summary>
/// <param name="builder">The <see cref="RazorProjectEngineBuilder"/>.</param>
/// <param name="rootNamespace">The root namespace.</param>
/// <returns>The <see cref="RazorProjectEngineBuilder"/>.</returns>
public static RazorProjectEngineBuilder SetRootNamespace(this RazorProjectEngineBuilder builder, string rootNamespace)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Features.Add(new ConfigureRootNamespaceFeature(rootNamespace));
return builder;
}
public static void SetImportFeature(this RazorProjectEngineBuilder builder, IImportProjectFeature feature)
{
if (builder == null)
@ -281,5 +298,29 @@ namespace Microsoft.AspNetCore.Razor.Language
public override Stream Read() => new MemoryStream(_importBytes);
}
}
private class ConfigureRootNamespaceFeature : IConfigureRazorCodeGenerationOptionsFeature
{
private readonly string _rootNamespace;
public ConfigureRootNamespaceFeature(string rootNamespace)
{
_rootNamespace = rootNamespace;
}
public int Order { get; set; }
public RazorEngine Engine { get; set; }
public void Configure(RazorCodeGenerationOptionsBuilder options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
options.RootNamespace = _rootNamespace;
}
}
}
}

View File

@ -29,6 +29,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
Configuration = Option("-c", "Razor configuration name", CommandOptionType.SingleValue);
ExtensionNames = Option("-n", "extension name", CommandOptionType.MultipleValue);
ExtensionFilePaths = Option("-e", "extension file path", CommandOptionType.MultipleValue);
RootNamespace = Option("--root-namespace", "root namespace for generated code", CommandOptionType.SingleValue);
GenerateDeclaration = Option("--generate-declaration", "Generate declaration", CommandOptionType.NoValue);
}
@ -52,6 +53,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
public CommandOption ExtensionFilePaths { get; }
public CommandOption RootNamespace { get; }
public CommandOption GenerateDeclaration { get; }
protected override Task<int> ExecuteCoreAsync()
@ -176,6 +179,11 @@ namespace Microsoft.AspNetCore.Razor.Tools
{
b.Features.Add(new SetSuppressPrimaryMethodBodyOptionFeature());
}
if (RootNamespace.HasValue())
{
b.SetRootNamespace(RootNamespace.Value());
}
});
var results = GenerateCode(engine, sourceItems);

View File

@ -24,6 +24,8 @@ namespace Microsoft.AspNetCore.Razor.Tasks
private const string AssemblyName = "AssemblyName";
private const string AssemblyFilePath = "AssemblyFilePath";
public string RootNamespace { get; set; }
[Required]
public string Version { get; set; }
@ -135,6 +137,13 @@ namespace Microsoft.AspNetCore.Razor.Tasks
builder.AppendLine("-c");
builder.AppendLine(Configuration[0].GetMetadata(Identity));
// Added in 3.0
if (parsedVersion.Major >= 3 && !string.IsNullOrEmpty(RootNamespace))
{
builder.AppendLine("--root-namespace");
builder.AppendLine(RootNamespace);
}
// Added in 3.0
if (parsedVersion.Major >= 3 && GenerateDeclaration)
{

View File

@ -155,6 +155,7 @@ Copyright (c) .NET Foundation. All rights reserved.
ForceServer="$(_RazorForceBuildServer)"
PipeName="$(_RazorBuildServerPipeName)"
Version="$(RazorLangVersion)"
RootNamespace="$(RootNamespace)"
Configuration="@(ResolvedRazorConfiguration)"
Extensions="@(ResolvedRazorExtension)"
Sources="@(RazorGenerateWithTargetPath)"

View File

@ -98,6 +98,7 @@ Copyright (c) .NET Foundation. All rights reserved.
ForceServer="$(_RazorForceBuildServer)"
PipeName="$(_RazorBuildServerPipeName)"
Version="$(RazorLangVersion)"
RootNamespace="$(RootNamespace)"
Configuration="@(ResolvedRazorConfiguration)"
Extensions="@(ResolvedRazorExtension)"
Sources="@(_RazorComponentDeclarationSources)"

View File

@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
PathSeparator = Path.DirectorySeparatorChar.ToString();
WorkingDirectory = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ArbitraryWindowsPath : ArbitraryMacLinuxPath;
DefaultBaseNamespace = "Test"; // Matches the default working directory
DefaultRootNamespace = "Test"; // Matches the default working directory
DefaultFileName = "TestComponent.cshtml";
}
@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
internal virtual RazorConfiguration Configuration { get; }
internal virtual string DefaultBaseNamespace { get; }
internal virtual string DefaultRootNamespace { get; }
internal virtual string DefaultFileName { get; }
@ -113,6 +113,8 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
{
return RazorProjectEngine.Create(configuration, FileSystem, b =>
{
b.SetRootNamespace(DefaultRootNamespace);
// Turn off checksums, we're testing code generation.
b.Features.Add(new SuppressChecksum());
@ -320,7 +322,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
{
var assemblyResult = CompileToAssembly(DefaultFileName, cshtmlSource);
var componentFullTypeName = $"{DefaultBaseNamespace}.{Path.GetFileNameWithoutExtension(DefaultFileName)}";
var componentFullTypeName = $"{DefaultRootNamespace}.{Path.GetFileNameWithoutExtension(DefaultFileName)}";
return CompileToComponent(assemblyResult, componentFullTypeName);
}