Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions Sources/SwiftParser/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1768,20 +1768,14 @@ extension Parser {
)
}

var body = [RawCodeBlockItemSyntax]()
var codeBlockProgress = LoopProgressCondition()
while !self.at(.rightBrace),
let newItem = self.parseCodeBlockItem(),
codeBlockProgress.evaluate(currentToken)
{
body.append(newItem)
}
let body = parseCodeBlockItemList(until: { $0.at(.rightBrace) })

let (unexpectedBeforeRBrace, rbrace) = self.expect(.rightBrace)
return .getter(
RawCodeBlockSyntax(
unexpectedBeforeLBrace,
leftBrace: lbrace,
statements: RawCodeBlockItemListSyntax(elements: body, arena: self.arena),
statements: body,
unexpectedBeforeRBrace,
rightBrace: rbrace,
arena: self.arena
Expand Down
23 changes: 5 additions & 18 deletions Sources/SwiftParser/Expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1710,21 +1710,15 @@ extension Parser {
let signature = self.parseClosureSignatureIfPresent()

// Parse the body.
var elements = [RawCodeBlockItemSyntax]()
do {
var loopProgress = LoopProgressCondition()
while !self.at(.rightBrace), let newItem = self.parseCodeBlockItem(), loopProgress.evaluate(currentToken) {
elements.append(newItem)
}
}
let elements = parseCodeBlockItemList(until: { $0.at(.rightBrace) })

// Parse the closing '}'.
let (unexpectedBeforeRBrace, rbrace) = self.expect(.rightBrace)
return RawClosureExprSyntax(
unexpectedBeforeLBrace,
leftBrace: lbrace,
signature: signature,
statements: RawCodeBlockItemListSyntax(elements: elements, arena: arena),
statements: elements,
unexpectedBeforeRBrace,
rightBrace: rbrace,
arena: self.arena
Expand Down Expand Up @@ -2326,16 +2320,9 @@ extension Parser {
}

mutating func parseSwitchCaseBody() -> RawCodeBlockItemListSyntax {
var items = [RawCodeBlockItemSyntax]()
var loopProgress = LoopProgressCondition()
while !self.at(.rightBrace) && !self.at(.poundEndifKeyword, .poundElseifKeyword, .poundElseKeyword)
&& !self.withLookahead({ $0.isStartOfConditionalSwitchCases() }),
let newItem = self.parseCodeBlockItem(),
loopProgress.evaluate(currentToken)
{
items.append(newItem)
}
return RawCodeBlockItemListSyntax(elements: items, arena: self.arena)
parseCodeBlockItemList(until: {
$0.at(.rightBrace) || $0.at(.poundEndifKeyword, .poundElseifKeyword, .poundElseKeyword) || $0.withLookahead({ $0.isStartOfConditionalSwitchCases() })
})
}

/// Parse a single switch case clause.
Expand Down
8 changes: 4 additions & 4 deletions Sources/SwiftParser/SwiftParser.docc/FixingBugs.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Once you’ve written a test case (see below), set a breakpoint in `Parser.parse

1. Add a new test case in `SwiftParserTest` that looks like the following
```swift
AssertParse(
assertParse(
"""
<#your code that does not round trip#>
"""
Expand All @@ -27,7 +27,7 @@ Diagnostics are produced when the parsed syntax tree contains missing or unexpec

1. Add a test case in `SwiftParserTest` that looks like the following
```swift
AssertParse(
assertParse(
"""
<#your code that produces an invalid syntax tree#>
""",
Expand All @@ -54,7 +54,7 @@ To add a new, more contextual diagnostic, perform the following steps.
1. Add a test case in `SwiftParserTest` that looks like the following

```swift
AssertParse(
assertParse(
"""
<#your code that produced the unhelpful diagnostic#>
""",
Expand All @@ -69,7 +69,7 @@ To add a new, more contextual diagnostic, perform the following steps.
5. If the function does not already exist, write a new visit method on <doc:SwiftParser/ParseDiagnosticsGenerator>.
6. In that visitation method, detect the pattern for which the improved diagnostic should be emitted and emit it using `diagnostics.append`.
7. Mark the missing or garbage nodes that are covered by the new diagnostic as handled by adding their `SyntaxIdentifier`s to `handledNodes`.
8. If the diagnostic produces Fix-Its assert that they are generated by adding the Fix-It's message to the `DiagnosticSpec` with the `fixIt` parameter and asserting that applying the Fix-Its produces the correct source code by adding the `fixedSource` parameter to `AssertParse`.
8. If the diagnostic produces Fix-Its assert that they are generated by adding the Fix-It's message to the `DiagnosticSpec` with the `fixIt` parameter and asserting that applying the Fix-Its produces the correct source code by adding the `fixedSource` parameter to `assertParse`.

> 💡 Tip: To make typing the marker emojis more convienient. you can set up code snippets in Xcode. To do this, perform the following steps:
> 1. Type the marker in any Xcode window or find it in some test case
Expand Down
10 changes: 5 additions & 5 deletions Sources/SwiftParser/TopLevel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extension Parser {
}

extension Parser {
mutating func parseCodeBlockItemList(isAtTopLevel: Bool, allowInitDecl: Bool = true, stopCondition: (inout Parser) -> Bool) -> RawCodeBlockItemListSyntax {
mutating func parseCodeBlockItemList(isAtTopLevel: Bool = false, allowInitDecl: Bool = true, until stopCondition: (inout Parser) -> Bool) -> RawCodeBlockItemListSyntax {
var elements = [RawCodeBlockItemSyntax]()
var loopProgress = LoopProgressCondition()
while !stopCondition(&self), loopProgress.evaluate(currentToken) {
Expand Down Expand Up @@ -89,7 +89,7 @@ extension Parser {
///
/// top-level-declaration → statements?
mutating func parseTopLevelCodeBlockItems() -> RawCodeBlockItemListSyntax {
return parseCodeBlockItemList(isAtTopLevel: true, stopCondition: { _ in false })
return parseCodeBlockItemList(isAtTopLevel: true, until: { _ in false })
}

/// The optional form of `parseCodeBlock` that checks to see if the parser has
Expand All @@ -116,7 +116,7 @@ extension Parser {
/// indented to close this code block or a surrounding context. See `expectRightBrace`.
mutating func parseCodeBlock(introducer: RawTokenSyntax? = nil, allowInitDecl: Bool = true) -> RawCodeBlockSyntax {
let (unexpectedBeforeLBrace, lbrace) = self.expect(.leftBrace)
let itemList = parseCodeBlockItemList(isAtTopLevel: false, allowInitDecl: allowInitDecl, stopCondition: { $0.at(.rightBrace) })
let itemList = parseCodeBlockItemList(allowInitDecl: allowInitDecl, until: { $0.at(.rightBrace) })
let (unexpectedBeforeRBrace, rbrace) = self.expectRightBrace(leftBrace: lbrace, introducer: introducer)

return .init(
Expand Down Expand Up @@ -148,7 +148,7 @@ extension Parser {
/// statement → compiler-control-statement
/// statements → statement statements?
@_spi(RawSyntax)
public mutating func parseCodeBlockItem(isAtTopLevel: Bool = false, allowInitDecl: Bool = true) -> RawCodeBlockItemSyntax? {
public mutating func parseCodeBlockItem(isAtTopLevel: Bool, allowInitDecl: Bool) -> RawCodeBlockItemSyntax? {
if let remainingTokens = remainingTokensIfMaximumNestingLevelReached() {
return RawCodeBlockItemSyntax(
remainingTokens,
Expand Down Expand Up @@ -229,7 +229,7 @@ extension Parser {
// If config of attributes is parsed as part of declaration parsing as it
// doesn't constitute its own code block item.
let directive = self.parsePoundIfDirective { (parser, _) in
parser.parseCodeBlockItem()
parser.parseCodeBlockItem(isAtTopLevel: isAtTopLevel, allowInitDecl: allowInitDecl)
} addSemicolonIfNeeded: { lastElement, newItemAtStartOfLine, parser in
if lastElement.semicolon == nil && !newItemAtStartOfLine {
return RawCodeBlockItemSyntax(
Expand Down
10 changes: 5 additions & 5 deletions Sources/_SwiftSyntaxTestSupport/AssertEqualWithDiff.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import XCTest
/// which this function was called.
/// - line: The line number on which failure occurred. Defaults to the line number on which this
/// function was called.
public func AssertStringsEqualWithDiff(
public func assertStringsEqualWithDiff(
_ actual: String,
_ expected: String,
_ message: String = "",
Expand All @@ -34,7 +34,7 @@ public func AssertStringsEqualWithDiff(
if actual == expected {
return
}
FailStringsEqualWithDiff(
failStringsEqualWithDiff(
actual,
expected,
message,
Expand All @@ -55,7 +55,7 @@ public func AssertStringsEqualWithDiff(
/// which this function was called.
/// - line: The line number on which failure occurred. Defaults to the line number on which this
/// function was called.
public func AssertDataEqualWithDiff(
public func assertDataEqualWithDiff(
_ actual: Data,
_ expected: Data,
_ message: String = "",
Expand All @@ -69,7 +69,7 @@ public func AssertDataEqualWithDiff(

// NOTE: Converting to `Stirng` here looses invalid UTF8 sequence difference,
// but at least we can see something is different.
FailStringsEqualWithDiff(
failStringsEqualWithDiff(
String(decoding: actual, as: UTF8.self),
String(decoding: expected, as: UTF8.self),
message,
Expand All @@ -80,7 +80,7 @@ public func AssertDataEqualWithDiff(
}

/// `XCTFail` with `diff`-style output.
public func FailStringsEqualWithDiff(
public func failStringsEqualWithDiff(
_ actual: String,
_ expected: String,
_ message: String = "",
Expand Down
14 changes: 7 additions & 7 deletions Tests/SwiftDiagnosticsTest/DiagnosticsFormatterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class DiagnosticsFormatterTests: XCTestCase {
│ ╰─ error: expected expression after operator

"""
AssertStringsEqualWithDiff(annotate(source: source), expectedOutput)
assertStringsEqualWithDiff(annotate(source: source), expectedOutput)
}

func testMultipleDiagnosticsInOneLine() {
Expand All @@ -47,7 +47,7 @@ final class DiagnosticsFormatterTests: XCTestCase {
│ ╰─ error: expected name in member access

"""
AssertStringsEqualWithDiff(annotate(source: source), expectedOutput)
assertStringsEqualWithDiff(annotate(source: source), expectedOutput)
}

func testLineSkipping() {
Expand Down Expand Up @@ -78,7 +78,7 @@ final class DiagnosticsFormatterTests: XCTestCase {
│ ╰─ error: expected value and ')' to end function call

"""
AssertStringsEqualWithDiff(annotate(source: source), expectedOutput)
assertStringsEqualWithDiff(annotate(source: source), expectedOutput)
}

func testTwoDiagnosticsAtSameLocation() throws {
Expand All @@ -91,7 +91,7 @@ final class DiagnosticsFormatterTests: XCTestCase {

"""

AssertStringsEqualWithDiff(annotate(source: source), expectedOutput)
assertStringsEqualWithDiff(annotate(source: source), expectedOutput)
}

func testAddsColoringToSingleErrorDiagnostic() {
Expand All @@ -104,7 +104,7 @@ final class DiagnosticsFormatterTests: XCTestCase {
\u{001B}[0;36m│\u{001B}[0;0m ╰─ \u{001B}[1;31merror: expected expression after operator\u{001B}[0;0m

"""
AssertStringsEqualWithDiff(annotate(source: source, colorize: true), expectedOutput)
assertStringsEqualWithDiff(annotate(source: source, colorize: true), expectedOutput)
}

func testAddsColoringToMultipleDiagnosticsInOneLine() {
Expand All @@ -118,7 +118,7 @@ final class DiagnosticsFormatterTests: XCTestCase {
\u{001B}[0;36m│\u{001B}[0;0m ╰─ \u{001B}[1;31merror: expected name in member access\u{001B}[0;0m

"""
AssertStringsEqualWithDiff(annotate(source: source, colorize: true), expectedOutput)
assertStringsEqualWithDiff(annotate(source: source, colorize: true), expectedOutput)
}

func testColoringWithHighlights() {
Expand All @@ -133,6 +133,6 @@ final class DiagnosticsFormatterTests: XCTestCase {

"""

AssertStringsEqualWithDiff(annotate(source: source, colorize: true), expectedOutput)
assertStringsEqualWithDiff(annotate(source: source, colorize: true), expectedOutput)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ final class GroupedDiagnosticsFormatterTests: XCTestCase {
)

let annotated = DiagnosticsFormatter.annotateSources(in: group)
AssertStringsEqualWithDiff(
assertStringsEqualWithDiff(
annotated,
"""
=== main.swift:5 ===
Expand Down Expand Up @@ -178,7 +178,7 @@ final class GroupedDiagnosticsFormatterTests: XCTestCase {
)

let annotated = DiagnosticsFormatter.annotateSources(in: group)
AssertStringsEqualWithDiff(
assertStringsEqualWithDiff(
annotated,
"""
=== main.swift:2 ===
Expand Down
Loading