VisualStudio15StructureTaggerProvider.cs 6.6 KB
Newer Older
1 2 3 4 5
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
6
using Microsoft.CodeAnalysis.Editor.Implementation.Structure;
7
using Microsoft.CodeAnalysis.Shared.TestHooks;
8
using Microsoft.CodeAnalysis.Structure;
9 10
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Text;
11
using Microsoft.VisualStudio.Text.Adornments;
12 13 14 15 16
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Projection;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;

17
namespace Microsoft.CodeAnalysis.Editor.Structure
18 19
{
    [Export(typeof(ITaggerProvider))]
C
CyrusNajmabadi 已提交
20
    [Export(typeof(VisualStudio15StructureTaggerProvider))]
21
    [TagType(typeof(IBlockTag))]
22
    [ContentType(ContentTypeNames.RoslynContentType)]
23
    internal partial class VisualStudio15StructureTaggerProvider :
24
        AbstractStructureTaggerProvider<IBlockTag>
25 26
    {
        [ImportingConstructor]
C
CyrusNajmabadi 已提交
27
        public VisualStudio15StructureTaggerProvider(
28 29 30 31 32 33 34 35 36
            IForegroundNotificationService notificationService,
            ITextEditorFactoryService textEditorFactoryService,
            IEditorOptionsFactoryService editorOptionsFactoryService,
            IProjectionBufferFactoryService projectionBufferFactoryService,
            [ImportMany] IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners)
                : base(notificationService, textEditorFactoryService, editorOptionsFactoryService, projectionBufferFactoryService, asyncListeners)
        {
        }

37
        public override bool Equals(IBlockTag x, IBlockTag y)
38 39 40 41 42 43
        {
            // This is only called if the spans for the tags were the same. In that case, we consider ourselves the same
            // unless the CollapsedForm properties are different.
            return EqualityComparer<object>.Default.Equals(x.CollapsedForm, y.CollapsedForm);
        }

44
        public override int GetHashCode(IBlockTag obj)
45 46 47 48
        {
            return EqualityComparer<object>.Default.GetHashCode(obj.CollapsedForm);
        }

49 50
        protected override IBlockTag CreateTag(
            IBlockTag parentTag, ITextSnapshot snapshot, BlockSpan region)
51
        {
52 53 54 55 56
            return new RoslynBlockTag(
                this.TextEditorFactoryService,
                this.ProjectionBufferFactoryService,
                this.EditorOptionsFactoryService,
                parentTag, snapshot, region);
57 58
        }

59
        private class RoslynBlockTag : RoslynOutliningRegionTag, IBlockTag
60
        {
61
            public IBlockTag Parent { get; }
62 63 64 65
            public int Level { get; }
            public SnapshotSpan Span { get; }
            public SnapshotSpan StatementSpan { get; }

66 67
            public string Type => ConvertType(BlockSpan.Type);

68
            public bool IsCollapsible => BlockSpan.IsCollapsible;
69

70 71 72 73
            public RoslynBlockTag(
                ITextEditorFactoryService textEditorFactoryService,
                IProjectionBufferFactoryService projectionBufferFactoryService,
                IEditorOptionsFactoryService editorOptionsFactoryService,
74
                IBlockTag parent,
75
                ITextSnapshot snapshot,
76 77 78 79 80
                BlockSpan outliningSpan) :
                base(textEditorFactoryService,
                    projectionBufferFactoryService,
                    editorOptionsFactoryService,
                    snapshot, outliningSpan)
81 82
            {
                Parent = parent;
83 84 85
                Level = parent == null ? 0 : parent.Level + 1;
                Span = outliningSpan.TextSpan.ToSnapshotSpan(snapshot);
                StatementSpan = outliningSpan.HintSpan.ToSnapshotSpan(snapshot);
86
            }
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131

            private string ConvertType(string type)
            {
                switch (type)
                {
                    // Basic types.
                    case BlockTypes.Structural: return PredefinedStructureTypes.Structural;
                    case BlockTypes.Nonstructural: return PredefinedStructureTypes.Nonstructural;

                    // Top level declarations.  Note that Enum is not currently supported
                    // and that we map Module down to Class.
                    case BlockTypes.Namespace: return PredefinedStructureTypes.Namespace;
                    case BlockTypes.Structure: return PredefinedStructureTypes.Struct;
                    case BlockTypes.Interface: return PredefinedStructureTypes.Interface;
                    case BlockTypes.Module:
                    case BlockTypes.Class: return PredefinedStructureTypes.Class;

                    // Member declarations
                    case BlockTypes.Accessor: return PredefinedStructureTypes.AccessorBlock;
                    case BlockTypes.Constructor: return PredefinedStructureTypes.Constructor;
                    case BlockTypes.Destructor: return PredefinedStructureTypes.Destructor;
                    case BlockTypes.Method: return PredefinedStructureTypes.Method;
                    case BlockTypes.Operator: return PredefinedStructureTypes.Operator;

                    // Map events/indexers/properties all to the 'property' type.
                    case BlockTypes.Event:
                    case BlockTypes.Indexer:
                    case BlockTypes.Property: return PredefinedStructureTypes.PropertyBlock;

                    // Statements
                    case BlockTypes.Case: return PredefinedStructureTypes.Case;
                    case BlockTypes.Conditional: return PredefinedStructureTypes.Conditional;
                    case BlockTypes.Lock: return PredefinedStructureTypes.Lock;
                    case BlockTypes.Loop: return PredefinedStructureTypes.Loop;
                    case BlockTypes.TryCatchFinally: return PredefinedStructureTypes.TryCatchFinally;
                    case BlockTypes.Standalone: return PredefinedStructureTypes.Standalone;

                    // Expressions
                    case BlockTypes.AnonymousMethod: return PredefinedStructureTypes.AnonymousMethodBlock;

                    // These types don't currently map to any editor types.  Just make them
                    // the 'Unknown' type for now.
                    case BlockTypes.Enum:
                    case BlockTypes.Other:
                    case BlockTypes.Xml:
132 133
                    case BlockTypes.LocalFunction:
                    case BlockTypes.Using:
C
CyrusNajmabadi 已提交
134
                    case BlockTypes.Switch:
135 136 137 138
                    default:
                        return PredefinedStructureTypes.Unknown;
                }
            }
139 140 141
        }
    }
}