private void BindName( XAttribute attribute, CSharpSyntaxNode originatingSyntax, bool isParameter, bool isTypeParameterRef ) { XmlNameAttributeSyntax attrSyntax = ParseNameAttribute( attribute.ToString(), attribute.Parent.Name.LocalName ); // CONSIDER: It would be easy to construct an XmlLocation from the XAttribute, so that // we could point the user at the actual problem. Location sourceLocation = originatingSyntax.Location; RecordSyntaxDiagnostics(attrSyntax, sourceLocation); // Respects DocumentationMode. MemberDeclarationSyntax memberDeclSyntax = BinderFactory.GetAssociatedMemberForXmlSyntax(originatingSyntax); Debug.Assert( memberDeclSyntax != null, "Why are we processing a documentation comment that is not attached to a member declaration?" ); var nameDiagnostics = BindingDiagnosticBag.GetInstance(_diagnostics); Binder binder = MakeNameBinder( isParameter, isTypeParameterRef, _memberSymbol, _compilation ); DocumentationCommentCompiler.BindName( attrSyntax, binder, _memberSymbol, ref _documentedParameters, ref _documentedTypeParameters, nameDiagnostics ); RecordBindingDiagnostics(nameDiagnostics, sourceLocation); // Respects DocumentationMode. nameDiagnostics.Free(); }
public override void DefaultVisit(SyntaxNode node) { SyntaxKind nodeKind = node.CSharpKind(); bool diagnose = ((SyntaxTree)node.SyntaxTree).ReportDocumentationCommentDiagnostics(); if (nodeKind == SyntaxKind.XmlCrefAttribute) { XmlCrefAttributeSyntax crefAttr = (XmlCrefAttributeSyntax)node; CrefSyntax cref = crefAttr.Cref; BinderFactory factory = compilation.GetBinderFactory(cref.SyntaxTree); Binder binder = factory.GetBinder(cref); // Do this for the diagnostics, even if it won't be written. DiagnosticBag crefDiagnostics = DiagnosticBag.GetInstance(); string docCommentId = GetDocumentationCommentId(cref, binder, crefDiagnostics); if (diagnose) { diagnostics.AddRange(crefDiagnostics); } crefDiagnostics.Free(); if ((object)writer != null) { Visit(crefAttr.Name); VisitToken(crefAttr.EqualsToken); // Not going to visit normally, because we want to skip trivia within // the attribute value. crefAttr.StartQuoteToken.WriteTo(writer, leading: true, trailing: false); // We're not going to visit the cref because we want to bind it // and write a doc comment ID in its place. writer.Write(docCommentId); // Not going to visit normally, because we want to skip trivia within // the attribute value. crefAttr.EndQuoteToken.WriteTo(writer, leading: false, trailing: true); } // Don't descend - we've already written out everything necessary. return; } else if (nodeKind == SyntaxKind.XmlNameAttribute && diagnose) { XmlNameAttributeSyntax nameAttr = (XmlNameAttributeSyntax)node; BinderFactory factory = compilation.GetBinderFactory(nameAttr.SyntaxTree); Binder binder = factory.GetBinder(nameAttr, nameAttr.Identifier.SpanStart); // Do this for diagnostics, even if we aren't writing. DocumentationCommentCompiler.BindName(nameAttr, binder, memberSymbol, ref documentedParameters, ref documentedTypeParameters, diagnostics); // Do descend - we still need to write out the tokens of the attribute. } // NOTE: if we're recording any include element nodes (i.e. if includeElementsNodes is non-null), // then we want to record all of them, because we won't be able to distinguish in the XML DOM. if ((object)includeElementNodes != null) { XmlNameSyntax nameSyntax = null; if (nodeKind == SyntaxKind.XmlEmptyElement) { nameSyntax = ((XmlEmptyElementSyntax)node).Name; } else if (nodeKind == SyntaxKind.XmlElementStartTag) { nameSyntax = ((XmlElementStartTagSyntax)node).Name; } if ((object)nameSyntax != null && (object)nameSyntax.Prefix == null && DocumentationCommentXmlNames.ElementEquals(nameSyntax.LocalName.ValueText, DocumentationCommentXmlNames.IncludeElementName)) { includeElementNodes.Add((CSharpSyntaxNode)node); } } base.DefaultVisit(node); }