private static XmlNameAttributeSyntax ParseNameAttribute( string attributeText, string elementName ) { // NOTE: Rather than introducing a new code path that will have to be kept in // sync with other mode changes distributed throughout Lexer, SyntaxParser, and // DocumentationCommentParser, we'll just wrap the text in some lexable syntax // and then extract the piece we want. string commentText = string.Format(@"/// <{0} {1}/>", elementName, attributeText); SyntaxTriviaList leadingTrivia = SyntaxFactory.ParseLeadingTrivia( commentText, CSharpParseOptions.Default.WithDocumentationMode(DocumentationMode.Diagnose) ); Debug.Assert(leadingTrivia.Count == 1); SyntaxTrivia trivia = leadingTrivia.ElementAt(0); DocumentationCommentTriviaSyntax structure = (DocumentationCommentTriviaSyntax)trivia.GetStructure(); Debug.Assert(structure.Content.Count == 2); XmlEmptyElementSyntax elementSyntax = (XmlEmptyElementSyntax)structure.Content[1]; Debug.Assert(elementSyntax.Attributes.Count == 1); return((XmlNameAttributeSyntax)elementSyntax.Attributes[0]); }
/// <summary> /// Visit an <see cref="XmlEmptyElementSyntax"/>. /// </summary> /// <param name="emptyElement"> /// The <see cref="XmlEmptyElementSyntax"/>. /// </param> /// <returns> /// The <see cref="XmlEmptyElementSyntax"/> (unchanged). /// </returns> public override SyntaxNode VisitXmlEmptyElement(XmlEmptyElementSyntax emptyElement) { Range elementRange = emptyElement.Span.ToNative(_textPositions); Range nameRange = emptyElement.NameNode?.Span.ToNative(_textPositions) ?? elementRange; Range attributesRange = emptyElement.AttributesNode?.FullSpan.ToNative(_textPositions) ?? elementRange; XSElement xsElement; if (String.IsNullOrWhiteSpace(emptyElement.Name)) { xsElement = new XSInvalidElement(emptyElement, elementRange, nameRange, attributesRange, parent: CurrentElement, hasContent: false); } else { xsElement = new XSEmptyElement(emptyElement, elementRange, nameRange, attributesRange, parent: CurrentElement); } if (xsElement.ParentElement is XSElementWithContent parentElement) { parentElement.Content = parentElement.Content.Add(xsElement); } PushElement(xsElement); foreach (XmlAttributeSyntax attribute in emptyElement.AsSyntaxElement.Attributes) { Visit(attribute); } PopElement(); return(emptyElement); }
private void FormatEmptyElementTag(XmlEmptyElementSyntax node) { if (node.ContainsSkippedText) { AddWord(node.Span); } else { AddWord(node.LessThanToken.Span); EnqueueTrailingTriviaChange(node.LessThanToken, string.Empty); EnqueueLeadingTriviaChange(node.Name, string.Empty); FormatTagName(node.Name); EnqueueTrailingTriviaChange(node.Name, string.Empty); foreach (var attribute in node.Attributes) { EnqueueLeadingTriviaChange(attribute, " "); FormatTagAttribute(attribute); EnqueueTrailingTriviaChange(attribute, string.Empty); } EnqueueLeadingTriviaChange(node.SlashGreaterThanToken, string.Empty); AddWord(node.SlashGreaterThanToken.Span); } }
private void FormatXmlEmptyElement(XmlEmptyElementSyntax node) { string name = node.Name.ToString(); ElementFormatting formatting; _ = _elements.TryGetValue(name, out formatting); if (formatting.HasFlag(ElementFormatting.Block)) { Break(BreakMode.LineBreak); } if (node.HasLeadingTrivia) { AddTrivia(node.GetLeadingTrivia()); } FormatEmptyElementTag(node); if (node.HasTrailingTrivia) { AddTrivia(node.GetTrailingTrivia()); } if (formatting.HasFlag(ElementFormatting.Block)) { Break(BreakMode.LineBreak); } }
public static IEnumerable <XmlNodeSyntax> GetXmlElements(this SyntaxList <XmlNodeSyntax> content, string elementName) { foreach (XmlNodeSyntax syntax in content) { XmlEmptyElementSyntax emptyElement = syntax as XmlEmptyElementSyntax; if (emptyElement != null) { if (string.Equals(elementName, emptyElement.Name.ToString(), StringComparison.Ordinal)) { yield return(emptyElement); } continue; } XmlElementSyntax elementSyntax = syntax as XmlElementSyntax; if (elementSyntax != null) { if (string.Equals(elementName, elementSyntax.StartTag?.Name?.ToString(), StringComparison.Ordinal)) { yield return(elementSyntax); } continue; } } }
private bool SeeTagIsCorrect(XmlEmptyElementSyntax classReferencePart, BaseMethodDeclarationSyntax constructorDeclarationSyntax) { if (classReferencePart.Name.ToString() == XmlCommentHelper.SeeXmlTag) { XmlCrefAttributeSyntax crefAttribute = classReferencePart.Attributes.OfType <XmlCrefAttributeSyntax>().FirstOrDefault(); if (crefAttribute != null) { NameMemberCrefSyntax nameMember = crefAttribute.Cref as NameMemberCrefSyntax; if (nameMember != null && nameMember.Parameters == null) { ClassDeclarationSyntax classDeclarationSyntax = constructorDeclarationSyntax.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (classDeclarationSyntax != null && classDeclarationSyntax.Identifier.ToString() == this.GetName(nameMember.Name)) { // Check if type parameters are called the same if (TypeParameterNamesMatch(classDeclarationSyntax, nameMember.Name)) { return(true); } } } } } return(false); }
private static void HandleXmlEmptyElement(SyntaxNodeAnalysisContext context) { XmlEmptyElementSyntax element = (XmlEmptyElementSyntax)context.Node; var name = element.Name; HandleElement(context, element, name, element.GetLocation()); }
private static void HandleXmlEmptyElement(SyntaxNodeAnalysisContext context) { XmlEmptyElementSyntax emptyElement = context.Node as XmlEmptyElementSyntax; var name = emptyElement?.Name; HandleElement(context, emptyElement, name, emptyElement?.GetLocation()); }
public override void VisitXmlEmptyElement(XmlEmptyElementSyntax node) { node.Name?.Accept(this); foreach (XmlAttributeSyntax syntax in node.Attributes) { syntax.Accept(this); } base.VisitXmlEmptyElement(node); }
private static void HandleXmlEmptyElement(SyntaxNodeAnalysisContext context) { XmlEmptyElementSyntax emptyElement = context.Node as XmlEmptyElementSyntax; if (string.Equals(emptyElement?.Name.ToString(), XmlCommentHelper.ReturnsXmlTag)) { // <returns .../> is empty. context.ReportDiagnostic(Diagnostic.Create(Descriptor, emptyElement.GetLocation())); } }
public override Evaluation VisitXmlEmptyElement(XmlEmptyElementSyntax node) { node.Name?.Accept <Evaluation>(this); foreach (XmlAttributeSyntax syntax in node.Attributes) { syntax.Accept <Evaluation>(this); } return(base.VisitXmlEmptyElement(node)); }
private static void HandleXmlEmptyElement(SyntaxNodeAnalysisContext context) { XmlEmptyElementSyntax emptyElement = (XmlEmptyElementSyntax)context.Node; if (string.Equals(emptyElement.Name.ToString(), XmlCommentHelper.TypeParamXmlTag)) { // <typeparam .../> is empty. context.ReportDiagnostic(Diagnostic.Create(Descriptor, emptyElement.GetLocation())); } }
private void HandleXmlEmptyElement(SyntaxNodeAnalysisContext context) { XmlEmptyElementSyntax syntax = (XmlEmptyElementSyntax)context.Node; if (!string.Equals("placeholder", syntax.Name?.ToString(), StringComparison.Ordinal)) { return; } context.ReportDiagnostic(Diagnostic.Create(Descriptor, syntax.GetLocation())); }
private void ClassifyXmlEmptyElement(XmlEmptyElementSyntax node) { AddXmlClassification(node.LessThanToken, ClassificationTypeNames.XmlDocCommentDelimiter); ClassifyXmlName(node.Name); foreach (var attribute in node.Attributes) { ClassifyXmlAttribute(attribute); } AddXmlClassification(node.SlashGreaterThanToken, ClassificationTypeNames.XmlDocCommentDelimiter); }
internal static XmlNodeSyntax GetTopLevelElement(DocumentationCommentTriviaSyntax syntax, string tagName) { XmlElementSyntax elementSyntax = syntax.Content.OfType <XmlElementSyntax>().FirstOrDefault(element => string.Equals(element.StartTag.Name.ToString(), tagName)); if (elementSyntax != null) { return(elementSyntax); } XmlEmptyElementSyntax emptyElementSyntax = syntax.Content.OfType <XmlEmptyElementSyntax>().FirstOrDefault(element => string.Equals(element.Name.ToString(), tagName)); return(emptyElementSyntax); }
private static bool HasXmlCrefAttribute(XmlNodeSyntax inheritDocElement) { XmlElementSyntax xmlElementSyntax = inheritDocElement as XmlElementSyntax; if (xmlElementSyntax?.StartTag?.Attributes.Any(SyntaxKind.XmlCrefAttribute) ?? false) { return true; } XmlEmptyElementSyntax xmlEmptyElementSyntax = inheritDocElement as XmlEmptyElementSyntax; if (xmlEmptyElementSyntax?.Attributes.Any(SyntaxKind.XmlCrefAttribute) ?? false) { return true; } return false; }
public override void VisitXmlEmptyElement(XmlEmptyElementSyntax node) { if (!PreVisit(node)) { return; } node.Name?.Accept(this); foreach (XmlAttributeSyntax syntax in node.Attributes) { syntax.Accept(this); } base.VisitXmlEmptyElement(node); PostVisit(node); }
private static bool SeeTagIsCorrect(SyntaxNodeAnalysisContext context, XmlEmptyElementSyntax classReferencePart, BaseMethodDeclarationSyntax constructorDeclarationSyntax) { XmlCrefAttributeSyntax crefAttribute = XmlCommentHelper.GetFirstAttributeOrDefault <XmlCrefAttributeSyntax>(classReferencePart); CrefSyntax crefSyntax = crefAttribute?.Cref; if (crefAttribute == null) { return(false); } SemanticModel semanticModel = context.SemanticModel; if (!(semanticModel.GetSymbolInfo(crefSyntax, context.CancellationToken).Symbol is INamedTypeSymbol actualSymbol)) { return(false); } INamedTypeSymbol expectedSymbol = semanticModel.GetDeclaredSymbol(constructorDeclarationSyntax.Parent, context.CancellationToken) as INamedTypeSymbol; return(Equals(actualSymbol.OriginalDefinition, expectedSymbol)); }
internal static string GetName(this XmlEmptyElementSyntax value) => value?.Name.LocalName.ValueText;
private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) { var documentRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); SyntaxNode syntax = documentRoot.FindNode(diagnostic.Location.SourceSpan); if (syntax == null) { return(document); } MethodDeclarationSyntax methodDeclarationSyntax = syntax.FirstAncestorOrSelf <MethodDeclarationSyntax>(); DelegateDeclarationSyntax delegateDeclarationSyntax = syntax.FirstAncestorOrSelf <DelegateDeclarationSyntax>(); if (methodDeclarationSyntax == null && delegateDeclarationSyntax == null) { return(document); } DocumentationCommentTriviaSyntax documentationComment = methodDeclarationSyntax?.GetDocumentationCommentTriviaSyntax() ?? delegateDeclarationSyntax?.GetDocumentationCommentTriviaSyntax(); if (documentationComment == null) { return(document); } SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); bool isTask; bool isAsynchronousTestMethod; if (methodDeclarationSyntax != null) { isTask = IsTaskReturningMethod(semanticModel, methodDeclarationSyntax, cancellationToken); isAsynchronousTestMethod = isTask && IsAsynchronousTestMethod(semanticModel, methodDeclarationSyntax, cancellationToken); } else { isTask = IsTaskReturningMethod(semanticModel, delegateDeclarationSyntax, cancellationToken); isAsynchronousTestMethod = false; } XmlNodeSyntax returnsElement = documentationComment.Content.GetFirstXmlElement(XmlCommentHelper.ReturnsXmlTag) as XmlNodeSyntax; if (returnsElement != null && !isTask) { // This code fix doesn't know how to do anything more than document Task-returning methods. return(document); } SyntaxList <XmlNodeSyntax> content = XmlSyntaxFactory.List(); if (isTask) { content = content.Add(XmlSyntaxFactory.Text("A ")); content = content.Add(XmlSyntaxFactory.SeeElement(SyntaxFactory.TypeCref(SyntaxFactory.ParseTypeName("global::System.Threading.Tasks.Task"))).WithAdditionalAnnotations(Simplifier.Annotation)); string operationKind = isAsynchronousTestMethod ? "unit test" : "operation"; content = content.Add(XmlSyntaxFactory.Text($" representing the asynchronous {operationKind}.")); // wrap the generated content in a <placeholder> element for review. content = XmlSyntaxFactory.List(XmlSyntaxFactory.PlaceholderElement(content)); } // Try to replace an existing <returns> element if the comment contains one. Otherwise, add it as a new element. SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); SyntaxNode newRoot; if (returnsElement != null) { XmlEmptyElementSyntax emptyElement = returnsElement as XmlEmptyElementSyntax; if (emptyElement != null) { XmlElementSyntax updatedReturns = XmlSyntaxFactory.Element(XmlCommentHelper.ReturnsXmlTag, content) .WithLeadingTrivia(returnsElement.GetLeadingTrivia()) .WithTrailingTrivia(returnsElement.GetTrailingTrivia()); newRoot = root.ReplaceNode(returnsElement, updatedReturns); } else { XmlElementSyntax updatedReturns = ((XmlElementSyntax)returnsElement).WithContent(content); newRoot = root.ReplaceNode(returnsElement, updatedReturns); } } else { string newLineText = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp); returnsElement = XmlSyntaxFactory.Element(XmlCommentHelper.ReturnsXmlTag, content); XmlNodeSyntax leadingNewLine = XmlSyntaxFactory.NewLine(newLineText); // HACK: The formatter isn't working when contents are added to an existing documentation comment, so we // manually apply the indentation from the last line of the existing comment to each new line of the // generated content. SyntaxTrivia exteriorTrivia = GetLastDocumentationCommentExteriorTrivia(documentationComment); if (!exteriorTrivia.Token.IsMissing) { leadingNewLine = leadingNewLine.ReplaceExteriorTrivia(exteriorTrivia); returnsElement = returnsElement.ReplaceExteriorTrivia(exteriorTrivia); } DocumentationCommentTriviaSyntax newDocumentationComment = documentationComment.WithContent( documentationComment.Content.InsertRange( documentationComment.Content.Count - 1, XmlSyntaxFactory.List(leadingNewLine, returnsElement))); newRoot = root.ReplaceNode(documentationComment, newDocumentationComment); } return(document.WithSyntaxRoot(newRoot)); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitXmlEmptyElement(XmlEmptyElementSyntax node) { this.OnNodeVisited(node); if (!this.traverseRootOnly) base.VisitXmlEmptyElement(node); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitXmlEmptyElement(XmlEmptyElementSyntax node) { this.OnNodeVisited(node, this.type.IsInstanceOfType(node)); base.VisitXmlEmptyElement(node); }
public override void VisitXmlEmptyElement(XmlEmptyElementSyntax node) { throw new NotImplementedException(); }
private static Task <Document> GetTransformedDocumentAsync(Document document, SyntaxNode root, XmlEmptyElementSyntax node) { var typeDeclaration = node.FirstAncestorOrSelf <BaseTypeDeclarationSyntax>(); TypeParameterListSyntax typeParameterList; if (typeDeclaration is ClassDeclarationSyntax classDeclaration) { typeParameterList = classDeclaration.TypeParameterList; } else { typeParameterList = (typeDeclaration as StructDeclarationSyntax)?.TypeParameterList; } var newRoot = root.ReplaceNode(node, BuildSeeElement(typeDeclaration.Identifier, typeParameterList)); var newDocument = document.WithSyntaxRoot(newRoot); return(Task.FromResult(newDocument)); }
private static bool SeeTagIsCorrect(SyntaxNodeAnalysisContext context, XmlEmptyElementSyntax classReferencePart, BaseMethodDeclarationSyntax constructorDeclarationSyntax) { XmlCrefAttributeSyntax crefAttribute = XmlCommentHelper.GetFirstAttributeOrDefault<XmlCrefAttributeSyntax>(classReferencePart); CrefSyntax crefSyntax = crefAttribute?.Cref; if (crefAttribute == null) { return false; } SemanticModel semanticModel = context.SemanticModel; INamedTypeSymbol actualSymbol = semanticModel.GetSymbolInfo(crefSyntax, context.CancellationToken).Symbol as INamedTypeSymbol; if (actualSymbol == null) { return false; } INamedTypeSymbol expectedSymbol = semanticModel.GetDeclaredSymbol(constructorDeclarationSyntax.Parent, context.CancellationToken) as INamedTypeSymbol; return actualSymbol.OriginalDefinition == expectedSymbol; }
private static bool IsBlockLevelElement(XmlEmptyElementSyntax element, bool includePotentialElements) { return(IsBlockLevelName(element.Name, includePotentialElements)); }
private static void HandleXmlEmptyElement(SyntaxNodeAnalysisContext context) { XmlEmptyElementSyntax syntax = (XmlEmptyElementSyntax)context.Node; CheckTag(context, syntax.Name?.ToString()); }
private static Task<Document> GetTransformedDocumentAsync(Document document, SyntaxNode root, XmlEmptyElementSyntax node) { var typeDeclaration = node.FirstAncestorOrSelf<BaseTypeDeclarationSyntax>(); var declarationSyntax = node.FirstAncestorOrSelf<BaseMethodDeclarationSyntax>(); bool isStruct = typeDeclaration.IsKind(SyntaxKind.StructDeclaration); TypeParameterListSyntax typeParameterList; ClassDeclarationSyntax classDeclaration = typeDeclaration as ClassDeclarationSyntax; if (classDeclaration != null) { typeParameterList = classDeclaration.TypeParameterList; } else { typeParameterList = (typeDeclaration as StructDeclarationSyntax)?.TypeParameterList; } var newRoot = root.ReplaceNode(node, BuildSeeElement(typeDeclaration.Identifier, typeParameterList)); var newDocument = document.WithSyntaxRoot(newRoot); return Task.FromResult(newDocument); }
public TameXmlEmptyElementSyntax(XmlEmptyElementSyntax node) { Node = node; AddChildren(); }
public override void VisitXmlEmptyElement(XmlEmptyElementSyntax node) { }
public override void VisitXmlEmptyElement(XmlEmptyElementSyntax node) { Debug.Fail(node.ToString()); base.VisitXmlEmptyElement(node); }
protected static XmlElementSyntax CommentStartingWith(XmlElementSyntax comment, string commentStart, XmlEmptyElementSyntax seeCref, string commentContinue) { var content = comment.Content; // when necessary adjust beginning text // Note: when on new line, then the text is not the 1st one but the 2nd one var index = GetIndex(content); var startText = SyntaxFactory.XmlText(commentStart).WithLeadingXmlComment(); XmlTextSyntax continueText; if (content[index] is XmlTextSyntax text) { // we have to remove the element as otherwise we duplicate the comment content = content.Remove(content[index]); // remove first "\r\n" token and remove ' /// ' trivia of second token if (text.TextTokens[0].IsKind(SyntaxKind.XmlTextLiteralNewLineToken)) { var newTokens = text.TextTokens.RemoveAt(0); text = SyntaxFactory.XmlText(newTokens.Replace(newTokens[0], newTokens[0].WithLeadingTrivia())); } continueText = text.WithStartText(commentContinue); } else { index = Math.Max(0, index - 1); continueText = SyntaxFactory.XmlText(commentContinue); } return(SyntaxFactory.XmlElement( comment.StartTag, content.Insert(index, startText).Insert(index + 1, seeCref).Insert(index + 2, continueText), comment.EndTag)); }
/// <summary> /// Verifies an empty XmlElement /// </summary> /// <param name="xmlElement">The XmlElement object to validate</param> /// <param name="tagName">The name of the tag the XML element should have</param> private void VerifyXmlElement(XmlEmptyElementSyntax xmlElement, string tagName) { Assert.Equal(tagName, xmlElement.Name.LocalName.Value); }
protected override ITagCommentReaderState AcceptXmlEmptyElement(XmlEmptyElementSyntax syntax) { StateMachine.AddText(syntax.ToString()); return(new TagCommentReaderInLineState(StateMachine)); }
private static bool ContainsException(XmlEmptyElementSyntax xmlEmptyElement, INamedTypeSymbol exceptionSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { return(ContainsException(xmlEmptyElement.Attributes, exceptionSymbol, semanticModel, cancellationToken)); }