Skip to content

Commit 13f688e

Browse files
authored
Merge pull request #1665 from ahoppen/ahoppen/rintaro-review-comments
Address review comments to #1650
2 parents 36f24a8 + 8bd739d commit 13f688e

13 files changed

+392
-240
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,30 @@ extension DeclarationModifier {
3030

3131
extension TokenConsumer {
3232
mutating func atStartOfFreestandingMacroExpansion() -> Bool {
33+
// Check if "'#' <identifier>" where the identifier is on the sameline.
3334
if !self.at(.pound) {
3435
return false
3536
}
36-
if self.peek().rawTokenKind != .identifier && !self.peek().isLexerClassifiedKeyword {
37+
if self.peek().isAtStartOfLine {
3738
return false
3839
}
39-
if self.currentToken.trailingTriviaByteLength != 0 || self.peek().leadingTriviaByteLength != 0 {
40+
switch self.peek().rawTokenKind {
41+
case .identifier:
42+
return true
43+
case .keyword:
44+
// allow keywords right after '#' so we can diagnose it when parsing.
45+
return (self.currentToken.trailingTriviaByteLength == 0 && self.peek().leadingTriviaByteLength == 0)
46+
default:
4047
return false
4148
}
42-
return true
4349
}
4450

4551
mutating func atStartOfDeclaration(
4652
isAtTopLevel: Bool = false,
4753
allowInitDecl: Bool = true,
4854
allowRecovery: Bool = false
4955
) -> Bool {
50-
if self.at(anyIn: PoundDeclarationStart.self) != nil {
56+
if self.at(.poundIfKeyword) {
5157
return true
5258
}
5359

@@ -188,13 +194,9 @@ extension Parser {
188194
/// If `inMemberDeclList` is `true`, we know that the next item must be a
189195
/// declaration and thus start with a keyword. This allows futher recovery.
190196
mutating func parseDeclaration(inMemberDeclList: Bool = false) -> RawDeclSyntax {
191-
switch self.at(anyIn: PoundDeclarationStart.self) {
192-
case (.poundIfKeyword, _)?:
193-
if self.withLookahead({ $0.consumeIfConfigOfAttributes() }) {
194-
// If we are at a `#if` of attributes, the `#if` directive should be
195-
// parsed when we're parsing the attributes.
196-
break
197-
}
197+
// If we are at a `#if` of attributes, the `#if` directive should be
198+
// parsed when we're parsing the attributes.
199+
if self.at(.poundIfKeyword) && !self.withLookahead({ $0.consumeIfConfigOfAttributes() }) {
198200
let directive = self.parsePoundIfDirective { (parser, _) in
199201
let parsedDecl = parser.parseDeclaration()
200202
let semicolon = parser.consume(if: .semicolon)
@@ -220,8 +222,6 @@ extension Parser {
220222
return .decls(RawMemberDeclListSyntax(elements: elements, arena: parser.arena))
221223
}
222224
return RawDeclSyntax(directive)
223-
case nil:
224-
break
225225
}
226226

227227
let attrs = DeclAttributes(
@@ -2096,25 +2096,24 @@ extension Parser {
20962096
_ handle: RecoveryConsumptionHandle
20972097
) -> RawMacroExpansionDeclSyntax {
20982098

2099-
let (unexpectedBeforePound, poundKeyword) = self.eat(handle)
2100-
// Don't allow space between '#' and the macro name.
2101-
if poundKeyword.trailingTriviaByteLength != 0 || self.currentToken.leadingTriviaByteLength != 0 {
2102-
return RawMacroExpansionDeclSyntax(
2103-
attributes: attrs.attributes,
2104-
modifiers: attrs.modifiers,
2105-
unexpectedBeforePound,
2106-
poundToken: poundKeyword,
2107-
macro: self.missingToken(.identifier),
2108-
genericArguments: nil,
2109-
leftParen: nil,
2110-
argumentList: .init(elements: [], arena: self.arena),
2111-
rightParen: nil,
2112-
trailingClosure: nil,
2113-
additionalTrailingClosures: nil,
2114-
arena: self.arena
2115-
)
2099+
var (unexpectedBeforePound, pound) = self.eat(handle)
2100+
if pound.trailingTriviaByteLength != 0 {
2101+
// `#` and the macro name must not be separated by a newline.
2102+
unexpectedBeforePound = RawUnexpectedNodesSyntax(combining: unexpectedBeforePound, pound, arena: self.arena)
2103+
pound = RawTokenSyntax(missing: .pound, text: "#", leadingTriviaPieces: pound.leadingTriviaPieces, arena: self.arena)
2104+
}
2105+
var unexpectedBeforeMacro: RawUnexpectedNodesSyntax?
2106+
var macro: RawTokenSyntax
2107+
if !self.currentToken.isAtStartOfLine {
2108+
(unexpectedBeforeMacro, macro) = self.expectIdentifier(keywordRecovery: true)
2109+
if macro.leadingTriviaByteLength != 0 {
2110+
unexpectedBeforeMacro = RawUnexpectedNodesSyntax(combining: unexpectedBeforeMacro, macro, arena: self.arena)
2111+
pound = self.missingToken(.identifier, text: macro.tokenText)
2112+
}
2113+
} else {
2114+
unexpectedBeforeMacro = nil
2115+
macro = self.missingToken(.identifier)
21162116
}
2117-
let (unexpectedBeforeMacro, macro) = self.expectIdentifier(keywordRecovery: true)
21182117

21192118
// Parse the optional generic argument list.
21202119
let generics: RawGenericArgumentClauseSyntax?
@@ -2155,7 +2154,7 @@ extension Parser {
21552154
attributes: attrs.attributes,
21562155
modifiers: attrs.modifiers,
21572156
unexpectedBeforePound,
2158-
poundToken: poundKeyword,
2157+
poundToken: pound,
21592158
unexpectedBeforeMacro,
21602159
macro: macro,
21612160
genericArguments: generics,

Sources/SwiftParser/Expressions.swift

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,21 +1411,25 @@ extension Parser {
14111411
pattern: PatternContext,
14121412
flavor: ExprFlavor
14131413
) -> RawMacroExpansionExprSyntax {
1414-
if !atStartOfFreestandingMacroExpansion() {
1415-
return RawMacroExpansionExprSyntax(
1416-
poundToken: self.consumeAnyToken(),
1417-
macro: self.missingToken(.identifier),
1418-
genericArguments: nil,
1419-
leftParen: nil,
1420-
argumentList: .init(elements: [], arena: self.arena),
1421-
rightParen: nil,
1422-
trailingClosure: nil,
1423-
additionalTrailingClosures: nil,
1424-
arena: self.arena
1425-
)
1414+
var (unexpectedBeforePound, pound) = self.expect(.pound)
1415+
if pound.trailingTriviaByteLength != 0 {
1416+
// If there are whitespaces after '#' diagnose.
1417+
unexpectedBeforePound = RawUnexpectedNodesSyntax(combining: unexpectedBeforePound, pound, arena: self.arena)
1418+
pound = self.missingToken(.pound)
1419+
}
1420+
var unexpectedBeforeMacro: RawUnexpectedNodesSyntax?
1421+
var macro: RawTokenSyntax
1422+
if !self.currentToken.isAtStartOfLine {
1423+
(unexpectedBeforeMacro, macro) = self.expectIdentifier(keywordRecovery: true)
1424+
if macro.leadingTriviaByteLength != 0 {
1425+
// If there're whitespaces after '#' diagnose.
1426+
unexpectedBeforeMacro = RawUnexpectedNodesSyntax(combining: unexpectedBeforeMacro, macro, arena: self.arena)
1427+
pound = self.missingToken(.identifier, text: macro.tokenText)
1428+
}
1429+
} else {
1430+
unexpectedBeforeMacro = nil
1431+
macro = self.missingToken(.identifier)
14261432
}
1427-
let poundKeyword = self.consumeAnyToken()
1428-
let (unexpectedBeforeMacro, macro) = self.expectIdentifier(keywordRecovery: true)
14291433

14301434
// Parse the optional generic argument list.
14311435
let generics: RawGenericArgumentClauseSyntax?
@@ -1460,7 +1464,8 @@ extension Parser {
14601464
}
14611465

14621466
return RawMacroExpansionExprSyntax(
1463-
poundToken: poundKeyword,
1467+
unexpectedBeforePound,
1468+
poundToken: pound,
14641469
unexpectedBeforeMacro,
14651470
macro: macro,
14661471
genericArguments: generics,

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -426,23 +426,6 @@ enum OperatorLike: TokenSpecSet {
426426
}
427427
}
428428

429-
enum PoundDeclarationStart: TokenSpecSet {
430-
case poundIfKeyword
431-
432-
init?(lexeme: Lexer.Lexeme) {
433-
switch lexeme.rawTokenKind {
434-
case .poundIfKeyword: self = .poundIfKeyword
435-
default: return nil
436-
}
437-
}
438-
439-
var spec: TokenSpec {
440-
switch self {
441-
case .poundIfKeyword: return .poundIfKeyword
442-
}
443-
}
444-
}
445-
446429
enum SwitchCaseStart: TokenSpecSet {
447430
case `case`
448431
case `default`

Sources/SwiftParserDiagnostics/DiagnosticExtensions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extension FixIt.MultiNodeChange {
5959
/// removed node will be transferred to the trailing trivia of the previous token.
6060
static func makeMissing(_ tokens: [TokenSyntax], transferTrivia: Bool = true) -> Self {
6161
precondition(!tokens.isEmpty)
62-
precondition(tokens.allSatisfy({ $0.presence == .present }))
62+
precondition(tokens.allSatisfy({ $0.isPresent }))
6363
var changes = tokens.map {
6464
FixIt.Change.replace(
6565
oldNode: Syntax($0),
@@ -111,7 +111,7 @@ extension FixIt.MultiNodeChange {
111111
class MissingNodesBasicFormatter: BasicFormat {
112112
override func isMutable(_ token: TokenSyntax) -> Bool {
113113
// Assume that all missing nodes will be made present by the Fix-It.
114-
return token.presence == .missing
114+
return token.isMissing
115115
}
116116
}
117117

@@ -153,7 +153,7 @@ extension FixIt.MultiNodeChange {
153153
}
154154

155155
if let previousToken = node.previousToken(viewMode: .fixedUp),
156-
previousToken.presence == .present,
156+
previousToken.isPresent,
157157
let firstToken = node.firstToken(viewMode: .all),
158158
previousToken.trailingTrivia.allSatisfy({ $0.isWhitespace }),
159159
!BasicFormat().requiresWhitespace(between: previousToken, and: firstToken),

Sources/SwiftParserDiagnostics/MissingNodesError.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fileprivate enum NodesDescriptionPart {
7676
for missingNode in nodes {
7777
if let token = missingNode.as(TokenSyntax.self) {
7878
let newPart: NodesDescriptionPart
79-
if token.presence == .present {
79+
if token.isPresent {
8080
newPart = .tokensWithDefaultText([token])
8181
} else {
8282
let (rawKind, text) = token.tokenKind.decomposeToRaw()
@@ -371,7 +371,7 @@ extension ParseDiagnosticsGenerator {
371371
let siblings = parentWithTokens.children(viewMode: .all)
372372
let siblingsAfter = siblings[siblings.index(after: index)...]
373373
for sibling in siblingsAfter {
374-
if sibling.as(TokenSyntax.self)?.presence == .missing {
374+
if sibling.as(TokenSyntax.self)?.isMissing ?? false {
375375
// Handle missing sibling tokens
376376
missingNodes += [sibling]
377377
} else if sibling.raw.kind.isMissing {

Sources/SwiftParserDiagnostics/MissingTokenError.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ extension ParseDiagnosticsGenerator {
108108

109109
if let identifier = missingToken.nextToken(viewMode: .all),
110110
identifier.tokenView.rawKind == .identifier,
111-
identifier.presence == .missing
111+
identifier.isMissing
112112
{
113113
// The extraneous whitespace caused a missing identifier, output a
114114
// diagnostic inserting it instead of a diagnostic to fix the trivia
@@ -126,7 +126,7 @@ extension ParseDiagnosticsGenerator {
126126
)
127127
} else {
128128
let fixIt = FixIt(message: .removeExtraneousWhitespace, changes: changes)
129-
addDiagnostic(invalidToken, .invalidWhitespaceAfterPeriod, fixIts: [fixIt], handledNodes: [invalidTokenContainer.id])
129+
addDiagnostic(invalidToken, ExtraneousWhitespace(tokenWithWhitespace: invalidToken), fixIts: [fixIt], handledNodes: [invalidTokenContainer.id])
130130
}
131131
return true
132132
}

0 commit comments

Comments
 (0)