зеркало из https://github.com/dotnet/razor.git
Change VisualStudioDescriptionFactory to interface
This commit is contained in:
Родитель
4ec65f6fcc
Коммит
7c378c8b75
|
@ -1,115 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
using Microsoft.CodeAnalysis.Razor.Tooltip;
|
||||
using Microsoft.VisualStudio.Core.Imaging;
|
||||
using Microsoft.VisualStudio.Text.Adornments;
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor.Completion;
|
||||
|
||||
[Shared]
|
||||
[Export(typeof(VisualStudioDescriptionFactory))]
|
||||
internal class DefaultVisualStudioDescriptionFactory : VisualStudioDescriptionFactory
|
||||
{
|
||||
// Internal for testing
|
||||
internal static readonly ContainerElement SeparatorElement = new(
|
||||
ContainerElementStyle.Wrapped,
|
||||
new ClassifiedTextElement(
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Comment, "------------")));
|
||||
|
||||
// Hardcoding the Guid here to avoid a reference to Microsoft.VisualStudio.ImageCatalog.dll
|
||||
// that is not present in Visual Studio for Mac
|
||||
private static readonly Guid s_imageCatalogGuid = new("{ae27a6b0-e345-4288-96df-5eaf394ee369}");
|
||||
private static readonly ImageElement s_propertyGlyph = new(
|
||||
new ImageId(s_imageCatalogGuid, 2429), // KnownImageIds.Type = 2429
|
||||
"Razor Attribute Glyph");
|
||||
private static readonly ClassifiedTextRun s_spaceLiteral = new(PredefinedClassificationNames.Literal, " ");
|
||||
private static readonly ClassifiedTextRun s_dotLiteral = new(PredefinedClassificationNames.Literal, ".");
|
||||
|
||||
public override ContainerElement CreateClassifiedDescription(AggregateBoundAttributeDescription completionDescription)
|
||||
{
|
||||
if (completionDescription is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(completionDescription));
|
||||
}
|
||||
|
||||
var descriptionElements = new List<object>();
|
||||
foreach (var descriptionInfo in completionDescription.DescriptionInfos)
|
||||
{
|
||||
if (descriptionElements.Count > 0)
|
||||
{
|
||||
descriptionElements.Add(SeparatorElement);
|
||||
}
|
||||
|
||||
var returnTypeClassification = PredefinedClassificationNames.Type;
|
||||
if (TypeNameStringResolver.TryGetSimpleName(descriptionInfo.ReturnTypeName, out var returnTypeName))
|
||||
{
|
||||
returnTypeClassification = PredefinedClassificationNames.Keyword;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnTypeName = descriptionInfo.ReturnTypeName;
|
||||
}
|
||||
|
||||
var tagHelperTypeName = descriptionInfo.TypeName;
|
||||
var tagHelperTypeNamePrefix = string.Empty;
|
||||
var tagHelperTypeNameProper = tagHelperTypeName;
|
||||
|
||||
var lastDot = tagHelperTypeName.LastIndexOf('.');
|
||||
if (lastDot > 0)
|
||||
{
|
||||
var afterLastDot = lastDot + 1;
|
||||
|
||||
// We're pulling apart the type name so the prefix looks like:
|
||||
//
|
||||
// Microsoft.AspnetCore.Components.
|
||||
tagHelperTypeNamePrefix = tagHelperTypeName[..afterLastDot];
|
||||
|
||||
// And the type name looks like BindBinds
|
||||
tagHelperTypeNameProper = tagHelperTypeName[afterLastDot..];
|
||||
}
|
||||
|
||||
descriptionElements.Add(
|
||||
new ContainerElement(
|
||||
ContainerElementStyle.Wrapped,
|
||||
s_propertyGlyph,
|
||||
new ClassifiedTextElement(
|
||||
new ClassifiedTextRun(returnTypeClassification, returnTypeName),
|
||||
s_spaceLiteral,
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Literal, tagHelperTypeNamePrefix),
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Type, tagHelperTypeNameProper),
|
||||
s_dotLiteral,
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Identifier, descriptionInfo.PropertyName))));
|
||||
|
||||
if (descriptionInfo.Documentation != null)
|
||||
{
|
||||
descriptionElements.Add(
|
||||
new ContainerElement(
|
||||
ContainerElementStyle.Wrapped,
|
||||
new ClassifiedTextElement(
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.NaturalLanguage, descriptionInfo.Documentation))));
|
||||
}
|
||||
}
|
||||
|
||||
var descriptionContainer = new ContainerElement(ContainerElementStyle.Stacked, descriptionElements);
|
||||
return descriptionContainer;
|
||||
}
|
||||
|
||||
private static class PredefinedClassificationNames
|
||||
{
|
||||
public const string Keyword = "keyword";
|
||||
|
||||
public const string Literal = "literal";
|
||||
|
||||
public const string Type = "Type";
|
||||
|
||||
public const string Identifier = "identifier";
|
||||
|
||||
public const string Comment = "comment";
|
||||
|
||||
public const string NaturalLanguage = "natural language";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.CodeAnalysis.Razor.Tooltip;
|
||||
using Microsoft.VisualStudio.Text.Adornments;
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor.Completion;
|
||||
|
||||
internal interface IVisualStudioDescriptionFactory
|
||||
{
|
||||
ContainerElement CreateClassifiedDescription(AggregateBoundAttributeDescription description);
|
||||
}
|
|
@ -40,7 +40,7 @@ internal class RazorDirectiveAttributeCompletionSource : IAsyncCompletionSource
|
|||
private readonly VisualStudioRazorParser _parser;
|
||||
private readonly IRazorCompletionFactsService _completionFactsService;
|
||||
private readonly ICompletionBroker _completionBroker;
|
||||
private readonly VisualStudioDescriptionFactory _descriptionFactory;
|
||||
private readonly IVisualStudioDescriptionFactory _descriptionFactory;
|
||||
private readonly JoinableTaskFactory _joinableTaskFactory;
|
||||
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
|
||||
|
||||
|
@ -49,7 +49,7 @@ internal class RazorDirectiveAttributeCompletionSource : IAsyncCompletionSource
|
|||
VisualStudioRazorParser parser,
|
||||
IRazorCompletionFactsService completionFactsService,
|
||||
ICompletionBroker completionBroker,
|
||||
VisualStudioDescriptionFactory descriptionFactory,
|
||||
IVisualStudioDescriptionFactory descriptionFactory,
|
||||
JoinableTaskFactory joinableTaskFactory)
|
||||
{
|
||||
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
|
||||
|
|
|
@ -25,7 +25,7 @@ internal class RazorDirectiveAttributeCompletionSourceProvider : IAsyncCompletio
|
|||
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
|
||||
private readonly IRazorCompletionFactsService _completionFactsService;
|
||||
private readonly ICompletionBroker _completionBroker;
|
||||
private readonly VisualStudioDescriptionFactory _descriptionFactory;
|
||||
private readonly IVisualStudioDescriptionFactory _descriptionFactory;
|
||||
private readonly JoinableTaskContext _joinableTaskContext;
|
||||
|
||||
[ImportingConstructor]
|
||||
|
@ -33,7 +33,7 @@ internal class RazorDirectiveAttributeCompletionSourceProvider : IAsyncCompletio
|
|||
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
|
||||
IRazorCompletionFactsService completionFactsService,
|
||||
ICompletionBroker completionBroker,
|
||||
VisualStudioDescriptionFactory descriptionFactory,
|
||||
IVisualStudioDescriptionFactory descriptionFactory,
|
||||
JoinableTaskContext joinableTaskContext)
|
||||
{
|
||||
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
|
||||
|
|
|
@ -1,12 +1,114 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
using Microsoft.CodeAnalysis.Razor.Tooltip;
|
||||
using Microsoft.VisualStudio.Core.Imaging;
|
||||
using Microsoft.VisualStudio.Text.Adornments;
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor.Completion;
|
||||
|
||||
internal abstract class VisualStudioDescriptionFactory
|
||||
[Shared]
|
||||
[Export(typeof(IVisualStudioDescriptionFactory))]
|
||||
internal class VisualStudioDescriptionFactory : IVisualStudioDescriptionFactory
|
||||
{
|
||||
public abstract ContainerElement CreateClassifiedDescription(AggregateBoundAttributeDescription completionDescription);
|
||||
// Internal for testing
|
||||
internal static readonly ContainerElement SeparatorElement = new(
|
||||
ContainerElementStyle.Wrapped,
|
||||
new ClassifiedTextElement(
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Comment, "------------")));
|
||||
|
||||
// Hardcoding the Guid here to avoid a reference to Microsoft.VisualStudio.ImageCatalog.dll
|
||||
// that is not present in Visual Studio for Mac
|
||||
private static readonly Guid s_imageCatalogGuid = new("{ae27a6b0-e345-4288-96df-5eaf394ee369}");
|
||||
private static readonly ImageElement s_propertyGlyph = new(
|
||||
new ImageId(s_imageCatalogGuid, 2429), // KnownImageIds.Type = 2429
|
||||
"Razor Attribute Glyph");
|
||||
private static readonly ClassifiedTextRun s_spaceLiteral = new(PredefinedClassificationNames.Literal, " ");
|
||||
private static readonly ClassifiedTextRun s_dotLiteral = new(PredefinedClassificationNames.Literal, ".");
|
||||
|
||||
public ContainerElement CreateClassifiedDescription(AggregateBoundAttributeDescription description)
|
||||
{
|
||||
if (description is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(description));
|
||||
}
|
||||
|
||||
var descriptionElements = new List<object>();
|
||||
foreach (var descriptionInfo in description.DescriptionInfos)
|
||||
{
|
||||
if (descriptionElements.Count > 0)
|
||||
{
|
||||
descriptionElements.Add(SeparatorElement);
|
||||
}
|
||||
|
||||
var returnTypeClassification = PredefinedClassificationNames.Type;
|
||||
if (TypeNameStringResolver.TryGetSimpleName(descriptionInfo.ReturnTypeName, out var returnTypeName))
|
||||
{
|
||||
returnTypeClassification = PredefinedClassificationNames.Keyword;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnTypeName = descriptionInfo.ReturnTypeName;
|
||||
}
|
||||
|
||||
var tagHelperTypeName = descriptionInfo.TypeName;
|
||||
var tagHelperTypeNamePrefix = string.Empty;
|
||||
var tagHelperTypeNameProper = tagHelperTypeName;
|
||||
|
||||
var lastDot = tagHelperTypeName.LastIndexOf('.');
|
||||
if (lastDot > 0)
|
||||
{
|
||||
var afterLastDot = lastDot + 1;
|
||||
|
||||
// We're pulling apart the type name so the prefix looks like:
|
||||
//
|
||||
// Microsoft.AspnetCore.Components.
|
||||
tagHelperTypeNamePrefix = tagHelperTypeName[..afterLastDot];
|
||||
|
||||
// And the type name looks like BindBinds
|
||||
tagHelperTypeNameProper = tagHelperTypeName[afterLastDot..];
|
||||
}
|
||||
|
||||
descriptionElements.Add(
|
||||
new ContainerElement(
|
||||
ContainerElementStyle.Wrapped,
|
||||
s_propertyGlyph,
|
||||
new ClassifiedTextElement(
|
||||
new ClassifiedTextRun(returnTypeClassification, returnTypeName),
|
||||
s_spaceLiteral,
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Literal, tagHelperTypeNamePrefix),
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Type, tagHelperTypeNameProper),
|
||||
s_dotLiteral,
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.Identifier, descriptionInfo.PropertyName))));
|
||||
|
||||
if (descriptionInfo.Documentation is { } documentation)
|
||||
{
|
||||
descriptionElements.Add(
|
||||
new ContainerElement(
|
||||
ContainerElementStyle.Wrapped,
|
||||
new ClassifiedTextElement(
|
||||
new ClassifiedTextRun(PredefinedClassificationNames.NaturalLanguage, documentation))));
|
||||
}
|
||||
}
|
||||
|
||||
return new ContainerElement(ContainerElementStyle.Stacked, descriptionElements);
|
||||
}
|
||||
|
||||
private static class PredefinedClassificationNames
|
||||
{
|
||||
public const string Keyword = "keyword";
|
||||
|
||||
public const string Literal = "literal";
|
||||
|
||||
public const string Type = "Type";
|
||||
|
||||
public const string Identifier = "identifier";
|
||||
|
||||
public const string Comment = "comment";
|
||||
|
||||
public const string NaturalLanguage = "natural language";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
public void CreateClassifiedDescription_SingleDescription_NoSeparator()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
@ -33,14 +33,14 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
var result = factory.CreateClassifiedDescription(description);
|
||||
|
||||
// Assert
|
||||
Assert.DoesNotContain(DefaultVisualStudioDescriptionFactory.SeparatorElement, result.Elements);
|
||||
Assert.DoesNotContain(VisualStudioDescriptionFactory.SeparatorElement, result.Elements);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateClassifiedDescription_MultipleDescription_Separator()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
@ -51,14 +51,14 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
var result = factory.CreateClassifiedDescription(description);
|
||||
|
||||
// Assert
|
||||
Assert.Contains(DefaultVisualStudioDescriptionFactory.SeparatorElement, result.Elements);
|
||||
Assert.Contains(VisualStudioDescriptionFactory.SeparatorElement, result.Elements);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateClassifiedDescription_RepresentsReturnType()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
@ -76,7 +76,7 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
public void CreateClassifiedDescription_RepresentsTypeName()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
@ -94,7 +94,7 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
public void CreateClassifiedDescription_RepresentsPropertyName()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
@ -112,7 +112,7 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
public void CreateClassifiedDescription_RepresentsDocumentation()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("TheReturnType", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
@ -130,7 +130,7 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
public void CreateClassifiedDescription_CanSimplifyKeywordReturnTypes()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("System.String", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
@ -149,7 +149,7 @@ public class DefaultVisualStudioDescriptionFactoryTest : TestBase
|
|||
public void CreateClassifiedDescription_CanRepresentMultipleDescriptions()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultVisualStudioDescriptionFactory();
|
||||
var factory = new VisualStudioDescriptionFactory();
|
||||
var description = new AggregateBoundAttributeDescription(new[]
|
||||
{
|
||||
new BoundAttributeDescriptionInfo("System.String", "TheTypeName", "ThePropertyName", "The documentation"),
|
||||
|
|
|
@ -46,7 +46,7 @@ public class RazorDirectiveAttributeCompletionSourceTest : ProjectSnapshotManage
|
|||
// Arrange
|
||||
var expectedResult = new ContainerElement(ContainerElementStyle.Wrapped);
|
||||
var description = new AggregateBoundAttributeDescription(Array.Empty<BoundAttributeDescriptionInfo>());
|
||||
var descriptionFactory = Mock.Of<VisualStudioDescriptionFactory>(factory => factory.CreateClassifiedDescription(description) == expectedResult, MockBehavior.Strict);
|
||||
var descriptionFactory = Mock.Of<IVisualStudioDescriptionFactory>(factory => factory.CreateClassifiedDescription(description) == expectedResult, MockBehavior.Strict);
|
||||
var source = new RazorDirectiveAttributeCompletionSource(
|
||||
Dispatcher,
|
||||
Mock.Of<VisualStudioRazorParser>(MockBehavior.Strict),
|
||||
|
@ -242,7 +242,7 @@ public class RazorDirectiveAttributeCompletionSourceTest : ProjectSnapshotManage
|
|||
Mock.Of<VisualStudioRazorParser>(MockBehavior.Strict),
|
||||
Mock.Of<IRazorCompletionFactsService>(MockBehavior.Strict),
|
||||
Mock.Of<ICompletionBroker>(MockBehavior.Strict),
|
||||
Mock.Of<VisualStudioDescriptionFactory>(MockBehavior.Strict),
|
||||
Mock.Of<IVisualStudioDescriptionFactory>(MockBehavior.Strict),
|
||||
JoinableTaskFactory);
|
||||
return source;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче