File: CodeModel\Collections\NodeSnapshot.cs
Web Access
Project: ..\..\..\src\VisualStudio\Core\Impl\Microsoft.VisualStudio.LanguageServices.Implementation_zmmkbl53_wpftmp.csproj (Microsoft.VisualStudio.LanguageServices.Implementation)
// 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.
 
#nullable disable
 
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.InternalElements;
using Microsoft.VisualStudio.LanguageServices.Implementation.Interop;
 
namespace Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.Collections
{
    internal class NodeSnapshot : Snapshot
    {
        private readonly CodeModelState _state;
        private readonly ComHandle<EnvDTE.FileCodeModel, FileCodeModel> _fileCodeModel;
        private readonly SyntaxNode _parentNode;
        private readonly AbstractCodeElement _parentElement;
        private readonly ImmutableArray<SyntaxNode> _nodes;
 
        public NodeSnapshot(
            CodeModelState state,
            ComHandle<EnvDTE.FileCodeModel, FileCodeModel> fileCodeModel,
            SyntaxNode parentNode,
            AbstractCodeElement parentElement,
            ImmutableArray<SyntaxNode> nodes)
        {
            _state = state;
            _fileCodeModel = fileCodeModel;
            _parentNode = parentNode;
            _parentElement = parentElement;
            _nodes = nodes;
        }
 
        private ICodeModelService CodeModelService
        {
            get { return _state.CodeModelService; }
        }
 
        private FileCodeModel FileCodeModel
        {
            get { return _fileCodeModel.Object; }
        }
 
        private EnvDTE.CodeElement CreateCodeOptionsStatement(SyntaxNode node)
        {
            this.CodeModelService.GetOptionNameAndOrdinal(_parentNode, node, out var name, out var ordinal);
 
            return CodeOptionsStatement.Create(_state, this.FileCodeModel, name, ordinal);
        }
 
        private EnvDTE.CodeElement CreateCodeImport(SyntaxNode node)
        {
            var name = this.CodeModelService.GetImportNamespaceOrType(node);
 
            return CodeImport.Create(_state, this.FileCodeModel, _parentElement, name);
        }
 
        private EnvDTE.CodeElement CreateCodeAttribute(SyntaxNode node)
        {
            this.CodeModelService.GetAttributeNameAndOrdinal(_parentNode, node, out var name, out var ordinal);
 
            return (EnvDTE.CodeElement)CodeAttribute.Create(_state, this.FileCodeModel, _parentElement, name, ordinal);
        }
 
        private EnvDTE.CodeElement CreateCodeParameter(SyntaxNode node)
        {
            Debug.Assert(_parentElement is AbstractCodeMember, "Parameters should always have an associated member!");
 
            var name = this.CodeModelService.GetParameterName(node);
 
            return (EnvDTE.CodeElement)CodeParameter.Create(_state, (AbstractCodeMember)_parentElement, name);
        }
 
        public override int Count
        {
            get { return _nodes.Length; }
        }
 
        public override EnvDTE.CodeElement this[int index]
        {
            get
            {
                if (index < 0 || index >= _nodes.Length)
                {
                    throw new ArgumentOutOfRangeException(nameof(index));
                }
 
                var node = _nodes[index];
 
                if (this.CodeModelService.IsOptionNode(node))
                {
                    return CreateCodeOptionsStatement(node);
                }
                else if (this.CodeModelService.IsImportNode(node))
                {
                    return CreateCodeImport(node);
                }
                else if (this.CodeModelService.IsAttributeNode(node))
                {
                    return CreateCodeAttribute(node);
                }
                else if (this.CodeModelService.IsParameterNode(node))
                {
                    return CreateCodeParameter(node);
                }
 
                // The node must be something that the FileCodeModel can create.
                return this.FileCodeModel.GetOrCreateCodeElement<EnvDTE.CodeElement>(node);
            }
        }
    }
}