private void RewriteUsage(ClassDeclarationIntermediateNode classNode, TagHelperIntermediateNode node, int index, ComponentAttributeExtensionNode attributeNode) { // If we can't get a nonempty attribute name, do nothing because there will // already be a diagnostic for empty values var identifierToken = DetermineIdentifierToken(attributeNode); if (identifierToken != null) { node.Children.Remove(attributeNode); // Determine whether this is an element capture or a component capture, and // if applicable the type name that will appear in the resulting capture code var componentTagHelper = node.TagHelpers.FirstOrDefault(x => x.IsComponentTagHelper()); if (componentTagHelper != null) { // For components, the RefExtensionNode must go after all ComponentAttributeExtensionNode // and ComponentBodyExtensionNode siblings because they translate to AddAttribute calls. // We can therefore put it immediately before the ComponentCloseExtensionNode. var componentCloseNodePosition = LastIndexOf(node.Children, n => n is ComponentCloseExtensionNode); if (componentCloseNodePosition < 0) { // Should never happen - would imply we're running the lowering passes in the wrong order throw new InvalidOperationException($"Cannot find {nameof(ComponentCloseExtensionNode)} among ref node siblings."); } var refExtensionNode = new RefExtensionNode(identifierToken, componentTagHelper.GetTypeName()); node.Children.Insert(componentCloseNodePosition, refExtensionNode); } else { // For elements, it doesn't matter how the RefExtensionNode is positioned // among the children, as the node writer takes care of emitting the // code at the right point after the AddAttribute calls node.Children.Add(new RefExtensionNode(identifierToken)); } } }
public abstract void WriteReferenceCapture(CodeRenderingContext context, RefExtensionNode node);
protected abstract void WriteReferenceCaptureInnards(CodeRenderingContext context, RefExtensionNode node, bool shouldTypeCheck);