From 8c17375be017d28e63cf98ff50f9c50bf8a7ffb6 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Thu, 16 Feb 2017 16:10:08 -0800 Subject: [PATCH] Surface TagHelper resolution errors. - Decided to not expose the resolutions errors in the Razor extension. If we feel that it's good debug information we can add it later. - Added a `TagHelperResolutionResult` type to Razor.Workspaces so it can be used in the language and remote service. #1014 --- .../DefaultTagHelperResolver.cs | 18 +++++++++++----- .../TagHelperResolutionResult.cs | 21 +++++++++++++++++++ .../TagHelperResolver.cs | 6 ++---- .../RazorLanguageService.cs | 6 +++--- .../DefaultTagHelperResolver.cs | 10 +++++---- .../ITagHelperResolver.cs | 5 ++--- .../RazorInfo/RazorInfoViewModel.cs | 4 ++-- 7 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolutionResult.cs diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/DefaultTagHelperResolver.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/DefaultTagHelperResolver.cs index 9d2540d65b..3b47b09c6c 100644 --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/DefaultTagHelperResolver.cs +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/DefaultTagHelperResolver.cs @@ -17,15 +17,23 @@ namespace Microsoft.CodeAnalysis.Razor public bool DesignTime { get; } - public override IReadOnlyList GetTagHelpers(Compilation compilation) + public override TagHelperResolutionResult GetTagHelpers(Compilation compilation) { - var results = new List(); + var descriptors = new List(); var errors = new ErrorSink(); - VisitTagHelpers(compilation, results, errors); - VisitViewComponents(compilation, results, errors); + VisitTagHelpers(compilation, descriptors, errors); + VisitViewComponents(compilation, descriptors, errors); - return results; + var diagnostics = new List(); + for (var i = 0; i < errors.Errors.Count; i++) + { + var diagnostic = RazorDiagnostic.Create(errors.Errors[i]); + diagnostics.Add(diagnostic); + } + var resolutionResult = new TagHelperResolutionResult(descriptors, diagnostics); + + return resolutionResult; } private void VisitTagHelpers(Compilation compilation, List results, ErrorSink errors) diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolutionResult.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolutionResult.cs new file mode 100644 index 0000000000..40067bb464 --- /dev/null +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolutionResult.cs @@ -0,0 +1,21 @@ +// 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.Collections.Generic; +using Microsoft.AspNetCore.Razor.Evolution; + +namespace Microsoft.CodeAnalysis.Razor +{ + public sealed class TagHelperResolutionResult + { + public TagHelperResolutionResult(IReadOnlyList descriptors, IReadOnlyList diagnostics) + { + Descriptors = descriptors; + Diagnostics = diagnostics; + } + + public IReadOnlyList Descriptors { get; } + + public IReadOnlyList Diagnostics { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs index 29945f8d86..a16f46400b 100644 --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs @@ -1,19 +1,17 @@ // 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.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.Evolution; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.Razor { internal abstract class TagHelperResolver : ILanguageService { - public abstract IReadOnlyList GetTagHelpers(Compilation compilation); + public abstract TagHelperResolutionResult GetTagHelpers(Compilation compilation); - public virtual async Task> GetTagHelpersAsync( + public virtual async Task GetTagHelpersAsync( Project project, CancellationToken cancellationToken = default(CancellationToken)) { diff --git a/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs b/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs index 69a9fad93e..f7a5eb1c37 100644 --- a/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs +++ b/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs @@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.Remote.Razor { } - public async Task> GetTagHelpersAsync(Guid projectIdBytes, string projectDebugName, CancellationToken cancellationToken = default(CancellationToken)) + public async Task GetTagHelpersAsync(Guid projectIdBytes, string projectDebugName, CancellationToken cancellationToken = default(CancellationToken)) { var projectId = ProjectId.CreateFromSerialized(projectIdBytes, projectDebugName); @@ -28,9 +28,9 @@ namespace Microsoft.CodeAnalysis.Remote.Razor var project = solution.GetProject(projectId); var resolver = new DefaultTagHelperResolver(designTime: true); - var results = await resolver.GetTagHelpersAsync(project, cancellationToken).ConfigureAwait(false); + var result = await resolver.GetTagHelpersAsync(project, cancellationToken).ConfigureAwait(false); - return results; + return result; } public Task> GetDirectivesAsync(Guid projectIdBytes, string projectDebugName, CancellationToken cancellationToken = default(CancellationToken)) diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs index 2cd272294d..793d100cb6 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Evolution; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Razor; namespace Microsoft.VisualStudio.LanguageServices.Razor { @@ -17,7 +18,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor [Import] public VisualStudioWorkspace Workspace { get; set; } - public async Task> GetTagHelpersAsync(Project project) + public async Task GetTagHelpersAsync(Project project) { try { @@ -26,13 +27,14 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor { // The OOP host is turned off, so let's do this in process. var resolver = new CodeAnalysis.Razor.DefaultTagHelperResolver(designTime: true); - return await resolver.GetTagHelpersAsync(project, CancellationToken.None).ConfigureAwait(false); + var result = await resolver.GetTagHelpersAsync(project, CancellationToken.None).ConfigureAwait(false); + return result; } using (var session = await client.CreateSessionAsync(project.Solution)) { - var results = await session.InvokeAsync>("GetTagHelpersAsync", new object[] { project.Id.Id, "Foo", }).ConfigureAwait(false); - return results; + var result = await session.InvokeAsync("GetTagHelpersAsync", new object[] { project.Id.Id, "Foo", }).ConfigureAwait(false); + return result; } } catch (Exception exception) diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/ITagHelperResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/ITagHelperResolver.cs index 18dfc759af..3ea134b9c2 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/ITagHelperResolver.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/ITagHelperResolver.cs @@ -1,15 +1,14 @@ // 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.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.Evolution; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Razor; namespace Microsoft.VisualStudio.LanguageServices.Razor { public interface ITagHelperResolver { - Task> GetTagHelpersAsync(Project project); + Task GetTagHelpersAsync(Project project); } } diff --git a/tooling/Microsoft.VisualStudio.RazorExtension/RazorInfo/RazorInfoViewModel.cs b/tooling/Microsoft.VisualStudio.RazorExtension/RazorInfo/RazorInfoViewModel.cs index f9052c6d75..de21bd9fef 100644 --- a/tooling/Microsoft.VisualStudio.RazorExtension/RazorInfo/RazorInfoViewModel.cs +++ b/tooling/Microsoft.VisualStudio.RazorExtension/RazorInfo/RazorInfoViewModel.cs @@ -169,7 +169,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo var assemblies = await _assemblyResolver.GetRazorEngineAssembliesAsync(project); var directives = await _directiveResolver.GetRazorEngineDirectivesAsync(_workspace, project); - var tagHelpers = await _tagHelperResolver.GetTagHelpersAsync(project); + var resolutionResult = await _tagHelperResolver.GetTagHelpersAsync(project); var files = GetCshtmlDocuments(project); @@ -178,7 +178,7 @@ namespace Microsoft.VisualStudio.RazorExtension.RazorInfo Assemblies = new ObservableCollection(assemblies.Select(a => new AssemblyViewModel(a))), Directives = new ObservableCollection(directives.Select(d => new DirectiveViewModel(d))), Documents = new ObservableCollection(documents.Select(d => new DocumentViewModel(d))), - TagHelpers = new ObservableCollection(tagHelpers.Select(t => new TagHelperViewModel(t))), + TagHelpers = new ObservableCollection(resolutionResult.Descriptors.Select(t => new TagHelperViewModel(t))), }; } catch (Exception ex)