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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#if RAZOR_EXTENSION_DEVELOPER_MODE
|
#if RAZOR_EXTENSION_DEVELOPER_MODE
|
||||||
using Microsoft.VisualStudio.LanguageServices.Razor;
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
|
|
||||||
namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
{
|
{
|
||||||
public class AssemblyViewModel : NotifyPropertyChanged
|
public class AssemblyViewModel : NotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private readonly RazorEngineAssembly _assembly;
|
private readonly ProjectExtensibilityAssembly _assembly;
|
||||||
|
|
||||||
internal AssemblyViewModel(RazorEngineAssembly assembly)
|
internal AssemblyViewModel(ProjectExtensibilityAssembly assembly)
|
||||||
{
|
{
|
||||||
_assembly = assembly;
|
_assembly = assembly;
|
||||||
|
|
||||||
Name = _assembly.Identity.GetDisplayName();
|
Name = _assembly.Identity.GetDisplayName();
|
||||||
FilePath = assembly.FilePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
public string FilePath { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -6,6 +6,7 @@ using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.ComponentModelHost;
|
using Microsoft.VisualStudio.ComponentModelHost;
|
||||||
using Microsoft.VisualStudio.LanguageServices;
|
using Microsoft.VisualStudio.LanguageServices;
|
||||||
using Microsoft.VisualStudio.LanguageServices.Razor;
|
using Microsoft.VisualStudio.LanguageServices.Razor;
|
||||||
|
|
@ -17,7 +18,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
[Guid("079e9499-d150-40af-8876-3047f7942c2a")]
|
[Guid("079e9499-d150-40af-8876-3047f7942c2a")]
|
||||||
public class RazorInfoToolWindow : ToolWindowPane
|
public class RazorInfoToolWindow : ToolWindowPane
|
||||||
{
|
{
|
||||||
private IRazorEngineAssemblyResolver _assemblyResolver;
|
private ProjectExtensibilityConfigurationFactory _configurationFactory;
|
||||||
private IRazorEngineDocumentGenerator _documentGenerator;
|
private IRazorEngineDocumentGenerator _documentGenerator;
|
||||||
private IRazorEngineDirectiveResolver _directiveResolver;
|
private IRazorEngineDirectiveResolver _directiveResolver;
|
||||||
private TagHelperResolver _tagHelperResolver;
|
private TagHelperResolver _tagHelperResolver;
|
||||||
|
|
@ -35,7 +36,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
|
|
||||||
var componentModel = (IComponentModel)GetService(typeof(SComponentModel));
|
var componentModel = (IComponentModel)GetService(typeof(SComponentModel));
|
||||||
|
|
||||||
_assemblyResolver = componentModel.GetService<IRazorEngineAssemblyResolver>();
|
_configurationFactory = componentModel.GetService<ProjectExtensibilityConfigurationFactory>();
|
||||||
_documentGenerator = componentModel.GetService<IRazorEngineDocumentGenerator>();
|
_documentGenerator = componentModel.GetService<IRazorEngineDocumentGenerator>();
|
||||||
_directiveResolver = componentModel.GetService<IRazorEngineDirectiveResolver>();
|
_directiveResolver = componentModel.GetService<IRazorEngineDirectiveResolver>();
|
||||||
_tagHelperResolver = componentModel.GetService<TagHelperResolver>();
|
_tagHelperResolver = componentModel.GetService<TagHelperResolver>();
|
||||||
|
|
@ -64,7 +65,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
return;
|
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)
|
foreach (var project in solution.Projects)
|
||||||
{
|
{
|
||||||
if (project.Language == LanguageNames.CSharp)
|
if (project.Language == LanguageNames.CSharp)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.LanguageServices;
|
using Microsoft.VisualStudio.LanguageServices;
|
||||||
using Microsoft.VisualStudio.LanguageServices.Razor;
|
using Microsoft.VisualStudio.LanguageServices.Razor;
|
||||||
using Microsoft.VisualStudio.Shell;
|
using Microsoft.VisualStudio.Shell;
|
||||||
|
|
@ -22,7 +23,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
{
|
{
|
||||||
internal class RazorInfoViewModel : NotifyPropertyChanged
|
internal class RazorInfoViewModel : NotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private readonly IRazorEngineAssemblyResolver _assemblyResolver;
|
private readonly ProjectExtensibilityConfigurationFactory _configurationFactory;
|
||||||
private readonly IRazorEngineDirectiveResolver _directiveResolver;
|
private readonly IRazorEngineDirectiveResolver _directiveResolver;
|
||||||
private readonly IRazorEngineDocumentGenerator _documentGenerator;
|
private readonly IRazorEngineDocumentGenerator _documentGenerator;
|
||||||
private readonly TagHelperResolver _tagHelperResolver;
|
private readonly TagHelperResolver _tagHelperResolver;
|
||||||
|
|
@ -41,7 +42,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
public RazorInfoViewModel(
|
public RazorInfoViewModel(
|
||||||
IServiceProvider services,
|
IServiceProvider services,
|
||||||
Workspace workspace,
|
Workspace workspace,
|
||||||
IRazorEngineAssemblyResolver assemblyResolver,
|
ProjectExtensibilityConfigurationFactory configurationFactory,
|
||||||
IRazorEngineDirectiveResolver directiveResolver,
|
IRazorEngineDirectiveResolver directiveResolver,
|
||||||
TagHelperResolver tagHelperResolver,
|
TagHelperResolver tagHelperResolver,
|
||||||
IRazorEngineDocumentGenerator documentGenerator,
|
IRazorEngineDocumentGenerator documentGenerator,
|
||||||
|
|
@ -49,7 +50,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
{
|
{
|
||||||
_services = services;
|
_services = services;
|
||||||
_workspace = workspace;
|
_workspace = workspace;
|
||||||
_assemblyResolver = assemblyResolver;
|
_configurationFactory = configurationFactory;
|
||||||
_directiveResolver = directiveResolver;
|
_directiveResolver = directiveResolver;
|
||||||
_tagHelperResolver = tagHelperResolver;
|
_tagHelperResolver = tagHelperResolver;
|
||||||
_documentGenerator = documentGenerator;
|
_documentGenerator = documentGenerator;
|
||||||
|
|
@ -169,7 +170,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
var project = solution.GetProject(projectViewModel.Id);
|
var project = solution.GetProject(projectViewModel.Id);
|
||||||
|
|
||||||
var documents = GetCshtmlDocuments(project);
|
var documents = GetCshtmlDocuments(project);
|
||||||
var assemblies = await _assemblyResolver.GetRazorEngineAssembliesAsync(project);
|
var configuration = await _configurationFactory.GetConfigurationAsync(project);
|
||||||
|
|
||||||
var directives = await _directiveResolver.GetRazorEngineDirectivesAsync(_workspace, project);
|
var directives = await _directiveResolver.GetRazorEngineDirectivesAsync(_workspace, project);
|
||||||
var assemblyFilters = project.MetadataReferences
|
var assemblyFilters = project.MetadataReferences
|
||||||
|
|
@ -182,7 +183,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo
|
||||||
|
|
||||||
CurrentProjectInfo = new ProjectInfoViewModel()
|
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))),
|
Directives = new ObservableCollection<DirectiveViewModel>(directives.Select(d => new DirectiveViewModel(d))),
|
||||||
Documents = new ObservableCollection<DocumentViewModel>(documents.Select(d => new DocumentViewModel(d))),
|
Documents = new ObservableCollection<DocumentViewModel>(documents.Select(d => new DocumentViewModel(d))),
|
||||||
TagHelpers = new ObservableCollection<TagHelperViewModel>(resolutionResult.Descriptors.Select(t => new TagHelperViewModel(t))),
|
TagHelpers = new ObservableCollection<TagHelperViewModel>(resolutionResult.Descriptors.Select(t => new TagHelperViewModel(t))),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue