/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Workspaces/VisualBasic/Portable/Classification/Worker.DocumentationCommentClassifier.vb
348 строк
17 KB
Joey Robichaud
Classify langword in VB code
09 янв 2025, 02:45
09 янв 2025, 02:45
dd335bb
Код
Авторство
О чём код?
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis.Classification Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.Classification Partial Friend Class Worker Private Class DocumentationCommentClassifier Private ReadOnly _worker As Worker Public Sub New(worker As Worker) _worker = worker End Sub Friend Sub Classify(documentationComment As DocumentationCommentTriviaSyntax) If Not _worker._textSpan.OverlapsWith(documentationComment.Span) Then Return End If For Each xmlNode In documentationComment.Content Dim childFullSpan = xmlNode.FullSpan If childFullSpan.Start > _worker._textSpan.End Then Return ElseIf childFullSpan.End < _worker._textSpan.Start Then Continue For End If ClassifyXmlNode(xmlNode) Next End Sub Private Sub ClassifyXmlNode(node As XmlNodeSyntax) If node Is Nothing Then Return End If Select Case node.Kind Case SyntaxKind.XmlText ClassifyXmlText(DirectCast(node, XmlTextSyntax)) Case SyntaxKind.XmlElement ClassifyElement(DirectCast(node, XmlElementSyntax)) Case SyntaxKind.XmlEmptyElement ClassifyEmptyElement(DirectCast(node, XmlEmptyElementSyntax)) Case SyntaxKind.XmlName ClassifyXmlName(DirectCast(node, XmlNameSyntax)) Case SyntaxKind.XmlString ClassifyString(DirectCast(node, XmlStringSyntax)) Case SyntaxKind.XmlComment ClassifyComment(DirectCast(node, XmlCommentSyntax)) Case SyntaxKind.XmlCDataSection ClassifyCData(DirectCast(node, XmlCDataSectionSyntax)) Case SyntaxKind.XmlProcessingInstruction ClassifyProcessingInstruction(DirectCast(node, XmlProcessingInstructionSyntax)) End Select End Sub Private Sub ClassifyXmlTrivia(trivialList As SyntaxTriviaList, Optional whitespaceClassificationType As String = Nothing) For Each t In trivialList Select Case t.Kind() Case SyntaxKind.DocumentationCommentExteriorTrivia ClassifyExteriorTrivia(t) Case SyntaxKind.WhitespaceTrivia If whitespaceClassificationType IsNot Nothing Then _worker.AddClassification(t, whitespaceClassificationType) End If End Select Next End Sub Private Sub ClassifyExteriorTrivia(trivia As SyntaxTrivia) ' Note: The exterior trivia can contain whitespace (usually leading) and we want to avoid classifying it. ' PERFORMANCE: ' While the call to SyntaxTrivia.ToString() looks Like an allocation, it isn't. ' The SyntaxTrivia green node holds the string text of the trivia in a field And ToString() ' just returns a reference to that. Dim text = trivia.ToString() Dim spanStart As Integer? = Nothing For index = 0 To text.Length - 1 Dim ch = text(index) If spanStart IsNot Nothing AndAlso Char.IsWhiteSpace(ch) Then Dim span = TextSpan.FromBounds(spanStart.Value, spanStart.Value + index) _worker.AddClassification(span, ClassificationTypeNames.XmlDocCommentDelimiter) spanStart = Nothing ElseIf spanStart Is Nothing AndAlso Not Char.IsWhiteSpace(ch) Then spanStart = trivia.Span.Start + index End If Next ' Add a final classification if we hadn't encountered anymore whitespace at the end If spanStart IsNot Nothing Then Dim span = TextSpan.FromBounds(spanStart.Value, trivia.Span.End) _worker.AddClassification(span, ClassificationTypeNames.XmlDocCommentDelimiter) End If End Sub Private Sub AddXmlClassification(token As SyntaxToken, classificationType As String) If token.HasLeadingTrivia Then ClassifyXmlTrivia(token.LeadingTrivia, classificationType) End If _worker.AddClassification(token, classificationType) If token.HasTrailingTrivia Then ClassifyXmlTrivia(token.TrailingTrivia, classificationType) End If End Sub Private Sub ClassifyXmlTextTokens(textTokens As SyntaxTokenList) For Each token In textTokens If token.HasLeadingTrivia Then ClassifyXmlTrivia(token.LeadingTrivia, whitespaceClassificationType:=ClassificationTypeNames.XmlDocCommentText) End If ClassifyXmlTextToken(token) If token.HasTrailingTrivia Then ClassifyXmlTrivia(token.TrailingTrivia, whitespaceClassificationType:=ClassificationTypeNames.XmlDocCommentText) End If Next token End Sub Private Sub ClassifyXmlTextToken(token As SyntaxToken) If token.Kind = SyntaxKind.XmlEntityLiteralToken Then _worker.AddClassification(token, ClassificationTypeNames.XmlDocCommentEntityReference) ElseIf token.Kind() <> SyntaxKind.DocumentationCommentLineBreakToken Then Select Case token.Parent.Kind Case SyntaxKind.XmlText _worker.AddClassification(token, ClassificationTypeNames.XmlDocCommentText) Case SyntaxKind.XmlString _worker.AddClassification(token, ClassificationTypeNames.XmlDocCommentAttributeValue) Case SyntaxKind.XmlComment _worker.AddClassification(token, ClassificationTypeNames.XmlDocCommentComment) Case SyntaxKind.XmlCDataSection _worker.AddClassification(token, ClassificationTypeNames.XmlDocCommentCDataSection) Case SyntaxKind.XmlProcessingInstruction _worker.AddClassification(token, ClassificationTypeNames.XmlDocCommentProcessingInstruction) End Select End If End Sub Private Sub ClassifyXmlName(node As XmlNameSyntax) Dim classificationType As String If TypeOf node.Parent Is BaseXmlAttributeSyntax Then classificationType = ClassificationTypeNames.XmlDocCommentAttributeName ElseIf TypeOf node.Parent Is XmlProcessingInstructionSyntax Then classificationType = ClassificationTypeNames.XmlDocCommentProcessingInstruction Else classificationType = ClassificationTypeNames.XmlDocCommentName End If Dim prefix = node.Prefix If prefix IsNot Nothing Then AddXmlClassification(prefix.Name, classificationType) AddXmlClassification(prefix.ColonToken, classificationType) End If AddXmlClassification(node.LocalName, classificationType) End Sub Private Sub ClassifyElement(xmlElementSyntax As XmlElementSyntax) ClassifyElementStart(xmlElementSyntax.StartTag) For Each xmlNode In xmlElementSyntax.Content ClassifyXmlNode(xmlNode) Next ClassifyElementEnd(xmlElementSyntax.EndTag) End Sub Private Sub ClassifyElementStart(node As XmlElementStartTagSyntax) AddXmlClassification(node.LessThanToken, ClassificationTypeNames.XmlDocCommentDelimiter) ClassifyXmlNode(node.Name) ' Note: In xml doc comments, attributes can only _be_ attributes. ' there are no expression holes here. For Each attribute In node.Attributes ClassifyBaseXmlAttribute(TryCast(attribute, BaseXmlAttributeSyntax)) Next AddXmlClassification(node.GreaterThanToken, ClassificationTypeNames.XmlDocCommentDelimiter) End Sub Private Sub ClassifyElementEnd(node As XmlElementEndTagSyntax) AddXmlClassification(node.LessThanSlashToken, ClassificationTypeNames.XmlDocCommentDelimiter) ClassifyXmlNode(node.Name) AddXmlClassification(node.GreaterThanToken, ClassificationTypeNames.XmlDocCommentDelimiter) End Sub Private Sub ClassifyEmptyElement(node As XmlEmptyElementSyntax) AddXmlClassification(node.LessThanToken, ClassificationTypeNames.XmlDocCommentDelimiter) ClassifyXmlNode(node.Name) ' Note: In xml doc comments, attributes can only _be_ attributes. ' there are no expression holes here. For Each attribute In node.Attributes ClassifyBaseXmlAttribute(TryCast(attribute, BaseXmlAttributeSyntax)) Next AddXmlClassification(node.SlashGreaterThanToken, ClassificationTypeNames.XmlDocCommentDelimiter) End Sub Private Sub ClassifyBaseXmlAttribute(attribute As BaseXmlAttributeSyntax) If attribute IsNot Nothing Then Select Case attribute.Kind Case SyntaxKind.XmlAttribute Dim xmlAttribute = DirectCast(attribute, XmlAttributeSyntax) If IsLangWordAttribute(xmlAttribute) Then ClassifyLangWordAttribute(xmlAttribute) Else ClassifyAttribute(xmlAttribute) End If Case SyntaxKind.XmlCrefAttribute ClassifyCrefAttribute(DirectCast(attribute, XmlCrefAttributeSyntax)) Case SyntaxKind.XmlNameAttribute ClassifyNameAttribute(DirectCast(attribute, XmlNameAttributeSyntax)) End Select End If End Sub Private Sub ClassifyAttribute(attribute As XmlAttributeSyntax) ClassifyXmlNode(attribute.Name) AddXmlClassification(attribute.EqualsToken, ClassificationTypeNames.XmlDocCommentDelimiter) ClassifyXmlNode(attribute.Value) End Sub Private Shared Function IsLangWordAttribute(attribute As XmlAttributeSyntax) As Boolean Dim nameNode = DirectCast(attribute.Name, XmlNameSyntax) If nameNode.LocalName.Text <> DocumentationCommentXmlNames.LangwordAttributeName Then Return False End If Dim startTag = TryCast(attribute.Parent, XmlElementStartTagSyntax) If (startTag IsNot Nothing) Then Dim startTagName = TryCast(startTag.Name, XmlNameSyntax) Return startTagName IsNot Nothing AndAlso startTagName.Prefix Is Nothing AndAlso startTagName.LocalName.Text = DocumentationCommentXmlNames.SeeElementName End If Dim emptyElement = TryCast(attribute.Parent, XmlEmptyElementSyntax) If (emptyElement IsNot Nothing) Then Dim emptyElementName = TryCast(emptyElement.Name, XmlNameSyntax) Return emptyElementName IsNot Nothing AndAlso emptyElementName.Prefix Is Nothing AndAlso emptyElementName.LocalName.Text = DocumentationCommentXmlNames.SeeElementName End If Return False End Function Private Sub ClassifyLangWordAttribute(attribute As XmlAttributeSyntax) ClassifyXmlNode(attribute.Name) AddXmlClassification(attribute.EqualsToken, ClassificationTypeNames.XmlDocCommentDelimiter) Dim node = (DirectCast(attribute.Value, XmlStringSyntax)) AddXmlClassification(node.StartQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) ClassifyLangWordTextTokenList(node.TextTokens) AddXmlClassification(node.EndQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) End Sub Private Sub ClassifyLangWordTextTokenList(list As SyntaxTokenList) For Each token In list If (token.HasLeadingTrivia) Then ClassifyXmlTrivia(token.LeadingTrivia, ClassificationTypeNames.XmlDocCommentText) End If ClassifyLangWordTextToken(token) If (token.HasTrailingTrivia) Then ClassifyXmlTrivia(token.TrailingTrivia, ClassificationTypeNames.XmlDocCommentText) End If Next End Sub Private Sub ClassifyLangWordTextToken(token As SyntaxToken) Dim kind = SyntaxFacts.GetKeywordKind(token.Text) If kind = SyntaxKind.None Then kind = SyntaxFacts.GetContextualKeywordKind(token.Text) End If If kind = SyntaxKind.None Then AddXmlClassification(token, ClassificationTypeNames.XmlDocCommentAttributeValue) Return End If Dim isControlKeyword = IsControlKeywordKind(kind) Or IsControlStatementKind(kind) AddXmlClassification(token, If(isControlKeyword, ClassificationTypeNames.ControlKeyword, ClassificationTypeNames.Keyword)) End Sub Private Sub ClassifyCrefAttribute(attribute As XmlCrefAttributeSyntax) ClassifyXmlNode(attribute.Name) AddXmlClassification(attribute.EqualsToken, ClassificationTypeNames.XmlDocCommentDelimiter) AddXmlClassification(attribute.StartQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) _worker.ClassifyNode(attribute.Reference) AddXmlClassification(attribute.EndQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) End Sub Private Sub ClassifyNameAttribute(attribute As XmlNameAttributeSyntax) ClassifyXmlNode(attribute.Name) AddXmlClassification(attribute.EqualsToken, ClassificationTypeNames.XmlDocCommentDelimiter) AddXmlClassification(attribute.StartQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) _worker.ClassifyNode(attribute.Reference) AddXmlClassification(attribute.EndQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) End Sub Private Sub ClassifyXmlText(xmlTextSyntax As XmlTextSyntax) ClassifyXmlTextTokens(xmlTextSyntax.TextTokens) End Sub Private Sub ClassifyString(node As XmlStringSyntax) AddXmlClassification(node.StartQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) ClassifyXmlTextTokens(node.TextTokens) AddXmlClassification(node.EndQuoteToken, ClassificationTypeNames.XmlDocCommentAttributeQuotes) End Sub Private Sub ClassifyComment(node As XmlCommentSyntax) AddXmlClassification(node.LessThanExclamationMinusMinusToken, ClassificationTypeNames.XmlDocCommentDelimiter) ClassifyXmlTextTokens(node.TextTokens) AddXmlClassification(node.MinusMinusGreaterThanToken, ClassificationTypeNames.XmlDocCommentDelimiter) End Sub Private Sub ClassifyCData(node As XmlCDataSectionSyntax) AddXmlClassification(node.BeginCDataToken, ClassificationTypeNames.XmlDocCommentDelimiter) ClassifyXmlTextTokens(node.TextTokens) AddXmlClassification(node.EndCDataToken, ClassificationTypeNames.XmlDocCommentDelimiter) End Sub Private Sub ClassifyProcessingInstruction(node As XmlProcessingInstructionSyntax) AddXmlClassification(node.LessThanQuestionToken, ClassificationTypeNames.XmlDocCommentProcessingInstruction) AddXmlClassification(node.Name, ClassificationTypeNames.XmlDocCommentProcessingInstruction) ClassifyXmlTextTokens(node.TextTokens) AddXmlClassification(node.QuestionGreaterThanToken, ClassificationTypeNames.XmlDocCommentProcessingInstruction) End Sub End Class End Class End Namespace