-
Notifications
You must be signed in to change notification settings - Fork 441
/
Copy pathCollectionNodes+Parsable.swift
142 lines (131 loc) · 5.68 KB
/
CollectionNodes+Parsable.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#if compiler(>=6)
@_spi(RawSyntax) public import SwiftSyntax
#else
@_spi(RawSyntax) import SwiftSyntax
#endif
extension SyntaxCollection where Self: SyntaxParseable {
fileprivate static func parse(
from parser: inout Parser,
parse: (_ parser: inout Parser) -> some RawSyntaxNodeProtocol,
makeMissing: (_ remainingTokens: [RawSyntax], _ arena: RawSyntaxArena) -> some RawSyntaxNodeProtocol
) -> Self {
// Keep the parser alive so that the arena in which `raw` is allocated
// doesn’t get deallocated before we have a chance to create a syntax node
// from it. We can’t use `parser.arena` as the parameter to
// `Syntax(raw:arena:)` because the node might have been re-used during an
// incremental parse and would then live in a different arena than
// `parser.arena`.
defer {
withExtendedLifetime(parser) {
}
}
let node = parse(&parser)
if parser.at(.endOfFile) {
return Syntax(raw: node.raw, rawNodeArena: node.raw.arena).cast(Self.self)
}
let layoutView = node.raw.layoutView!
if layoutView.children.isEmpty {
let remainingTokens = parser.consumeRemainingTokens()
assert(!remainingTokens.isEmpty)
let missing = makeMissing(remainingTokens, parser.arena)
let raw = layoutView.insertingChild(missing.raw, at: node.raw.layoutView!.children.count, arena: parser.arena)
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
} else {
// First unwrap: We know that children.last exists because children is not empty
// Second unwrap: This is a collection and collections never have optional children. Thus the last child can’t be nil.
let lastWithRemainder = parser.parseRemainder(into: layoutView.children[layoutView.children.count - 1]!)
let raw = layoutView.replacingChild(
at: layoutView.children.count - 1,
with: lastWithRemainder,
arena: parser.arena
)
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
}
}
}
extension AccessorDeclListSyntax: SyntaxParseable {
public static func parse(from parser: inout Parser) -> Self {
return parse(from: &parser) { parser in
return parser.parseAccessorList() ?? RawAccessorDeclListSyntax(elements: [], arena: parser.arena)
} makeMissing: { remainingTokens, arena in
return RawAccessorDeclSyntax(
attributes: RawAttributeListSyntax(elements: [], arena: arena),
modifier: nil,
accessorSpecifier: RawTokenSyntax(missing: .keyword, text: "get", arena: arena),
parameters: nil,
effectSpecifiers: nil,
body: nil,
RawUnexpectedNodesSyntax(remainingTokens, arena: arena),
arena: arena
)
}
}
}
extension AttributeListSyntax: SyntaxParseable {
public static func parse(from parser: inout Parser) -> Self {
return parse(from: &parser) { parser in
return parser.parseAttributeList()
} makeMissing: { remainingTokens, arena in
return RawAttributeSyntax(
atSign: RawTokenSyntax(missing: .atSign, arena: arena),
attributeName: RawMissingTypeSyntax(arena: arena),
leftParen: nil,
arguments: nil,
rightParen: nil,
RawUnexpectedNodesSyntax(remainingTokens, arena: arena),
arena: arena
)
}
}
}
extension CodeBlockItemListSyntax: SyntaxParseable {
public static func parse(from parser: inout Parser) -> Self {
return parse(from: &parser) { parser in
let node = parser.parseCodeBlockItemList(until: { _ in false })
return node
} makeMissing: { remainingTokens, arena in
RawCodeBlockItemSyntax(
item: .init(expr: RawMissingExprSyntax(arena: arena)),
semicolon: nil,
RawUnexpectedNodesSyntax(remainingTokens, arena: arena),
arena: arena
)
}
}
}
extension MemberBlockItemListSyntax: SyntaxParseable {
public static func parse(from parser: inout Parser) -> Self {
return parse(from: &parser) { parser in
return parser.parseMemberDeclList()
} makeMissing: { remainingTokens, arena in
let missingDecl = RawMissingDeclSyntax(
attributes: RawAttributeListSyntax(elements: [], arena: arena),
modifiers: RawDeclModifierListSyntax(elements: [], arena: arena),
placeholder: RawTokenSyntax(missing: .identifier, text: "<#declaration#>", arena: arena),
RawUnexpectedNodesSyntax(remainingTokens, arena: arena),
arena: arena
)
return RawMemberBlockItemSyntax(decl: missingDecl, semicolon: nil, arena: arena)
}
}
}
//==========================================================================//
// IMPORTANT: When adding a new conformance, also add a corrsponding //
// conformance to SyntaxExpressibleByStringInterpolation in //
// SyntaxExpressibleByStringInterpolationConformances.swift //
//==========================================================================//
//==========================================================================//
// IMPORTANT: If you are tempted to add a new conformances here please //
// insert in in alphabetical order above //
//==========================================================================//