Skip to content

Add a new test mutation strategy to flip the presence of token in the assertParse tests (fixes 5 parser bugs) #1706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 2, 2023

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented May 25, 2023

The idea is simple: From the tree generated during parsing, iterate over all the tokens. For each token create a new test case that has the token missing, if it was present in the original source or present if it was missing in the original source. Then run the parser to check that it round-trips and check that generating diagnostics for the mutated tree doesn’t crash.

This testing strategy found three parser bugs:

  1. A round-trip failure for unexpected modifiers in a tuple type
func test(a: (borrowing F o))
  1. A round-trip failure for modifiers in front of an editor placeholder in declaration position
struct a {
  public<#declaration#>
}
  1. A precondition failure when the primary associated type clause of a protocol is empty
protocol X<> {}
  1. It also uncovered an issue where we weren’t able to retrieve the trivia pieces of a token after it had been modified using with because after the modification the token was a parsedToken that no longer resided in a ParsingSyntaxArena. The fix is to search through an arena’s childRefs to find the ParsingSyntaxArena that created it. @rintaro can you review this change?
  2. It uncovered that we were making assumptions about the presence of tokens in ParseDiagnosticGenerator, mostly that tokens in UnexpectedNodesSyntax are present. While this assumption is valid for trees generated by SwiftParser, it doesn’t need to hold for manually generated trees. A couple of minor adjustments to filter for only present tokens fixes this.

rdar://109783066

@ahoppen
Copy link
Member Author

ahoppen commented May 25, 2023

@swift-ci Please test

@ahoppen
Copy link
Member Author

ahoppen commented May 26, 2023

@swift-ci Please test macOS

@ahoppen
Copy link
Member Author

ahoppen commented May 26, 2023

@swift-ci Please test Windows

ahoppen added 2 commits June 1, 2023 11:38
This uncovered two round-trip parsing failures which I’m fixing in this commit.

rdar://109783066
Just make sure that we don’t crash the diagnostic generator with the mutated test cases.
@ahoppen ahoppen force-pushed the ahoppen/flip-token-presence branch from 53db44a to e9a8683 Compare June 1, 2023 18:39
This uncovered a couple of implicit assumptions, mostly around the fact that tokens insided `UnexpectedNodesSyntax` are present, which isn’t true in general for manually generated trees.

It also uncovered an issue where we weren’t able to retrieve the trivia pieces of a token after it had been modified using `with` because after the modification the token was a `parsedToken` that no longer resided in a `ParsingSyntaxArena`.
@ahoppen ahoppen force-pushed the ahoppen/flip-token-presence branch from e9a8683 to e912ad4 Compare June 1, 2023 19:00
@ahoppen
Copy link
Member Author

ahoppen commented Jun 1, 2023

@swift-ci Please test

@ahoppen
Copy link
Member Author

ahoppen commented Jun 1, 2023

@swift-ci Please test Windows

2 similar comments
@ahoppen
Copy link
Member Author

ahoppen commented Jun 1, 2023

@swift-ci Please test Windows

@ahoppen
Copy link
Member Author

ahoppen commented Jun 1, 2023

@swift-ci Please test Windows

@@ -333,7 +333,7 @@ extension Parser {
}

mutating func parsePrimaryAssociatedTypes() -> RawPrimaryAssociatedTypeClauseSyntax {
let langle = self.consumeAnyToken(remapping: .leftAngle)
let langle = self.consumePrefix("<", as: .leftAngle)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you search for consumeAnyToken(.*leftAngle and rightAngle to make sure we don't have any more of these 😅?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, all other consumeAnyToken(remapping:) calls are fine.

@@ -1920,7 +1933,7 @@ final class DeclarationTests: XCTestCase {
}
""",
substructure: Syntax(
MemberDeclListItemSyntax(decl: EditorPlaceholderDeclSyntax(identifier: .identifier("<#code#>")))
MemberDeclListItemSyntax(decl: EditorPlaceholderDeclSyntax(placeholder: .identifier("<#code#>")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really need to merge my refactoring PR. More conflicts :)!

let nest = 20
let nest = 10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was this one for? Do we hit the stack limit in debug at only 10 😓?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don’t know what this test was meant to test. But I figured that there won’t really be any issues that we’d catch with 20 nested if statements that we wouldn’t catch if we nest 10.

And yes, this was hitting the maximum nesting level in debug builds. Not entirely sure why.

@kimdv
Copy link
Contributor

kimdv commented Jun 2, 2023

@swift-ci please test windows

@ahoppen ahoppen merged commit e6b40de into swiftlang:main Jun 2, 2023
@ahoppen ahoppen deleted the ahoppen/flip-token-presence branch June 2, 2023 18:55
@ahoppen ahoppen mentioned this pull request Jun 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants