diff options
author | ET <48451158+etvorun@users.noreply.github.com> | 2021-11-03 20:08:55 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-03 20:08:55 +0300 |
commit | bb2e2214146ffd0d3185b3c5f838617bfdda1338 (patch) | |
tree | 84a6dc4bef9406f631adb56571b406689641ed0d | |
parent | 838aee97b4e6e2e7f91c4e0ce83e03acd2f327a5 (diff) | |
parent | dcaa4dbd6b69045798aafe1ba86bc9e7ad71e0e5 (diff) |
Merge pull request #41 from microsoft/dev/evgenyt/implement_new_interfaces
Implement new interfaces
6 files changed, 192 insertions, 28 deletions
diff --git a/src/Editor/Text/Def/TextLogic/Classification/ClassificationLayer.cs b/src/Editor/Text/Def/TextLogic/Classification/ClassificationLayer.cs new file mode 100644 index 0000000..0eb05d8 --- /dev/null +++ b/src/Editor/Text/Def/TextLogic/Classification/ClassificationLayer.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// +#nullable enable +namespace Microsoft.VisualStudio.Text.Classification +{ + using Microsoft.VisualStudio.Text.Tagging; + + /// <summary> + /// Defines a set of well known classification layers to which an + /// <see cref="ILayeredClassificationType"/> can belong. + /// </summary> + /// <remarks> + /// <see cref="IClassificationTag"/> layers with greater numeric values take + /// precedence over layers with smaller values. e.g.: <see cref="Semantic"/> + /// classifications override <see cref="Lexical"/> classifications in cases + /// of overlap. + /// </remarks> + public enum ClassificationLayer + { + /// <summary> + /// The default behavior, assigned to any classifications that + /// implement <see cref="IClassificationType"/> but do not + /// implement <see cref="ILayeredClassificationType"/>. + /// </summary> + /// <remarks> + /// The default behavior is 'non-layered', meaning that these classifications + /// can be merged into any layer. This behavior exists primarily for backwards + /// compatibility. + /// </remarks> + Default = 0, + + /// <summary> + /// The lexical layer, including classifications generated through pure + /// lexical analysis of a file. + /// </summary> + Lexical = 1_000, + + /// <summary> + /// The syntatic layer, including classifications generated through parsing + /// the lexed syntactic tokens into a parse tree. + /// </summary> + Syntactic = 2_000, + + /// <summary> + /// The semantic layer, including classifications generated through type checking + /// of a file, resolving of references, and other complex analyses. + /// </summary> + Semantic = 3_000 + } +} diff --git a/src/Editor/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs b/src/Editor/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs index 03a45bf..b7f2171 100644 --- a/src/Editor/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs +++ b/src/Editor/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs @@ -86,5 +86,35 @@ namespace Microsoft.VisualStudio.Text.Classification /// </para> /// </remarks> IClassificationType CreateTransientClassificationType(params IClassificationType[] baseTypes); + + /// <summary> + /// Gets the <see cref="IClassificationType"></see> object identified by the specified <paramref name="type"/>. + /// </summary> + /// <param name="layer"> + /// Specifies the layer to which this classification belongs. Layers are specializations + /// of <see cref="IClassificationType"/>s that can be used to make all classifications from + /// one source supersede another. + /// </param> + /// <param name="type"> + /// The name of the classification type. + /// </param> + /// <returns> + /// The classification type, <c>null</c> if there is no classification type of that name. + /// </returns> + ILayeredClassificationType GetClassificationType(ClassificationLayer layer, string type); + + /// <summary> + /// Initializes a new instance of a <see cref="IClassificationType"/> and adds it to the registry. + /// </summary> + /// <param name="layer"> + /// Specifies the layer to which this classification belongs. Layers are specializations + /// of <see cref="IClassificationType"/>s that can be used to make all classifications from + /// one source supersede another. + /// </param> + /// <param name="type">The name of the classification type to create.</param> + /// <param name="baseTypes">The base types of the classification.</param> + /// <returns>A new <see cref="IClassificationType"/>.</returns> + /// <exception cref="InvalidOperationException"><paramref name="type"/> is already in the registry.</exception> + ILayeredClassificationType CreateClassificationType(ClassificationLayer layer, string type, IEnumerable<IClassificationType> baseTypes); } } diff --git a/src/Editor/Text/Def/TextLogic/Classification/ILayeredClassificationType.cs b/src/Editor/Text/Def/TextLogic/Classification/ILayeredClassificationType.cs new file mode 100644 index 0000000..8f8b29d --- /dev/null +++ b/src/Editor/Text/Def/TextLogic/Classification/ILayeredClassificationType.cs @@ -0,0 +1,22 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// +namespace Microsoft.VisualStudio.Text.Classification +{ + /// <summary> + /// A specialization of <see cref="IClassificationType"/> that includes a 'layer' + /// designation. + /// </summary> + /// <remarks> + /// <see cref="ILayeredClassificationType"/> can be used instead of <see cref="IClassificationType"/> + /// to enable one component's classifications to categorically supersede another's classifications. + /// </remarks> + public interface ILayeredClassificationType : IClassificationType + { + /// <summary> + /// The classification layer to which this classification belongs. + /// </summary> + ClassificationLayer Layer { get; } + } +} diff --git a/src/Editor/Text/Impl/ClassificationType/ClassificationKey.cs b/src/Editor/Text/Impl/ClassificationType/ClassificationKey.cs new file mode 100644 index 0000000..10cf1bc --- /dev/null +++ b/src/Editor/Text/Impl/ClassificationType/ClassificationKey.cs @@ -0,0 +1,47 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// +// This file contain implementations details that are subject to change without notice. +// Use at your own risk. +// +using System; +using System.Diagnostics; + +namespace Microsoft.VisualStudio.Text.Classification.Implementation +{ + [DebuggerDisplay("{Name,nq}, {Layer}")] + internal struct ClassificationKey : IEquatable<ClassificationKey> + { + public ClassificationKey(string name, ClassificationLayer layer = ClassificationLayer.Default) : this() + { + this.Name = name ?? string.Empty; + this.Layer = layer; + } + + public string Name { get; } + public ClassificationLayer Layer { get; } + + public bool Equals(ClassificationKey other) + { + return this.Layer == other.Layer && string.Equals(this.Name, other.Name, StringComparison.OrdinalIgnoreCase); + } + + public override bool Equals(object obj) + { + if (obj is ClassificationKey other) + return this.Equals(other); + return false; + } + + public override int GetHashCode() + { + return StringComparer.OrdinalIgnoreCase.GetHashCode(this.Name) ^ this.Layer.GetHashCode(); + } + + public override string ToString() + { + return $"{this.Name}, layer={this.Layer}"; + } + } +} diff --git a/src/Editor/Text/Impl/ClassificationType/ClassificationTypeImpl.cs b/src/Editor/Text/Impl/ClassificationType/ClassificationTypeImpl.cs index 5a47305..dcad4e8 100644 --- a/src/Editor/Text/Impl/ClassificationType/ClassificationTypeImpl.cs +++ b/src/Editor/Text/Impl/ClassificationType/ClassificationTypeImpl.cs @@ -6,19 +6,25 @@ // Use at your own risk. // using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using Microsoft.VisualStudio.Text.Utilities; namespace Microsoft.VisualStudio.Text.Classification.Implementation { - internal class ClassificationTypeImpl : IClassificationType + [DebuggerDisplay("{key}")] + internal class ClassificationTypeImpl : ILayeredClassificationType, IClassificationType { - private string name; + private ClassificationKey key; private FrugalList<IClassificationType> baseTypes; - internal ClassificationTypeImpl(string name) + internal ClassificationTypeImpl(string name) : this(new ClassificationKey(name)) { - this.name = name; + } + + internal ClassificationTypeImpl(ClassificationKey key) + { + this.key = key; } internal void AddBaseType(IClassificationType baseType) @@ -31,14 +37,12 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation this.baseTypes.Add(baseType); } - public string Classification - { - get { return this.name; } - } + public string Classification => this.key.Name; + public ClassificationLayer Layer => this.key.Layer; public bool IsOfType(string type) { - if (string.Equals(this.name, type, System.StringComparison.Ordinal)) + if (string.Equals(this.key.Name, type, System.StringComparison.OrdinalIgnoreCase)) return true; else if (this.baseTypes != null) { @@ -59,7 +63,7 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation public override string ToString() { - return this.name; + return this.key.ToString(); } } } diff --git a/src/Editor/Text/Impl/ClassificationType/ClassificationTypeRegistryService.cs b/src/Editor/Text/Impl/ClassificationType/ClassificationTypeRegistryService.cs index 6f746a0..0f392a3 100644 --- a/src/Editor/Text/Impl/ClassificationType/ClassificationTypeRegistryService.cs +++ b/src/Editor/Text/Impl/ClassificationType/ClassificationTypeRegistryService.cs @@ -9,11 +9,9 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation { using System; using System.Collections.Generic; - using System.Linq; - using System.Text; using System.ComponentModel.Composition; + using System.Text; using Microsoft.VisualStudio.Utilities; - using System.Collections; public interface IClassificationTypeDefinitionMetadata { @@ -37,7 +35,7 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation public ClassificationTypeDefinition textClassificationType; #region Private Members - private Dictionary<string, ClassificationTypeImpl> _classificationTypes; + private Dictionary<ClassificationKey, ClassificationTypeImpl> _classificationTypes; private Dictionary<string, ClassificationTypeImpl> _transientClassificationTypes; #endregion // Private Members @@ -45,10 +43,12 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation #region Public Members public IClassificationType GetClassificationType(string type) { - ClassificationTypeImpl classificationType = null; - - this.ClassificationTypes.TryGetValue(type, out classificationType); + return this.GetClassificationType(ClassificationLayer.Default, type); + } + public ILayeredClassificationType GetClassificationType(ClassificationLayer layer, string type) + { + this.ClassificationTypes.TryGetValue(new ClassificationKey(type, layer), out ClassificationTypeImpl classificationType); return classificationType; } @@ -57,6 +57,11 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation /// </summary> public IClassificationType CreateClassificationType(string type, IEnumerable<IClassificationType> baseTypes) { + return this.CreateClassificationType(ClassificationLayer.Default, type, baseTypes); + } + + public ILayeredClassificationType CreateClassificationType(ClassificationLayer layer, string type, IEnumerable<IClassificationType> baseTypes) + { if (type == null) { throw new ArgumentNullException(nameof(type)); @@ -66,7 +71,9 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation { throw new ArgumentNullException(nameof(baseTypes)); } - if (ClassificationTypes.ContainsKey(type)) + + ClassificationKey key = new ClassificationKey(type, layer); + if (ClassificationTypes.ContainsKey(key)) { throw new InvalidOperationException(LookUp.Strings.ClassificationAlreadyAdded); } @@ -78,7 +85,7 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation classificationType.AddBaseType(baseType); } - ClassificationTypes.Add(type, classificationType); + ClassificationTypes.Add(key, classificationType); return classificationType; } @@ -135,7 +142,7 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation { get { - return ClassificationTypes["(TRANSIENT)"]; + return ClassificationTypes[new ClassificationKey("(TRANSIENT)")]; } } @@ -144,13 +151,13 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation /// /// Used to lazily init the map. /// </summary> - private Dictionary<string, ClassificationTypeImpl> ClassificationTypes + private Dictionary<ClassificationKey, ClassificationTypeImpl> ClassificationTypes { get { if (_classificationTypes == null) { - _classificationTypes = new Dictionary<string, ClassificationTypeImpl>(StringComparer.OrdinalIgnoreCase); + _classificationTypes = new Dictionary<ClassificationKey, ClassificationTypeImpl>(); BuildClassificationTypes(_classificationTypes); } return _classificationTypes; @@ -161,19 +168,19 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation /// Consumes all of the IClassificationTypeProvisions in the system to build the /// list of classification types in the system. /// </summary> - private void BuildClassificationTypes(Dictionary<string,ClassificationTypeImpl> classificationTypes) + private void BuildClassificationTypes(Dictionary<ClassificationKey, ClassificationTypeImpl> classificationTypes) { // For each content baseType provision, create an IClassificationType. foreach (Lazy<ClassificationTypeDefinition, IClassificationTypeDefinitionMetadata> classificationTypeDefinition in _classificationTypeDefinitions) { string classificationName = classificationTypeDefinition.Metadata.Name; - + ClassificationKey key = new ClassificationKey(classificationName); ClassificationTypeImpl type = null; - if (!classificationTypes.TryGetValue(classificationName, out type)) + if (!classificationTypes.TryGetValue(key, out type)) { type = new ClassificationTypeImpl(classificationName); - classificationTypes.Add(classificationName, type); + classificationTypes.Add(key, type); } IEnumerable<string> baseTypes = classificationTypeDefinition.Metadata.BaseDefinition; @@ -183,10 +190,11 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation foreach (string baseClassificationType in baseTypes) { - if (!classificationTypes.TryGetValue(baseClassificationType, out baseType)) + ClassificationKey baseKey = new ClassificationKey(baseClassificationType); + if (!classificationTypes.TryGetValue(baseKey, out baseType)) { baseType = new ClassificationTypeImpl(baseClassificationType); - classificationTypes.Add(baseClassificationType, baseType); + classificationTypes.Add(baseKey, baseType); } type.AddBaseType(baseType); @@ -248,6 +256,7 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation return transientType; } + #endregion // Private Methods } } |