Expose locations of `_ViewImports.cshtml` that affect a given Razor file.
- Added `ChunkTreeResult` to associate inherited chunks with a specific source file. - Updated existing tests to validate file path. #2256
This commit is contained in:
parent
91c0081939
commit
b871172dd0
|
|
@ -40,17 +40,18 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ordered <see cref="IReadOnlyList{T}"/> of parsed <see cref="ChunkTree"/> for each
|
||||
/// <c>_ViewImports</c> that is applicable to the page located at <paramref name="pagePath"/>. The list is
|
||||
/// ordered so that the <see cref="ChunkTree"/> for the <c>_ViewImports</c> closest to the
|
||||
/// Gets an ordered <see cref="IReadOnlyList{ChunkTreeResult}"/> of parsed <see cref="ChunkTree"/>s and
|
||||
/// file paths for each <c>_ViewImports</c> that is applicable to the page located at
|
||||
/// <paramref name="pagePath"/>. The list is ordered so that the <see cref="ChunkTreeResult"/>'s
|
||||
/// <see cref="ChunkTreeResult.ChunkTree"/> for the <c>_ViewImports</c> closest to the
|
||||
/// <paramref name="pagePath"/> in the file system appears first.
|
||||
/// </summary>
|
||||
/// <param name="pagePath">The path of the page to locate inherited chunks for.</param>
|
||||
/// <returns>A <see cref="IReadOnlyList{ChunkTree}"/> of parsed <c>_ViewImports</c>
|
||||
/// <see cref="ChunkTree"/>s.</returns>
|
||||
public virtual IReadOnlyList<ChunkTree> GetInheritedChunkTrees([NotNull] string pagePath)
|
||||
/// <returns>A <see cref="IReadOnlyList{ChunkTreeResult}"/> of parsed <c>_ViewImports</c>
|
||||
/// <see cref="ChunkTree"/>s and their file paths.</returns>
|
||||
public virtual IReadOnlyList<ChunkTreeResult> GetInheritedChunkTreeResults([NotNull] string pagePath)
|
||||
{
|
||||
var inheritedChunkTrees = new List<ChunkTree>();
|
||||
var inheritedChunkTreeResults = new List<ChunkTreeResult>();
|
||||
var templateEngine = new RazorTemplateEngine(_razorHost);
|
||||
foreach (var viewImportsPath in ViewHierarchyUtility.GetViewImportsLocations(pagePath))
|
||||
{
|
||||
|
|
@ -67,11 +68,12 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
|
||||
if (chunkTree != null)
|
||||
{
|
||||
inheritedChunkTrees.Add(chunkTree);
|
||||
var result = new ChunkTreeResult(chunkTree, viewImportsPath);
|
||||
inheritedChunkTreeResults.Add(result);
|
||||
}
|
||||
}
|
||||
|
||||
return inheritedChunkTrees;
|
||||
return inheritedChunkTreeResults;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Razor.Chunks;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor.Directives
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains <see cref="AspNet.Razor.Chunks.ChunkTree"/> information.
|
||||
/// </summary>
|
||||
public class ChunkTreeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ChunkTreeResult"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunkTree">The <see cref="AspNet.Razor.Chunks.ChunkTree"/> generated from the file at the
|
||||
/// given <paramref name="filePath"/>.</param>
|
||||
/// <param name="filePath">The path to the file that generated the given <paramref name="chunkTree"/>.</param>
|
||||
public ChunkTreeResult([NotNull] ChunkTree chunkTree, [NotNull] string filePath)
|
||||
{
|
||||
ChunkTree = chunkTree;
|
||||
FilePath = filePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="AspNet.Razor.Chunks.ChunkTree"/> generated from the file at <see cref="FilePath"/>.
|
||||
/// </summary>
|
||||
public ChunkTree ChunkTree { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the file that generated the <see cref="ChunkTree"/>.
|
||||
/// </summary>
|
||||
public string FilePath { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
ChunkTree chunkTree;
|
||||
if (!_chunkTreeCache.TryGetValue(pagePath, out chunkTree))
|
||||
{
|
||||
// GetOrAdd is invoked for each _GlobalImport that might potentially exist in the path.
|
||||
// GetOrAdd is invoked for each _ViewImport that might potentially exist in the path.
|
||||
// We can avoid performing file system lookups for files that do not exist by caching
|
||||
// negative results and adding a Watch for that file.
|
||||
|
||||
|
|
@ -58,7 +58,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
var file = _fileProvider.GetFileInfo(pagePath);
|
||||
chunkTree = file.Exists ? getChunkTree(file) : null;
|
||||
|
||||
|
||||
_chunkTreeCache.Set(pagePath, chunkTree, options);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
#if NET45
|
||||
using Microsoft.AspNet.FileProviders;
|
||||
#endif
|
||||
|
|
@ -224,6 +225,21 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locates and parses _ViewImports.cshtml files applying to the given <paramref name="sourceFileName"/> to
|
||||
/// create <see cref="ChunkTreeResult"/>s.
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">The path to a Razor file to locate _ViewImports.cshtml for.</param>
|
||||
/// <returns>Inherited <see cref="ChunkTreeResult"/>s.</returns>
|
||||
public IReadOnlyList<ChunkTreeResult> GetInheritedChunkTreeResults([NotNull] string sourceFileName)
|
||||
{
|
||||
// Need the normalized path to resolve inherited chunks only. Full paths are needed for generated Razor
|
||||
// files checksum and line pragmas to enable DesignTime debugging.
|
||||
var normalizedPath = _pathNormalizer.NormalizePath(sourceFileName);
|
||||
|
||||
return ChunkInheritanceUtility.GetInheritedChunkTreeResults(normalizedPath);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public GeneratorResults GenerateCode(string rootRelativePath, Stream inputStream)
|
||||
{
|
||||
|
|
@ -236,9 +252,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// <inheritdoc />
|
||||
public override RazorParser DecorateRazorParser([NotNull] RazorParser razorParser, string sourceFileName)
|
||||
{
|
||||
sourceFileName = _pathNormalizer.NormalizePath(sourceFileName);
|
||||
var inheritedChunkTrees = GetInheritedChunkTrees(sourceFileName);
|
||||
|
||||
var inheritedChunkTrees = ChunkInheritanceUtility.GetInheritedChunkTrees(sourceFileName);
|
||||
return new MvcRazorParser(razorParser, inheritedChunkTrees, DefaultInheritedChunks, ModelExpressionType);
|
||||
}
|
||||
|
||||
|
|
@ -253,14 +268,11 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
[NotNull] CodeGenerator incomingGenerator,
|
||||
[NotNull] CodeGeneratorContext context)
|
||||
{
|
||||
// Need the normalized path to resolve inherited chunks only. Full paths are needed for generated Razor
|
||||
// files checksum and line pragmas to enable DesignTime debugging.
|
||||
var normalizedPath = _pathNormalizer.NormalizePath(context.SourceFile);
|
||||
var inheritedChunks = ChunkInheritanceUtility.GetInheritedChunkTrees(normalizedPath);
|
||||
var inheritedChunkTrees = GetInheritedChunkTrees(context.SourceFile);
|
||||
|
||||
ChunkInheritanceUtility.MergeInheritedChunkTrees(
|
||||
context.ChunkTreeBuilder.ChunkTree,
|
||||
inheritedChunks,
|
||||
inheritedChunkTrees,
|
||||
DefaultModel);
|
||||
|
||||
return new MvcCSharpCodeGenerator(
|
||||
|
|
@ -273,5 +285,14 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
CreateModelExpressionMethodName = CreateModelExpressionMethod
|
||||
});
|
||||
}
|
||||
|
||||
private IReadOnlyList<ChunkTree> GetInheritedChunkTrees(string sourceFileName)
|
||||
{
|
||||
var inheritedChunkTrees = GetInheritedChunkTreeResults(sourceFileName)
|
||||
.Select(result => result.ChunkTree)
|
||||
.ToList();
|
||||
|
||||
return inheritedChunkTrees;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Razor.Chunks;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor.Directives
|
||||
|
|
@ -36,14 +35,15 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);
|
||||
|
||||
// Act
|
||||
var chunkTrees = utility.GetInheritedChunkTrees(PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));
|
||||
var chunkTreeResults = utility.GetInheritedChunkTreeResults(
|
||||
PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));
|
||||
|
||||
// Assert
|
||||
Assert.Collection(chunkTrees,
|
||||
chunkTree =>
|
||||
Assert.Collection(chunkTreeResults,
|
||||
chunkTreeResult =>
|
||||
{
|
||||
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\home\_ViewImports.cshtml");
|
||||
Assert.Collection(chunkTree.Chunks,
|
||||
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
|
||||
chunk =>
|
||||
{
|
||||
Assert.IsType<LiteralChunk>(chunk);
|
||||
|
|
@ -60,11 +60,12 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
Assert.IsType<LiteralChunk>(chunk);
|
||||
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
|
||||
});
|
||||
Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
|
||||
},
|
||||
chunkTree =>
|
||||
chunkTreeResult =>
|
||||
{
|
||||
var viewImportsPath = PlatformNormalizer.NormalizePath(@"Views\_ViewImports.cshtml");
|
||||
Assert.Collection(chunkTree.Chunks,
|
||||
Assert.Collection(chunkTreeResult.ChunkTree.Chunks,
|
||||
chunk =>
|
||||
{
|
||||
Assert.IsType<LiteralChunk>(chunk);
|
||||
|
|
@ -104,6 +105,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
Assert.IsType<LiteralChunk>(chunk);
|
||||
Assert.Equal(viewImportsPath, chunk.Start.FilePath);
|
||||
});
|
||||
Assert.Equal(viewImportsPath, chunkTreeResult.FilePath);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +127,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
var utility = new ChunkInheritanceUtility(host, cache, defaultChunks);
|
||||
|
||||
// Act
|
||||
var chunkTrees = utility.GetInheritedChunkTrees(PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));
|
||||
var chunkTrees = utility.GetInheritedChunkTreeResults(PlatformNormalizer.NormalizePath(@"Views\home\Index.cshtml"));
|
||||
|
||||
// Assert
|
||||
Assert.Empty(chunkTrees);
|
||||
|
|
@ -168,9 +170,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
var chunkTree = new ChunkTree();
|
||||
|
||||
// Act
|
||||
utility.MergeInheritedChunkTrees(chunkTree,
|
||||
inheritedChunkTrees,
|
||||
"dynamic");
|
||||
utility.MergeInheritedChunkTrees(chunkTree, inheritedChunkTrees, "dynamic");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3, chunkTree.Chunks.Count);
|
||||
|
|
|
|||
|
|
@ -486,11 +486,11 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
public string InheritedChunkTreePagePath { get; private set; }
|
||||
|
||||
public override IReadOnlyList<ChunkTree> GetInheritedChunkTrees([NotNull] string pagePath)
|
||||
public override IReadOnlyList<ChunkTreeResult> GetInheritedChunkTreeResults([NotNull] string pagePath)
|
||||
{
|
||||
InheritedChunkTreePagePath = pagePath;
|
||||
|
||||
return new ChunkTree[0];
|
||||
return new ChunkTreeResult[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +533,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
protected override CSharpCodeWriter CreateCodeWriter()
|
||||
{
|
||||
// We normalize newlines so no matter what platform we're on
|
||||
// We normalize newlines so no matter what platform we're on
|
||||
// they're consistent (for code generation tests).
|
||||
var codeWriter = base.CreateCodeWriter();
|
||||
codeWriter.NewLine = "\r\n";
|
||||
|
|
|
|||
Loading…
Reference in New Issue