コード例 #1
0
 private void ResetElementKey(GlobalNodeKey globalNodeKey)
 {
     // Failure to find the element is not an error -- it just means the code
     // element didn't exist...
     if (_codeElementTable.TryGetValue(globalNodeKey.NodeKey, out var element))
     {
         var keyedElement = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>(element);
         if (keyedElement != null)
         {
             keyedElement.ReacquireNodeKey(globalNodeKey.Path, default);
         }
     }
 }
コード例 #2
0
ファイル: CodeNamespace.cs プロジェクト: lameox/roslyn
        public void Remove(object element)
        {
            var codeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(element);

            codeElement ??= ComAggregate.TryGetManagedObject <AbstractCodeElement>(this.Members.Item(element));

            if (codeElement == null)
            {
                throw new ArgumentException(ServicesVSResources.Element_is_not_valid, nameof(element));
            }

            codeElement.Delete();
        }
コード例 #3
0
ファイル: CodeEnum.cs プロジェクト: layomia/dotnet_roslyn
        internal static EnvDTE.CodeEnum Create(
            CodeModelState state,
            FileCodeModel fileCodeModel,
            SyntaxNodeKey nodeKey,
            int?nodeKind)
        {
            var element = new CodeEnum(state, fileCodeModel, nodeKey, nodeKind);
            var result  = (EnvDTE.CodeEnum)ComAggregate.CreateAggregatedObject(element);

            fileCodeModel.OnCodeElementCreated(nodeKey, (EnvDTE.CodeElement)result);

            return(result);
        }
コード例 #4
0
        internal static new EnvDTE.CodeFunction Create(
            CodeModelState state,
            FileCodeModel fileCodeModel,
            SyntaxNodeKey nodeKey,
            int?nodeKind)
        {
            var element = new CodeFunctionWithEventHandler(state, fileCodeModel, nodeKey, nodeKind);
            var result  = (EnvDTE.CodeFunction)ComAggregate.CreateAggregatedObject(element);

            fileCodeModel.OnCodeElementCreated(nodeKey, (EnvDTE.CodeElement)result);

            return(result);
        }
コード例 #5
0
        protected EnvDTE.CodeElements GetCollection <T>(object parentObject)
        {
            var parentInstance = ComAggregate.GetManagedObject <object>(parentObject);

            Debug.Assert(!Marshal.IsComObject(parentInstance), "We should have a pure managed object!");

            if (parentInstance is ICodeElementContainer <T> container)
            {
                return(container.GetCollection());
            }

            throw Exceptions.ThrowEFail();
        }
コード例 #6
0
        internal static IEnumerator Create(
            CodeModelState state,
            ProjectId projectId,
            SymbolKey namespaceSymbolId
            )
        {
            var newEnumerator = new ExternalNamespaceEnumerator(
                state,
                projectId,
                namespaceSymbolId
                );

            return((IEnumerator)ComAggregate.CreateAggregatedObject(newEnumerator));
        }
コード例 #7
0
        private EnvDTE.CodeElement CreateInternalCodeMember(CodeModelState state, FileCodeModel fileCodeModel, SyntaxNode node)
        {
            var element = CodeModelService.CreateInternalCodeElement(state, fileCodeModel, node);

            if (IsBatchOpen)
            {
                var codeElement = ComAggregate.TryGetManagedObject <AbstractKeyedCodeElement>(element);
                if (codeElement != null)
                {
                    _batchElements.Add(codeElement);
                }
            }

            return(element);
        }
コード例 #8
0
        internal static EnvDTE.CodeElements Create(
            CodeModelState state,
            object parent,
            ProjectId projectId,
            INamespaceSymbol namespaceSymbol
            )
        {
            var collection = new ExternalNamespaceCollection(
                state,
                parent,
                projectId,
                namespaceSymbol
                );

            return((EnvDTE.CodeElements)ComAggregate.CreateAggregatedObject(collection));
        }
