Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,33 @@ private static Dictionary<Type, IChunkMerger> GetMergerMappings(CodeTree codeTre

private static CodeTree ParseViewFile(RazorTemplateEngine engine,
IFileInfo fileInfo,
string viewStartPath)
string globalImportPath)
{
using (var stream = fileInfo.CreateReadStream())
{
using (var streamReader = new StreamReader(stream))
{
var parseResults = engine.ParseTemplate(streamReader, viewStartPath);
var parseResults = engine.ParseTemplate(streamReader, globalImportPath);
var className = ParserHelpers.SanitizeClassName(fileInfo.Name);
var language = engine.Host.CodeLanguage;
var codeGenerator = language.CreateCodeGenerator(className,
engine.Host.DefaultNamespace,
viewStartPath,
globalImportPath,
engine.Host);
codeGenerator.Visit(parseResults);

return codeGenerator.Context.CodeTreeBuilder.CodeTree;
var codeTree = codeGenerator.Context.CodeTreeBuilder.CodeTree;
// Rewrite the location of inherited chunks so they point to the global import file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: blank line before mid-block comments. in this case, might be best to move this comment above previous line.

foreach (var chunk in codeTree.Chunks)
{
chunk.Start = new SourceLocation(
globalImportPath,
chunk.Start.AbsoluteIndex,
chunk.Start.LineIndex,
chunk.Start.CharacterIndex);
}

return codeTree;
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private static IEnumerable<TagHelperDirectiveDescriptor> GetTagHelperDirectiveDe
{
var descriptor = new TagHelperDirectiveDescriptor(
addTagHelperChunk.LookupText,
SourceLocation.Undefined,
chunk.Start,
TagHelperDirectiveType.AddTagHelper);

descriptors.Add(descriptor);
Expand All @@ -89,7 +89,7 @@ private static IEnumerable<TagHelperDirectiveDescriptor> GetTagHelperDirectiveDe
{
var descriptor = new TagHelperDirectiveDescriptor(
removeTagHelperChunk.LookupText,
SourceLocation.Undefined,
chunk.Start,
TagHelperDirectiveType.RemoveTagHelper);

descriptors.Add(descriptor);
Expand All @@ -102,7 +102,7 @@ private static IEnumerable<TagHelperDirectiveDescriptor> GetTagHelperDirectiveDe
{
var descriptor = new TagHelperDirectiveDescriptor(
tagHelperPrefixDirectiveChunk.Prefix,
SourceLocation.Undefined,
chunk.Start,
TagHelperDirectiveType.TagHelperPrefix);

descriptors.Add(descriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@ public class CompilationFailedException : Exception, ICompilationException
/// <summary>
/// Instantiates a new instance of <see cref="CompilationFailedException"/>.
/// </summary>
/// <param name="compilationFailure">The <see cref="ICompilationFailure"/> instance containing
/// <param name="compilationFailures"><see cref="ICompilationFailure"/>s containing
/// details of the compilation failure.</param>
public CompilationFailedException(
[NotNull] ICompilationFailure compilationFailure)
: base(FormatMessage(compilationFailure))
[NotNull] IEnumerable<ICompilationFailure> compilationFailures)
: base(FormatMessage(compilationFailures))
{
CompilationFailures = new[] { compilationFailure };
CompilationFailures = compilationFailures;
}

/// <inheritdoc />
public IEnumerable<ICompilationFailure> CompilationFailures { get; }

private static string FormatMessage(ICompilationFailure compilationFailure)
private static string FormatMessage(IEnumerable<ICompilationFailure> compilationFailure)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compilationFailures (add an 's')

{
return Resources.CompilationFailed + Environment.NewLine +
string.Join(
Environment.NewLine,
compilationFailure.Messages.Select(message => message.FormattedMessage));
compilationFailure.SelectMany(f => f.Messages).Select(message => message.FormattedMessage));
}
}
}
17 changes: 9 additions & 8 deletions src/Microsoft.AspNet.Mvc.Razor/Compilation/CompilationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Microsoft.Framework.Runtime;
using System.Collections.Generic;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Runtime;

namespace Microsoft.AspNet.Mvc.Razor.Compilation
{
Expand Down Expand Up @@ -31,10 +32,10 @@ protected CompilationResult()
public string CompiledContent { get; protected set; }

/// <summary>
/// Gets the <see cref="ICompilationFailure"/> produced from parsing or compiling the Razor file.
/// Gets the <see cref="ICompilationFailure"/>s produced from parsing or compiling the Razor file.
/// </summary>
/// <remarks>This property is <c>null</c> when compilation succeeded.</remarks>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does it mean if the collection is empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still considered a compilation failure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆗 this comment should mention that case

public ICompilationFailure CompilationFailure { get; private set; }
public IEnumerable<ICompilationFailure> CompilationFailures { get; private set; }

/// <summary>
/// Gets the <see cref="CompilationResult"/>.
Expand All @@ -43,9 +44,9 @@ protected CompilationResult()
/// <exception cref="CompilationFailedException">Thrown if compilation failed.</exception>
public CompilationResult EnsureSuccessful()
{
if (CompilationFailure != null)
if (CompilationFailures != null)
{
throw new CompilationFailedException(CompilationFailure);
throw new CompilationFailedException(CompilationFailures);
}

return this;
Expand All @@ -54,14 +55,14 @@ public CompilationResult EnsureSuccessful()
/// <summary>
/// Creates a <see cref="CompilationResult"/> for a failed compilation.
/// </summary>
/// <param name="compilationFailure">The <see cref="ICompilationFailure"/> produced from parsing or
/// <param name="compilationFailures"><see cref="ICompilationFailure"/>s produced from parsing or
/// compiling the Razor file.</param>
/// <returns>A <see cref="CompilationResult"/> instance for a failed compilation.</returns>
public static CompilationResult Failed([NotNull] ICompilationFailure compilationFailure)
public static CompilationResult Failed([NotNull] IEnumerable<ICompilationFailure> compilationFailures)
{
return new CompilationResult
{
CompilationFailure = compilationFailure
CompilationFailures = compilationFailures
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNet.FileProviders;
using Microsoft.AspNet.Razor;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;

namespace Microsoft.AspNet.Mvc.Razor.Compilation
{
Expand All @@ -16,12 +19,15 @@ public class RazorCompilationService : IRazorCompilationService
{
private readonly ICompilationService _compilationService;
private readonly IMvcRazorHost _razorHost;
private readonly IFileProvider _fileProvider;

public RazorCompilationService(ICompilationService compilationService,
IMvcRazorHost razorHost)
IMvcRazorHost razorHost,
IOptions<RazorViewEngineOptions> viewEngineOptions)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious: Why not just do IFileProvider?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file system that we use for views specifically hangs off of RazorViewEngineOptions. It allows doing things like using resources as view sources - https://github.com/aspnet/Mvc/blob/dev/test/WebSites/RazorEmbeddedViewsWebSite/Startup.cs#L20-L23

{
_compilationService = compilationService;
_razorHost = razorHost;
_fileProvider = viewEngineOptions.Options.FileProvider;
}

/// <inheritdoc />
Expand All @@ -30,39 +36,61 @@ public CompilationResult Compile([NotNull] RelativeFileInfo file)
GeneratorResults results;
using (var inputStream = file.FileInfo.CreateReadStream())
{
results = _razorHost.GenerateCode(
file.RelativePath, inputStream);
results = _razorHost.GenerateCode(file.RelativePath, inputStream);
}

if (!results.Success)
{
var messages = results.ParserErrors
.Select(parseError => new RazorCompilationMessage(parseError, file.RelativePath));
var failure = new RazorCompilationFailure(
file.RelativePath,
ReadFileContentsSafely(file.FileInfo),
messages);

return CompilationResult.Failed(failure);
return GetCompilationFailedResult(file, results.ParserErrors);
}

return _compilationService.Compile(file, results.GeneratedCode);
}

private static string ReadFileContentsSafely(IFileInfo fileInfo)
// Internal for unit testing
internal CompilationResult GetCompilationFailedResult(RelativeFileInfo file, IEnumerable<RazorError> errors)
{
try
var messageGroups = errors
.GroupBy(razorError =>
// If a SourceLocation does not specify a file path, assume it is produced
// from parsing the current file.
razorError.Location.FilePath ?? file.RelativePath,
StringComparer.OrdinalIgnoreCase);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be Ordinal


var failures = new List<RazorCompilationFailure>();
foreach (var group in messageGroups)
{
using (var reader = new StreamReader(fileInfo.CreateReadStream()))
{
return reader.ReadToEnd();
}
var filePath = group.Key;
var fileContent = ReadFileContentsSafely(filePath);
var compilationFailure = new RazorCompilationFailure(
filePath,
fileContent,
group.Select(parserError => new RazorCompilationMessage(parserError, filePath)));
failures.Add(compilationFailure);
}
catch

return CompilationResult.Failed(failures);
}

private string ReadFileContentsSafely(string relativePath)
{
var fileInfo = _fileProvider.GetFileInfo(relativePath);
if (fileInfo.Exists)
{
// Ignore any failures
return null;
try
{
using (var reader = new StreamReader(fileInfo.CreateReadStream()))
{
return reader.ReadToEnd();
}
}
catch
{
// Ignore any failures
}
}

return null;
}
}
}
Loading