Add assembly name filtering to GetTagHelpers calls.

- Updated the Razor extension to properly discover all assembly names available to a project and use those as a TagHelper filter.

#1022
This commit is contained in:
N. Taylor Mullen 2017-02-17 12:15:56 -08:00
parent 965ae5490f
commit 7a2f89b5de
6 changed files with 35 additions and 18 deletions

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Evolution; using Microsoft.AspNetCore.Razor.Evolution;
using Microsoft.AspNetCore.Razor.Evolution.Legacy; using Microsoft.AspNetCore.Razor.Evolution.Legacy;
using System.Linq;
namespace Microsoft.CodeAnalysis.Razor namespace Microsoft.CodeAnalysis.Razor
{ {
@ -17,12 +18,12 @@ namespace Microsoft.CodeAnalysis.Razor
public bool DesignTime { get; } public bool DesignTime { get; }
public override TagHelperResolutionResult GetTagHelpers(Compilation compilation) public override TagHelperResolutionResult GetTagHelpers(Compilation compilation, IEnumerable<string> assemblyNameFilters)
{ {
var descriptors = new List<TagHelperDescriptor>(); var descriptors = new List<TagHelperDescriptor>();
var errors = new ErrorSink(); var errors = new ErrorSink();
VisitTagHelpers(compilation, descriptors, errors); VisitTagHelpers(compilation, assemblyNameFilters, descriptors, errors);
VisitViewComponents(compilation, descriptors, errors); VisitViewComponents(compilation, descriptors, errors);
var diagnostics = new List<RazorDiagnostic>(); var diagnostics = new List<RazorDiagnostic>();
@ -36,7 +37,7 @@ namespace Microsoft.CodeAnalysis.Razor
return resolutionResult; return resolutionResult;
} }
private void VisitTagHelpers(Compilation compilation, List<TagHelperDescriptor> results, ErrorSink errors) private void VisitTagHelpers(Compilation compilation, IEnumerable<string> assemblyNameFilters, List<TagHelperDescriptor> results, ErrorSink errors)
{ {
var types = new List<INamedTypeSymbol>(); var types = new List<INamedTypeSymbol>();
var visitor = TagHelperTypeVisitor.Create(compilation, types); var visitor = TagHelperTypeVisitor.Create(compilation, types);
@ -47,12 +48,15 @@ namespace Microsoft.CodeAnalysis.Razor
foreach (var type in types) foreach (var type in types)
{ {
var descriptors = factory.CreateDescriptors(type, errors); if (assemblyNameFilters.Contains(type.ContainingAssembly.Identity.Name))
results.AddRange(descriptors); {
var descriptors = factory.CreateDescriptors(type, errors);
results.AddRange(descriptors);
}
} }
} }
private void VisitViewComponents(Compilation compilation, List<TagHelperDescriptor> results, ErrorSink errors) private void VisitViewComponents(Compilation compilation, IEnumerable<string> assemblyNameFilters, List<TagHelperDescriptor> results, ErrorSink errors)
{ {
var types = new List<INamedTypeSymbol>(); var types = new List<INamedTypeSymbol>();
var visitor = ViewComponentTypeVisitor.Create(compilation, types); var visitor = ViewComponentTypeVisitor.Create(compilation, types);
@ -65,9 +69,12 @@ namespace Microsoft.CodeAnalysis.Razor
{ {
try try
{ {
var descriptor = factory.CreateDescriptor(type); if (assemblyNameFilters.Contains(type.ContainingAssembly.Identity.Name))
{
var descriptor = factory.CreateDescriptor(type);
results.Add(descriptor); results.Add(descriptor);
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host;
@ -9,14 +10,15 @@ namespace Microsoft.CodeAnalysis.Razor
{ {
internal abstract class TagHelperResolver : ILanguageService internal abstract class TagHelperResolver : ILanguageService
{ {
public abstract TagHelperResolutionResult GetTagHelpers(Compilation compilation); public abstract TagHelperResolutionResult GetTagHelpers(Compilation compilation, IEnumerable<string> assemblyNameFilters);
public virtual async Task<TagHelperResolutionResult> GetTagHelpersAsync( public virtual async Task<TagHelperResolutionResult> GetTagHelpersAsync(
Project project, Project project,
IEnumerable<string> assemblyNameFilters,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
return GetTagHelpers(compilation); return GetTagHelpers(compilation, assemblyNameFilters);
} }
} }
} }

View File

@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.Remote.Razor
{ {
} }
public async Task<TagHelperResolutionResult> GetTagHelpersAsync(Guid projectIdBytes, string projectDebugName, CancellationToken cancellationToken = default(CancellationToken)) public async Task<TagHelperResolutionResult> GetTagHelpersAsync(Guid projectIdBytes, string projectDebugName, IEnumerable<string> assemblyNameFilters, CancellationToken cancellationToken = default(CancellationToken))
{ {
var projectId = ProjectId.CreateFromSerialized(projectIdBytes, projectDebugName); var projectId = ProjectId.CreateFromSerialized(projectIdBytes, projectDebugName);
@ -28,7 +28,7 @@ namespace Microsoft.CodeAnalysis.Remote.Razor
var project = solution.GetProject(projectId); var project = solution.GetProject(projectId);
var resolver = new DefaultTagHelperResolver(designTime: true); var resolver = new DefaultTagHelperResolver(designTime: true);
var result = await resolver.GetTagHelpersAsync(project, cancellationToken).ConfigureAwait(false); var result = await resolver.GetTagHelpersAsync(project, assemblyNameFilters, cancellationToken).ConfigureAwait(false);
return result; return result;
} }

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Composition; using System.Composition;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Evolution;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor;
@ -18,7 +17,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
[Import] [Import]
public VisualStudioWorkspace Workspace { get; set; } public VisualStudioWorkspace Workspace { get; set; }
public async Task<TagHelperResolutionResult> GetTagHelpersAsync(Project project) public async Task<TagHelperResolutionResult> GetTagHelpersAsync(Project project, IEnumerable<string> assemblyNameFilters)
{ {
try try
{ {
@ -27,13 +26,13 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
{ {
// The OOP host is turned off, so let's do this in process. // The OOP host is turned off, so let's do this in process.
var resolver = new CodeAnalysis.Razor.DefaultTagHelperResolver(designTime: true); var resolver = new CodeAnalysis.Razor.DefaultTagHelperResolver(designTime: true);
var result = await resolver.GetTagHelpersAsync(project, CancellationToken.None).ConfigureAwait(false); var result = await resolver.GetTagHelpersAsync(project, assemblyNameFilters, CancellationToken.None).ConfigureAwait(false);
return result; return result;
} }
using (var session = await client.CreateSessionAsync(project.Solution)) using (var session = await client.CreateSessionAsync(project.Solution))
{ {
var result = await session.InvokeAsync<TagHelperResolutionResult>("GetTagHelpersAsync", new object[] { project.Id.Id, "Foo", }).ConfigureAwait(false); var result = await session.InvokeAsync<TagHelperResolutionResult>("GetTagHelpersAsync", new object[] { project.Id.Id, "Foo", assemblyNameFilters, }).ConfigureAwait(false);
return result; return result;
} }
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor;
@ -9,6 +10,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
{ {
public interface ITagHelperResolver public interface ITagHelperResolver
{ {
Task<TagHelperResolutionResult> GetTagHelpersAsync(Project project); Task<TagHelperResolutionResult> GetTagHelpersAsync(Project project, IEnumerable<string> assemblyNameFilters);
} }
} }

View File

@ -14,6 +14,7 @@ using Microsoft.VisualStudio.LanguageServices.Razor;
using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TextManager.Interop; using Microsoft.VisualStudio.TextManager.Interop;
using System.IO;
namespace Microsoft.VisualStudio.RazorExtension.RazorInfo namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
{ {
@ -169,7 +170,14 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
var assemblies = await _assemblyResolver.GetRazorEngineAssembliesAsync(project); var assemblies = await _assemblyResolver.GetRazorEngineAssembliesAsync(project);
var directives = await _directiveResolver.GetRazorEngineDirectivesAsync(_workspace, project); var directives = await _directiveResolver.GetRazorEngineDirectivesAsync(_workspace, project);
var resolutionResult = await _tagHelperResolver.GetTagHelpersAsync(project); var assemblyFilters = project.MetadataReferences
.Select(reference => reference.Display)
.Select(filter => Path.GetFileNameWithoutExtension(filter));
var projectFilters = project.AllProjectReferences.Select(filter => solution.GetProject(filter.ProjectId).AssemblyName);
var tagHelperAssemblyFilters = assemblyFilters
.Concat(projectFilters)
.Concat(new[] { project.AssemblyName });
var resolutionResult = await _tagHelperResolver.GetTagHelpersAsync(project, tagHelperAssemblyFilters);
var files = GetCshtmlDocuments(project); var files = GetCshtmlDocuments(project);