diff --git a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/KeywordFile.swift b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/KeywordFile.swift index 9b89f040daf..71b80a09b9e 100644 --- a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/KeywordFile.swift +++ b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/KeywordFile.swift @@ -40,20 +40,27 @@ let keywordFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try! SwitchExprSyntax("switch text.count") { for (length, keywords) in keywordsByLength() { SwitchCaseSyntax("case \(raw: length):") { - try! SwitchExprSyntax("switch text") { - for keyword in keywords { - SwitchCaseSyntax("case \(literal: keyword.name):") { - ExprSyntax("self = .\(keyword.enumCaseCallName)") - } - } - SwitchCaseSyntax("default: return nil") - } + ExprSyntax("self.init(_length\(raw: length): text)") } } SwitchCaseSyntax("default: return nil") } } + // Split into individual initializers by length to reduce stack use + for (length, keywords) in keywordsByLength() { + try! InitializerDeclSyntax("private init?(_length\(raw: length) text: SyntaxText)") { + try! SwitchExprSyntax("switch text") { + for keyword in keywords { + SwitchCaseSyntax("case \(literal: keyword.name):") { + ExprSyntax("self = .\(keyword.enumCaseCallName)") + } + } + SwitchCaseSyntax("default: return nil") + } + } + } + DeclSyntax( """ /// This is really unfortunate. Really, we should have a `switch` in diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index 8a8b7481a43..bfe5d3022e1 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -68,36 +68,7 @@ extension TokenConsumer { ) -> Bool { var subparser = self.lookahead() - var hasAttribute = false - var attributeProgress = LoopProgressCondition() - while subparser.hasProgressed(&attributeProgress) { - if subparser.at(.atSign) { - _ = subparser.consumeAttributeList() - hasAttribute = true - } else if subparser.at(.poundIf) && subparser.consumeIfConfigOfAttributes() { - hasAttribute = true - } else { - break - } - } - - var hasModifier = false - if subparser.currentToken.isLexerClassifiedKeyword || subparser.currentToken.rawTokenKind == .identifier { - var modifierProgress = LoopProgressCondition() - while let (modifierKind, handle) = subparser.at(anyIn: DeclarationModifier.self), - modifierKind != .class, - subparser.hasProgressed(&modifierProgress) - { - hasModifier = true - subparser.eat(handle) - if modifierKind != .open && subparser.at(.leftParen) && modifierKind.canHaveParenthesizedArgument { - // When determining whether we are at a declaration, don't consume anything in parentheses after 'open' - // so we don't consider a function call to open as a decl modifier. This matches the C++ parser. - subparser.consumeAnyToken() - subparser.consume(to: .rightParen) - } - } - } + let (hasAttribute, hasModifier) = subparser.skipAttributesAndModifiers() if hasAttribute { if subparser.at(.rightBrace) || subparser.at(.endOfFile) || subparser.at(.poundEndif) { @@ -112,17 +83,7 @@ extension TokenConsumer { switch subparser.at(anyIn: DeclarationKeyword.self)?.0 { case .lhs(.actor): // actor Foo {} - if subparser.peek().rawTokenKind == .identifier { - return true - } - // actor may be somewhere in the modifier list. Eat the tokens until we get - // to something that isn't the start of a decl. If that is an identifier, - // it's an actor declaration, otherwise, it isn't. - var lookahead = subparser.lookahead() - repeat { - lookahead.consumeAnyToken() - } while lookahead.atStartOfDeclaration(allowInitDecl: allowInitDecl, requiresDecl: requiresDecl) - return lookahead.at(.identifier) + return subparser.atStartOfActor(allowInitDecl: allowInitDecl, requiresDecl: requiresDecl) case .lhs(.case): // When 'case' appears inside a function, it's probably a switch // case, not an enum case declaration. @@ -146,23 +107,7 @@ extension TokenConsumer { return false } - var lookahead = subparser.lookahead() - - // Consume 'using' - lookahead.consumeAnyToken() - - // Allow parsing 'using' as declaration only if - // it's immediately followed by either `@` or - // an identifier. - if lookahead.atStartOfLine { - return false - } - - guard lookahead.at(.atSign) || lookahead.at(.identifier) else { - return false - } - - return true + return subparser.atStartOfUsing() case .some(_): // All other decl start keywords unconditionally start a decl. return true @@ -200,6 +145,80 @@ extension TokenConsumer { } } +extension Parser.Lookahead { + fileprivate mutating func skipAttributesAndModifiers() -> (hasAttribute: Bool, hasModifier: Bool) { + var hasAttribute = false + var attributeProgress = LoopProgressCondition() + while self.hasProgressed(&attributeProgress) { + if self.at(.atSign) { + _ = self.consumeAttributeList() + hasAttribute = true + } else if self.at(.poundIf) && self.consumeIfConfigOfAttributes() { + hasAttribute = true + } else { + break + } + } + + var hasModifier = false + if self.currentToken.isLexerClassifiedKeyword || self.currentToken.rawTokenKind == .identifier { + var modifierProgress = LoopProgressCondition() + while let (modifierKind, handle) = self.at(anyIn: DeclarationModifier.self), + modifierKind != .class, + self.hasProgressed(&modifierProgress) + { + hasModifier = true + self.eat(handle) + if modifierKind != .open && self.at(.leftParen) && modifierKind.canHaveParenthesizedArgument { + // When determining whether we are at a declaration, don't consume anything in parentheses after 'open' + // so we don't consider a function call to open as a decl modifier. This matches the C++ parser. + self.consumeAnyToken() + self.consume(to: .rightParen) + } + } + } + + return (hasAttribute, hasModifier) + } + + fileprivate mutating func atStartOfActor( + allowInitDecl: Bool, + requiresDecl: Bool + ) -> Bool { + if self.peek().rawTokenKind == .identifier { + return true + } + // actor may be somewhere in the modifier list. Eat the tokens until we get + // to something that isn't the start of a decl. If that is an identifier, + // it's an actor declaration, otherwise, it isn't. + var lookahead = self.lookahead() + repeat { + lookahead.consumeAnyToken() + } while lookahead.atStartOfDeclaration(allowInitDecl: allowInitDecl, requiresDecl: requiresDecl) + return lookahead.at(.identifier) + } + + fileprivate mutating func atStartOfUsing() -> Bool { + var lookahead = self.lookahead() + + // Consume 'using' + lookahead.consumeAnyToken() + + // Allow parsing 'using' as declaration only if + // it's immediately followed by either `@` or + // an identifier. + if lookahead.atStartOfLine { + return false + } + + guard lookahead.at(.atSign) || lookahead.at(.identifier) else { + return false + } + + return true + } +} + extension Parser { struct DeclAttributes { var attributes: RawAttributeListSyntax diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index b768e586462..d00b7026426 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -387,11 +387,14 @@ extension Parser { /// Make sure that we only accept `nonisolated(nonsending)` as a valid type specifier /// in expression context to minimize source compatibility impact. - func canParseNonisolatedAsSpecifierInExpressionContext() -> Bool { + mutating func canParseNonisolatedAsSpecifierInExpressionContext() -> Bool { + // If the token isn't even here, bail out before creating a lookahead. + guard self.at(.keyword(.nonisolated)) else { + return false + } + return withLookahead { - guard $0.consume(if: .keyword(.nonisolated)) != nil else { - return false - } + $0.consumeAnyToken() if $0.currentToken.isAtStartOfLine { return false @@ -415,21 +418,37 @@ extension Parser { pattern: PatternContext = .none ) -> RawExprSyntax { // Try to parse '@' sign, 'inout', or 'nonisolated' as an attributed typerepr. + if let type = parseAttributedTypeExprIfPresent() { + return RawExprSyntax(type) + } + + if let prefixExpr = parseSequenceExpressionElementPrefixIfPresent(flavor: flavor, pattern: pattern) { + return prefixExpr + } + + return self.parseUnaryExpression(flavor: flavor, pattern: pattern) + } + + private mutating func parseAttributedTypeExprIfPresent() -> RawTypeExprSyntax? { if self.at(.atSign, .keyword(.inout)) || self.canParseNonisolatedAsSpecifierInExpressionContext() { var lookahead = self.lookahead() if lookahead.canParseType() { let type = self.parseType() - return RawExprSyntax( - RawTypeExprSyntax( - type: type, - arena: self.arena - ) + return RawTypeExprSyntax( + type: type, + arena: self.arena ) } } + return nil + } + private mutating func parseSequenceExpressionElementPrefixIfPresent( + flavor: ExprFlavor, + pattern: PatternContext + ) -> RawExprSyntax? { EXPR_PREFIX: switch self.at(anyIn: ExpressionModifierKeyword.self) { case (.await, let handle)?: let awaitTok = self.eat(handle) @@ -444,6 +463,7 @@ extension Parser { arena: self.arena ) ) + case (.try, let handle)?: let tryKeyword = self.eat(handle) let mark = self.consume(if: .exclamationMark, .postfixQuestionMark) @@ -568,7 +588,7 @@ extension Parser { case nil: break } - return self.parseUnaryExpression(flavor: flavor, pattern: pattern) + return nil } /// Parse an optional prefix operator followed by an expression. @@ -768,99 +788,32 @@ extension Parser { } // If there is an expr-call-suffix, parse it and form a call. - if let lparen = self.consume(if: TokenSpec(.leftParen, allowAtStartOfLine: false)) { - let args = self.parseArgumentListElements( - pattern: pattern, - flavor: flavor.callArgumentFlavor, - allowTrailingComma: true - ) - let (unexpectedBeforeRParen, rparen) = self.expect(.rightParen) - - // If we can parse trailing closures, do so. - let trailingClosure: RawClosureExprSyntax? - let additionalTrailingClosures: RawMultipleTrailingClosureElementListSyntax - if case .basic = flavor, self.at(.leftBrace), self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) - { - (trailingClosure, additionalTrailingClosures) = self.parseTrailingClosures(flavor: flavor) - } else { - trailingClosure = nil - additionalTrailingClosures = self.emptyCollection(RawMultipleTrailingClosureElementListSyntax.self) - } - - leadingExpr = RawExprSyntax( - RawFunctionCallExprSyntax( - calledExpression: leadingExpr, - leftParen: lparen, - arguments: RawLabeledExprListSyntax(elements: args, arena: self.arena), - unexpectedBeforeRParen, - rightParen: rparen, - trailingClosure: trailingClosure, - additionalTrailingClosures: additionalTrailingClosures, - arena: self.arena - ) - ) + if let call = self.parsePostfixExpressionCallSuffixIfPresent( + leadingExpr: leadingExpr, + flavor: flavor, + pattern: pattern + ) { + leadingExpr = call continue } // Check for a [expr] suffix. // Note that this cannot be the start of a new line. - if let lsquare = self.consume(if: TokenSpec(.leftSquare, allowAtStartOfLine: false)) { - let args: [RawLabeledExprSyntax] - if self.at(.rightSquare) { - args = [] - } else { - args = self.parseArgumentListElements( - pattern: pattern, - allowTrailingComma: true - ) - } - let (unexpectedBeforeRSquare, rsquare) = self.expect(.rightSquare) - - // If we can parse trailing closures, do so. - let trailingClosure: RawClosureExprSyntax? - let additionalTrailingClosures: RawMultipleTrailingClosureElementListSyntax - if case .basic = flavor, self.at(.leftBrace), self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) - { - (trailingClosure, additionalTrailingClosures) = self.parseTrailingClosures(flavor: flavor) - } else { - trailingClosure = nil - additionalTrailingClosures = self.emptyCollection(RawMultipleTrailingClosureElementListSyntax.self) - } - - leadingExpr = RawExprSyntax( - RawSubscriptCallExprSyntax( - calledExpression: leadingExpr, - leftSquare: lsquare, - arguments: RawLabeledExprListSyntax(elements: args, arena: self.arena), - unexpectedBeforeRSquare, - rightSquare: rsquare, - trailingClosure: trailingClosure, - additionalTrailingClosures: additionalTrailingClosures, - arena: self.arena - ) - ) + if let sub = self.parsePostfixExpressionSubscriptSuffixIfPresent( + leadingExpr: leadingExpr, + flavor: flavor, + pattern: pattern + ) { + leadingExpr = sub continue } // Check for a trailing closure, if allowed. - if self.at(.leftBrace) && !leadingExpr.raw.kind.isLiteral - && self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) - { - // Add dummy blank argument list to the call expression syntax. - let list = RawLabeledExprListSyntax(elements: [], arena: self.arena) - let (first, rest) = self.parseTrailingClosures(flavor: flavor) - - leadingExpr = RawExprSyntax( - RawFunctionCallExprSyntax( - calledExpression: leadingExpr, - leftParen: nil, - arguments: list, - rightParen: nil, - trailingClosure: first, - additionalTrailingClosures: rest, - arena: self.arena - ) - ) + if let implicitCall = self.parsePostfixExpressionTrailingClosureSuffixIfPresent( + leadingExpr: leadingExpr, + flavor: flavor + ) { + leadingExpr = implicitCall // We only allow a single trailing closure on a call. This could be // generalized in the future, but needs further design. @@ -870,77 +823,209 @@ extension Parser { continue } - // Check for a ? suffix. - if let question = self.consume(if: .postfixQuestionMark) { - leadingExpr = RawExprSyntax( - RawOptionalChainingExprSyntax( - expression: leadingExpr, - questionMark: question, - arena: self.arena - ) - ) + // Check for a ?, !, or operator suffix. + if let postfixOp = self.parsePostfixExpressionOperatorSuffixIfPresent(leadingExpr: leadingExpr) { + leadingExpr = postfixOp continue } - // Check for a ! suffix. - if let exlaim = self.consume(if: .exclamationMark) { - leadingExpr = RawExprSyntax( - RawForceUnwrapExprSyntax( - expression: leadingExpr, - exclamationMark: exlaim, - arena: self.arena - ) - ) + if self.at(.poundIf) { + guard let ifConfigExpr = self.parsePostfixExpressionIfConfigSuffix(leadingExpr: leadingExpr, flavor: flavor) + else { + break + } + leadingExpr = ifConfigExpr continue } - // Check for a postfix-operator suffix. - if let op = self.consume(if: .postfixOperator) { - leadingExpr = RawExprSyntax( - RawPostfixOperatorExprSyntax( - expression: leadingExpr, - operator: op, - arena: self.arena - ) + // Otherwise, we don't know what this token is, it must end the expression. + break + } + return leadingExpr + } + + private mutating func parsePostfixExpressionCallSuffixIfPresent( + leadingExpr: RawExprSyntax, + flavor: ExprFlavor, + pattern: PatternContext + ) -> RawExprSyntax? { + guard let lparen = self.consume(if: TokenSpec(.leftParen, allowAtStartOfLine: false)) else { + return nil + } + + let args = self.parseArgumentListElements( + pattern: pattern, + flavor: flavor.callArgumentFlavor, + allowTrailingComma: true + ) + let (unexpectedBeforeRParen, rparen) = self.expect(.rightParen) + + // If we can parse trailing closures, do so. + let trailingClosure: RawClosureExprSyntax? + let additionalTrailingClosures: RawMultipleTrailingClosureElementListSyntax + if case .basic = flavor, self.at(.leftBrace), self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) { + (trailingClosure, additionalTrailingClosures) = self.parseTrailingClosures(flavor: flavor) + } else { + trailingClosure = nil + additionalTrailingClosures = self.emptyCollection(RawMultipleTrailingClosureElementListSyntax.self) + } + + return RawExprSyntax( + RawFunctionCallExprSyntax( + calledExpression: leadingExpr, + leftParen: lparen, + arguments: RawLabeledExprListSyntax(elements: args, arena: self.arena), + unexpectedBeforeRParen, + rightParen: rparen, + trailingClosure: trailingClosure, + additionalTrailingClosures: additionalTrailingClosures, + arena: self.arena + ) + ) + } + + private mutating func parsePostfixExpressionSubscriptSuffixIfPresent( + leadingExpr: RawExprSyntax, + flavor: ExprFlavor, + pattern: PatternContext + ) -> RawExprSyntax? { + guard let lsquare = self.consume(if: TokenSpec(.leftSquare, allowAtStartOfLine: false)) else { + return nil + } + + let args: [RawLabeledExprSyntax] + if self.at(.rightSquare) { + args = [] + } else { + args = self.parseArgumentListElements( + pattern: pattern, + allowTrailingComma: true + ) + } + let (unexpectedBeforeRSquare, rsquare) = self.expect(.rightSquare) + + // If we can parse trailing closures, do so. + let trailingClosure: RawClosureExprSyntax? + let additionalTrailingClosures: RawMultipleTrailingClosureElementListSyntax + if case .basic = flavor, self.at(.leftBrace), self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) { + (trailingClosure, additionalTrailingClosures) = self.parseTrailingClosures(flavor: flavor) + } else { + trailingClosure = nil + additionalTrailingClosures = self.emptyCollection(RawMultipleTrailingClosureElementListSyntax.self) + } + + return RawExprSyntax( + RawSubscriptCallExprSyntax( + calledExpression: leadingExpr, + leftSquare: lsquare, + arguments: RawLabeledExprListSyntax(elements: args, arena: self.arena), + unexpectedBeforeRSquare, + rightSquare: rsquare, + trailingClosure: trailingClosure, + additionalTrailingClosures: additionalTrailingClosures, + arena: self.arena + ) + ) + } + + private mutating func parsePostfixExpressionTrailingClosureSuffixIfPresent( + leadingExpr: RawExprSyntax, + flavor: ExprFlavor + ) -> RawExprSyntax? { + guard + self.at(.leftBrace) && !leadingExpr.raw.kind.isLiteral + && self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) + else { + return nil + } + + // Add dummy blank argument list to the call expression syntax. + let list = RawLabeledExprListSyntax(elements: [], arena: self.arena) + let (first, rest) = self.parseTrailingClosures(flavor: flavor) + + return RawExprSyntax( + RawFunctionCallExprSyntax( + calledExpression: leadingExpr, + leftParen: nil, + arguments: list, + rightParen: nil, + trailingClosure: first, + additionalTrailingClosures: rest, + arena: self.arena + ) + ) + } + + private mutating func parsePostfixExpressionOperatorSuffixIfPresent( + leadingExpr: RawExprSyntax + ) -> RawExprSyntax? { + // Check for a ? suffix. + if let question = self.consume(if: .postfixQuestionMark) { + return RawExprSyntax( + RawOptionalChainingExprSyntax( + expression: leadingExpr, + questionMark: question, + arena: self.arena ) - continue - } + ) + } - if self.at(.poundIf) { - // Check if the first '#if' body starts with '.' , and parse - // it as a "postfix ifconfig expression". - do { - var lookahead = self.lookahead() - // Skip to the first body. We may need to skip multiple '#if' directives - // since we support nested '#if's. e.g. - // baseExpr - // #if CONDITION_1 - // #if CONDITION_2 - // .someMember - var loopProgress = LoopProgressCondition() - repeat { - lookahead.eat(.poundIf) - while !lookahead.at(.endOfFile) && !lookahead.currentToken.isAtStartOfLine { - lookahead.skipSingle() - } - } while lookahead.at(.poundIf) && lookahead.hasProgressed(&loopProgress) + // Check for a ! suffix. + if let exlaim = self.consume(if: .exclamationMark) { + return RawExprSyntax( + RawForceUnwrapExprSyntax( + expression: leadingExpr, + exclamationMark: exlaim, + arena: self.arena + ) + ) + } - guard lookahead.atStartOfPostfixExprSuffix() else { - break - } + // Check for a postfix-operator suffix. + if let op = self.consume(if: .postfixOperator) { + return RawExprSyntax( + RawPostfixOperatorExprSyntax( + expression: leadingExpr, + operator: op, + arena: self.arena + ) + ) + } + + return nil + } + + private mutating func parsePostfixExpressionIfConfigSuffix( + leadingExpr: RawExprSyntax, + flavor: ExprFlavor + ) -> RawExprSyntax? { + // Check if the first '#if' body starts with '.' , and parse + // it as a "postfix ifconfig expression". + do { + var lookahead = self.lookahead() + // Skip to the first body. We may need to skip multiple '#if' directives + // since we support nested '#if's. e.g. + // baseExpr + // #if CONDITION_1 + // #if CONDITION_2 + // .someMember + var loopProgress = LoopProgressCondition() + repeat { + lookahead.eat(.poundIf) + while !lookahead.at(.endOfFile) && !lookahead.currentToken.isAtStartOfLine { + lookahead.skipSingle() } + } while lookahead.at(.poundIf) && lookahead.hasProgressed(&loopProgress) - leadingExpr = self.parseIfConfigExpressionSuffix( - leadingExpr, - flavor: flavor - ) - continue + guard lookahead.atStartOfPostfixExprSuffix() else { + return nil } - - // Otherwise, we don't know what this token is, it must end the expression. - break } - return leadingExpr + + return self.parseIfConfigExpressionSuffix( + leadingExpr, + flavor: flavor + ) } } @@ -1559,6 +1644,76 @@ extension Parser { value: RawExprSyntax ) case array(RawExprSyntax) + + fileprivate func makeElement(trailingComma: RawTokenSyntax?, arena: RawSyntaxArena) -> RawSyntax { + switch self { + case .array(let el): + return RawSyntax( + RawArrayElementSyntax( + expression: el, + trailingComma: trailingComma, + arena: arena + ) + ) + case .dictionary(let key, let unexpectedBeforeColon, let colon, let value): + return RawSyntax( + RawDictionaryElementSyntax( + key: key, + unexpectedBeforeColon, + colon: colon, + value: value, + trailingComma: trailingComma, + arena: arena + ) + ) + } + } + + fileprivate func makeCollection( + _ unexpectedBeforeLSquare: RawUnexpectedNodesSyntax?, + lsquare: RawTokenSyntax, + elements: [RawSyntax], + _ unexpectedBeforeRSquare: RawUnexpectedNodesSyntax?, + rsquare: RawTokenSyntax, + arena: RawSyntaxArena + ) -> RawExprSyntax { + switch self { + case .dictionary: + return RawExprSyntax( + RawDictionaryExprSyntax( + unexpectedBeforeLSquare, + leftSquare: lsquare, + content: .elements( + RawDictionaryElementListSyntax( + elements: elements.map { + $0.as(RawDictionaryElementSyntax.self)! + }, + arena: arena + ) + ), + unexpectedBeforeRSquare, + rightSquare: rsquare, + arena: arena + ) + ) + case .array: + return RawExprSyntax( + RawArrayExprSyntax( + unexpectedBeforeLSquare, + leftSquare: lsquare, + elements: RawArrayElementListSyntax( + elements: elements.map { + $0.as(RawArrayElementSyntax.self)! + }, + arena: arena + ), + unexpectedBeforeRSquare, + rightSquare: rsquare, + arena: arena + ) + ) + } + } } /// Parse an element of an array or dictionary literal. @@ -1595,37 +1750,11 @@ extension Parser { let (unexpectedBeforeLSquare, lsquare) = self.expect(.leftSquare) - // Check to see if we have an InlineArray type in expression position. - if self.isAtStartOfInlineArrayTypeBody() { - let type = self.parseInlineArrayType( - unexpectedBeforeLSquare: unexpectedBeforeLSquare, - leftSquare: lsquare - ) - return RawExprSyntax(RawTypeExprSyntax(type: type, arena: self.arena)) - } - - if let rsquare = self.consume(if: .rightSquare) { - return RawExprSyntax( - RawArrayExprSyntax( - unexpectedBeforeLSquare, - leftSquare: lsquare, - elements: RawArrayElementListSyntax(elements: [], arena: self.arena), - rightSquare: rsquare, - arena: self.arena - ) - ) - } - - if let (colon, rsquare) = self.consume(if: .colon, followedBy: .rightSquare) { - return RawExprSyntax( - RawDictionaryExprSyntax( - unexpectedBeforeLSquare, - leftSquare: lsquare, - content: .colon(colon), - rightSquare: rsquare, - arena: self.arena - ) - ) + if let specialLiteral = parseSpecialCollectionLiteral( + unexpectedBeforeLSquare: unexpectedBeforeLSquare, + lsquare: lsquare + ) { + return specialLiteral } var elementKind: CollectionKind? = nil @@ -1659,71 +1788,64 @@ extension Parser { keepGoing = nil } - switch elementKind! { - case .array(let el): - let element = RawArrayElementSyntax( - expression: el, - trailingComma: keepGoing, - arena: self.arena - ) - if element.isEmpty { - break COLLECTION_LOOP - } else { - elements.append(RawSyntax(element)) - } - case .dictionary(let key, let unexpectedBeforeColon, let colon, let value): - let element = RawDictionaryElementSyntax( - key: key, - unexpectedBeforeColon, - colon: colon, - value: value, - trailingComma: keepGoing, - arena: self.arena - ) - if element.isEmpty { - break COLLECTION_LOOP - } else { - elements.append(RawSyntax(element)) - } + let element = elementKind!.makeElement(trailingComma: keepGoing, arena: self.arena) + if element.isEmpty { + break COLLECTION_LOOP + } else { + elements.append(RawSyntax(element)) } } while keepGoing != nil && self.hasProgressed(&collectionProgress) } let (unexpectedBeforeRSquare, rsquare) = self.expect(.rightSquare) - switch elementKind! { - case .dictionary: + return elementKind!.makeCollection( + unexpectedBeforeLSquare, + lsquare: lsquare, + elements: elements, + unexpectedBeforeRSquare, + rsquare: rsquare, + arena: self.arena + ) + } + + private mutating func parseSpecialCollectionLiteral( + unexpectedBeforeLSquare: RawUnexpectedNodesSyntax?, + lsquare: RawTokenSyntax + ) -> RawExprSyntax? { + // Check to see if we have an InlineArray type in expression position. + if self.isAtStartOfInlineArrayTypeBody() { + let type = self.parseInlineArrayType( + unexpectedBeforeLSquare: unexpectedBeforeLSquare, + leftSquare: lsquare + ) + return RawExprSyntax(RawTypeExprSyntax(type: type, arena: self.arena)) + } + + if let rsquare = self.consume(if: .rightSquare) { return RawExprSyntax( - RawDictionaryExprSyntax( + RawArrayExprSyntax( + unexpectedBeforeLSquare, leftSquare: lsquare, - content: .elements( - RawDictionaryElementListSyntax( - elements: elements.map { - $0.as(RawDictionaryElementSyntax.self)! - }, - arena: self.arena - ) - ), - unexpectedBeforeRSquare, + elements: RawArrayElementListSyntax(elements: [], arena: self.arena), rightSquare: rsquare, arena: self.arena ) ) - case .array: + } + + if let (colon, rsquare) = self.consume(if: .colon, followedBy: .rightSquare) { return RawExprSyntax( - RawArrayExprSyntax( + RawDictionaryExprSyntax( + unexpectedBeforeLSquare, leftSquare: lsquare, - elements: RawArrayElementListSyntax( - elements: elements.map { - $0.as(RawArrayElementSyntax.self)! - }, - arena: self.arena - ), - unexpectedBeforeRSquare, + content: .colon(colon), rightSquare: rsquare, arena: self.arena ) ) } + + return nil } } @@ -1767,6 +1889,17 @@ extension Parser { extension Parser { /// Parse a closure expression. mutating func parseClosureExpression() -> RawClosureExprSyntax { + if let remainingTokens = self.remainingTokensIfMaximumNestingLevelReached() { + return RawClosureExprSyntax( + remainingTokens, + leftBrace: missingToken(.leftBrace), + signature: nil, + statements: RawCodeBlockItemListSyntax(elements: [], arena: self.arena), + rightBrace: missingToken(.rightBrace), + arena: self.arena + ) + } + // Parse the opening left brace. let (unexpectedBeforeLBrace, lbrace) = self.expect(.leftBrace) // Parse the closure-signature, if present. diff --git a/Sources/SwiftParser/Lexer/Cursor.swift b/Sources/SwiftParser/Lexer/Cursor.swift index cf06623cb3b..21471dbb098 100644 --- a/Sources/SwiftParser/Lexer/Cursor.swift +++ b/Sources/SwiftParser/Lexer/Cursor.swift @@ -945,52 +945,17 @@ extension Lexer.Cursor { case ";": _ = self.advance(); return Lexer.Result(.semicolon) case "\\": _ = self.advance(); return Lexer.Result(.backslash) - case ":": - _ = self.advance() - guard self.experimentalFeatures.contains(.moduleSelector) && self.peek() == ":" else { - return Lexer.Result(.colon) - } - - _ = self.advance() - return Lexer.Result(.colonColon) - - case "#": - // Try lex shebang. - if self.isAtStartOfFile, self.peek(at: 1) == "!" { - self.advanceToEndOfLine() - return Lexer.Result(.shebang) - } - // Try lex a raw string literal. - if let delimiterLength = self.advanceIfOpeningRawStringDelimiter() { - return Lexer.Result( - .rawStringPoundDelimiter, - stateTransition: .push(newState: .afterRawStringDelimiter(delimiterLength: delimiterLength)) - ) - } - - // Try lex a regex literal. - if let result = self.lexRegexLiteral() { - return result - } - // Otherwise try lex a magic pound literal. - return self.lexMagicPoundLiteral() + case ":": return self.lexNormalColon() + case "#": return self.lexNormalPound() case "!", "?": - if let result = lexPostfixOptionalChain(sourceBufferStart: sourceBufferStart) { - return result - } - return self.lexOperatorIdentifier( + return self.lexNormalQuestionOrExclamation( sourceBufferStart: sourceBufferStart, preferRegexOverBinaryOperator: preferRegexOverBinaryOperator ) case "<": - if self.is(offset: 1, at: "#"), - let result = self.tryLexEditorPlaceholder(sourceBufferStart: sourceBufferStart) - { - return result - } - return self.lexOperatorIdentifier( + return self.lexNormalLeftAngle( sourceBufferStart: sourceBufferStart, preferRegexOverBinaryOperator: preferRegexOverBinaryOperator ) @@ -1016,24 +981,94 @@ extension Lexer.Cursor { case nil: return Lexer.Result(.endOfFile) default: - var tmp = self - if tmp.advance(if: { $0.isValidIdentifierStartCodePoint }) { - return self.lexIdentifier() - } + return lexNormalMiscellaneous( + sourceBufferStart: sourceBufferStart, + preferRegexOverBinaryOperator: preferRegexOverBinaryOperator + ) + } + } - if tmp.advance(if: { $0.isOperatorStartCodePoint }) { - return self.lexOperatorIdentifier( - sourceBufferStart: sourceBufferStart, - preferRegexOverBinaryOperator: preferRegexOverBinaryOperator - ) - } + private mutating func lexNormalColon() -> Lexer.Result { + _ = self.advance() + guard self.experimentalFeatures.contains(.moduleSelector) && self.peek() == ":" else { + return Lexer.Result(.colon) + } - switch self.lexUnknown() { - case .lexemeContents(let result): - return result - case .trivia: - preconditionFailure("Invalid UTF-8 sequence should be eaten by lexTrivia as LeadingTrivia") - } + _ = self.advance() + return Lexer.Result(.colonColon) + } + + private mutating func lexNormalPound() -> Lexer.Result { + // Try lex shebang. + if self.isAtStartOfFile, self.peek(at: 1) == "!" { + self.advanceToEndOfLine() + return Lexer.Result(.shebang) + } + // Try lex a raw string literal. + if let delimiterLength = self.advanceIfOpeningRawStringDelimiter() { + return Lexer.Result( + .rawStringPoundDelimiter, + stateTransition: .push(newState: .afterRawStringDelimiter(delimiterLength: delimiterLength)) + ) + } + + // Try lex a regex literal. + if let result = self.lexRegexLiteral() { + return result + } + // Otherwise try lex a magic pound literal. + return self.lexMagicPoundLiteral() + } + + private mutating func lexNormalQuestionOrExclamation( + sourceBufferStart: Lexer.Cursor, + preferRegexOverBinaryOperator: Bool + ) -> Lexer.Result { + if let result = lexPostfixOptionalChain(sourceBufferStart: sourceBufferStart) { + return result + } + return self.lexOperatorIdentifier( + sourceBufferStart: sourceBufferStart, + preferRegexOverBinaryOperator: preferRegexOverBinaryOperator + ) + } + + private mutating func lexNormalLeftAngle( + sourceBufferStart: Lexer.Cursor, + preferRegexOverBinaryOperator: Bool + ) -> Lexer.Result { + if self.is(offset: 1, at: "#"), + let result = self.tryLexEditorPlaceholder(sourceBufferStart: sourceBufferStart) + { + return result + } + return self.lexOperatorIdentifier( + sourceBufferStart: sourceBufferStart, + preferRegexOverBinaryOperator: preferRegexOverBinaryOperator + ) + } + + private mutating func lexNormalMiscellaneous( + sourceBufferStart: Lexer.Cursor, + preferRegexOverBinaryOperator: Bool + ) -> Lexer.Result { + var tmp = self + if tmp.advance(if: { $0.isValidIdentifierStartCodePoint }) { + return self.lexIdentifier() + } + + if tmp.advance(if: { $0.isOperatorStartCodePoint }) { + return self.lexOperatorIdentifier( + sourceBufferStart: sourceBufferStart, + preferRegexOverBinaryOperator: preferRegexOverBinaryOperator + ) + } + + switch self.lexUnknown() { + case .lexemeContents(let result): + return result + case .trivia: + preconditionFailure("Invalid UTF-8 sequence should be eaten by lexTrivia as LeadingTrivia") } } diff --git a/Sources/SwiftSyntax/generated/Keyword.swift b/Sources/SwiftSyntax/generated/Keyword.swift index f557d35d503..31007c1ade1 100644 --- a/Sources/SwiftSyntax/generated/Keyword.swift +++ b/Sources/SwiftSyntax/generated/Keyword.swift @@ -230,525 +230,613 @@ public enum Keyword: UInt8, Hashable, Sendable { @_spi(RawSyntax) public init?(_ text: SyntaxText) { switch text.count { case 2: - switch text { - case "as": - self = .as - case "do": - self = .do - case "if": - self = .if - case "in": - self = .in - case "is": - self = .is - case "of": - self = .of - default: - return nil - } + self.init(_length2: text) case 3: - switch text { - case "abi": - self = .abi - case "any": - self = .any - case "Any": - self = .Any - case "for": - self = .for - case "get": - self = .get - case "let": - self = .let - case "nil": - self = .nil - case "set": - self = .set - case "spi": - self = .spi - case "try": - self = .try - case "var": - self = .var - case "wrt": - self = .wrt - default: - return nil - } + self.init(_length3: text) case 4: - switch text { - case "case": - self = .case - case "copy": - self = .copy - case "each": - self = .each - case "else": - self = .else - case "enum": - self = .enum - case "file": - self = .file - case "func": - self = .func - case "init": - self = .`init` - case "kind": - self = .kind - case "lazy": - self = .lazy - case "left": - self = .left - case "line": - self = .line - case "none": - self = .none - case "objc": - self = .objc - case "open": - self = .open - case "read": - self = .read - case "safe": - self = .safe - case "self": - self = .self - case "Self": - self = .Self - case "some": - self = .some - case "then": - self = .then - case "true": - self = .true - case "Type": - self = .Type - case "weak": - self = .weak - default: - return nil - } + self.init(_length4: text) case 5: - switch text { - case "_move": - self = ._move - case "_read": - self = ._read - case "actor": - self = .actor - case "async": - self = .async - case "await": - self = .await - case "block": - self = .block - case "break": - self = .break - case "catch": - self = .catch - case "class": - self = .class - case "defer": - self = .defer - case "false": - self = .false - case "final": - self = .final - case "guard": - self = .guard - case "infix": - self = .infix - case "inout": - self = .inout - case "macro": - self = .macro - case "right": - self = .right - case "super": - self = .super - case "swift": - self = .swift - case "throw": - self = .throw - case "using": - self = .using - case "where": - self = .where - case "while": - self = .while - case "yield": - self = .yield - default: - return nil - } + self.init(_length5: text) case 6: - switch text { - case "_Class": - self = ._Class - case "_const": - self = ._const - case "_local": - self = ._local - case "before": - self = .before - case "borrow": - self = .borrow - case "deinit": - self = .deinit - case "didSet": - self = .didSet - case "import": - self = .import - case "linear": - self = .linear - case "modify": - self = .modify - case "module": - self = .module - case "mutate": - self = .mutate - case "prefix": - self = .prefix - case "public": - self = .public - case "repeat": - self = .repeat - case "return": - self = .return - case "scoped": - self = .scoped - case "static": - self = .static - case "struct": - self = .struct - case "switch": - self = .switch - case "target": - self = .target - case "throws": - self = .throws - case "unsafe": - self = .unsafe - default: - return nil - } + self.init(_length6: text) case 7: - switch text { - case "__owned": - self = .__owned - case "_borrow": - self = ._borrow - case "_linear": - self = ._linear - case "_modify": - self = ._modify - case "consume": - self = .consume - case "default": - self = .default - case "dynamic": - self = .dynamic - case "discard": - self = .discard - case "forward": - self = .forward - case "message": - self = .message - case "noasync": - self = .noasync - case "package": - self = .package - case "postfix": - self = .postfix - case "private": - self = .private - case "reasync": - self = .reasync - case "renamed": - self = .renamed - case "reverse": - self = .reverse - case "sending": - self = .sending - case "unowned": - self = .unowned - case "willSet": - self = .willSet - default: - return nil - } + self.init(_length7: text) case 8: - switch text { - case "__shared": - self = .__shared - case "_effects": - self = ._effects - case "_forward": - self = ._forward - case "_Trivial": - self = ._Trivial - case "_version": - self = ._version - case "accesses": - self = .accesses - case "attached": - self = .attached - case "compiler": - self = .compiler - case "continue": - self = .continue - case "escaping": - self = .escaping - case "exported": - self = .exported - case "indirect": - self = .indirect - case "internal": - self = .internal - case "isolated": - self = .isolated - case "metadata": - self = .metadata - case "mutating": - self = .mutating - case "noescape": - self = .noescape - case "operator": - self = .operator - case "optional": - self = .optional - case "override": - self = .override - case "Protocol": - self = .Protocol - case "protocol": - self = .protocol - case "required": - self = .required - case "rethrows": - self = .rethrows - case "Sendable": - self = .Sendable - default: - return nil - } + self.init(_length8: text) case 9: - switch text { - case "_mutating": - self = ._mutating - case "available": - self = .available - case "borrowing": - self = .borrowing - case "canImport": - self = .canImport - case "consuming": - self = .consuming - case "dependsOn": - self = .dependsOn - case "extension": - self = .extension - case "lowerThan": - self = .lowerThan - case "obsoleted": - self = .obsoleted - case "spiModule": - self = .spiModule - case "subscript": - self = .subscript - case "transpose": - self = .transpose - case "typealias": - self = .typealias - case "unchecked": - self = .unchecked - default: - return nil - } + self.init(_length9: text) case 10: - switch text { - case "_borrowing": - self = ._borrowing - case "_consuming": - self = ._consuming - case "assignment": - self = .assignment - case "convention": - self = .convention - case "deprecated": - self = .deprecated - case "derivative": - self = .derivative - case "higherThan": - self = .higherThan - case "introduced": - self = .introduced - case "nonsending": - self = .nonsending - case "visibility": - self = .visibility - default: - return nil - } + self.init(_length10: text) case 11: - switch text { - case "__consuming": - self = .__consuming - case "_backDeploy": - self = ._backDeploy - case "_implements": - self = ._implements - case "_noMetadata": - self = ._noMetadata - case "specialized": - self = .specialized - case "_specialize": - self = ._specialize - case "autoclosure": - self = .autoclosure - case "convenience": - self = .convenience - case "distributed": - self = .distributed - case "fallthrough": - self = .fallthrough - case "fileprivate": - self = .fileprivate - case "initializes": - self = .initializes - case "nonisolated": - self = .nonisolated - case "nonmutating": - self = .nonmutating - case "retroactive": - self = .retroactive - case "unavailable": - self = .unavailable - default: - return nil - } + self.init(_length11: text) case 12: - switch text { - case "_NativeClass": - self = ._NativeClass - case "availability": - self = .availability - case "backDeployed": - self = .backDeployed - case "freestanding": - self = .freestanding - case "noDerivative": - self = .noDerivative - default: - return nil - } + self.init(_length12: text) case 13: - switch text { - case "_BridgeObject": - self = ._BridgeObject - case "associativity": - self = .associativity - case "unsafeAddress": - self = .unsafeAddress - default: - return nil - } + self.init(_length13: text) case 14: - switch text { - case "_documentation": - self = ._documentation - case "_spi_available": - self = ._spi_available - case "_TrivialAtMost": - self = ._TrivialAtMost - case "_TrivialStride": - self = ._TrivialStride - case "_UnknownLayout": - self = ._UnknownLayout - case "associatedtype": - self = .associatedtype - case "differentiable": - self = .differentiable - case "preconcurrency": - self = .preconcurrency - default: - return nil - } + self.init(_length14: text) case 15: - switch text { - case "__setter_access": - self = .__setter_access - case "precedencegroup": - self = .precedencegroup - default: - return nil - } + self.init(_length15: text) case 16: - switch text { - case "addressWithOwner": - self = .addressWithOwner - default: - return nil - } + self.init(_length16: text) case 17: - switch text { - case "_RefCountedObject": - self = ._RefCountedObject - default: - return nil - } + self.init(_length17: text) case 18: - switch text { - case "_underlyingVersion": - self = ._underlyingVersion - default: - return nil - } + self.init(_length18: text) case 19: - switch text { - case "_dynamicReplacement": - self = ._dynamicReplacement - case "_opaqueReturnTypeOf": - self = ._opaqueReturnTypeOf - case "_PackageDescription": - self = ._PackageDescription - default: - return nil - } + self.init(_length19: text) case 20: - switch text { - case "_compilerInitialized": - self = ._compilerInitialized - case "_originallyDefinedIn": - self = ._originallyDefinedIn - case "unsafeMutableAddress": - self = .unsafeMutableAddress - default: - return nil - } + self.init(_length20: text) case 22: - switch text { - case "addressWithNativeOwner": - self = .addressWithNativeOwner - default: - return nil - } + self.init(_length22: text) case 23: - switch text { - case "_NativeRefCountedObject": - self = ._NativeRefCountedObject - case "mutableAddressWithOwner": - self = .mutableAddressWithOwner - default: - return nil - } + self.init(_length23: text) case 29: - switch text { - case "mutableAddressWithNativeOwner": - self = .mutableAddressWithNativeOwner - default: - return nil - } + self.init(_length29: text) + default: + return nil + } + } + + private init?(_length2 text: SyntaxText) { + switch text { + case "as": + self = .as + case "do": + self = .do + case "if": + self = .if + case "in": + self = .in + case "is": + self = .is + case "of": + self = .of + default: + return nil + } + } + + private init?(_length3 text: SyntaxText) { + switch text { + case "abi": + self = .abi + case "any": + self = .any + case "Any": + self = .Any + case "for": + self = .for + case "get": + self = .get + case "let": + self = .let + case "nil": + self = .nil + case "set": + self = .set + case "spi": + self = .spi + case "try": + self = .try + case "var": + self = .var + case "wrt": + self = .wrt + default: + return nil + } + } + + private init?(_length4 text: SyntaxText) { + switch text { + case "case": + self = .case + case "copy": + self = .copy + case "each": + self = .each + case "else": + self = .else + case "enum": + self = .enum + case "file": + self = .file + case "func": + self = .func + case "init": + self = .`init` + case "kind": + self = .kind + case "lazy": + self = .lazy + case "left": + self = .left + case "line": + self = .line + case "none": + self = .none + case "objc": + self = .objc + case "open": + self = .open + case "read": + self = .read + case "safe": + self = .safe + case "self": + self = .self + case "Self": + self = .Self + case "some": + self = .some + case "then": + self = .then + case "true": + self = .true + case "Type": + self = .Type + case "weak": + self = .weak + default: + return nil + } + } + + private init?(_length5 text: SyntaxText) { + switch text { + case "_move": + self = ._move + case "_read": + self = ._read + case "actor": + self = .actor + case "async": + self = .async + case "await": + self = .await + case "block": + self = .block + case "break": + self = .break + case "catch": + self = .catch + case "class": + self = .class + case "defer": + self = .defer + case "false": + self = .false + case "final": + self = .final + case "guard": + self = .guard + case "infix": + self = .infix + case "inout": + self = .inout + case "macro": + self = .macro + case "right": + self = .right + case "super": + self = .super + case "swift": + self = .swift + case "throw": + self = .throw + case "using": + self = .using + case "where": + self = .where + case "while": + self = .while + case "yield": + self = .yield + default: + return nil + } + } + + private init?(_length6 text: SyntaxText) { + switch text { + case "_Class": + self = ._Class + case "_const": + self = ._const + case "_local": + self = ._local + case "before": + self = .before + case "borrow": + self = .borrow + case "deinit": + self = .deinit + case "didSet": + self = .didSet + case "import": + self = .import + case "linear": + self = .linear + case "modify": + self = .modify + case "module": + self = .module + case "mutate": + self = .mutate + case "prefix": + self = .prefix + case "public": + self = .public + case "repeat": + self = .repeat + case "return": + self = .return + case "scoped": + self = .scoped + case "static": + self = .static + case "struct": + self = .struct + case "switch": + self = .switch + case "target": + self = .target + case "throws": + self = .throws + case "unsafe": + self = .unsafe + default: + return nil + } + } + + private init?(_length7 text: SyntaxText) { + switch text { + case "__owned": + self = .__owned + case "_borrow": + self = ._borrow + case "_linear": + self = ._linear + case "_modify": + self = ._modify + case "consume": + self = .consume + case "default": + self = .default + case "dynamic": + self = .dynamic + case "discard": + self = .discard + case "forward": + self = .forward + case "message": + self = .message + case "noasync": + self = .noasync + case "package": + self = .package + case "postfix": + self = .postfix + case "private": + self = .private + case "reasync": + self = .reasync + case "renamed": + self = .renamed + case "reverse": + self = .reverse + case "sending": + self = .sending + case "unowned": + self = .unowned + case "willSet": + self = .willSet + default: + return nil + } + } + + private init?(_length8 text: SyntaxText) { + switch text { + case "__shared": + self = .__shared + case "_effects": + self = ._effects + case "_forward": + self = ._forward + case "_Trivial": + self = ._Trivial + case "_version": + self = ._version + case "accesses": + self = .accesses + case "attached": + self = .attached + case "compiler": + self = .compiler + case "continue": + self = .continue + case "escaping": + self = .escaping + case "exported": + self = .exported + case "indirect": + self = .indirect + case "internal": + self = .internal + case "isolated": + self = .isolated + case "metadata": + self = .metadata + case "mutating": + self = .mutating + case "noescape": + self = .noescape + case "operator": + self = .operator + case "optional": + self = .optional + case "override": + self = .override + case "Protocol": + self = .Protocol + case "protocol": + self = .protocol + case "required": + self = .required + case "rethrows": + self = .rethrows + case "Sendable": + self = .Sendable + default: + return nil + } + } + + private init?(_length9 text: SyntaxText) { + switch text { + case "_mutating": + self = ._mutating + case "available": + self = .available + case "borrowing": + self = .borrowing + case "canImport": + self = .canImport + case "consuming": + self = .consuming + case "dependsOn": + self = .dependsOn + case "extension": + self = .extension + case "lowerThan": + self = .lowerThan + case "obsoleted": + self = .obsoleted + case "spiModule": + self = .spiModule + case "subscript": + self = .subscript + case "transpose": + self = .transpose + case "typealias": + self = .typealias + case "unchecked": + self = .unchecked + default: + return nil + } + } + + private init?(_length10 text: SyntaxText) { + switch text { + case "_borrowing": + self = ._borrowing + case "_consuming": + self = ._consuming + case "assignment": + self = .assignment + case "convention": + self = .convention + case "deprecated": + self = .deprecated + case "derivative": + self = .derivative + case "higherThan": + self = .higherThan + case "introduced": + self = .introduced + case "nonsending": + self = .nonsending + case "visibility": + self = .visibility + default: + return nil + } + } + + private init?(_length11 text: SyntaxText) { + switch text { + case "__consuming": + self = .__consuming + case "_backDeploy": + self = ._backDeploy + case "_implements": + self = ._implements + case "_noMetadata": + self = ._noMetadata + case "specialized": + self = .specialized + case "_specialize": + self = ._specialize + case "autoclosure": + self = .autoclosure + case "convenience": + self = .convenience + case "distributed": + self = .distributed + case "fallthrough": + self = .fallthrough + case "fileprivate": + self = .fileprivate + case "initializes": + self = .initializes + case "nonisolated": + self = .nonisolated + case "nonmutating": + self = .nonmutating + case "retroactive": + self = .retroactive + case "unavailable": + self = .unavailable + default: + return nil + } + } + + private init?(_length12 text: SyntaxText) { + switch text { + case "_NativeClass": + self = ._NativeClass + case "availability": + self = .availability + case "backDeployed": + self = .backDeployed + case "freestanding": + self = .freestanding + case "noDerivative": + self = .noDerivative + default: + return nil + } + } + + private init?(_length13 text: SyntaxText) { + switch text { + case "_BridgeObject": + self = ._BridgeObject + case "associativity": + self = .associativity + case "unsafeAddress": + self = .unsafeAddress + default: + return nil + } + } + + private init?(_length14 text: SyntaxText) { + switch text { + case "_documentation": + self = ._documentation + case "_spi_available": + self = ._spi_available + case "_TrivialAtMost": + self = ._TrivialAtMost + case "_TrivialStride": + self = ._TrivialStride + case "_UnknownLayout": + self = ._UnknownLayout + case "associatedtype": + self = .associatedtype + case "differentiable": + self = .differentiable + case "preconcurrency": + self = .preconcurrency + default: + return nil + } + } + + private init?(_length15 text: SyntaxText) { + switch text { + case "__setter_access": + self = .__setter_access + case "precedencegroup": + self = .precedencegroup + default: + return nil + } + } + + private init?(_length16 text: SyntaxText) { + switch text { + case "addressWithOwner": + self = .addressWithOwner + default: + return nil + } + } + + private init?(_length17 text: SyntaxText) { + switch text { + case "_RefCountedObject": + self = ._RefCountedObject + default: + return nil + } + } + + private init?(_length18 text: SyntaxText) { + switch text { + case "_underlyingVersion": + self = ._underlyingVersion + default: + return nil + } + } + + private init?(_length19 text: SyntaxText) { + switch text { + case "_dynamicReplacement": + self = ._dynamicReplacement + case "_opaqueReturnTypeOf": + self = ._opaqueReturnTypeOf + case "_PackageDescription": + self = ._PackageDescription + default: + return nil + } + } + + private init?(_length20 text: SyntaxText) { + switch text { + case "_compilerInitialized": + self = ._compilerInitialized + case "_originallyDefinedIn": + self = ._originallyDefinedIn + case "unsafeMutableAddress": + self = .unsafeMutableAddress + default: + return nil + } + } + + private init?(_length22 text: SyntaxText) { + switch text { + case "addressWithNativeOwner": + self = .addressWithNativeOwner + default: + return nil + } + } + + private init?(_length23 text: SyntaxText) { + switch text { + case "_NativeRefCountedObject": + self = ._NativeRefCountedObject + case "mutableAddressWithOwner": + self = .mutableAddressWithOwner + default: + return nil + } + } + + private init?(_length29 text: SyntaxText) { + switch text { + case "mutableAddressWithNativeOwner": + self = .mutableAddressWithNativeOwner default: return nil }