コード例 #9
0
        public void Remove(object element)
        {
            var codeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(element);

            if (codeElement == null)
            {
                codeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(this.CodeElements.Item(element));
            }

            if (codeElement == null)
            {
                throw new ArgumentException(ServicesVSResources.ElementIsNotValid, "element");
            }

            codeElement.Delete();
        }
コード例 #10
0
        internal static EnvDTE.CodeElements Create(
            CodeModelState state,
            object parent,
            FileCodeModel fileCodeModel,
            SyntaxNodeKey nodeKey
            )
        {
            var collection = new InheritsImplementsCollection(
                state,
                parent,
                fileCodeModel,
                nodeKey
                );

            return((EnvDTE.CodeElements)ComAggregate.CreateAggregatedObject(collection));
        }
コード例 #11
0
ファイル: FileCodeModel_CodeGen.cs プロジェクト: belav/roslyn
        internal EnvDTE.CodeParameter AddParameter(
            EnvDTE.CodeElement parent,
            SyntaxNode containerNode,
            string name,
            object type,
            object position
            )
        {
            var typeSymbol = CodeModelService.GetTypeSymbol(
                type,
                this.GetSemanticModel(),
                containerNode.SpanStart
                );
            var typeName = typeSymbol.GetEscapedFullName();

            var parameterNode = CodeModelService.CreateParameterNode(
                CodeModelService.GetUnescapedName(name),
                typeName
                );
            var insertionIndex = CodeModelService.PositionVariantToParameterInsertionIndex(
                position,
                containerNode,
                fileCodeModel: this
                );

            var newNode = InsertParameter(containerNode, parameterNode, insertionIndex);

            // Since parameters form part of the NodeKey for functions, delegates, and indexers,
            // creating a CodeParameter hooked up to the correct parent is a little tricky. After
            // the call to InsertParameter, the syntax tree has been updated, but not the NodeKey
            // map or the NodeKey in the parent CodeParameter. If we delegate the creation of the
            // CodeParameter to CodeModelService.CreateInternalCodeElement, it will attempt to
            // look up an element in the NodeKey map based on the new syntax tree. This will fail,
            // causing it to create a new, duplicate element for the parent. Later, when we
            // reacquire the NodeKeys, the original element will get the proper NodeKey, while the
            // duplicate will be updated to a meaningless NodeKey. Since the duplicate is the one
            // being used by the CodeParameter, most operations on it will then fail.
            // Instead, we need to have the parent passed in to us.
            var parentObj = ComAggregate.GetManagedObject <AbstractCodeMember>(parent);

            return(CodeParameter.Create(
                       this.State,
                       parentObj,
                       CodeModelService.GetParameterName(newNode)
                       ));
        }
コード例 #12
0
        /// <summary>
        /// This function re-adds a code element to the table, taking care not to duplicate
        /// an element (i.e., making sure that no two elements with the same key-ordinal
        /// appear in the same element chain in the table).  To resolve any conflict, each
        /// node with the given key is examined positionally, and the existing order is
        /// maintained as closely as possible -- but it is still possible the code element
        /// references to duplicate elements can get "bumped" by odd edits -- nothing we
        /// can do about this.
        /// </summary>
        internal void ResetElementNodeKey(AbstractKeyedCodeElement element, SyntaxNodeKey nodeKey)
        {
            EnvDTE.CodeElement elementInTable;
            _elementTable.Remove(element.NodeKey, out elementInTable);

            var abstractElementInTable = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>(elementInTable);

            if (!object.Equals(abstractElementInTable, element))
            {
                Debug.Fail("Found a different element with the same key!");
                throw new InvalidOperationException();
            }

            abstractElementInTable.NodeKey = nodeKey;

            _elementTable.Add(nodeKey, elementInTable);
        }
コード例 #13
0
        public void RenameNoUI(
            EnvDTE.CodeElement element,
            string newName,
            bool fPreview,
            bool fSearchComments,
            bool fOverloads
            )
        {
            // TODO: Support options

            var codeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(element);

            if (codeElement != null)
            {
                codeElement.RenameSymbol(newName);
            }
        }
