private void CompareCompilationUnits( CompilationUnitSyntax oldCompilationUnit, CompilationUnitSyntax newCompilationUnit, CodeModelEventQueue eventQueue ) { // Note: In the C# legacy code model, events are generated for the top-level // namespace that is at the root of every parse tree. In the Roslyn C# code model // implementation, we won't bother. CompareChildren( CompareNamespacesOrTypes, GetValidMembers(oldCompilationUnit), GetValidMembers(newCompilationUnit), (SyntaxNode)null, CodeModelEventType.Unknown, 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); } }
private bool CompareFieldDeclarations( BaseFieldDeclarationSyntax oldField, BaseFieldDeclarationSyntax newField, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldField != null && newField != null); bool same = true; same &= CompareChildren( CompareVariableDeclarators, oldField.Declaration.Variables.AsReadOnlyList(), newField.Declaration.Variables.AsReadOnlyList(), newNodeParent, CodeModelEventType.Unknown, eventQueue); // If modifiers have changed enqueue a element changed (unknown change) node if ((oldField.Kind() != newField.Kind()) || !CompareModifiers(oldField, newField)) { EnqueueChangeEvent(newField, newNodeParent, CodeModelEventType.Unknown, eventQueue); same = false; } // If type had changed enqueue a element changed (typeref changed) node if (!CompareTypes(oldField.Declaration.Type, newField.Declaration.Type)) { EnqueueChangeEvent(newField, newNodeParent, CodeModelEventType.TypeRefChange, eventQueue); same = false; } same &= CompareChildren( CompareAttributeLists, oldField.AttributeLists.AsReadOnlyList(), newField.AttributeLists.AsReadOnlyList(), newField, CodeModelEventType.Unknown, eventQueue); return(same); }
private bool CompareMemberDeclarations( MemberDeclarationSyntax oldMember, MemberDeclarationSyntax newMember, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldMember != null && newMember != null); // If the kind doesn't match, it has to be a remove/add. if (oldMember.Kind() != newMember.Kind()) { EnqueueRemoveEvent(oldMember, newNodeParent, eventQueue); EnqueueAddEvent(newMember, newNodeParent, eventQueue); return(false); } if (oldMember is BaseTypeDeclarationSyntax || oldMember is DelegateDeclarationSyntax) { return(CompareTypeDeclarations(oldMember, newMember, newNodeParent, eventQueue)); } else if (oldMember is BaseMethodDeclarationSyntax) { return(CompareMethodDeclarations((BaseMethodDeclarationSyntax)oldMember, (BaseMethodDeclarationSyntax)newMember, newNodeParent, eventQueue)); } else if (oldMember is BaseFieldDeclarationSyntax) { return(CompareFieldDeclarations((BaseFieldDeclarationSyntax)oldMember, (BaseFieldDeclarationSyntax)newMember, newNodeParent, eventQueue)); } else if (oldMember is BasePropertyDeclarationSyntax) { return(ComparePropertyDeclarations((BasePropertyDeclarationSyntax)oldMember, (BasePropertyDeclarationSyntax)newMember, newNodeParent, eventQueue)); } else if (oldMember is EnumMemberDeclarationSyntax) { return(CompareEnumMemberDeclarations((EnumMemberDeclarationSyntax)oldMember, (EnumMemberDeclarationSyntax)newMember, newNodeParent, eventQueue)); } throw new NotImplementedException(); }
private bool CompareNamespacesOrTypes( MemberDeclarationSyntax oldNamespaceOrType, MemberDeclarationSyntax newNamespaceOrType, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue ) { // If the kind doesn't match, it has to be a remove/add. if (oldNamespaceOrType.Kind() != newNamespaceOrType.Kind()) { EnqueueRemoveEvent(oldNamespaceOrType, newNodeParent, eventQueue); EnqueueAddEvent(newNamespaceOrType, newNodeParent, eventQueue); return(false); } if ( oldNamespaceOrType is BaseTypeDeclarationSyntax || oldNamespaceOrType is DelegateDeclarationSyntax ) { return(CompareTypeDeclarations( oldNamespaceOrType, newNamespaceOrType, newNodeParent, eventQueue )); } else if (oldNamespaceOrType is NamespaceDeclarationSyntax namespaceDecl) { return(CompareNamespaceDeclarations( namespaceDecl, (NamespaceDeclarationSyntax)newNamespaceOrType, newNodeParent, eventQueue )); } return(false); }
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); } }
private bool CompareMemberDeclarations( MemberDeclarationSyntax oldMember, MemberDeclarationSyntax newMember, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldMember != null && newMember != null); // If the kind doesn't match, it has to be a remove/add. if (oldMember.Kind() != newMember.Kind()) { EnqueueRemoveEvent(oldMember, newNodeParent, eventQueue); EnqueueAddEvent(newMember, newNodeParent, eventQueue); return(false); } if (oldMember is BaseTypeDeclarationSyntax or DelegateDeclarationSyntax) { return(CompareTypeDeclarations(oldMember, newMember, newNodeParent, eventQueue)); }
private bool CompareAttributes( AttributeSyntax oldAttribute, AttributeSyntax newAttribute, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue ) { Debug.Assert(oldAttribute != null && newAttribute != null); var same = true; if (!CompareNames(oldAttribute.Name, newAttribute.Name)) { EnqueueChangeEvent( newAttribute, newNodeParent, CodeModelEventType.Rename, eventQueue ); same = false; } // If arguments have changed enqueue a element changed (arguments changed) node if ( !CompareAttributeArguments(oldAttribute.ArgumentList, newAttribute.ArgumentList) ) { EnqueueChangeEvent( newAttribute, newNodeParent, CodeModelEventType.ArgChange, eventQueue ); same = false; } return(same); }
private bool CompareEnumMemberDeclarations( EnumMemberDeclarationSyntax oldEnumMember, EnumMemberDeclarationSyntax newEnumMember, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue ) { Debug.Assert(oldEnumMember != null && newEnumMember != null); var same = true; if ( !StringComparer.Ordinal.Equals( CodeModelService.GetName(oldEnumMember), CodeModelService.GetName(newEnumMember) ) ) { EnqueueChangeEvent( newEnumMember, newNodeParent, CodeModelEventType.Rename, eventQueue ); same = false; } same &= CompareChildren( CompareAttributeLists, oldEnumMember.AttributeLists.AsReadOnlyList(), newEnumMember.AttributeLists.AsReadOnlyList(), newEnumMember, CodeModelEventType.Unknown, eventQueue ); return(same); }
private bool CompareNamespaceDeclarations( NamespaceDeclarationSyntax oldNamespace, NamespaceDeclarationSyntax newNamespace, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldNamespace != null && newNamespace != null); // Check if the namespace nodes are identical w.r.t Name if (!CompareNames(oldNamespace.Name, newNamespace.Name)) { var change = CompareRenamedDeclarations( CompareNamespacesOrTypes, GetValidMembers(oldNamespace.Members), GetValidMembers(newNamespace.Members), oldNamespace, newNamespace, newNodeParent, eventQueue); if (change == DeclarationChange.NameOnly) { EnqueueChangeEvent(newNamespace, newNodeParent, CodeModelEventType.Rename, eventQueue); } return(false); } return(CompareChildren( CompareNamespacesOrTypes, GetValidMembers(oldNamespace.Members), GetValidMembers(newNamespace.Members), newNamespace, CodeModelEventType.Unknown, eventQueue)); }
private bool CompareParameters(ParameterSyntax oldParameter, ParameterSyntax newParameter, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldParameter != null && newParameter != null); var same = true; if (!StringComparer.Ordinal.Equals(CodeModelService.GetName(oldParameter), CodeModelService.GetName(newParameter))) { EnqueueChangeEvent(newParameter, newNodeParent, CodeModelEventType.Rename, eventQueue); same = false; } // If modifiers or the type have changed enqueue a element changed (unknown change) node if (!CompareModifiers(oldParameter, newParameter) || !CompareTypes(oldParameter.Type, newParameter.Type)) { EnqueueChangeEvent(newParameter, newNodeParent, CodeModelEventType.Unknown, eventQueue); same = false; } return(same); }
protected override void EnqueueRemoveEvent(SyntaxNode node, SyntaxNode parent, CodeModelEventQueue eventQueue) { if (eventQueue == null) { return; } if (node is IncompleteMemberSyntax) { return; } if (node is BaseFieldDeclarationSyntax) { foreach (var variableDeclarator in ((BaseFieldDeclarationSyntax)node).Declaration.Variables) { eventQueue.EnqueueRemoveEvent(variableDeclarator, parent); } } else if (node is AttributeListSyntax) { foreach (var attribute in ((AttributeListSyntax)node).Attributes) { AddEventToEventQueueForAttributes(attribute, parent, eventQueue.EnqueueRemoveEvent); } } else if (node is AttributeSyntax) { AddEventToEventQueueForAttributes((AttributeSyntax)node, parent, eventQueue.EnqueueRemoveEvent); } else { eventQueue.EnqueueRemoveEvent(node, parent); } }
protected override void CollectCore(SyntaxNode oldRoot, SyntaxNode newRoot, CodeModelEventQueue eventQueue) { CompareCompilationUnits((CompilationUnitSyntax)oldRoot, (CompilationUnitSyntax)newRoot, eventQueue); }
private bool CompareTypeDeclarations( MemberDeclarationSyntax oldMember, MemberDeclarationSyntax newMember, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldMember != null && newMember != null); Debug.Assert(oldMember is BaseTypeDeclarationSyntax || oldMember is DelegateDeclarationSyntax); Debug.Assert(newMember is BaseTypeDeclarationSyntax || newMember is DelegateDeclarationSyntax); // If the kind doesn't match, it has to be a remove/add. if (oldMember.Kind() != newMember.Kind()) { EnqueueRemoveEvent(oldMember, newNodeParent, eventQueue); EnqueueAddEvent(newMember, newNodeParent, eventQueue); return(false); } if (oldMember is BaseTypeDeclarationSyntax) { var oldType = (BaseTypeDeclarationSyntax)oldMember; var newType = (BaseTypeDeclarationSyntax)newMember; var oldMembers = oldType is TypeDeclarationSyntax ? GetValidMembers(((TypeDeclarationSyntax)oldType).Members) : GetValidMembers(((EnumDeclarationSyntax)oldType).Members); var newMembers = newType is TypeDeclarationSyntax ? GetValidMembers(((TypeDeclarationSyntax)newType).Members) : GetValidMembers(((EnumDeclarationSyntax)newType).Members); bool same = true; // If the type name is different, it might mean that the whole type has been removed and a new one added. // In that case, we shouldn't do any other checks and instead return immediately. if (!StringComparer.Ordinal.Equals(oldType.Identifier.ToString(), newType.Identifier.ToString())) { var change = CompareRenamedDeclarations(CompareMemberDeclarations, oldMembers, newMembers, oldType, newType, newNodeParent, eventQueue); if (change == DeclarationChange.WholeDeclaration) { return(false); } same = false; EnqueueChangeEvent(newType, newNodeParent, CodeModelEventType.Rename, eventQueue); } if (!CompareModifiers(oldType, newType)) { same = false; EnqueueChangeEvent(newType, newNodeParent, CodeModelEventType.Unknown, eventQueue); } if (!CompareBaseLists(oldType, newType)) { same = false; EnqueueChangeEvent(newType, newNodeParent, CodeModelEventType.BaseChange, eventQueue); } same &= CompareChildren( CompareAttributeLists, oldType.AttributeLists.AsReadOnlyList(), newType.AttributeLists.AsReadOnlyList(), newType, CodeModelEventType.Unknown, eventQueue); same &= CompareChildren(CompareMemberDeclarations, oldMembers, newMembers, newType, CodeModelEventType.Unknown, eventQueue); return(same); } else if (oldMember is DelegateDeclarationSyntax) { var oldDelegate = (DelegateDeclarationSyntax)oldMember; var newDelegate = (DelegateDeclarationSyntax)newMember; bool same = true; // If the delegate name is different, it might mean that the whole delegate has been removed and a new one added. // In that case, we shouldn't do any other checks and instead return immediately. if (!StringComparer.Ordinal.Equals(oldDelegate.Identifier.ToString(), newDelegate.Identifier.ToString())) { var change = CompareRenamedDeclarations( CompareParameters, oldDelegate.ParameterList.Parameters.AsReadOnlyList(), newDelegate.ParameterList.Parameters.AsReadOnlyList(), oldDelegate, newDelegate, newNodeParent, eventQueue); if (change == DeclarationChange.WholeDeclaration) { return(false); } same = false; EnqueueChangeEvent(newDelegate, newNodeParent, CodeModelEventType.Rename, eventQueue); } if (!CompareModifiers(oldDelegate, newDelegate)) { same = false; EnqueueChangeEvent(newDelegate, newNodeParent, CodeModelEventType.Unknown, eventQueue); } if (!CompareTypes(oldDelegate.ReturnType, newDelegate.ReturnType)) { same = false; EnqueueChangeEvent(newDelegate, newNodeParent, CodeModelEventType.TypeRefChange, eventQueue); } same &= CompareChildren( CompareAttributeLists, oldDelegate.AttributeLists.AsReadOnlyList(), newDelegate.AttributeLists.AsReadOnlyList(), newDelegate, CodeModelEventType.Unknown, eventQueue); same &= CompareChildren( CompareParameters, oldDelegate.ParameterList.Parameters.AsReadOnlyList(), newDelegate.ParameterList.Parameters.AsReadOnlyList(), newDelegate, CodeModelEventType.SigChange, eventQueue); return(same); } return(false); }
private bool CompareMethodDeclarations( BaseMethodDeclarationSyntax oldMethod, BaseMethodDeclarationSyntax newMethod, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldMethod != null && newMethod != null); if (!StringComparer.Ordinal.Equals(CodeModelService.GetName(oldMethod), CodeModelService.GetName(newMethod))) { var change = CompareRenamedDeclarations( CompareParameters, oldMethod.ParameterList.Parameters.AsReadOnlyList(), newMethod.ParameterList.Parameters.AsReadOnlyList(), oldMethod, newMethod, newNodeParent, eventQueue); if (change == DeclarationChange.NameOnly) { EnqueueChangeEvent(newMethod, newNodeParent, CodeModelEventType.Rename, eventQueue); } return(false); } else { bool same = true; if (!CompareModifiers(oldMethod, newMethod)) { same = false; EnqueueChangeEvent(newMethod, newNodeParent, CodeModelEventType.Unknown, eventQueue); } if (!CompareTypes(GetReturnType(oldMethod), GetReturnType(newMethod))) { same = false; EnqueueChangeEvent(newMethod, newNodeParent, CodeModelEventType.TypeRefChange, eventQueue); } same &= CompareChildren( CompareAttributeLists, oldMethod.AttributeLists.AsReadOnlyList(), newMethod.AttributeLists.AsReadOnlyList(), newMethod, CodeModelEventType.Unknown, eventQueue); same &= CompareChildren( CompareParameters, oldMethod.ParameterList.Parameters.AsReadOnlyList(), newMethod.ParameterList.Parameters.AsReadOnlyList(), newMethod, CodeModelEventType.SigChange, eventQueue); return(same); } }
private bool ComparePropertyDeclarations( BasePropertyDeclarationSyntax oldProperty, BasePropertyDeclarationSyntax newProperty, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue ) { Debug.Assert(oldProperty != null && newProperty != null); var same = true; if ( !StringComparer.Ordinal.Equals( CodeModelService.GetName(oldProperty), CodeModelService.GetName(newProperty) ) ) { EnqueueChangeEvent( newProperty, newNodeParent, CodeModelEventType.Rename, eventQueue ); same = false; } // If modifiers have changed enqueue a element changed (unknown change) node if (!CompareModifiers(oldProperty, newProperty)) { EnqueueChangeEvent( newProperty, newNodeParent, CodeModelEventType.Unknown, eventQueue ); same = false; } // If return type had changed enqueue a element changed (typeref changed) node if (!CompareTypes(oldProperty.Type, newProperty.Type)) { EnqueueChangeEvent( newProperty, newNodeParent, CodeModelEventType.TypeRefChange, eventQueue ); same = false; } same &= CompareChildren( CompareAttributeLists, oldProperty.AttributeLists.AsReadOnlyList(), newProperty.AttributeLists.AsReadOnlyList(), newProperty, CodeModelEventType.Unknown, eventQueue ); if (oldProperty is IndexerDeclarationSyntax oldIndexer) { var newIndexer = (IndexerDeclarationSyntax)newProperty; same &= CompareChildren( CompareParameters, oldIndexer.ParameterList.Parameters.AsReadOnlyList(), newIndexer.ParameterList.Parameters.AsReadOnlyList(), newIndexer, CodeModelEventType.SigChange, eventQueue ); } return(same); }