diff --git a/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpJsonEmbeddedLanguageBraceMatchingService.cs b/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpJsonBraceMatcher.cs
similarity index 71%
rename from src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpJsonEmbeddedLanguageBraceMatchingService.cs
rename to src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpJsonBraceMatcher.cs
index a99b25263b972..9b3dff1af348a 100644
--- a/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpJsonEmbeddedLanguageBraceMatchingService.cs
+++ b/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpJsonBraceMatcher.cs
@@ -12,13 +12,12 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.EmbeddedLanguages
{
[ExportEmbeddedLanguageBraceMatcher(
- PredefinedEmbeddedLanguageBraceMatcherNames.Json, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Json"), Shared]
- internal sealed class CSharpJsonEmbeddedLanguageBraceMatcher :
- AbstractJsonEmbeddedLanguageBraceMatcher
+ PredefinedEmbeddedLanguageNames.Json, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Json"), Shared]
+ internal sealed class CSharpJsonBraceMatcher : AbstractJsonBraceMatcher
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
- public CSharpJsonEmbeddedLanguageBraceMatcher()
+ public CSharpJsonBraceMatcher()
: base(CSharpEmbeddedLanguagesProvider.Info)
{
}
diff --git a/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpRegexEmbeddedLanguageBraceMatcher.cs b/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpRegexBraceMatcher.cs
similarity index 71%
rename from src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpRegexEmbeddedLanguageBraceMatcher.cs
rename to src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpRegexBraceMatcher.cs
index 80051f0b28bb4..565bc556abe99 100644
--- a/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpRegexEmbeddedLanguageBraceMatcher.cs
+++ b/src/EditorFeatures/CSharp/EmbeddedLanguages/CSharpRegexBraceMatcher.cs
@@ -12,13 +12,12 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.EmbeddedLanguages
{
[ExportEmbeddedLanguageBraceMatcher(
- PredefinedEmbeddedLanguageBraceMatcherNames.Regex, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Regex", "Regexp"), Shared]
- internal sealed class CSharpRegexEmbeddedLanguageBraceMatcher :
- AbstractRegexEmbeddedLanguageBraceMatcher
+ PredefinedEmbeddedLanguageNames.Regex, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Regex", "Regexp"), Shared]
+ internal sealed class CSharpRegexBraceMatcher : AbstractRegexBraceMatcher
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
- public CSharpRegexEmbeddedLanguageBraceMatcher()
+ public CSharpRegexBraceMatcher()
: base(CSharpEmbeddedLanguagesProvider.Info)
{
}
diff --git a/src/EditorFeatures/Core/BraceMatching/PredefinedEmbeddedLanguageBraceMatcherNames.cs b/src/EditorFeatures/Core/BraceMatching/PredefinedEmbeddedLanguageBraceMatcherNames.cs
deleted file mode 100644
index 48ab7824ea75f..0000000000000
--- a/src/EditorFeatures/Core/BraceMatching/PredefinedEmbeddedLanguageBraceMatcherNames.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace Microsoft.CodeAnalysis.BraceMatching
-{
- internal static class PredefinedEmbeddedLanguageBraceMatcherNames
- {
- public const string Regex = nameof(Regex);
-
- public const string Json = nameof(Json);
- }
-}
diff --git a/src/EditorFeatures/Core/EmbeddedLanguages/Json/AbstractJsonEmbeddedLanguageBraceMatcher.cs b/src/EditorFeatures/Core/EmbeddedLanguages/Json/AbstractJsonBraceMatcher.cs
similarity index 95%
rename from src/EditorFeatures/Core/EmbeddedLanguages/Json/AbstractJsonEmbeddedLanguageBraceMatcher.cs
rename to src/EditorFeatures/Core/EmbeddedLanguages/Json/AbstractJsonBraceMatcher.cs
index 631b407a2f847..abf09b90b5673 100644
--- a/src/EditorFeatures/Core/EmbeddedLanguages/Json/AbstractJsonEmbeddedLanguageBraceMatcher.cs
+++ b/src/EditorFeatures/Core/EmbeddedLanguages/Json/AbstractJsonBraceMatcher.cs
@@ -18,11 +18,11 @@ namespace Microsoft.CodeAnalysis.EmbeddedLanguages.Json
///
/// Brace matcher impl for embedded json strings.
///
- internal abstract class AbstractJsonEmbeddedLanguageBraceMatcher : IEmbeddedLanguageBraceMatcher
+ internal abstract class AbstractJsonBraceMatcher : IEmbeddedLanguageBraceMatcher
{
private readonly EmbeddedLanguageInfo _info;
- public AbstractJsonEmbeddedLanguageBraceMatcher(EmbeddedLanguageInfo info)
+ public AbstractJsonBraceMatcher(EmbeddedLanguageInfo info)
=> _info = info;
public BraceMatchingResult? FindBraces(
diff --git a/src/EditorFeatures/Core/EmbeddedLanguages/RegularExpressions/AbstractRegexEmbeddedLanguageBraceMatcher.cs b/src/EditorFeatures/Core/EmbeddedLanguages/RegularExpressions/AbstractRegexBraceMatcher.cs
similarity index 96%
rename from src/EditorFeatures/Core/EmbeddedLanguages/RegularExpressions/AbstractRegexEmbeddedLanguageBraceMatcher.cs
rename to src/EditorFeatures/Core/EmbeddedLanguages/RegularExpressions/AbstractRegexBraceMatcher.cs
index 0a84d0168c2ab..9d9950a12a127 100644
--- a/src/EditorFeatures/Core/EmbeddedLanguages/RegularExpressions/AbstractRegexEmbeddedLanguageBraceMatcher.cs
+++ b/src/EditorFeatures/Core/EmbeddedLanguages/RegularExpressions/AbstractRegexBraceMatcher.cs
@@ -19,11 +19,11 @@ namespace Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions
///
/// Brace matching impl for embedded regex strings.
///
- internal abstract class AbstractRegexEmbeddedLanguageBraceMatcher : IEmbeddedLanguageBraceMatcher
+ internal abstract class AbstractRegexBraceMatcher : IEmbeddedLanguageBraceMatcher
{
private readonly EmbeddedLanguageInfo _info;
- protected AbstractRegexEmbeddedLanguageBraceMatcher(EmbeddedLanguageInfo info)
+ protected AbstractRegexBraceMatcher(EmbeddedLanguageInfo info)
=> _info = info;
public BraceMatchingResult? FindBraces(
diff --git a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicJsonEmbeddedLanguageBraceMatcher.vb b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicJsonBraceMatcher.vb
similarity index 77%
rename from src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicJsonEmbeddedLanguageBraceMatcher.vb
rename to src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicJsonBraceMatcher.vb
index 85dc5b50cc612..75432ae869ca1 100644
--- a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicJsonEmbeddedLanguageBraceMatcher.vb
+++ b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicJsonBraceMatcher.vb
@@ -10,9 +10,9 @@ Imports Microsoft.CodeAnalysis.VisualBasic.EmbeddedLanguages.LanguageServices
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EmbeddedLanguages
- Friend Class VisualBasicJsonEmbeddedLanguageBraceMatcher
- Inherits AbstractJsonEmbeddedLanguageBraceMatcher
+ PredefinedEmbeddedLanguageNames.Json, LanguageNames.VisualBasic, True, "Json"), [Shared]>
+ Friend Class VisualBasicJsonBraceMatcher
+ Inherits AbstractJsonBraceMatcher
diff --git a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicRegexEmbeddedLanguageBraceMatcher.vb b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicRegexBraceMatcher.vb
similarity index 76%
rename from src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicRegexEmbeddedLanguageBraceMatcher.vb
rename to src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicRegexBraceMatcher.vb
index 58205e1a93562..0056a49122cea 100644
--- a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicRegexEmbeddedLanguageBraceMatcher.vb
+++ b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicRegexBraceMatcher.vb
@@ -10,9 +10,9 @@ Imports Microsoft.CodeAnalysis.VisualBasic.EmbeddedLanguages.LanguageServices
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EmbeddedLanguages
- Friend Class VisualBasicRegexEmbeddedLanguageBraceMatcher
- Inherits AbstractRegexEmbeddedLanguageBraceMatcher
+ PredefinedEmbeddedLanguageNames.Regex, LanguageNames.VisualBasic, True, "Regex", "Regexp"), [Shared]>
+ Friend Class VisualBasicRegexBraceMatcher
+ Inherits AbstractRegexBraceMatcher
diff --git a/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs b/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs
index 970e96da01e6a..729486de888cc 100644
--- a/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs
+++ b/src/Features/CSharp/Portable/DocumentHighlighting/CSharpDocumentHighlightsService.cs
@@ -5,13 +5,17 @@
#nullable disable
using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CSharp.EmbeddedLanguages.LanguageServices;
+using Microsoft.CodeAnalysis.CSharp.LanguageServices;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.DocumentHighlighting;
+using Microsoft.CodeAnalysis.EmbeddedLanguages;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.PooledObjects;
@@ -22,7 +26,12 @@ internal class CSharpDocumentHighlightsService : AbstractDocumentHighlightsServi
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
- public CSharpDocumentHighlightsService()
+ public CSharpDocumentHighlightsService(
+ [ImportMany] IEnumerable> services)
+ : base(LanguageNames.CSharp,
+ CSharpEmbeddedLanguagesProvider.Info,
+ CSharpSyntaxKinds.Instance,
+ services)
{
}
diff --git a/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpJsonEmbeddedLanguageClassifier.cs b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpJsonClassifier.cs
similarity index 74%
rename from src/Features/CSharp/Portable/EmbeddedLanguages/CSharpJsonEmbeddedLanguageClassifier.cs
rename to src/Features/CSharp/Portable/EmbeddedLanguages/CSharpJsonClassifier.cs
index b41771ce0860d..6d82003cca449 100644
--- a/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpJsonEmbeddedLanguageClassifier.cs
+++ b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpJsonClassifier.cs
@@ -12,12 +12,12 @@
namespace Microsoft.CodeAnalysis.CSharp.Features.EmbeddedLanguages
{
[ExportEmbeddedLanguageClassifier(
- PredefinedEmbeddedLanguageClassifierNames.Json, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Json"), Shared]
- internal class CSharpJsonEmbeddedLanguageClassifier : AbstractJsonEmbeddedLanguageClassifier
+ PredefinedEmbeddedLanguageNames.Json, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Json"), Shared]
+ internal class CSharpJsonClassifier : AbstractJsonClassifier
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
- public CSharpJsonEmbeddedLanguageClassifier()
+ public CSharpJsonClassifier()
: base(CSharpEmbeddedLanguagesProvider.Info)
{
}
diff --git a/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexEmbeddedLanguageClassifier.cs b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexClassifier.cs
similarity index 73%
rename from src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexEmbeddedLanguageClassifier.cs
rename to src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexClassifier.cs
index 5cb209d6d72ac..ac68a92c43226 100644
--- a/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexEmbeddedLanguageClassifier.cs
+++ b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexClassifier.cs
@@ -13,14 +13,14 @@ namespace Microsoft.CodeAnalysis.CSharp.Features.EmbeddedLanguages
{
// Order regex classification before json classification. Json lights up on probable-json strings, but we don't
// want that to happen for APIs that are certain to be another language like Regex.
- [ExtensionOrder(Before = PredefinedEmbeddedLanguageClassifierNames.Json)]
+ [ExtensionOrder(Before = PredefinedEmbeddedLanguageNames.Json)]
[ExportEmbeddedLanguageClassifier(
- PredefinedEmbeddedLanguageClassifierNames.Regex, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Regex", "Regexp"), Shared]
- internal class CSharpRegexEmbeddedLanguageClassifier : AbstractRegexEmbeddedLanguageClassifier
+ PredefinedEmbeddedLanguageNames.Regex, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Regex", "Regexp"), Shared]
+ internal class CSharpRegexClassifier : AbstractRegexClassifier
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
- public CSharpRegexEmbeddedLanguageClassifier()
+ public CSharpRegexClassifier()
: base(CSharpEmbeddedLanguagesProvider.Info)
{
}
diff --git a/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexDocumentHighlighter.cs b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexDocumentHighlighter.cs
new file mode 100644
index 0000000000000..02f9cb521f892
--- /dev/null
+++ b/src/Features/CSharp/Portable/EmbeddedLanguages/CSharpRegexDocumentHighlighter.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Composition;
+using Microsoft.CodeAnalysis.CSharp.EmbeddedLanguages.LanguageServices;
+using Microsoft.CodeAnalysis.DocumentHighlighting;
+using Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions.LanguageServices;
+using Microsoft.CodeAnalysis.Host.Mef;
+
+namespace Microsoft.CodeAnalysis.CSharp.Features.EmbeddedLanguages
+{
+ [ExtensionOrder(Before = PredefinedEmbeddedLanguageNames.Json)]
+ [ExportEmbeddedLanguageDocumentHighlighter(
+ PredefinedEmbeddedLanguageNames.Regex, LanguageNames.CSharp, supportsUnannotatedAPIs: true, "Regex", "Regexp"), Shared]
+ internal class CSharpRegexDocumentHighlighter : AbstractRegexDocumentHighlighter
+ {
+ [ImportingConstructor]
+ [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
+ public CSharpRegexDocumentHighlighter()
+ : base(CSharpEmbeddedLanguagesProvider.Info)
+ {
+ }
+ }
+}
diff --git a/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs b/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs
index 64a1da145f1b8..d3e7679e64fd8 100644
--- a/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs
+++ b/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs
@@ -11,7 +11,6 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.EmbeddedLanguages;
using Microsoft.CodeAnalysis.ErrorReporting;
-using Microsoft.CodeAnalysis.Features.EmbeddedLanguages;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.PooledObjects;
@@ -21,8 +20,19 @@
namespace Microsoft.CodeAnalysis.DocumentHighlighting
{
- internal abstract partial class AbstractDocumentHighlightsService : IDocumentHighlightsService
+ internal abstract partial class AbstractDocumentHighlightsService :
+ AbstractEmbeddedLanguageFeatureService,
+ IDocumentHighlightsService
{
+ protected AbstractDocumentHighlightsService(
+ string languageName,
+ EmbeddedLanguageInfo info,
+ ISyntaxKinds syntaxKinds,
+ IEnumerable> allServices)
+ : base(languageName, info, syntaxKinds, allServices)
+ {
+ }
+
public async Task> GetDocumentHighlightsAsync(
Document document, int position, IImmutableSet documentsToSearch, HighlightingOptions options, CancellationToken cancellationToken)
{
@@ -53,14 +63,13 @@ public async Task> GetDocumentHighlightsAsync
private async Task> GetDocumentHighlightsInCurrentProcessAsync(
Document document, int position, IImmutableSet documentsToSearch, HighlightingOptions options, CancellationToken cancellationToken)
{
- var result = await TryGetEmbeddedLanguageHighlightsAsync(
- document, position, documentsToSearch, options, cancellationToken).ConfigureAwait(false);
+ var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var result = TryGetEmbeddedLanguageHighlights(document, semanticModel, position, options, cancellationToken);
if (!result.IsDefaultOrEmpty)
return result;
var solution = document.Project.Solution;
- var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var symbol = await SymbolFinder.FindSymbolAtPositionAsync(
semanticModel, position, solution.Workspace, cancellationToken).ConfigureAwait(false);
if (symbol == null)
@@ -80,26 +89,18 @@ private async Task> GetDocumentHighlightsInCu
return tags;
}
- private static async Task> TryGetEmbeddedLanguageHighlightsAsync(
- Document document, int position, IImmutableSet documentsToSearch, HighlightingOptions options, CancellationToken cancellationToken)
+ private ImmutableArray TryGetEmbeddedLanguageHighlights(
+ Document document, SemanticModel semanticModel, int position, HighlightingOptions options, CancellationToken cancellationToken)
{
- var languagesProvider = document.GetLanguageService();
- if (languagesProvider != null)
+ var root = semanticModel.SyntaxTree.GetRoot(cancellationToken);
+ var token = root.FindToken(position);
+ var embeddedHighlightsServices = this.GetServices(semanticModel, token, cancellationToken);
+ foreach (var service in embeddedHighlightsServices)
{
- foreach (var language in languagesProvider.Languages)
- {
- var highlighter = (language as IEmbeddedLanguageFeatures)?.DocumentHighlightsService;
- if (highlighter != null)
- {
- var highlights = await highlighter.GetDocumentHighlightsAsync(
- document, position, documentsToSearch, options, cancellationToken).ConfigureAwait(false);
-
- if (!highlights.IsDefaultOrEmpty)
- {
- return highlights;
- }
- }
- }
+ var result = service.Value.GetDocumentHighlights(
+ document, semanticModel, token, position, options, cancellationToken);
+ if (!result.IsDefaultOrEmpty)
+ return result;
}
return default;
@@ -116,7 +117,7 @@ private async Task> GetTagsForReferencedSymbo
{
var progress = new StreamingProgressCollector();
- var options = FindSymbols.FindReferencesSearchOptions.GetFeatureOptionsForStartingSymbol(symbol);
+ var options = FindReferencesSearchOptions.GetFeatureOptionsForStartingSymbol(symbol);
await SymbolFinder.FindReferencesAsync(
symbol, document.Project.Solution, progress,
documentsToSearch, options, cancellationToken).ConfigureAwait(false);
diff --git a/src/Features/Core/Portable/DocumentHighlighting/ExportEmbeddedLanguageDocumentHighlighterAttribute.cs b/src/Features/Core/Portable/DocumentHighlighting/ExportEmbeddedLanguageDocumentHighlighterAttribute.cs
new file mode 100644
index 0000000000000..4592d47cf3a1f
--- /dev/null
+++ b/src/Features/Core/Portable/DocumentHighlighting/ExportEmbeddedLanguageDocumentHighlighterAttribute.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.CodeAnalysis.EmbeddedLanguages;
+
+namespace Microsoft.CodeAnalysis.DocumentHighlighting
+{
+ ///
+ /// Use this attribute to export a .
+ ///
+ internal class ExportEmbeddedLanguageDocumentHighlighterAttribute : ExportEmbeddedLanguageFeatureServiceAttribute
+ {
+ public ExportEmbeddedLanguageDocumentHighlighterAttribute(
+ string name, string language, params string[] identifiers)
+ : this(name, language, supportsUnannotatedAPIs: false, identifiers)
+ {
+ }
+
+ public ExportEmbeddedLanguageDocumentHighlighterAttribute(
+ string name, string language, bool supportsUnannotatedAPIs, params string[] identifiers)
+ : base(typeof(IEmbeddedLanguageDocumentHighlighter), name, language, supportsUnannotatedAPIs, identifiers)
+ {
+ }
+ }
+}
diff --git a/src/Features/Core/Portable/DocumentHighlighting/IEmbeddedLanguageDocumentHighlighter.cs b/src/Features/Core/Portable/DocumentHighlighting/IEmbeddedLanguageDocumentHighlighter.cs
new file mode 100644
index 0000000000000..5d7e6fba9253b
--- /dev/null
+++ b/src/Features/Core/Portable/DocumentHighlighting/IEmbeddedLanguageDocumentHighlighter.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Immutable;
+using System.Threading;
+using Microsoft.CodeAnalysis.EmbeddedLanguages;
+
+namespace Microsoft.CodeAnalysis.DocumentHighlighting
+{
+ ///
+ internal interface IEmbeddedLanguageDocumentHighlighter : IEmbeddedLanguageFeatureService
+ {
+ ///
+ ImmutableArray GetDocumentHighlights(
+ Document document,
+ SemanticModel semanticModel,
+ SyntaxToken token,
+ int position,
+ HighlightingOptions options,
+ CancellationToken cancellationToken);
+ }
+}
diff --git a/src/Features/Core/Portable/EmbeddedLanguages/IEmbeddedLanguageFeatures.cs b/src/Features/Core/Portable/EmbeddedLanguages/IEmbeddedLanguageFeatures.cs
index e59d78437770e..5864f01b91d9b 100644
--- a/src/Features/Core/Portable/EmbeddedLanguages/IEmbeddedLanguageFeatures.cs
+++ b/src/Features/Core/Portable/EmbeddedLanguages/IEmbeddedLanguageFeatures.cs
@@ -13,11 +13,6 @@ namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages
///
internal interface IEmbeddedLanguageFeatures : IEmbeddedLanguage
{
- ///
- /// A optional highlighter that can highlight spans for an embedded language string.
- ///
- IDocumentHighlightsService? DocumentHighlightsService { get; }
-
///
/// Completion provider that can provide completion items for this
/// specific embedded language.
diff --git a/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonEmbeddedLanguageClassifier.cs b/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonClassifier.cs
similarity index 97%
rename from src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonEmbeddedLanguageClassifier.cs
rename to src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonClassifier.cs
index 514a909bae8b0..5b4ff21062573 100644
--- a/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonEmbeddedLanguageClassifier.cs
+++ b/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonClassifier.cs
@@ -17,12 +17,12 @@ namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.Json.LanguageService
///
/// Classifier impl for embedded json strings.
///
- internal abstract class AbstractJsonEmbeddedLanguageClassifier : IEmbeddedLanguageClassifier
+ internal abstract class AbstractJsonClassifier : IEmbeddedLanguageClassifier
{
private static readonly ObjectPool s_visitorPool = new(() => new Visitor());
private readonly EmbeddedLanguageInfo _info;
- public AbstractJsonEmbeddedLanguageClassifier(EmbeddedLanguageInfo info)
+ public AbstractJsonClassifier(EmbeddedLanguageInfo info)
{
_info = info;
}
diff --git a/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/JsonEmbeddedLanguage.cs b/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/JsonEmbeddedLanguage.cs
index 35fe94a28c045..8bfd3b49ceb1e 100644
--- a/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/JsonEmbeddedLanguage.cs
+++ b/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/JsonEmbeddedLanguage.cs
@@ -9,9 +9,6 @@ namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.Json.LanguageService
{
internal class JsonEmbeddedLanguage : IEmbeddedLanguageFeatures
{
- // No document-highlights for embedded json currently.
- public IDocumentHighlightsService? DocumentHighlightsService => null;
-
// No completion for embedded json currently.
public EmbeddedLanguageCompletionProvider? CompletionProvider => null;
}
diff --git a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexEmbeddedLanguageClassifier.cs b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexClassifier.cs
similarity index 98%
rename from src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexEmbeddedLanguageClassifier.cs
rename to src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexClassifier.cs
index 1a66b8761ce6b..638c1632d8c6d 100644
--- a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexEmbeddedLanguageClassifier.cs
+++ b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexClassifier.cs
@@ -18,13 +18,13 @@ namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions.L
///
/// Classifier impl for embedded regex strings.
///
- internal abstract class AbstractRegexEmbeddedLanguageClassifier : IEmbeddedLanguageClassifier
+ internal abstract class AbstractRegexClassifier : IEmbeddedLanguageClassifier
{
private static readonly ObjectPool s_visitorPool = SharedPools.Default();
private readonly EmbeddedLanguageInfo _info;
- protected AbstractRegexEmbeddedLanguageClassifier(EmbeddedLanguageInfo info)
+ protected AbstractRegexClassifier(EmbeddedLanguageInfo info)
{
_info = info;
}
diff --git a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexDocumentHighlightsService.cs b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexDocumentHighlighter.cs
similarity index 84%
rename from src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexDocumentHighlightsService.cs
rename to src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexDocumentHighlighter.cs
index 00753e8bbfa32..3d97b028e2645 100644
--- a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexDocumentHighlightsService.cs
+++ b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/AbstractRegexDocumentHighlighter.cs
@@ -2,13 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-#nullable disable
-
using System;
using System.Collections.Immutable;
using System.Threading;
-using System.Threading.Tasks;
using Microsoft.CodeAnalysis.DocumentHighlighting;
+using Microsoft.CodeAnalysis.EmbeddedLanguages;
using Microsoft.CodeAnalysis.EmbeddedLanguages.Common;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions;
using Microsoft.CodeAnalysis.EmbeddedLanguages.VirtualChars;
@@ -18,22 +16,22 @@ namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions.L
{
using RegexToken = EmbeddedSyntaxToken;
- internal sealed class RegexDocumentHighlightsService : IDocumentHighlightsService
+ internal abstract class AbstractRegexDocumentHighlighter : IEmbeddedLanguageDocumentHighlighter
{
- private readonly RegexEmbeddedLanguage _language;
+ private readonly EmbeddedLanguageInfo _info;
- public RegexDocumentHighlightsService(RegexEmbeddedLanguage language)
- => _language = language;
+ protected AbstractRegexDocumentHighlighter(EmbeddedLanguageInfo info)
+ => _info = info;
- public async Task> GetDocumentHighlightsAsync(
- Document document, int position, IImmutableSet documentsToSearch, HighlightingOptions options, CancellationToken cancellationToken)
+ public ImmutableArray GetDocumentHighlights(
+ Document document, SemanticModel semanticModel, SyntaxToken token, int position, HighlightingOptions options, CancellationToken cancellationToken)
{
if (!options.HighlightRelatedRegexComponentsUnderCursor)
- {
return default;
- }
- var tree = await _language.TryGetTreeAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);
+ var detector = RegexLanguageDetector.GetOrCreate(semanticModel.Compilation, _info);
+ var tree = detector.TryParseString(token, semanticModel, cancellationToken);
+
return tree == null
? default
: ImmutableArray.Create(new DocumentHighlights(document, GetHighlights(tree, position)));
@@ -115,7 +113,7 @@ private static RegexToken GetCaptureToken(RegexEscapeNode node)
_ => throw new InvalidOperationException(),
};
- private RegexEscapeNode FindReferenceNode(RegexNode node, VirtualChar virtualChar)
+ private RegexEscapeNode? FindReferenceNode(RegexNode node, VirtualChar virtualChar)
{
if (node.Kind is RegexKind.BackreferenceEscape or
RegexKind.CaptureEscape or
diff --git a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexEmbeddedLanguage.cs b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexEmbeddedLanguage.cs
index d8d7fb443f444..2c96c08d1a21d 100644
--- a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexEmbeddedLanguage.cs
+++ b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexEmbeddedLanguage.cs
@@ -5,9 +5,9 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Completion.Providers;
-using Microsoft.CodeAnalysis.DocumentHighlighting;
using Microsoft.CodeAnalysis.EmbeddedLanguages;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions;
+using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions.LanguageServices
{
@@ -17,7 +17,6 @@ internal class RegexEmbeddedLanguage : IEmbeddedLanguageFeatures
private readonly AbstractEmbeddedLanguageFeaturesProvider _provider;
- public IDocumentHighlightsService? DocumentHighlightsService { get; }
public EmbeddedLanguageCompletionProvider CompletionProvider { get; }
public RegexEmbeddedLanguage(
@@ -28,18 +27,16 @@ public RegexEmbeddedLanguage(
_provider = provider;
- DocumentHighlightsService = new RegexDocumentHighlightsService(this);
CompletionProvider = new RegexEmbeddedCompletionProvider(this);
}
-#nullable disable
internal async Task<(RegexTree tree, SyntaxToken token)> TryGetTreeAndTokenAtPositionAsync(
Document document, int position, CancellationToken cancellationToken)
{
- var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var token = root.FindToken(position);
- var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var detector = RegexLanguageDetector.GetOrCreate(semanticModel.Compilation, this.Info);
var tree = detector.TryParseString(token, semanticModel, cancellationToken);
return tree == null ? default : (tree, token);
diff --git a/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb b/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb
index 9ba01d722e9b9..280a9004efa96 100644
--- a/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb
+++ b/src/Features/VisualBasic/Portable/DocumentHighlighting/VisualBasicDocumentHighlightsService.vb
@@ -4,7 +4,10 @@
Imports System.Composition
Imports Microsoft.CodeAnalysis.DocumentHighlighting
+Imports Microsoft.CodeAnalysis.EmbeddedLanguages
Imports Microsoft.CodeAnalysis.Host.Mef
+Imports Microsoft.CodeAnalysis.VisualBasic.EmbeddedLanguages.LanguageServices
+Imports Microsoft.CodeAnalysis.VisualBasic.LanguageServices
Namespace Microsoft.CodeAnalysis.VisualBasic.DocumentHighlighting
@@ -13,7 +16,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.DocumentHighlighting
- Public Sub New()
+ Public Sub New(
+ services As IEnumerable(Of Lazy(Of IEmbeddedLanguageDocumentHighlighter, EmbeddedLanguageMetadata)))
+ MyBase.New(
+ LanguageNames.VisualBasic,
+ VisualBasicEmbeddedLanguagesProvider.Info,
+ VisualBasicSyntaxKinds.Instance,
+ services)
End Sub
End Class
End Namespace
diff --git a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicJsonEmbeddedLanguageClassifier.vb b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicJsonClassifier.vb
similarity index 78%
rename from src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicJsonEmbeddedLanguageClassifier.vb
rename to src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicJsonClassifier.vb
index 4ddcd12a53ff2..7019e7e4e0c3a 100644
--- a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicJsonEmbeddedLanguageClassifier.vb
+++ b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicJsonClassifier.vb
@@ -10,9 +10,9 @@ Imports Microsoft.CodeAnalysis.VisualBasic.EmbeddedLanguages.LanguageServices
Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages
- Friend Class VisualBasicJsonEmbeddedLanguageClassifier
- Inherits AbstractJsonEmbeddedLanguageClassifier
+ PredefinedEmbeddedLanguageNames.Json, LanguageNames.VisualBasic, True, "Json"), [Shared]>
+ Friend Class VisualBasicJsonClassifier
+ Inherits AbstractJsonClassifier
diff --git a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexEmbeddedLanguageClassifier.vb b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexClassifier.vb
similarity index 76%
rename from src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexEmbeddedLanguageClassifier.vb
rename to src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexClassifier.vb
index 89816f2a8bfcd..a5ebd4edf9e74 100644
--- a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexEmbeddedLanguageClassifier.vb
+++ b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexClassifier.vb
@@ -11,11 +11,11 @@ Imports Microsoft.CodeAnalysis.VisualBasic.EmbeddedLanguages.LanguageServices
Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages
' Order regex classification before json classification. Json lights up on probable-json strings, but we don't
' want that to happen for APIs that are certain to be another language Like Regex.
-
+
- Friend Class VisualBasicRegexEmbeddedLanguageClassifier
- Inherits AbstractRegexEmbeddedLanguageClassifier
+ PredefinedEmbeddedLanguageNames.Regex, LanguageNames.VisualBasic, True, "Regex", "Regexp"), [Shared]>
+ Friend Class VisualBasicRegexClassifier
+ Inherits AbstractRegexClassifier
diff --git a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexDocumentHighlighter.vb b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexDocumentHighlighter.vb
new file mode 100644
index 0000000000000..479bb67ee7eaa
--- /dev/null
+++ b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicRegexDocumentHighlighter.vb
@@ -0,0 +1,27 @@
+' Licensed to the .NET Foundation under one or more agreements.
+' The .NET Foundation licenses this file to you under the MIT license.
+' See the LICENSE file in the project root for more information.
+
+Imports System.Composition
+Imports Microsoft.CodeAnalysis.Classification
+Imports Microsoft.CodeAnalysis.DocumentHighlighting
+Imports Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions.LanguageServices
+Imports Microsoft.CodeAnalysis.Host.Mef
+Imports Microsoft.CodeAnalysis.VisualBasic.EmbeddedLanguages.LanguageServices
+
+Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages
+ ' Order regex classification before json classification. Json lights up on probable-json strings, but we don't
+ ' want that to happen for APIs that are certain to be another language Like Regex.
+
+
+ Friend Class VisualBasicRegexDocumentHighlighter
+ Inherits AbstractRegexDocumentHighlighter
+
+
+
+ Public Sub New()
+ MyBase.New(VisualBasicEmbeddedLanguagesProvider.Info)
+ End Sub
+ End Class
+End Namespace
diff --git a/src/Workspaces/Core/Portable/EmbeddedLanguages/ExportEmbeddedLanguageFeatureServiceAttribute.cs b/src/Workspaces/Core/Portable/EmbeddedLanguages/ExportEmbeddedLanguageFeatureServiceAttribute.cs
index d7c8a79825605..eb5a9a9b22e7f 100644
--- a/src/Workspaces/Core/Portable/EmbeddedLanguages/ExportEmbeddedLanguageFeatureServiceAttribute.cs
+++ b/src/Workspaces/Core/Portable/EmbeddedLanguages/ExportEmbeddedLanguageFeatureServiceAttribute.cs
@@ -59,8 +59,8 @@ internal ExportEmbeddedLanguageFeatureServiceAttribute(
if (SupportsUnannotatedAPIs)
{
- Contract.ThrowIfFalse(name is PredefinedEmbeddedLanguageClassifierNames.Regex or PredefinedEmbeddedLanguageClassifierNames.Json,
- $"Only '{PredefinedEmbeddedLanguageClassifierNames.Regex}' or '{PredefinedEmbeddedLanguageClassifierNames.Json}' are allowed to '{nameof(SupportsUnannotatedAPIs)}'");
+ Contract.ThrowIfFalse(name is PredefinedEmbeddedLanguageNames.Regex or PredefinedEmbeddedLanguageNames.Json,
+ $"Only '{PredefinedEmbeddedLanguageNames.Regex}' or '{PredefinedEmbeddedLanguageNames.Json}' are allowed to '{nameof(SupportsUnannotatedAPIs)}'");
}
}
}
diff --git a/src/Workspaces/Core/Portable/Classification/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs b/src/Workspaces/Core/Portable/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs
similarity index 73%
rename from src/Workspaces/Core/Portable/Classification/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs
rename to src/Workspaces/Core/Portable/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs
index 94e9a645b8e4c..567234a4e5f9a 100644
--- a/src/Workspaces/Core/Portable/Classification/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs
+++ b/src/Workspaces/Core/Portable/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs
@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace Microsoft.CodeAnalysis.Classification
+namespace Microsoft.CodeAnalysis
{
- internal static class PredefinedEmbeddedLanguageClassifierNames
+ internal static class PredefinedEmbeddedLanguageNames
{
public const string Regex = nameof(Regex);