コード例 #14
0
        internal T CreateCodeElement <T>(SyntaxNode node)
        {
            var nodeKey = CodeModelService.TryGetNodeKey(node);

            if (!nodeKey.IsEmpty)
            {
                // Check if the node exists in the parse tree.
                // Note that in designer spew the nodes don't get created right away so we skip this check.
                if (!IsBatchOpen && CodeModelService.LookupNode(nodeKey, GetSyntaxTree()) == null)
                {
                    throw Exceptions.ThrowEFail();
                }

                // See if the element exists.
                var previousElement = _elementTable.TryGetValue(nodeKey);

                // Here's our element... possibly.  It must be valid -- if it isn't,
                // we need to remove it.
                if (previousElement != null)
                {
                    var previousElementImpl = ComAggregate.TryGetManagedObject <AbstractCodeElement>(previousElement);

                    if (previousElementImpl.IsValidNode())
                    {
                        if (previousElement is T)
                        {
                            return((T)previousElement);
                        }
                        else
                        {
                            Debug.Fail("Called asked for the wrong type!");
                            throw new InvalidOperationException();
                        }
                    }
                    else
                    {
                        // This guy is no longer valid, so yank it out.  No sense
                        // continuing to look for a match, either.
                        RemoveElement(nodeKey);
                    }
                }
            }

            return((T)CodeModelService.CreateInternalCodeElement(this.State, this, node));
        }
コード例 #15
0
        internal void UpdateCodeElementNodeKey(AbstractKeyedCodeElement keyedElement, SyntaxNodeKey oldNodeKey, SyntaxNodeKey newNodeKey)
        {
            if (!_codeElementTable.TryGetValue(oldNodeKey, out var codeElement))
            {
                throw new InvalidOperationException($"Could not find {oldNodeKey} in Code Model element table.");
            }

            _codeElementTable.Remove(oldNodeKey);

            var managedElement = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>(codeElement);

            if (!object.Equals(managedElement, keyedElement))
            {
                throw new InvalidOperationException($"Unexpected failure in Code Model while updating node keys {oldNodeKey} -> {newNodeKey}");
            }

            _codeElementTable.Add(newNodeKey, codeElement);
        }
コード例 #16
0
ファイル: PartialTypeCollection.cs プロジェクト: belav/roslyn
        private ImmutableArray <EnvDTE.CodeElement> GetParts()
        {
            // Retrieving the parts is potentially very expensive because it can force multiple FileCodeModels to be instantiated.
            // Here, we cache the result to avoid having to perform these calculations each time GetParts() is called.
            // This *could* be an issue because it means that a PartialTypeCollection will not necessarily reflect the
            // current state of the user's code. However, because a new PartialTypeCollection is created every time the Parts
            // property is accessed on CodeClass, CodeStruct or CodeInterface, consumers would hit this behavior rarely.
            if (_parts == null)
            {
                var partsBuilder = ArrayBuilder <EnvDTE.CodeElement> .GetInstance();

                var solution = this.Workspace.CurrentSolution;
                var symbol   = ParentType.LookupSymbol();

                foreach (var location in symbol.Locations.Where(l => l.IsInSource))
                {
                    var document = solution.GetDocument(location.SourceTree);
                    if (document != null)
                    {
                        var fileCodeModelObject = this.Workspace.GetFileCodeModel(document.Id);
                        if (fileCodeModelObject != null)
                        {
                            var fileCodeModel = ComAggregate.GetManagedObject <FileCodeModel>(
                                fileCodeModelObject
                                );

                            var element = fileCodeModel.CodeElementFromPosition(
                                location.SourceSpan.Start,
                                ParentType.Kind
                                );
                            if (element != null)
                            {
                                partsBuilder.Add(element);
                            }
                        }
                    }
                }

                _parts = partsBuilder.ToImmutableAndFree();
            }

            return(_parts);
        }
