File: CodeModel\Collections\NodeSnapshot.cs
Web Access
Project: src\src\VisualStudio\Core\Impl\Microsoft.VisualStudio.LanguageServices.Implementation.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 sealed 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);
        }
    }
}