Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Remove ParseOptions and CompilationOptions from RazorViewEngineOptions
Browse files Browse the repository at this point in the history
Fixes #6009
  • Loading branch information
pranavkm committed Jul 3, 2017
1 parent 7c5a16c commit 97b5e1e
Show file tree
Hide file tree
Showing 11 changed files with 395 additions and 569 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,8 @@ internal static void AddRazorViewEngineServices(IServiceCollection services)
services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<MvcViewOptions>, MvcRazorMvcViewOptionsSetup>());

// DependencyContextRazorViewEngineOptionsSetup needs to run after RazorViewEngineOptionsSetup.
// The ordering of the following two lines is important to ensure this behavior.
services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<
IConfigureOptions<RazorViewEngineOptions>,
DependencyContextRazorViewEngineOptionsSetup>());

services.TryAddSingleton<
IRazorViewEngineFileProviderAccessor,
Expand Down
117 changes: 108 additions & 9 deletions src/Microsoft.AspNetCore.Mvc.Razor/Internal/CSharpCompiler.cs
Original file line number Diff line number Diff line change
@@ -1,47 +1,146 @@
// 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.Reflection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Text;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyModel;
using DependencyContextCompilationOptions = Microsoft.Extensions.DependencyModel.CompilationOptions;

namespace Microsoft.AspNetCore.Mvc.Razor.Internal
{
public class CSharpCompiler
{
private readonly CSharpCompilationOptions _compilationOptions;
private readonly CSharpParseOptions _parseOptions;
private readonly RazorReferenceManager _referenceManager;
private readonly DebugInformationFormat _pdbFormat = SymbolsUtility.SupportsFullPdbGeneration() ?
DebugInformationFormat.Pdb :
DebugInformationFormat.PortablePdb;

public CSharpCompiler(RazorReferenceManager manager, IOptions<RazorViewEngineOptions> optionsAccessor)
public CSharpCompiler(RazorReferenceManager manager, IHostingEnvironment hostingEnvironment)
: this(manager, hostingEnvironment, GetDependencyContextCompilationOptions(hostingEnvironment))
{
_referenceManager = manager;
_compilationOptions = optionsAccessor.Value.CompilationOptions;
_parseOptions = optionsAccessor.Value.ParseOptions;
}

internal CSharpCompiler(
RazorReferenceManager manager,
IHostingEnvironment hostingEnvironment,
DependencyContextCompilationOptions dependencyContextOptions)
{
_referenceManager = manager ?? throw new ArgumentNullException(nameof(manager));
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}

ParseOptions = GetParseOptions(hostingEnvironment, dependencyContextOptions);
CSharpCompilationOptions = GetCompilationOptions(hostingEnvironment, dependencyContextOptions);
EmitOptions = new EmitOptions(debugInformationFormat: _pdbFormat);
}

public CSharpParseOptions ParseOptions { get; }

public CSharpCompilationOptions CSharpCompilationOptions { get; }

public EmitOptions EmitOptions { get; }

private static CSharpCompilationOptions GetCompilationOptions(
IHostingEnvironment hostingEnvironment,
DependencyContextCompilationOptions dependencyContextOptions)
{
var csharpCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

// Disable 1702 until roslyn turns this off by default
csharpCompilationOptions = csharpCompilationOptions.WithSpecificDiagnosticOptions(
new Dictionary<string, ReportDiagnostic>
{
{"CS1701", ReportDiagnostic.Suppress}, // Binding redirects
{"CS1702", ReportDiagnostic.Suppress},
{"CS1705", ReportDiagnostic.Suppress}
});

if (dependencyContextOptions.AllowUnsafe.HasValue)
{
csharpCompilationOptions = csharpCompilationOptions.WithAllowUnsafe(
dependencyContextOptions.AllowUnsafe.Value);
}

OptimizationLevel optimizationLevel;
if (dependencyContextOptions.Optimize.HasValue)
{
optimizationLevel = dependencyContextOptions.Optimize.Value ?
OptimizationLevel.Release :
OptimizationLevel.Debug;
}
else
{
optimizationLevel = hostingEnvironment.IsDevelopment() ?
OptimizationLevel.Debug :
OptimizationLevel.Release;
}
csharpCompilationOptions = csharpCompilationOptions.WithOptimizationLevel(optimizationLevel);

if (dependencyContextOptions.WarningsAsErrors.HasValue)
{
var reportDiagnostic = dependencyContextOptions.WarningsAsErrors.Value ?
ReportDiagnostic.Error :
ReportDiagnostic.Default;
csharpCompilationOptions = csharpCompilationOptions.WithGeneralDiagnosticOption(reportDiagnostic);
}

return csharpCompilationOptions;
}

private static CSharpParseOptions GetParseOptions(
IHostingEnvironment hostingEnvironment,
DependencyContextCompilationOptions dependencyContextOptions)
{
var configurationSymbol = hostingEnvironment.IsDevelopment() ? "DEBUG" : "RELEASE";
var defines = dependencyContextOptions.Defines.Concat(new[] { configurationSymbol });

var parseOptions = new CSharpParseOptions(
LanguageVersion.CSharp7_1,
preprocessorSymbols: defines);

return parseOptions;
}

public SyntaxTree CreateSyntaxTree(SourceText sourceText)
{
return CSharpSyntaxTree.ParseText(
sourceText,
options: _parseOptions);
options: ParseOptions);
}

public CSharpCompilation CreateCompilation(string assemblyName)
{
return CSharpCompilation.Create(
assemblyName,
options: _compilationOptions,
options: CSharpCompilationOptions,
references: _referenceManager.CompilationReferences);
}

// Internal for unit testing.
internal static DependencyContextCompilationOptions GetDependencyContextCompilationOptions(
IHostingEnvironment hostingEnvironment)
{
if (!string.IsNullOrEmpty(hostingEnvironment.ApplicationName))
{
var applicationAssembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
var dependencyContext = DependencyContext.Load(applicationAssembly);
if (dependencyContext?.CompilationOptions != null)
{
return dependencyContext.CompilationOptions;
}
}

return DependencyContextCompilationOptions.Default;
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Mvc.Razor.Internal
Expand All @@ -22,12 +20,7 @@ public class RazorViewEngineOptionsSetup : IConfigureOptions<RazorViewEngineOpti
/// <param name="hostingEnvironment"><see cref="IHostingEnvironment"/> for the application.</param>
public RazorViewEngineOptionsSetup(IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}

_hostingEnvironment = hostingEnvironment;
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
}

public void Configure(RazorViewEngineOptions options)
Expand All @@ -42,24 +35,6 @@ public void Configure(RazorViewEngineOptions options)
options.FileProviders.Add(_hostingEnvironment.ContentRootFileProvider);
}

var compilationOptions = options.CompilationOptions;
string configurationSymbol;

if (_hostingEnvironment.IsDevelopment())
{
configurationSymbol = "DEBUG";
options.CompilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Debug);
}
else
{
configurationSymbol = "RELEASE";
options.CompilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Release);
}

var parseOptions = options.ParseOptions;
options.ParseOptions = parseOptions.WithPreprocessorSymbols(
parseOptions.PreprocessorSymbolNames.Concat(new[] { configurationSymbol }));

options.ViewLocationFormats.Add("/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
options.ViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);

Expand Down
Loading

0 comments on commit 97b5e1e

Please sign in to comment.