コード例 #17
0
        internal List <GlobalNodeKey> GetCurrentNodeKeys()
        {
            var currentNodeKeys = new List <GlobalNodeKey>();

            foreach (var element in _codeElementTable.Values)
            {
                var keyedElement = ComAggregate.TryGetManagedObject <AbstractKeyedCodeElement>(element);
                if (keyedElement == null)
                {
                    continue;
                }

                if (keyedElement.TryLookupNode(out var node))
                {
                    var nodeKey = keyedElement.NodeKey;
                    currentNodeKeys.Add(new GlobalNodeKey(nodeKey, new SyntaxPath(node)));
                }
            }

            return(currentNodeKeys);
        }
コード例 #18
0
        internal void OnBeforeCodeElementCreated(SyntaxNode node)
        {
            // It's conceivable that a consumer is creating a code element with the same node key as a "dead" element
            // that hasn't been removed from the cache yet. For example, the element could have been "deleted" by
            // simply replacing its text in the underlying buffer. To handle this situation, we test to see if the
            // element is "dead" by checking whether it's underlying node is invalid (that is, it can't be found by
            // its node key). If the element is "dead", we'll go ahead and remove it from the cache here to avoid a
            // collision with the new element.

            var nodeKey = CodeModelService.TryGetNodeKey(node);

            EnvDTE.CodeElement codeElement;
            if (!nodeKey.IsEmpty && _codeElementTable.TryGetValue(nodeKey, out codeElement))
            {
                var managedElement = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>(codeElement);
                if (managedElement?.IsValidNode() != true)
                {
                    _codeElementTable.Remove(nodeKey);
                }
            }
        }
コード例 #19
0
ファイル: OverloadsCollection.cs プロジェクト: yicong/roslyn
        private ImmutableArray<EnvDTE.CodeElement> EnumerateOverloads()
        {
            var symbol = (IMethodSymbol)ParentElement.LookupSymbol();

            // Only methods and constructors can be overloaded.  However, all functions
            // can successfully return a collection of overloaded functions; if not
            // really overloaded, the collection contains just the original function.
            if (symbol.MethodKind != MethodKind.Ordinary &&
                symbol.MethodKind != MethodKind.Constructor)
            {
                return ImmutableArray.Create((EnvDTE.CodeElement)Parent);
            }

            var overloadsBuilder = ImmutableArray.CreateBuilder<EnvDTE.CodeElement>();
            foreach (var method in symbol.ContainingType.GetMembers(symbol.Name))
            {
                if (method.Kind != SymbolKind.Method)
                {
                    continue;
                }

                var location = method.Locations.FirstOrDefault(l => l.IsInSource);
                if (location != null)
                {
                    var tree = location.SourceTree;
                    var document = this.Workspace.CurrentSolution.GetDocument(tree);

                    var fileCodeModelObject = this.Workspace.GetFileCodeModel(document.Id);
                    var fileCodeModel = ComAggregate.GetManagedObject<FileCodeModel>(fileCodeModelObject);

                    var element = fileCodeModel.CodeElementFromPosition(location.SourceSpan.Start, EnvDTE.vsCMElement.vsCMElementFunction);
                    if (element != null)
                    {
                        overloadsBuilder.Add(element);
                    }
                }
            }

            return overloadsBuilder.ToImmutable();
        }
