Use checksum for classname if filepath is null

This commit is contained in:
Ajay Bhargav Baaskaran 2018-06-06 08:45:57 -07:00
parent 74c12b22d6
commit ad07036020
6 changed files with 167 additions and 3 deletions

View File

@ -1,6 +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;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
@ -25,7 +27,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
@namespace.Content = "AspNetCore";
var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
if (string.IsNullOrEmpty(filePath))
{
// It's possible for a Razor document to not have a file path.
// Eg. When we try to generate code for an in memory document like default imports.
var checksum = BytesToString(codeDocument.Source.GetChecksum());
@class.ClassName = $"AspNetCore_{checksum}";
}
else
{
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
}
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
@class.Modifiers.Clear();
@class.Modifiers.Add("public");
@ -37,5 +50,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
method.Modifiers.Add("override");
method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";
}
private static string BytesToString(byte[] bytes)
{
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes));
}
var result = new StringBuilder(bytes.Length);
for (var i = 0; i < bytes.Length; i++)
{
// The x2 format means lowercase hex, where each byte is a 2-character string.
result.Append(bytes[i].ToString("x2"));
}
return result.ToString();
}
}
}

View File

@ -1,6 +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;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
@ -25,7 +27,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
@namespace.Content = "AspNetCore";
var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
if (string.IsNullOrEmpty(filePath))
{
// It's possible for a Razor document to not have a file path.
// Eg. When we try to generate code for an in memory document like default imports.
var checksum = BytesToString(codeDocument.Source.GetChecksum());
@class.ClassName = $"AspNetCore_{checksum}";
}
else
{
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
}
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>";
@class.Modifiers.Clear();
@class.Modifiers.Add("public");
@ -37,5 +50,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
method.Modifiers.Add("override");
method.ReturnType = $"global::{typeof(System.Threading.Tasks.Task).FullName}";
}
private static string BytesToString(byte[] bytes)
{
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes));
}
var result = new StringBuilder(bytes.Length);
for (var i = 0; i < bytes.Length; i++)
{
// The x2 format means lowercase hex, where each byte is a 2-character string.
result.Append(bytes[i].ToString("x2"));
}
return result.ToString();
}
}
}

View File

@ -1,7 +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.
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;
@ -52,7 +54,17 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
@class.BaseType = "global::Microsoft.AspNetCore.Mvc.RazorPages.Page";
var filePath = codeDocument.Source.RelativePath ?? codeDocument.Source.FilePath;
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
if (string.IsNullOrEmpty(filePath))
{
// It's possible for a Razor document to not have a file path.
// Eg. When we try to generate code for an in memory document like default imports.
var checksum = BytesToString(codeDocument.Source.GetChecksum());
@class.ClassName = $"AspNetCore_{checksum}";
}
else
{
@class.ClassName = CSharpIdentifier.GetClassNameFromPath(filePath);
}
@class.Modifiers.Clear();
@class.Modifiers.Add("public");
@ -131,5 +143,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
options.ParseLeadingDirectives = true;
}
}
private static string BytesToString(byte[] bytes)
{
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes));
}
var result = new StringBuilder(bytes.Length);
for (var i = 0; i < bytes.Length; i++)
{
// The x2 format means lowercase hex, where each byte is a 2-character string.
result.Append(bytes[i].ToString("x2"));
}
return result.ToString();
}
}
}

View File

@ -97,6 +97,31 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
Assert.Equal("Test", visitor.Class.ClassName);
}
[Fact]
public void MvcViewDocumentClassifierPass_NullFilePath_SetsClass()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>", visitor.Class.BaseType);
Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
Assert.Equal("AspNetCore_d9f877a857a7e9928eac04d09a59f25967624155", visitor.Class.ClassName);
}
[Theory]
[InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")]
[InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")]

View File

@ -212,6 +212,31 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
Assert.Equal("Test", visitor.Class.ClassName);
}
[Fact]
public void RazorPageDocumentClassifierPass_NullFilePath_SetsClass()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));
var engine = CreateEngine();
var irDocument = CreateIRDocument(engine, codeDocument);
var pass = new RazorPageDocumentClassifierPass
{
Engine = engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType);
Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
Assert.Equal("AspNetCore_74fbaab062bb228ed1ab09c5ff8d6ed2417320e2", visitor.Class.ClassName);
}
[Theory]
[InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")]
[InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")]

View File

@ -97,6 +97,31 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
Assert.Equal("Test", visitor.Class.ClassName);
}
[Fact]
public void MvcViewDocumentClassifierPass_NullFilePath_SetsClass()
{
// Arrange
var properties = new RazorSourceDocumentProperties(filePath: null, relativePath: null);
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));
var projectEngine = CreateProjectEngine();
var irDocument = CreateIRDocument(projectEngine, codeDocument);
var pass = new MvcViewDocumentClassifierPass
{
Engine = projectEngine.Engine
};
// Act
pass.Execute(codeDocument, irDocument);
var visitor = new Visitor();
visitor.Visit(irDocument);
// Assert
Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>", visitor.Class.BaseType);
Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
Assert.Equal("AspNetCore_d9f877a857a7e9928eac04d09a59f25967624155", visitor.Class.ClassName);
}
[Theory]
[InlineData("/Views/Home/Index.cshtml", "_Views_Home_Index")]
[InlineData("/Areas/MyArea/Views/Home/About.cshtml", "_Areas_MyArea_Views_Home_About")]