Esempio n. 1
0
        public static bool IsChange(this CodeModelEventType eventType)
        {
            if (eventType is CodeModelEventType.Add or CodeModelEventType.Remove)
            {
                return(false);
            }

            // Check that Add and Remove are not set
            if ((eventType & CodeModelEventType.Add) == 0 &&
                (eventType & CodeModelEventType.Remove) == 0)
            {
                // Check that one or more of the change flags are set
                var allChanges =
                    CodeModelEventType.Rename |
                    CodeModelEventType.Unknown |
                    CodeModelEventType.BaseChange |
                    CodeModelEventType.SigChange |
                    CodeModelEventType.TypeRefChange |
                    CodeModelEventType.ArgChange;

                if ((eventType & allChanges) != 0)
                {
                    return(true);
                }
            }

            Debug.Fail("Invalid combination of change type flags!");
            return(false);
        }
Esempio n. 2
0
            protected bool CompareChildren <TNode, TParent>(
                NodeComparison <TNode, TParent> compare,
                IReadOnlyList <TNode> oldChildren,
                IReadOnlyList <TNode> newChildren,
                TParent newNodeParent,
                CodeModelEventType eventType,
                CodeModelEventQueue eventQueue
                )
                where TNode : SyntaxNode
                where TParent : SyntaxNode
            {
                var oldCount = oldChildren.Count;
                var newCount = newChildren.Count;

                if (oldCount == newCount)
                {
                    return(FindDifferentChild(
                               compare,
                               oldChildren,
                               newChildren,
                               newNodeParent,
                               eventQueue
                               ));
                }
                else if (Math.Abs(oldCount - newCount) > MaxChildDelta)
                {
                    // We got two discrepancies, enqueue element changed node for containing node
                    EnqueueChangeEvent(newNodeParent, null, eventType, eventQueue);
                }
                else
                {
                    if (oldCount > newCount)
                    {
                        FindRemovedChild(
                            compare,
                            oldChildren,
                            newChildren,
                            newNodeParent,
                            oldCount - newCount,
                            eventQueue
                            );
                    }
                    else
                    {
                        FindAddedChild(
                            compare,
                            oldChildren,
                            newChildren,
                            newNodeParent,
                            newCount - oldCount,
                            eventQueue
                            );
                    }
                }

                return(false);
            }
Esempio n. 3
0
            // Finds the child node which is different OR enqueues a unknown on containing node.
            private bool FindDifferentChild <TNode, TParent>(
                NodeComparison <TNode, TParent> compare,
                IReadOnlyList <TNode> oldChildren,
                IReadOnlyList <TNode> newChildren,
                TParent newNodeParent,
                CodeModelEventType codeModelEventType,
                CodeModelEventQueue eventQueue)
                where TNode : SyntaxNode
                where TParent : SyntaxNode
            {
                Debug.Assert(oldChildren.Count == newChildren.Count);

                var eventCount = eventQueue != null
                    ? eventQueue.Count
                    : 0;

                var hasChanges = false;

                // Find first child that is different.
                int i;

                for (i = 0; i < oldChildren.Count; i++)
                {
                    if (!compare(oldChildren[i], newChildren[i], newNodeParent, eventQueue))
                    {
                        hasChanges = true;
                        i++;
                        break;
                    }
                }

                // Look for a second different child. If there is one, we'll throw away any events from
                // the first different child and enqueue an unknown event on the containing node.
                for (; i < oldChildren.Count; i++)
                {
                    if (!compare(oldChildren[i], newChildren[i], newNodeParent, null))
                    {
                        // rollback any events added by the first difference
                        if (eventQueue != null)
                        {
                            while (eventQueue.Count > eventCount)
                            {
                                eventQueue.Discard();
                            }
                        }

                        EnqueueChangeEvent(newNodeParent, null, CodeModelEventType.Unknown, eventQueue);
                        return(false);
                    }
                }

                return(!hasChanges);
            }
Esempio n. 4
0
            private void FindRemovedChild <TNode, TParent>(
                NodeComparison <TNode, TParent> compare,
                IReadOnlyList <TNode> oldChildren,
                IReadOnlyList <TNode> newChildren,
                TParent newNodeParent,
                CodeModelEventType codeModelEventType,
                int delta,
                CodeModelEventQueue eventQueue)
                where TNode : SyntaxNode
                where TParent : SyntaxNode
            {
                Debug.Assert(oldChildren.Count - delta == newChildren.Count);

                // The strategy is to assume that all of the removed children are contiguous.
                // If that turns out not to be the case, an unknown change event is raised
                // for the containing node.

                var firstRemoved = -1;

                // Look for the first different child. If there is one, track that index as
                // the first added node.
                int oldIndex, newIndex;

                for (oldIndex = 0, newIndex = 0; oldIndex < oldChildren.Count; oldIndex++, newIndex++)
                {
                    if (newIndex >= newChildren.Count || !compare(oldChildren[oldIndex], newChildren[newIndex], newNodeParent, null))
                    {
                        firstRemoved = oldIndex;
                        oldIndex    += delta;
                        break;
                    }
                }

                // Look for a second different child. If there is one, we'll throw away any events from
                // the first different child and enqueue an unknown event on the containing node.
                for (; oldIndex < oldChildren.Count; oldIndex++, newIndex++)
                {
                    if (!compare(oldChildren[oldIndex], newChildren[newIndex], newNodeParent, null))
                    {
                        EnqueueChangeEvent(newNodeParent, null, CodeModelEventType.Unknown, eventQueue);
                        return;
                    }
                }

                if (firstRemoved >= 0)
                {
                    for (var i = 0; i < delta; i++)
                    {
                        EnqueueRemoveEvent(oldChildren[firstRemoved + i], newNodeParent, eventQueue);
                    }
                }
            }
 private static void ChangeEventQueueForAttributes(
     AttributeSyntax attribute,
     SyntaxNode parent,
     CodeModelEventType eventType,
     CodeModelEventQueue eventQueue
     )
 {
     if (parent is BaseFieldDeclarationSyntax baseField)
     {
         foreach (var variableDeclarator in baseField.Declaration.Variables)
         {
             eventQueue.EnqueueChangeEvent(attribute, variableDeclarator, eventType);
         }
     }
     else
     {
         eventQueue.EnqueueChangeEvent(attribute, parent, eventType);
     }
 }
            protected override void EnqueueChangeEvent(
                SyntaxNode node,
                SyntaxNode parent,
                CodeModelEventType eventType,
                CodeModelEventQueue eventQueue
                )
            {
                if (eventQueue == null)
                {
                    return;
                }

                if (node is IncompleteMemberSyntax)
                {
                    return;
                }

                if (node is BaseFieldDeclarationSyntax baseField)
                {
                    foreach (var variableDeclarator in baseField.Declaration.Variables)
                    {
                        eventQueue.EnqueueChangeEvent(variableDeclarator, parent, eventType);
                    }
                }
                else if (node is AttributeListSyntax attributeList)
                {
                    foreach (var attribute in attributeList.Attributes)
                    {
                        ChangeEventQueueForAttributes(attribute, parent, eventType, eventQueue);
                    }
                }
                else if (node is AttributeSyntax attribute)
                {
                    ChangeEventQueueForAttributes(attribute, parent, eventType, eventQueue);
                }
                else
                {
                    eventQueue.EnqueueChangeEvent(node, parent, eventType);
                }
            }