コード例 #20
0
        public void RemoveMember(object element)
        {
            // Is this an EnvDTE.CodeElement that we created? If so, try to get the underlying code element object.
            var abstractCodeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(
                element
                );

            if (abstractCodeElement == null)
            {
                if (element is EnvDTE.CodeElement codeElement)
                {
                    // Is at least an EnvDTE.CodeElement? If so, try to retrieve it from the Members collection by name.
                    // Note: This might throw an ArgumentException if the name isn't found in the collection.

                    abstractCodeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(
                        this.Members.Item(codeElement.Name)
                        );
                }
                else if (element is string || element is int)
                {
                    // Is this a string or int? If so, try to retrieve it from the Members collection. Again, this will
                    // throw an ArgumentException if the name or index isn't found in the collection.

                    abstractCodeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(
                        this.Members.Item(element)
                        );
                }
            }

            if (abstractCodeElement == null)
            {
                throw new ArgumentException(
                          ServicesVSResources.Element_is_not_valid,
                          nameof(element)
                          );
            }

            abstractCodeElement.Delete();
        }
コード例 #21
0
        private ImmutableArray <EnvDTE.CodeElement> GetParts()
        {
            var partsBuilder = ImmutableArray.CreateBuilder <EnvDTE.CodeElement>();
            var symbol       = ParentType.LookupSymbol();

            foreach (var location in symbol.Locations.Where(l => l.IsInSource))
            {
                var tree     = location.SourceTree;
                var document = this.Workspace.CurrentSolution.GetDocument(tree);

                var fileCodeModelObject = this.Workspace.GetFileCodeModel(document.Id);
                var fileCodeModel       = ComAggregate.GetManagedObject <FileCodeModel>(fileCodeModelObject);

                var element = fileCodeModel.CodeElementFromPosition(location.SourceSpan.Start, ParentType.Kind);
                if (element != null)
                {
                    partsBuilder.Add(element);
                }
            }

            return(partsBuilder.ToImmutable());
        }
コード例 #22
0
        public void RemoveParameter(object element)
        {
            FileCodeModel.EnsureEditor(() =>
            {
                // The parameters are part of the node key, so we need to update it
                // after removing a parameter.
                var node     = LookupNode();
                var nodePath = new SyntaxPath(node);

                var codeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(element);

                codeElement ??= ComAggregate.TryGetManagedObject <AbstractCodeElement>(this.Parameters.Item(element));

                if (codeElement == null)
                {
                    throw new ArgumentException(ServicesVSResources.Element_is_not_valid, nameof(element));
                }

                codeElement.Delete();

                ReacquireNodeKey(nodePath, CancellationToken.None);
            });
        }
コード例 #23
0
ファイル: FileCodeModel.cs プロジェクト: belav/roslyn
        internal void UpdateCodeElementNodeKey(
            AbstractKeyedCodeElement keyedElement,
            SyntaxNodeKey oldNodeKey,
            SyntaxNodeKey newNodeKey
            )
        {
            if (!_codeElementTable.TryGetValue(oldNodeKey, out var codeElement))
            {
                throw new InvalidOperationException(
                          $"Could not find {oldNodeKey} in Code Model element table."
                          );
            }

            _codeElementTable.Remove(oldNodeKey);

            var managedElement = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>(
                codeElement
                );

            if (!object.Equals(managedElement, keyedElement))
            {
                throw new InvalidOperationException(
                          $"Unexpected failure in Code Model while updating node keys {oldNodeKey} -> {newNodeKey}"
                          );
            }

            // If we're updating this element with the same node key as an element that's already in the table,
            // just remove the old element. The old element will continue to function (through its node key), but
            // the new element will replace it in the cache.
            if (_codeElementTable.ContainsKey(newNodeKey))
            {
                _codeElementTable.Remove(newNodeKey);
            }

            _codeElementTable.Add(newNodeKey, codeElement);
        }
コード例 #24
0
        private EnvDTE.CodeElement GetParameterElementForCodeModelEvent(CodeModelEvent codeModelEvent, EnvDTE.CodeElements parentParameters, object parentElement)
        {
            if (parentParameters == null)
            {
                return(null);
            }

            var parameterName = this.CodeModelService.GetName(codeModelEvent.Node);

            if (codeModelEvent.Type == CodeModelEventType.Remove)
            {
                var parentCodeElement = ComAggregate.TryGetManagedObject <AbstractCodeMember>(parentElement);
                if (parentCodeElement != null)
                {
                    return((EnvDTE.CodeElement)CodeParameter.Create(this.State, parentCodeElement, parameterName));
                }
            }
            else
            {
                return(parentParameters.Item(parameterName));
            }

            return(null);
        }
