Skip to content

Commit

Permalink
Ensure VB parser is disposed (#76636)
Browse files Browse the repository at this point in the history
Noticed then when I was trying out adding a pooled object to the parser and that the dispose wasn't always being called to release the object back to the pool. I'm still investigating whether I want to add the pooled data to the parser, but minimially, the existing dispose method should be called.
  • Loading branch information
ToddGrun authored Jan 8, 2025
1 parent 095410a commit df75ee9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 59 deletions.
8 changes: 4 additions & 4 deletions src/Compilers/VisualBasic/Portable/Scanner/Directives.vb
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Me.GetNextTokenInState(ScannerState.VB)

Else
Dim parser As New Parser(Me)

directiveTrivia = parser.ParseConditionalCompilationStatement()
directiveTrivia = parser.ConsumeStatementTerminatorAfterDirective(directiveTrivia)
Using parser = New Parser(Me)
directiveTrivia = parser.ParseConditionalCompilationStatement()
directiveTrivia = parser.ConsumeStatementTerminatorAfterDirective(directiveTrivia)
End Using
End If

Debug.Assert(directiveTrivia.FullWidth > 0, "should at least get #")
Expand Down
100 changes: 50 additions & 50 deletions src/Compilers/VisualBasic/Portable/Scanner/XmlDocComments.vb
Original file line number Diff line number Diff line change
Expand Up @@ -68,62 +68,62 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Me.MoveToNextSyntaxNodeInTrivia()

Else
Dim parser As New Parser(Me)

Me.IsScanningXmlDoc = True
Me._isStartingFirstXmlDocLine = True

' NOTE: Documentation comment syntax trivia must have at least one child xml node, because
' all the ['''] trivia are created as leading trivia for appropriate tokens.
' This means that we have to create at least one XmlText having trailing
' EOL to represent an empty documentation comment: ['''<eol>]
'
' The problem with this approach is that in presence of some errors (like
' not closed XML tags) we create missing tokens needed to represent the nodes
' *after* that last <eol> of the doc comment trivia, that means all the locations
' of created diagnostics will land on the first character of the next line
' after documentation comment
'
' To workaround this we parse XML nodes in two phases:
' - in the first phase we detect the last DocCommentLineBreak and create
' end-of-xml token instead; this should force all diagnostics to be
' reported on the next token location;
' - in the second phase we continue parsing XML nodes but don't create
' end-of-xml token which should just result in parsing one single node
' of XmlText type containing EOL;
' Then we merge the results and create resulting DocumentationCommentTrivia

' The first phase
Me._endOfXmlInsteadOfLastDocCommentLineBreak = True
Dim nodes = parser.ParseXmlContent(ScannerState.Content)

' The second phase
Me._endOfXmlInsteadOfLastDocCommentLineBreak = False
If nodes.Count = 0 AndAlso parser.CurrentToken.Kind = SyntaxKind.EndOfXmlToken Then
' This must be an empty documentation comment, we need to reset scanner so
' that the doc comment exterior trivia ([''']) lands on the final XmlNode

ResetLineBufferOffset()
restorePoint.RestoreTokens(includeLookAhead:=False)
Using parser = New Parser(Me)
Me.IsScanningXmlDoc = True
Me._isStartingFirstXmlDocLine = True
End If

nodes = parser.ParseRestOfDocCommentContent(nodes)
Me.IsScanningXmlDoc = False
' NOTE: Documentation comment syntax trivia must have at least one child xml node, because
' all the ['''] trivia are created as leading trivia for appropriate tokens.
' This means that we have to create at least one XmlText having trailing
' EOL to represent an empty documentation comment: ['''<eol>]
'
' The problem with this approach is that in presence of some errors (like
' not closed XML tags) we create missing tokens needed to represent the nodes
' *after* that last <eol> of the doc comment trivia, that means all the locations
' of created diagnostics will land on the first character of the next line
' after documentation comment
'
' To workaround this we parse XML nodes in two phases:
' - in the first phase we detect the last DocCommentLineBreak and create
' end-of-xml token instead; this should force all diagnostics to be
' reported on the next token location;
' - in the second phase we continue parsing XML nodes but don't create
' end-of-xml token which should just result in parsing one single node
' of XmlText type containing EOL;
' Then we merge the results and create resulting DocumentationCommentTrivia