Esempio n. 7
0
        private EnvDTE80.vsCMChangeKind ConvertToChangeKind(CodeModelEventType eventType)
        {
            EnvDTE80.vsCMChangeKind result = 0;

            if ((eventType & CodeModelEventType.Rename) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindRename;
            }

            if ((eventType & CodeModelEventType.Unknown) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindUnknown;
            }

            if ((eventType & CodeModelEventType.BaseChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindBaseChange;
            }

            if ((eventType & CodeModelEventType.TypeRefChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindTypeRefChange;
            }

            if ((eventType & CodeModelEventType.SigChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindSignatureChange;
            }

            if ((eventType & CodeModelEventType.ArgChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindArgumentChange;
            }

            return(result);
        }
Esempio n. 8
0
        private EnvDTE.CodeElement GetAttributeElementForCodeModelEvent(SyntaxNode node, SyntaxNode parentNode, CodeModelEventType eventType, EnvDTE.CodeElements elementsToSearch, object parentObject)
        {
            if (elementsToSearch == null)
            {
                return(null);
            }

            string name;
            int    ordinal;

            CodeModelService.GetAttributeNameAndOrdinal(parentNode, node, out name, out ordinal);

            if (eventType == CodeModelEventType.Remove)
            {
                if (parentObject is EnvDTE.CodeElement)
                {
                    var parentCodeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(parentObject);
                    if (parentCodeElement != null)
                    {
                        return((EnvDTE.CodeElement)CodeAttribute.Create(this.State, this, parentCodeElement, name, ordinal));
                    }
                }
                else if (parentObject is EnvDTE.FileCodeModel)
                {
                    var parentFileCodeModel = ComAggregate.TryGetManagedObject <FileCodeModel>(parentObject);
                    if (parentFileCodeModel != null && parentFileCodeModel == this)
                    {
                        return((EnvDTE.CodeElement)CodeAttribute.Create(this.State, this, null, name, ordinal));
                    }
                }
            }
            else
            {
                int testOridinal = 0;
                foreach (EnvDTE.CodeElement element in elementsToSearch)
                {
                    if (element.Kind != EnvDTE.vsCMElement.vsCMElementAttribute)
                    {
                        continue;
                    }

                    if (element.Name == name)
                    {
                        if (ordinal == testOridinal)
                        {
                            return(element);
                        }

                        testOridinal++;
                    }
                }
            }

            return(null);
        }
 private static void ChangeEventQueueForAttributes(AttributeSyntax attribute, SyntaxNode parent, CodeModelEventType eventType, CodeModelEventQueue eventQueue)
 {
     if (parent is BaseFieldDeclarationSyntax)
     {
         foreach (var variableDeclarator in ((BaseFieldDeclarationSyntax)parent).Declaration.Variables)
         {
             eventQueue.EnqueueChangeEvent(attribute, variableDeclarator, eventType);
         }
     }
     else
     {
         eventQueue.EnqueueChangeEvent(attribute, parent, eventType);
     }
 }
            protected override void EnqueueChangeEvent(SyntaxNode node, SyntaxNode parent, CodeModelEventType eventType, CodeModelEventQueue eventQueue)
            {
                if (eventQueue == null)
                {
                    return;
                }

                if (node is IncompleteMemberSyntax)
                {
                    return;
                }

                if (node is BaseFieldDeclarationSyntax)
                {
                    foreach (var variableDeclarator in ((BaseFieldDeclarationSyntax)node).Declaration.Variables)
                    {
                        eventQueue.EnqueueChangeEvent(variableDeclarator, parent, eventType);
                    }
                }
                else if (node is AttributeListSyntax)
                {
                    foreach (var attribute in ((AttributeListSyntax)node).Attributes)
                    {
                        ChangeEventQueueForAttributes(attribute, parent, eventType, eventQueue);
                    }
                }
                else if (node is AttributeSyntax)
                {
                    ChangeEventQueueForAttributes((AttributeSyntax)node, parent, eventType, eventQueue);
                }
                else
                {
                    eventQueue.EnqueueChangeEvent(node, parent, eventType);
                }
            }
Esempio n. 11
0
        private EnvDTE80.vsCMChangeKind ConvertToChangeKind(CodeModelEventType eventType)
        {
            EnvDTE80.vsCMChangeKind result = 0;

            if ((eventType & CodeModelEventType.Rename) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindRename;
            }

            if ((eventType & CodeModelEventType.Unknown) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindUnknown;
            }

            if ((eventType & CodeModelEventType.BaseChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindBaseChange;
            }

            if ((eventType & CodeModelEventType.TypeRefChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindTypeRefChange;
            }

            if ((eventType & CodeModelEventType.SigChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindSignatureChange;
            }

            if ((eventType & CodeModelEventType.ArgChange) != 0)
            {
                result |= EnvDTE80.vsCMChangeKind.vsCMChangeKindArgumentChange;
            }

            return result;
        }
Esempio n. 12
0
        private EnvDTE.CodeElement GetAttributeElementForCodeModelEvent(SyntaxNode node, SyntaxNode parentNode, CodeModelEventType eventType, EnvDTE.CodeElements elementsToSearch, object parentObject)
        {
            if (elementsToSearch == null)
            {
                return null;
            }

            CodeModelService.GetAttributeNameAndOrdinal(parentNode, node, out var name, out var ordinal);

            if (eventType == CodeModelEventType.Remove)
            {
                if (parentObject is EnvDTE.CodeElement)
                {
                    var parentCodeElement = ComAggregate.TryGetManagedObject<AbstractCodeElement>(parentObject);
                    if (parentCodeElement != null)
                    {
                        return (EnvDTE.CodeElement)CodeAttribute.Create(this.State, this, parentCodeElement, name, ordinal);
                    }
                }
                else if (parentObject is EnvDTE.FileCodeModel)
                {
                    var parentFileCodeModel = ComAggregate.TryGetManagedObject<FileCodeModel>(parentObject);
                    if (parentFileCodeModel != null && parentFileCodeModel == this)
                    {
                        return (EnvDTE.CodeElement)CodeAttribute.Create(this.State, this, null, name, ordinal);
                    }
                }
            }
            else
            {
                int testOrdinal = 0;
                foreach (EnvDTE.CodeElement element in elementsToSearch)
                {
                    if (element.Kind != EnvDTE.vsCMElement.vsCMElementAttribute)
                    {
                        continue;
                    }

                    if (element.Name == name)
                    {
                        if (ordinal == testOrdinal)
                        {
                            return element;
                        }

                        testOrdinal++;
                    }
                }
            }

            return null;
        }
Esempio n. 13
0
 public void EnqueueChangeEvent(SyntaxNode node, SyntaxNode parent, CodeModelEventType eventType)
 {
     EnqueueEvent(new CodeModelEvent(node, parent, eventType));
 }
Esempio n. 14
0
 public CodeModelEvent(SyntaxNode node, SyntaxNode parentNode, CodeModelEventType type)
 {
     this.Node       = node;
     this.ParentNode = parentNode;
     this.Type       = type;
 }
Esempio n. 15
0
 protected abstract void EnqueueChangeEvent(SyntaxNode node, SyntaxNode parent, CodeModelEventType eventType, CodeModelEventQueue eventQueue);
Esempio n. 16
0
 public void EnqueueChangeEvent(SyntaxNode node, SyntaxNode parent, CodeModelEventType eventType)
 {
     EnqueueEvent(new CodeModelEvent(node, parent, eventType));
 }