コード例 #25
0
ファイル: FileCodeModel.cs プロジェクト: belav/roslyn
        internal T GetOrCreateCodeElement <T>(SyntaxNode node)
        {
            var nodeKey = CodeModelService.TryGetNodeKey(node);

            if (!nodeKey.IsEmpty)
            {
                // Since the node already has a key, check to see if a code element already
                // exists for it. If so, return that element it it's still valid; otherwise,
                // remove it from the table.
                if (_codeElementTable.TryGetValue(nodeKey, out var codeElement))
                {
                    if (codeElement != null)
                    {
                        var element = ComAggregate.TryGetManagedObject <AbstractCodeElement>(
                            codeElement
                            );
                        if (element.IsValidNode())
                        {
                            if (codeElement is T tcodeElement)
                            {
                                return(tcodeElement);
                            }

                            throw new InvalidOperationException(
                                      $"Found a valid code element for {nodeKey}, but it is not of type, {typeof(T).ToString()}"
                                      );
                        }
                    }
                }

                // Go ahead and remove the nodeKey from the table. At this point, we'll be creating a new one.
                _codeElementTable.Remove(nodeKey);
            }

            return((T)CodeModelService.CreateInternalCodeElement(this.State, this, node));
        }
コード例 #26
0
ファイル: FileCodeModel_Events.cs プロジェクト: khm1600/CJing
        private EnvDTE.CodeElement GetAttributeArgumentForCodeModelEvent(CodeModelEvent codeModelEvent, EnvDTE.CodeElements parentAttributeArguments, object parentElement)
        {
            if (parentAttributeArguments == null)
            {
                return(null);
            }

            CodeModelService.GetAttributeArgumentParentAndIndex(codeModelEvent.Node, out var attributeNode, out var ordinal);

            if (codeModelEvent.Type == CodeModelEventType.Remove)
            {
                var parentCodeElement = ComAggregate.TryGetManagedObject <CodeAttribute>(parentElement);
                if (parentCodeElement != null)
                {
                    return((EnvDTE.CodeElement)CodeAttributeArgument.Create(this.State, parentCodeElement, ordinal));
                }
            }
            else
            {
                return(parentAttributeArguments.Item(ordinal + 1)); // Needs to be 1-based to call back into code model
            }

            return(null);
        }
コード例 #27
0
        internal static EnvDTE.CodeParameter Create(CodeModelState state, ProjectId projectId, IParameterSymbol symbol, AbstractExternalCodeMember parent)
        {
            var element = new ExternalCodeParameter(state, projectId, symbol, parent);

            return((EnvDTE.CodeParameter)ComAggregate.CreateAggregatedObject(element));
        }
コード例 #28
0
ファイル: CodeAccessorFunction.cs プロジェクト: khm1600/CJing
        internal static EnvDTE.CodeFunction Create(CodeModelState state, AbstractCodeMember parent, MethodKind kind)
        {
            var newElement = new CodeAccessorFunction(state, parent, kind);

            return((EnvDTE.CodeFunction)ComAggregate.CreateAggregatedObject(newElement));
        }
コード例 #29
0
 internal ComHandle <THandle, TObject> GetComHandle <THandle, TObject>()
     where THandle : class
     where TObject : ApartmentSensitiveComObject, THandle
 {
     return(new ComHandle <THandle, TObject>((THandle)ComAggregate.CreateAggregatedObject((TObject)this), (TObject)this));
 }
コード例 #30
0
        internal static ICSCodeTypeLocation Create(string externalLocation)
        {
            var result = new CodeTypeLocationExtender(externalLocation);

            return((ICSCodeTypeLocation)ComAggregate.CreateAggregatedObject(result));
        }