Skip to content

Commit b5ccba0

Browse files
authored
[Swift] reduce Optionals in APIs (#3621)
* ParserRuleContext.children see comment in removeLastChild * TokenStream.getText * Parser._parseListeners this might require changes to the code templates? * ATN {various} * make computeReachSet return empty, not nil * overrides refine optionality * BufferedTokenStream getHiddenTokensTo{Left, Right} return empty not nil * Update Swift.stg * avoid breakage by adding overload of `getText` in extension
1 parent 37496e2 commit b5ccba0

File tree

12 files changed

+111
-115
lines changed

12 files changed

+111
-115
lines changed

runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ public class BufferedTokenStream: TokenStream {
372372
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or
373373
/// EOF. If channel is -1, find any non default channel token.
374374
///
375-
public func getHiddenTokensToRight(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token]? {
375+
public func getHiddenTokensToRight(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token] {
376376
try lazyInit()
377377
guard tokens.indices.contains(tokenIndex) else {
378378
throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0 ..< \(tokens.count)")
@@ -397,28 +397,28 @@ public class BufferedTokenStream: TokenStream {
397397
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
398398
/// If channel is -1, find any non default channel token.
399399
///
400-
public func getHiddenTokensToLeft(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token]? {
400+
public func getHiddenTokensToLeft(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token] {
401401
try lazyInit()
402402
guard tokens.indices.contains(tokenIndex) else {
403403
throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0 ..< \(tokens.count)")
404404
}
405405

406406
if tokenIndex == 0 {
407407
// obviously no tokens can appear before the first token
408-
return nil
408+
return []
409409
}
410410

411411
let prevOnChannel = try previousTokenOnChannel(tokenIndex - 1, Lexer.DEFAULT_TOKEN_CHANNEL)
412412
if prevOnChannel == tokenIndex - 1 {
413-
return nil
413+
return []
414414
}
415415
// if none onchannel to left, prevOnChannel=-1 then from=0
416416
let from = prevOnChannel + 1
417417
let to = tokenIndex - 1
418418
return filterForChannel(from, to, channel)
419419
}
420420

421-
internal func filterForChannel(_ from: Int, _ to: Int, _ channel: Int) -> [Token]? {
421+
internal func filterForChannel(_ from: Int, _ to: Int, _ channel: Int) -> [Token] {
422422
var hidden = [Token]()
423423
for t in tokens[from...to] {
424424
if channel == -1 {
@@ -431,9 +431,6 @@ public class BufferedTokenStream: TokenStream {
431431
}
432432
}
433433
}
434-
if hidden.isEmpty {
435-
return nil
436-
}
437434
return hidden
438435
}
439436

@@ -472,12 +469,8 @@ public class BufferedTokenStream: TokenStream {
472469
}
473470

474471

475-
public func getText(_ start: Token?, _ stop: Token?) throws -> String {
476-
if let start = start, let stop = stop {
477-
return try getText(Interval.of(start.getTokenIndex(), stop.getTokenIndex()))
478-
}
479-
480-
return ""
472+
public func getText(_ start: Token, _ stop: Token) throws -> String {
473+
return try getText(Interval.of(start.getTokenIndex(), stop.getTokenIndex()))
481474
}
482475

483476
///

runtime/Swift/Sources/Antlr4/Parser.swift

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
126126
///
127127
/// - SeeAlso: #addParseListener
128128
///
129-
public var _parseListeners: Array<ParseTreeListener>?
129+
public var _parseListeners: Array<ParseTreeListener> = []
130130

131131
///
132132
/// The number of syntax errors reported during parsing. This value is
@@ -285,7 +285,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
285285
}
286286

287287
public func getParseListeners() -> [ParseTreeListener] {
288-
return _parseListeners ?? [ParseTreeListener]()
288+
return _parseListeners
289289
}
290290

291291
///
@@ -314,11 +314,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
314314
/// - Parameter listener: the listener to add
315315
///
316316
public func addParseListener(_ listener: ParseTreeListener) {
317-
if _parseListeners == nil {
318-
_parseListeners = [ParseTreeListener]()
319-
}
320-
321-
_parseListeners!.append(listener)
317+
_parseListeners.append(listener)
322318
}
323319

324320
///
@@ -333,16 +329,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
333329
///
334330

335331
public func removeParseListener(_ listener: ParseTreeListener?) {
336-
if _parseListeners != nil {
337-
if !_parseListeners!.filter({ $0 === listener }).isEmpty {
338-
_parseListeners = _parseListeners!.filter({
339-
$0 !== listener
340-
})
341-
if _parseListeners!.isEmpty {
342-
_parseListeners = nil
343-
}
344-
}
345-
}
332+
_parseListeners.removeAll(where: { $0 === listener })
346333
}
347334

348335
///
@@ -351,7 +338,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
351338
/// - SeeAlso: #addParseListener
352339
///
353340
public func removeParseListeners() {
354-
_parseListeners = nil
341+
_parseListeners = []
355342
}
356343

357344
///
@@ -360,7 +347,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
360347
/// - SeeAlso: #addParseListener
361348
///
362349
public func triggerEnterRuleEvent() throws {
363-
if let _parseListeners = _parseListeners, let _ctx = _ctx {
350+
if let _ctx = _ctx {
364351
for listener: ParseTreeListener in _parseListeners {
365352
try listener.enterEveryRule(_ctx)
366353
_ctx.enterRule(listener)
@@ -375,7 +362,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
375362
///
376363
public func triggerExitRuleEvent() throws {
377364
// reverse order walk of listeners
378-
if let _parseListeners = _parseListeners, let _ctx = _ctx {
365+
if let _ctx = _ctx {
379366
for listener in _parseListeners.reversed() {
380367
_ctx.exitRule(listener)
381368
try listener.exitEveryRule(_ctx)
@@ -542,24 +529,20 @@ open class Parser: Recognizer<ParserATNSimulator> {
542529
guard let _ctx = _ctx else {
543530
return o
544531
}
545-
let hasListener = _parseListeners != nil && !_parseListeners!.isEmpty
532+
let hasListener = !_parseListeners.isEmpty
546533

547534
if _buildParseTrees || hasListener {
548535
if _errHandler.inErrorRecoveryMode(self) {
549536
let node = createErrorNode(parent: _ctx, t: o)
550537
_ctx.addErrorNode(node)
551-
if let _parseListeners = _parseListeners {
552-
for listener in _parseListeners {
553-
listener.visitErrorNode(node)
554-
}
538+
for listener in _parseListeners {
539+
listener.visitErrorNode(node)
555540
}
556541
} else {
557542
let node = createTerminalNode(parent: _ctx, t: o)
558543
_ctx.addChild(node)
559-
if let _parseListeners = _parseListeners {
560-
for listener in _parseListeners {
561-
listener.visitTerminal(node)
562-
}
544+
for listener in _parseListeners {
545+
listener.visitTerminal(node)
563546
}
564547
}
565548
}
@@ -611,7 +594,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
611594
}
612595
ctx.stop = try _input.LT(-1)
613596
// trigger event on _ctx, before it reverts to parent
614-
if _parseListeners != nil {
597+
if !_parseListeners.isEmpty {
615598
try triggerExitRuleEvent()
616599
}
617600
setState(ctx.invokingState)
@@ -629,7 +612,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
629612
}
630613
}
631614
_ctx = localctx
632-
if _parseListeners != nil {
615+
if !_parseListeners.isEmpty {
633616
try triggerEnterRuleEvent()
634617
}
635618
}
@@ -664,7 +647,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
664647
_precedenceStack.push(precedence)
665648
_ctx = localctx
666649
_ctx!.start = try _input.LT(1)
667-
if _parseListeners != nil {
650+
if !_parseListeners.isEmpty {
668651
try triggerEnterRuleEvent() // simulates rule entry for left-recursive rules
669652
}
670653
}
@@ -684,7 +667,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
684667
_ctx!.addChild(previous)
685668
}
686669

687-
if _parseListeners != nil {
670+
if !_parseListeners.isEmpty {
688671
try triggerEnterRuleEvent() // simulates rule entry for left-recursive rules
689672
}
690673
}
@@ -695,7 +678,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
695678
let retctx = _ctx! // save current ctx (return value)
696679

697680
// unroll so _ctx is as it was before call to recursive method
698-
if _parseListeners != nil {
681+
if !_parseListeners.isEmpty {
699682
while let ctxWrap = _ctx, ctxWrap !== _parentctx {
700683
try triggerExitRuleEvent()
701684
_ctx = ctxWrap.parent as? ParserRuleContext

runtime/Swift/Sources/Antlr4/ParserRuleContext.swift

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ open class ParserRuleContext: RuleContext {
3535
/// operation because we don't the need to track the details about
3636
/// how we parse this rule.
3737
///
38-
public var children: [ParseTree]?
38+
public var children: [ParseTree] = []
3939

4040
/// For debugging/tracing purposes, we want to track all of the nodes in
4141
/// the ATN traversed by the parser for a particular rule.
@@ -89,13 +89,12 @@ open class ParserRuleContext: RuleContext {
8989
self.stop = ctx.stop
9090

9191
// copy any error nodes to alt label node
92-
if let ctxChildren = ctx.children {
93-
self.children = [ParseTree]()
94-
// reset parent pointer for any error nodes
95-
for child in ctxChildren {
96-
if let errNode = child as? ErrorNode {
97-
addChild(errNode)
98-
}
92+
let ctxChildren = ctx.children
93+
self.children = [ParseTree]()
94+
// reset parent pointer for any error nodes
95+
for child in ctxChildren {
96+
if let errNode = child as? ErrorNode {
97+
addChild(errNode)
9998
}
10099
}
101100
}
@@ -120,10 +119,7 @@ open class ParserRuleContext: RuleContext {
120119
/// - Since: 4.7
121120
///
122121
open func addAnyChild(_ t: ParseTree) {
123-
if children == nil {
124-
children = [ParseTree]()
125-
}
126-
children!.append(t)
122+
children.append(t)
127123
}
128124

129125
open func addChild(_ ruleInvocation: RuleContext) {
@@ -148,20 +144,22 @@ open class ParserRuleContext: RuleContext {
148144
/// generic ruleContext object.
149145
///
150146
open func removeLastChild() {
151-
children?.removeLast()
147+
// removeLast asserts if called when empty, popLast does not,
148+
// this preserves edge case behavior, perhaps unnecessarily.
149+
_ = children.popLast()
152150
}
153151

154152

155153
override
156154
open func getChild(_ i: Int) -> Tree? {
157-
guard let children = children, i >= 0 && i < children.count else {
155+
guard i >= 0 && i < children.count else {
158156
return nil
159157
}
160158
return children[i]
161159
}
162160

163161
open func getChild<T: ParseTree>(_ ctxType: T.Type, i: Int) -> T? {
164-
guard let children = children, i >= 0 && i < children.count else {
162+
guard i >= 0 && i < children.count else {
165163
return nil
166164
}
167165
var j = -1 // what element have we found with ctxType?
@@ -178,7 +176,7 @@ open class ParserRuleContext: RuleContext {
178176
}
179177

180178
open func getToken(_ ttype: Int, _ i: Int) -> TerminalNode? {
181-
guard let children = children, i >= 0 && i < children.count else {
179+
guard i >= 0 && i < children.count else {
182180
return nil
183181
}
184182
var j = -1 // what token with ttype have we found?
@@ -198,10 +196,6 @@ open class ParserRuleContext: RuleContext {
198196
}
199197

200198
open func getTokens(_ ttype: Int) -> [TerminalNode] {
201-
guard let children = children else {
202-
return [TerminalNode]()
203-
}
204-
205199
return children.compactMap {
206200
if let tnode = $0 as? TerminalNode, let symbol = tnode.getSymbol(), symbol.getType() == ttype {
207201
return tnode
@@ -217,20 +211,17 @@ open class ParserRuleContext: RuleContext {
217211
}
218212

219213
open func getRuleContexts<T: ParserRuleContext>(_ ctxType: T.Type) -> [T] {
220-
guard let children = children else {
221-
return [T]()
222-
}
223214
return children.compactMap { $0 as? T }
224215
}
225216

226217
override
227218
open func getChildCount() -> Int {
228-
return children?.count ?? 0
219+
return children.count
229220
}
230221

231222
override
232223
open subscript(index: Int) -> ParseTree {
233-
return children![index]
224+
return children[index]
234225
}
235226

236227
override

runtime/Swift/Sources/Antlr4/TokenStream.swift

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,41 @@ public protocol TokenStream: IntStream {
133133
/// and `stop` tokens.
134134
///
135135
///
136-
func getText(_ start: Token?, _ stop: Token?) throws -> String
136+
func getText(_ start: Token, _ stop: Token) throws -> String
137+
}
138+
139+
extension TokenStream {
140+
///
141+
/// Return the text of all tokens in this stream between `start` and
142+
/// `stop` (inclusive).
143+
///
144+
/// If the specified `start` or `stop` token was not provided by
145+
/// this stream, or if the `stop` occurred before the `start`
146+
/// token, the behavior is unspecified.
147+
///
148+
/// For streams which ensure that the _org.antlr.v4.runtime.Token#getTokenIndex_ method is
149+
/// accurate for all of its provided tokens, this method behaves like the
150+
/// following code. Other streams may implement this method in other ways
151+
/// provided the behavior is consistent with this at a high level.
152+
///
153+
///
154+
/// TokenStream stream = ...;
155+
/// String text = "";
156+
/// for (int i = start.getTokenIndex(); i &lt;= stop.getTokenIndex(); i++) {
157+
/// text += stream.get(i).getText();
158+
/// }
159+
///
160+
///
161+
/// - Parameter start: The first token in the interval to get text for.
162+
/// - Parameter stop: The last token in the interval to get text for (inclusive).
163+
/// - Throws: ANTLRError.unsupportedOperation if this stream does not support
164+
/// this method for the specified tokens
165+
/// - Returns: The text of all tokens lying between the specified `start`
166+
/// and `stop` tokens.
167+
///
168+
///
169+
func getText(_ start: Token?, _ stop: Token?) throws -> String {
170+
guard let start = start, let stop = stop else { return "" }
171+
return try getText(start, stop)
172+
}
137173
}

runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ public class UnbufferedTokenStream: TokenStream {
116116
}
117117

118118

119-
public func getText(_ start: Token?, _ stop: Token?) throws -> String {
120-
return try getText(Interval.of(start!.getTokenIndex(), stop!.getTokenIndex()))
119+
public func getText(_ start: Token, _ stop: Token) throws -> String {
120+
return try getText(Interval.of(start.getTokenIndex(), stop.getTokenIndex()))
121121
}
122122

123123

0 commit comments

Comments
 (0)