private void ProcessDuplicates(IntermediateNode parent) { // Reverse order because we will remove nodes. // // Each 'property' node could be duplicated if there are multiple tag helpers that match that // particular attribute. This is likely to happen when a component also defines something like // OnClick. We want to remove the 'onclick' and let it fall back to be handled by the component. for (var i = parent.Children.Count - 1; i >= 0; i--) { var eventHandler = parent.Children[i] as TagHelperPropertyIntermediateNode; if (eventHandler != null && eventHandler.TagHelper != null && eventHandler.TagHelper.IsEventHandlerTagHelper()) { for (var j = 0; j < parent.Children.Count; j++) { var componentAttribute = parent.Children[j] as ComponentAttributeIntermediateNode; if (componentAttribute != null && componentAttribute.TagHelper != null && componentAttribute.TagHelper.IsComponentTagHelper() && componentAttribute.AttributeName == eventHandler.AttributeName) { // Found a duplicate - remove the 'fallback' in favor of the component's own handling. parent.Children.RemoveAt(i); break; } } } } // If we still have duplicates at this point then they are genuine conflicts. var duplicates = parent.Children .OfType <TagHelperDirectiveAttributeIntermediateNode>() .Where(p => p.TagHelper?.IsEventHandlerTagHelper() ?? false) .GroupBy(p => p.AttributeName) .Where(g => g.Count() > 1); foreach (var duplicate in duplicates) { parent.Diagnostics.Add(ComponentDiagnosticFactory.CreateEventHandler_Duplicates( parent.Source, duplicate.Key, duplicate.ToArray())); foreach (var property in duplicate) { parent.Children.Remove(property); } } var parameterDuplicates = parent.Children .OfType <TagHelperDirectiveAttributeParameterIntermediateNode>() .Where(p => p.TagHelper?.IsEventHandlerTagHelper() ?? false) .GroupBy(p => p.AttributeName) .Where(g => g.Count() > 1); foreach (var duplicate in parameterDuplicates) { parent.Diagnostics.Add(ComponentDiagnosticFactory.CreateEventHandlerParameter_Duplicates( parent.Source, duplicate.Key, duplicate.ToArray())); foreach (var property in duplicate) { parent.Children.Remove(property); } } }