Update our diagnostics window
Updates our diagnostics window to use the 'in the box' version of the assembly/version discovery logic.
This commit is contained in:
parent
67f255adca
commit
00dc95098f
|
|
@ -1,153 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#if RAZOR_EXTENSION_DEVELOPER_MODE
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using static Microsoft.VisualStudio.LanguageServices.Razor.ReflectionNames;
|
||||
|
||||
namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||
{
|
||||
[Export(typeof(IRazorEngineAssemblyResolver))]
|
||||
internal class DefaultRazorEngineAssemblyResolver : IRazorEngineAssemblyResolver
|
||||
{
|
||||
public async Task<IEnumerable<RazorEngineAssembly>> GetRazorEngineAssembliesAsync(Project project)
|
||||
{
|
||||
try
|
||||
{
|
||||
var compilation = await project.GetCompilationAsync().ConfigureAwait(false);
|
||||
var assemblies = GetRazorCustomizationAssemblies(compilation);
|
||||
|
||||
return assemblies;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new RazorLanguageServiceException(
|
||||
typeof(DefaultRazorEngineAssemblyResolver).FullName,
|
||||
nameof(GetRazorEngineAssembliesAsync),
|
||||
exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<RazorEngineAssembly> GetRazorCustomizationAssemblies(Compilation compilation)
|
||||
{
|
||||
// The goal here is to find the set of assemblies + paths that have some kind of
|
||||
// Razor extensibility.
|
||||
//
|
||||
// We do that by making a compilation and then looking through the set of assembly names
|
||||
// (AssemblyIdentity) and references to dlls on disk (PortableExecutableReference) to find
|
||||
// uses of RazorEngineCustomizationAttribute and RazorEngineDependencyAttribute.
|
||||
//
|
||||
// We're limited to supporting files on disk because we will need to shadow copy them
|
||||
// and manually load them.
|
||||
//
|
||||
// Also note that we're not doing anything here to explicitly uniquify this list, since
|
||||
// we're limiting the set of candidates to the set of assemblies used for compilation, which
|
||||
// has already been processed by Roslyn.
|
||||
var results = new List<RazorEngineAssembly>();
|
||||
|
||||
// The RazorEngineDependencyAttribute also allows specifying an assembly name to go along
|
||||
// with a piece of extensibility. We'll collect these on the first pass through the assemblies
|
||||
// and then look those up by name.
|
||||
var unresolvedIdentities = new List<AssemblyIdentity>();
|
||||
|
||||
foreach (var reference in compilation.References)
|
||||
{
|
||||
var peReference = reference as PortableExecutableReference;
|
||||
if (peReference == null || peReference.FilePath == null)
|
||||
{
|
||||
// No path, can't load it.
|
||||
continue;
|
||||
}
|
||||
|
||||
var assemblySymbol = compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol;
|
||||
if (assemblySymbol == null)
|
||||
{
|
||||
// It's unlikely, but possible that a reference might be a module instead of an assembly.
|
||||
// We can't load that, so just skip it.
|
||||
continue;
|
||||
}
|
||||
|
||||
var identity = assemblySymbol.Identity;
|
||||
if (identity.Name == RazorAssemblyName)
|
||||
{
|
||||
// This is the main Razor assembly.
|
||||
results.Add(new RazorEngineAssembly(identity, peReference.FilePath));
|
||||
}
|
||||
|
||||
// Now we're looking for the Razor exensibility attributes.
|
||||
var attributes = assemblySymbol.GetAttributes();
|
||||
for (var i = 0; i < attributes.Length; i++)
|
||||
{
|
||||
var attribute = attributes[i];
|
||||
var name = attribute.AttributeClass.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
if (string.Equals(
|
||||
CustomizationAttribute,
|
||||
name,
|
||||
StringComparison.Ordinal))
|
||||
{
|
||||
results.Add(new RazorEngineAssembly(identity, peReference.FilePath));
|
||||
}
|
||||
|
||||
if (string.Equals(
|
||||
DependencyAttribute,
|
||||
name,
|
||||
StringComparison.Ordinal))
|
||||
{
|
||||
// This attribute refers to a separate assembly for which we will need to resolve a path.
|
||||
//
|
||||
// Ignore parsing failures here.
|
||||
AssemblyIdentity dependency;
|
||||
if (AssemblyIdentity.TryParseDisplayName((string)attribute.ConstructorArguments[0].Value, out dependency))
|
||||
{
|
||||
unresolvedIdentities.Add(dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Now we need to do another pass to resolve all the unresolved names.
|
||||
if (unresolvedIdentities.Count > 0)
|
||||
{
|
||||
//while (identities.MoveNext() && references.MoveNext())
|
||||
//{
|
||||
// var peReference = references.Current as PortableExecutableReference;
|
||||
// if (peReference == null || peReference.FilePath == null)
|
||||
// {
|
||||
// // No path, can't load it.
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// var assemblySymbol = compilation.GetAssemblyOrModuleSymbol(peReference) as IAssemblySymbol;
|
||||
// if (assemblySymbol == null)
|
||||
// {
|
||||
// // It's unlikely, but possible that a reference might be a module instead of an assembly.
|
||||
// // We can't load that, so just skip it.
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// for (var i = 0; i < unresolvedIdentities.Count; i++)
|
||||
// {
|
||||
// // Note: argument ordering here is significant. We expect that the attribute will often refer to a
|
||||
// // partial name and omit details like the version and public-key, therefore the value from the
|
||||
// // attribute must be the first argument.
|
||||
// if (AssemblyIdentityComparer.Default.ReferenceMatchesDefinition(
|
||||
// unresolvedIdentities[i],
|
||||
// identities.Current))
|
||||
// {
|
||||
// results.Add(new RazorEngineAssembly(identities.Current, peReference.FilePath));
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#if RAZOR_EXTENSION_DEVELOPER_MODE
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||
{
|
||||
internal interface IRazorEngineAssemblyResolver
|
||||
{
|
||||
Task<IEnumerable<RazorEngineAssembly>> GetRazorEngineAssembliesAsync(Project project);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#if RAZOR_EXTENSION_DEVELOPER_MODE
|
||||
using System;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||
{
|
||||
internal struct RazorEngineAssembly
|
||||
{
|
||||
public RazorEngineAssembly(AssemblyIdentity identity, string filePath)
|
||||
{
|
||||
if (identity == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(identity));
|
||||
}
|
||||
|
||||
if (filePath == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
Identity = identity;
|
||||
FilePath = filePath;
|
||||
}
|
||||
|
||||
public string FilePath { get; }
|
||||
|
||||
public AssemblyIdentity Identity { get; }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#if RAZOR_EXTENSION_DEVELOPER_MODE
|
||||
namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||
{
|
||||
internal static class ReflectionNames
|
||||
{
|
||||
public static readonly string RazorAssemblyName = "Microsoft.AspNetCore.Razor.Language";
|
||||
|
||||
public static readonly string CustomizationAttribute = RazorAssemblyName + ".RazorEngineCustomizationAttribute";
|
||||
|
||||
public static readonly string DependencyAttribute = RazorAssemblyName + ".RazorEngineDependencyAttribute";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2,25 +2,22 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if RAZOR_EXTENSION_DEVELOPER_MODE
|
||||
using Microsoft.VisualStudio.LanguageServices.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||
{
|
||||
public class AssemblyViewModel : NotifyPropertyChanged
|
||||
{
|
||||
private readonly RazorEngineAssembly _assembly;
|
||||
private readonly ProjectExtensibilityAssembly _assembly;
|
||||
|
||||
internal AssemblyViewModel(RazorEngineAssembly assembly)
|
||||
internal AssemblyViewModel(ProjectExtensibilityAssembly assembly)
|
||||
{
|
||||
_assembly = assembly;
|
||||
|
||||
Name = _assembly.Identity.GetDisplayName();
|
||||
FilePath = assembly.FilePath;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string FilePath { get; }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -6,6 +6,7 @@ using System;
|
|||
using System.Runtime.InteropServices;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
using Microsoft.VisualStudio.ComponentModelHost;
|
||||
using Microsoft.VisualStudio.LanguageServices;
|
||||
using Microsoft.VisualStudio.LanguageServices.Razor;
|
||||
|
|
@ -17,7 +18,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
[Guid("079e9499-d150-40af-8876-3047f7942c2a")]
|
||||
public class RazorInfoToolWindow : ToolWindowPane
|
||||
{
|
||||
private IRazorEngineAssemblyResolver _assemblyResolver;
|
||||
private ProjectExtensibilityConfigurationFactory _configurationFactory;
|
||||
private IRazorEngineDocumentGenerator _documentGenerator;
|
||||
private IRazorEngineDirectiveResolver _directiveResolver;
|
||||
private TagHelperResolver _tagHelperResolver;
|
||||
|
|
@ -35,7 +36,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
|
||||
var componentModel = (IComponentModel)GetService(typeof(SComponentModel));
|
||||
|
||||
_assemblyResolver = componentModel.GetService<IRazorEngineAssemblyResolver>();
|
||||
_configurationFactory = componentModel.GetService<ProjectExtensibilityConfigurationFactory>();
|
||||
_documentGenerator = componentModel.GetService<IRazorEngineDocumentGenerator>();
|
||||
_directiveResolver = componentModel.GetService<IRazorEngineDirectiveResolver>();
|
||||
_tagHelperResolver = componentModel.GetService<TagHelperResolver>();
|
||||
|
|
@ -64,7 +65,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
return;
|
||||
}
|
||||
|
||||
var viewModel = new RazorInfoViewModel(this, _workspace, _assemblyResolver, _directiveResolver, _tagHelperResolver, _documentGenerator, OnException);
|
||||
var viewModel = new RazorInfoViewModel(this, _workspace, _configurationFactory, _directiveResolver, _tagHelperResolver, _documentGenerator, OnException);
|
||||
foreach (var project in solution.Projects)
|
||||
{
|
||||
if (project.Language == LanguageNames.CSharp)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Linq;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
using Microsoft.VisualStudio.LanguageServices;
|
||||
using Microsoft.VisualStudio.LanguageServices.Razor;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
|
|
@ -22,7 +23,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
{
|
||||
internal class RazorInfoViewModel : NotifyPropertyChanged
|
||||
{
|
||||
private readonly IRazorEngineAssemblyResolver _assemblyResolver;
|
||||
private readonly ProjectExtensibilityConfigurationFactory _configurationFactory;
|
||||
private readonly IRazorEngineDirectiveResolver _directiveResolver;
|
||||
private readonly IRazorEngineDocumentGenerator _documentGenerator;
|
||||
private readonly TagHelperResolver _tagHelperResolver;
|
||||
|
|
@ -41,7 +42,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
public RazorInfoViewModel(
|
||||
IServiceProvider services,
|
||||
Workspace workspace,
|
||||
IRazorEngineAssemblyResolver assemblyResolver,
|
||||
ProjectExtensibilityConfigurationFactory configurationFactory,
|
||||
IRazorEngineDirectiveResolver directiveResolver,
|
||||
TagHelperResolver tagHelperResolver,
|
||||
IRazorEngineDocumentGenerator documentGenerator,
|
||||
|
|
@ -49,7 +50,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
{
|
||||
_services = services;
|
||||
_workspace = workspace;
|
||||
_assemblyResolver = assemblyResolver;
|
||||
_configurationFactory = configurationFactory;
|
||||
_directiveResolver = directiveResolver;
|
||||
_tagHelperResolver = tagHelperResolver;
|
||||
_documentGenerator = documentGenerator;
|
||||
|
|
@ -169,7 +170,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
var project = solution.GetProject(projectViewModel.Id);
|
||||
|
||||
var documents = GetCshtmlDocuments(project);
|
||||
var assemblies = await _assemblyResolver.GetRazorEngineAssembliesAsync(project);
|
||||
var configuration = await _configurationFactory.GetConfigurationAsync(project);
|
||||
|
||||
var directives = await _directiveResolver.GetRazorEngineDirectivesAsync(_workspace, project);
|
||||
var assemblyFilters = project.MetadataReferences
|
||||
|
|
@ -182,7 +183,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
|||
|
||||
CurrentProjectInfo = new ProjectInfoViewModel()
|
||||
{
|
||||
Assemblies = new ObservableCollection<AssemblyViewModel>(assemblies.Select(a => new AssemblyViewModel(a))),
|
||||
Assemblies = new ObservableCollection<AssemblyViewModel>(configuration.Assemblies.Select(a => new AssemblyViewModel(a))),
|
||||
Directives = new ObservableCollection<DirectiveViewModel>(directives.Select(d => new DirectiveViewModel(d))),
|
||||
Documents = new ObservableCollection<DocumentViewModel>(documents.Select(d => new DocumentViewModel(d))),
|
||||
TagHelpers = new ObservableCollection<TagHelperViewModel>(resolutionResult.Descriptors.Select(t => new TagHelperViewModel(t))),
|
||||
|
|
|
|||
Loading…
Reference in New Issue