private bool IsAttributeValueContext(SyntaxToken token, out string tagName, out string attributeName) { XmlAttributeSyntax attributeSyntax = null; if (token.Parent.IsKind(SyntaxKind.IdentifierName) && token.Parent.IsParentKind(SyntaxKind.XmlNameAttribute, out XmlNameAttributeSyntax xmlName)) { // Handle the special 'name' attributes: name="bar$$ attributeSyntax = xmlName; } else if (token.IsKind(SyntaxKind.XmlTextLiteralToken) && token.Parent.IsKind(SyntaxKind.XmlTextAttribute, out XmlTextAttributeSyntax xmlText)) { // Handle the other general text attributes: foo="bar$$ attributeSyntax = xmlText; } else if (token.Parent.IsKind(SyntaxKind.XmlNameAttribute, out attributeSyntax) || token.Parent.IsKind(SyntaxKind.XmlTextAttribute, out attributeSyntax)) { // When there's no attribute value yet, the parent attribute is returned: // name="$$ // foo="$$ if (token != attributeSyntax.StartQuoteToken) { attributeSyntax = null; } } if (attributeSyntax != null) { attributeName = attributeSyntax.Name.LocalName.ValueText; var emptyElement = attributeSyntax.GetAncestor <XmlEmptyElementSyntax>(); if (emptyElement != null) { // Empty element tags: <tag attr=... /> tagName = emptyElement.Name.LocalName.Text; return(true); } var startTagSyntax = token.GetAncestor <XmlElementStartTagSyntax>(); if (startTagSyntax != null) { // Non-empty element start tags: <tag attr=... > tagName = startTagSyntax.Name.LocalName.Text; return(true); } } attributeName = null; tagName = null; return(false); }
/// <summary> /// This is used to determine whether or not the current caret location is in an attribute value context /// </summary> /// <param name="token">The token to check</param> /// <param name="elementName">On return, this will contain the element name if it is an attribute value /// context, null if not.</param> /// <param name="attributeName">On return, this will contain the attribute name if it is an attribute /// value context, null if not.</param> /// <returns>True if it is within the attribute value context, false if not.</returns> private static bool IsAttributeValueContext(SyntaxToken token, out string elementName, out string attributeName) { XmlAttributeSyntax attributeSyntax = null; if (token.IsKind(SyntaxKind.XmlTextLiteralToken) && token.Parent.IsKind(SyntaxKind.XmlTextAttribute)) { // General attribute: attr="value| attributeSyntax = (XmlTextAttributeSyntax)token.Parent; } else if (token.Parent.IsKind(SyntaxKind.XmlNameAttribute) || token.Parent.IsKind(SyntaxKind.XmlTextAttribute)) { // Return the parent attribute if there is no value yet: attr="| attributeSyntax = (XmlAttributeSyntax)token.Parent; if (token != attributeSyntax.StartQuoteToken) { attributeSyntax = null; } } if (attributeSyntax != null) { attributeName = attributeSyntax.Name.LocalName.ValueText; var emptyElement = attributeSyntax.GetAncestor <XmlEmptyElementSyntax>(); if (emptyElement != null) { // Self-closing or incomplete element: <elem attr="|" /> or <elem attr="|" elementName = emptyElement.Name.LocalName.Text; return(true); } var startTag = token.Parent?.FirstAncestorOrSelf <XmlElementStartTagSyntax>(); if (startTag != null) { // Start tag: <elem attr="|"> elementName = startTag.Name.LocalName.Text; return(true); } } attributeName = elementName = null; return(false); }