' The first phase
Me._endOfXmlInsteadOfLastDocCommentLineBreak = True
Dim nodes = parser.ParseXmlContent(ScannerState.Content)

' The second phase
Me._endOfXmlInsteadOfLastDocCommentLineBreak = False
If nodes.Count = 0 AndAlso parser.CurrentToken.Kind = SyntaxKind.EndOfXmlToken Then
' This must be an empty documentation comment, we need to reset scanner so
' that the doc comment exterior trivia ([''']) lands on the final XmlNode

ResetLineBufferOffset()
restorePoint.RestoreTokens(includeLookAhead:=False)
Me._isStartingFirstXmlDocLine = True
End If

nodes = parser.ParseRestOfDocCommentContent(nodes)
Me.IsScanningXmlDoc = False

Debug.Assert(nodes.Any)
Debug.Assert(nodes(0).FullWidth > 0, "should at least get {'''EoL} ")
Debug.Assert(nodes.Any)
Debug.Assert(nodes(0).FullWidth > 0, "should at least get {'''EoL} ")

' restore _currentToken and lookahead,
' but keep offset and PP state
ResetLineBufferOffset()
' restore _currentToken and lookahead,
' but keep offset and PP state
ResetLineBufferOffset()

docCommentSyntax = SyntaxFactory.DocumentationCommentTrivia(nodes)
docCommentSyntax = SyntaxFactory.DocumentationCommentTrivia(nodes)

If Me.Options.DocumentationMode < DocumentationMode.Diagnose Then
' All diagnostics coming from documentation comment are ignored
docCommentSyntax.ClearFlags(GreenNode.NodeFlags.ContainsDiagnostics)
End If
If Me.Options.DocumentationMode < DocumentationMode.Diagnose Then
' All diagnostics coming from documentation comment are ignored
docCommentSyntax.ClearFlags(GreenNode.NodeFlags.ContainsDiagnostics)
End If
End Using
End If

' RESTORE lookahead state and current token if there were any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,17 +292,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Using scanner As New InternalSyntax.Scanner(MakeSourceText(text, 0), VisualBasicParseOptions.Default) ' NOTE: Default options should be enough
scanner.ForceScanningXmlDocMode()

Dim parser = New InternalSyntax.Parser(scanner)
parser.GetNextToken(InternalSyntax.ScannerState.Element)
Using parser = New InternalSyntax.Parser(scanner)
parser.GetNextToken(InternalSyntax.ScannerState.Element)

Dim xmlName = InternalSyntax.SyntaxFactory.XmlName(
Dim xmlName = InternalSyntax.SyntaxFactory.XmlName(
Nothing, InternalSyntax.SyntaxFactory.XmlNameToken(parentElementName, SyntaxKind.XmlNameToken, Nothing, Nothing))

Return DirectCast(
Return DirectCast(
parser.ParseXmlAttribute(
requireLeadingWhitespace:=False,
AllowNameAsExpression:=False,
xmlElementName:=xmlName).CreateRed(Nothing, 0), BaseXmlAttributeSyntax)
End Using
End Using
End Function

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic

Dim node As InternalSyntax.CompilationUnitSyntax
Using scanner
node = New Parser(scanner).ParseCompilationUnit()
Using parser = New Parser(scanner)
node = parser.ParseCompilationUnit()
End Using
End Using

Dim root = DirectCast(node.CreateRed(Nothing, 0), CompilationUnitSyntax)
Expand Down

0 comments on commit df75ee9

Please sign in to comment.