From b5ccba03c8fa9108975bf13044ce10caed6f579c Mon Sep 17 00:00:00 2001 From: Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com> Date: Sun, 10 Apr 2022 13:35:27 -0400 Subject: [PATCH] [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 --- .../Sources/Antlr4/BufferedTokenStream.swift | 21 +++----- runtime/Swift/Sources/Antlr4/Parser.swift | 51 +++++++------------ .../Sources/Antlr4/ParserRuleContext.swift | 41 ++++++--------- .../Swift/Sources/Antlr4/TokenStream.swift | 38 +++++++++++++- .../Antlr4/UnbufferedTokenStream.swift | 4 +- runtime/Swift/Sources/Antlr4/atn/ATN.swift | 8 +-- .../Sources/Antlr4/atn/AtomTransition.swift | 2 +- .../Antlr4/atn/ParserATNSimulator.swift | 47 ++++++++--------- .../Antlr4/atn/ProfilingATNSimulator.swift | 8 ++- .../Sources/Antlr4/atn/RangeTransition.swift | 2 +- .../Sources/Antlr4/atn/SetTransition.swift | 2 +- .../v4/tool/templates/codegen/Swift/Swift.stg | 2 +- 12 files changed, 111 insertions(+), 115 deletions(-) diff --git a/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift b/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift index 162085acf2..7f939dca84 100644 --- a/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift +++ b/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift @@ -372,7 +372,7 @@ public class BufferedTokenStream: TokenStream { /// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or /// EOF. If channel is -1, find any non default channel token. /// - public func getHiddenTokensToRight(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token]? { + public func getHiddenTokensToRight(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token] { try lazyInit() guard tokens.indices.contains(tokenIndex) else { throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0 ..< \(tokens.count)") @@ -397,7 +397,7 @@ public class BufferedTokenStream: TokenStream { /// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL. /// If channel is -1, find any non default channel token. /// - public func getHiddenTokensToLeft(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token]? { + public func getHiddenTokensToLeft(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token] { try lazyInit() guard tokens.indices.contains(tokenIndex) else { throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0 ..< \(tokens.count)") @@ -405,12 +405,12 @@ public class BufferedTokenStream: TokenStream { if tokenIndex == 0 { // obviously no tokens can appear before the first token - return nil + return [] } let prevOnChannel = try previousTokenOnChannel(tokenIndex - 1, Lexer.DEFAULT_TOKEN_CHANNEL) if prevOnChannel == tokenIndex - 1 { - return nil + return [] } // if none onchannel to left, prevOnChannel=-1 then from=0 let from = prevOnChannel + 1 @@ -418,7 +418,7 @@ public class BufferedTokenStream: TokenStream { return filterForChannel(from, to, channel) } - internal func filterForChannel(_ from: Int, _ to: Int, _ channel: Int) -> [Token]? { + internal func filterForChannel(_ from: Int, _ to: Int, _ channel: Int) -> [Token] { var hidden = [Token]() for t in tokens[from...to] { if channel == -1 { @@ -431,9 +431,6 @@ public class BufferedTokenStream: TokenStream { } } } - if hidden.isEmpty { - return nil - } return hidden } @@ -472,12 +469,8 @@ public class BufferedTokenStream: TokenStream { } - public func getText(_ start: Token?, _ stop: Token?) throws -> String { - if let start = start, let stop = stop { - return try getText(Interval.of(start.getTokenIndex(), stop.getTokenIndex())) - } - - return "" + public func getText(_ start: Token, _ stop: Token) throws -> String { + return try getText(Interval.of(start.getTokenIndex(), stop.getTokenIndex())) } /// diff --git a/runtime/Swift/Sources/Antlr4/Parser.swift b/runtime/Swift/Sources/Antlr4/Parser.swift index 74fd32e83e..962fe0778d 100644 --- a/runtime/Swift/Sources/Antlr4/Parser.swift +++ b/runtime/Swift/Sources/Antlr4/Parser.swift @@ -126,7 +126,7 @@ open class Parser: Recognizer { /// /// - SeeAlso: #addParseListener /// - public var _parseListeners: Array? + public var _parseListeners: Array = [] /// /// The number of syntax errors reported during parsing. This value is @@ -285,7 +285,7 @@ open class Parser: Recognizer { } public func getParseListeners() -> [ParseTreeListener] { - return _parseListeners ?? [ParseTreeListener]() + return _parseListeners } /// @@ -314,11 +314,7 @@ open class Parser: Recognizer { /// - Parameter listener: the listener to add /// public func addParseListener(_ listener: ParseTreeListener) { - if _parseListeners == nil { - _parseListeners = [ParseTreeListener]() - } - - _parseListeners!.append(listener) + _parseListeners.append(listener) } /// @@ -333,16 +329,7 @@ open class Parser: Recognizer { /// public func removeParseListener(_ listener: ParseTreeListener?) { - if _parseListeners != nil { - if !_parseListeners!.filter({ $0 === listener }).isEmpty { - _parseListeners = _parseListeners!.filter({ - $0 !== listener - }) - if _parseListeners!.isEmpty { - _parseListeners = nil - } - } - } + _parseListeners.removeAll(where: { $0 === listener }) } /// @@ -351,7 +338,7 @@ open class Parser: Recognizer { /// - SeeAlso: #addParseListener /// public func removeParseListeners() { - _parseListeners = nil + _parseListeners = [] } /// @@ -360,7 +347,7 @@ open class Parser: Recognizer { /// - SeeAlso: #addParseListener /// public func triggerEnterRuleEvent() throws { - if let _parseListeners = _parseListeners, let _ctx = _ctx { + if let _ctx = _ctx { for listener: ParseTreeListener in _parseListeners { try listener.enterEveryRule(_ctx) _ctx.enterRule(listener) @@ -375,7 +362,7 @@ open class Parser: Recognizer { /// public func triggerExitRuleEvent() throws { // reverse order walk of listeners - if let _parseListeners = _parseListeners, let _ctx = _ctx { + if let _ctx = _ctx { for listener in _parseListeners.reversed() { _ctx.exitRule(listener) try listener.exitEveryRule(_ctx) @@ -542,24 +529,20 @@ open class Parser: Recognizer { guard let _ctx = _ctx else { return o } - let hasListener = _parseListeners != nil && !_parseListeners!.isEmpty + let hasListener = !_parseListeners.isEmpty if _buildParseTrees || hasListener { if _errHandler.inErrorRecoveryMode(self) { let node = createErrorNode(parent: _ctx, t: o) _ctx.addErrorNode(node) - if let _parseListeners = _parseListeners { - for listener in _parseListeners { - listener.visitErrorNode(node) - } + for listener in _parseListeners { + listener.visitErrorNode(node) } } else { let node = createTerminalNode(parent: _ctx, t: o) _ctx.addChild(node) - if let _parseListeners = _parseListeners { - for listener in _parseListeners { - listener.visitTerminal(node) - } + for listener in _parseListeners { + listener.visitTerminal(node) } } } @@ -611,7 +594,7 @@ open class Parser: Recognizer { } ctx.stop = try _input.LT(-1) // trigger event on _ctx, before it reverts to parent - if _parseListeners != nil { + if !_parseListeners.isEmpty { try triggerExitRuleEvent() } setState(ctx.invokingState) @@ -629,7 +612,7 @@ open class Parser: Recognizer { } } _ctx = localctx - if _parseListeners != nil { + if !_parseListeners.isEmpty { try triggerEnterRuleEvent() } } @@ -664,7 +647,7 @@ open class Parser: Recognizer { _precedenceStack.push(precedence) _ctx = localctx _ctx!.start = try _input.LT(1) - if _parseListeners != nil { + if !_parseListeners.isEmpty { try triggerEnterRuleEvent() // simulates rule entry for left-recursive rules } } @@ -684,7 +667,7 @@ open class Parser: Recognizer { _ctx!.addChild(previous) } - if _parseListeners != nil { + if !_parseListeners.isEmpty { try triggerEnterRuleEvent() // simulates rule entry for left-recursive rules } } @@ -695,7 +678,7 @@ open class Parser: Recognizer { let retctx = _ctx! // save current ctx (return value) // unroll so _ctx is as it was before call to recursive method - if _parseListeners != nil { + if !_parseListeners.isEmpty { while let ctxWrap = _ctx, ctxWrap !== _parentctx { try triggerExitRuleEvent() _ctx = ctxWrap.parent as? ParserRuleContext diff --git a/runtime/Swift/Sources/Antlr4/ParserRuleContext.swift b/runtime/Swift/Sources/Antlr4/ParserRuleContext.swift index 060317920f..ad2d0779ae 100644 --- a/runtime/Swift/Sources/Antlr4/ParserRuleContext.swift +++ b/runtime/Swift/Sources/Antlr4/ParserRuleContext.swift @@ -35,7 +35,7 @@ open class ParserRuleContext: RuleContext { /// operation because we don't the need to track the details about /// how we parse this rule. /// - public var children: [ParseTree]? + public var children: [ParseTree] = [] /// For debugging/tracing purposes, we want to track all of the nodes in /// the ATN traversed by the parser for a particular rule. @@ -89,13 +89,12 @@ open class ParserRuleContext: RuleContext { self.stop = ctx.stop // copy any error nodes to alt label node - if let ctxChildren = ctx.children { - self.children = [ParseTree]() - // reset parent pointer for any error nodes - for child in ctxChildren { - if let errNode = child as? ErrorNode { - addChild(errNode) - } + let ctxChildren = ctx.children + self.children = [ParseTree]() + // reset parent pointer for any error nodes + for child in ctxChildren { + if let errNode = child as? ErrorNode { + addChild(errNode) } } } @@ -120,10 +119,7 @@ open class ParserRuleContext: RuleContext { /// - Since: 4.7 /// open func addAnyChild(_ t: ParseTree) { - if children == nil { - children = [ParseTree]() - } - children!.append(t) + children.append(t) } open func addChild(_ ruleInvocation: RuleContext) { @@ -148,20 +144,22 @@ open class ParserRuleContext: RuleContext { /// generic ruleContext object. /// open func removeLastChild() { - children?.removeLast() + // removeLast asserts if called when empty, popLast does not, + // this preserves edge case behavior, perhaps unnecessarily. + _ = children.popLast() } override open func getChild(_ i: Int) -> Tree? { - guard let children = children, i >= 0 && i < children.count else { + guard i >= 0 && i < children.count else { return nil } return children[i] } open func getChild(_ ctxType: T.Type, i: Int) -> T? { - guard let children = children, i >= 0 && i < children.count else { + guard i >= 0 && i < children.count else { return nil } var j = -1 // what element have we found with ctxType? @@ -178,7 +176,7 @@ open class ParserRuleContext: RuleContext { } open func getToken(_ ttype: Int, _ i: Int) -> TerminalNode? { - guard let children = children, i >= 0 && i < children.count else { + guard i >= 0 && i < children.count else { return nil } var j = -1 // what token with ttype have we found? @@ -198,10 +196,6 @@ open class ParserRuleContext: RuleContext { } open func getTokens(_ ttype: Int) -> [TerminalNode] { - guard let children = children else { - return [TerminalNode]() - } - return children.compactMap { if let tnode = $0 as? TerminalNode, let symbol = tnode.getSymbol(), symbol.getType() == ttype { return tnode @@ -217,20 +211,17 @@ open class ParserRuleContext: RuleContext { } open func getRuleContexts(_ ctxType: T.Type) -> [T] { - guard let children = children else { - return [T]() - } return children.compactMap { $0 as? T } } override open func getChildCount() -> Int { - return children?.count ?? 0 + return children.count } override open subscript(index: Int) -> ParseTree { - return children![index] + return children[index] } override diff --git a/runtime/Swift/Sources/Antlr4/TokenStream.swift b/runtime/Swift/Sources/Antlr4/TokenStream.swift index 536f33b90f..5966aee369 100644 --- a/runtime/Swift/Sources/Antlr4/TokenStream.swift +++ b/runtime/Swift/Sources/Antlr4/TokenStream.swift @@ -133,5 +133,41 @@ public protocol TokenStream: IntStream { /// and `stop` tokens. /// /// - func getText(_ start: Token?, _ stop: Token?) throws -> String + func getText(_ start: Token, _ stop: Token) throws -> String +} + +extension TokenStream { + /// + /// Return the text of all tokens in this stream between `start` and + /// `stop` (inclusive). + /// + /// If the specified `start` or `stop` token was not provided by + /// this stream, or if the `stop` occurred before the `start` + /// token, the behavior is unspecified. + /// + /// For streams which ensure that the _org.antlr.v4.runtime.Token#getTokenIndex_ method is + /// accurate for all of its provided tokens, this method behaves like the + /// following code. Other streams may implement this method in other ways + /// provided the behavior is consistent with this at a high level. + /// + /// + /// TokenStream stream = ...; + /// String text = ""; + /// for (int i = start.getTokenIndex(); i <= stop.getTokenIndex(); i++) { + /// text += stream.get(i).getText(); + /// } + /// + /// + /// - Parameter start: The first token in the interval to get text for. + /// - Parameter stop: The last token in the interval to get text for (inclusive). + /// - Throws: ANTLRError.unsupportedOperation if this stream does not support + /// this method for the specified tokens + /// - Returns: The text of all tokens lying between the specified `start` + /// and `stop` tokens. + /// + /// + func getText(_ start: Token?, _ stop: Token?) throws -> String { + guard let start = start, let stop = stop else { return "" } + return try getText(start, stop) + } } diff --git a/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift b/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift index 3f3dcc0cbf..dd9ec7bd6f 100644 --- a/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift +++ b/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift @@ -116,8 +116,8 @@ public class UnbufferedTokenStream: TokenStream { } - public func getText(_ start: Token?, _ stop: Token?) throws -> String { - return try getText(Interval.of(start!.getTokenIndex(), stop!.getTokenIndex())) + public func getText(_ start: Token, _ stop: Token) throws -> String { + return try getText(Interval.of(start.getTokenIndex(), stop.getTokenIndex())) } diff --git a/runtime/Swift/Sources/Antlr4/atn/ATN.swift b/runtime/Swift/Sources/Antlr4/atn/ATN.swift index 2ed963677c..101b55dd14 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ATN.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ATN.swift @@ -20,12 +20,12 @@ public class ATN { /// /// Maps from rule index to starting state number. /// - public internal(set) final var ruleToStartState: [RuleStartState]! + public internal(set) final var ruleToStartState: [RuleStartState] = [] /// /// Maps from rule index to stop state number. /// - public internal(set) final var ruleToStopState: [RuleStopState]! + public internal(set) final var ruleToStopState: [RuleStopState] = [] /// /// The type of the ATN. @@ -43,13 +43,13 @@ public class ATN { /// type if the `ATNDeserializationOptions.generateRuleBypassTransitions` /// deserialization option was specified; otherwise, this is `null`. /// - public internal(set) final var ruleToTokenType: [Int]! + public internal(set) final var ruleToTokenType: [Int] = [] /// /// For lexer ATNs, this is an array of _org.antlr.v4.runtime.atn.LexerAction_ objects which may /// be referenced by action transitions in the ATN. /// - public internal(set) final var lexerActions: [LexerAction]! + public internal(set) final var lexerActions: [LexerAction] = [] public internal(set) final var modeToStartState = [TokensStartState]() diff --git a/runtime/Swift/Sources/Antlr4/atn/AtomTransition.swift b/runtime/Swift/Sources/Antlr4/atn/AtomTransition.swift index b51c7147e4..822506d1c4 100644 --- a/runtime/Swift/Sources/Antlr4/atn/AtomTransition.swift +++ b/runtime/Swift/Sources/Antlr4/atn/AtomTransition.swift @@ -27,7 +27,7 @@ public final class AtomTransition: Transition, CustomStringConvertible { } override - public func labelIntervalSet() -> IntervalSet? { + public func labelIntervalSet() -> IntervalSet { return IntervalSet(label) } diff --git a/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift b/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift index d3cffff196..dbe77f3a1a 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift @@ -571,7 +571,8 @@ open class ParserATNSimulator: ATNSimulator { /// func computeTargetState(_ dfa: DFA, _ previousD: DFAState, _ t: Int) throws -> DFAState { - guard let reach = try computeReachSet(previousD.configs, t, false) else { + let reach = try computeReachSet(previousD.configs, t, false) + guard !reach.isEmpty() else { addDFAEdge(dfa, previousD, t, ATNSimulator.ERROR) return ATNSimulator.ERROR } @@ -649,7 +650,8 @@ open class ParserATNSimulator: ATNSimulator { var predictedAlt = ATN.INVALID_ALT_NUMBER while true { // while more work - if let computeReach = try computeReachSet(previous, t, fullCtx) { + let computeReach = try computeReachSet(previous, t, fullCtx) + if !computeReach.isEmpty() { reach = computeReach } else { // if any configs in previous dipped into outer context, that @@ -752,7 +754,7 @@ open class ParserATNSimulator: ATNSimulator { } func computeReachSet(_ closureConfigSet: ATNConfigSet, _ t: Int, - _ fullCtx: Bool) throws -> ATNConfigSet? { + _ fullCtx: Bool) throws -> ATNConfigSet { if debug { print("in computeReachSet, starting closure: \(closureConfigSet)") @@ -775,7 +777,7 @@ open class ParserATNSimulator: ATNSimulator { /// ensure that the alternative matching the longest overall sequence is /// chosen when multiple such configurations can match the input. /// - var skippedStopStates: [ATNConfig]? = nil + var skippedStopStates: [ATNConfig] = [] // First figure out where we can reach on input t let configs = closureConfigSet.configs @@ -787,10 +789,7 @@ open class ParserATNSimulator: ATNSimulator { if config.state is RuleStopState { assert(config.context!.isEmpty(), "Expected: c.context.isEmpty()") if fullCtx || t == BufferedTokenStream.EOF { - if skippedStopStates == nil { - skippedStopStates = [ATNConfig]() - } - skippedStopStates!.append(config) + skippedStopStates.append(config) } continue @@ -808,7 +807,7 @@ open class ParserATNSimulator: ATNSimulator { // Now figure out where the reach operation can take us... - var reach: ATNConfigSet? = nil + var prepReach: ATNConfigSet? = nil /// /// This block optimizes the reach operation for intermediate sets which @@ -820,18 +819,18 @@ open class ParserATNSimulator: ATNSimulator { /// condition is not true when one or more configurations have been /// withheld in skippedStopStates, or when the current symbol is EOF. /// - if skippedStopStates == nil && t != CommonToken.EOF { + if skippedStopStates.isEmpty && t != CommonToken.EOF { if intermediate.size() == 1 { // Don't pursue the closure if there is just one state. // It can only have one alternative; just add to result // Also don't pursue the closure if there is unique alternative // among the configurations. - reach = intermediate + prepReach = intermediate } else { if ParserATNSimulator.getUniqueAlt(intermediate) != ATN.INVALID_ALT_NUMBER { // Also don't pursue the closure if there is unique alternative // among the configurations. - reach = intermediate + prepReach = intermediate } } } @@ -840,12 +839,15 @@ open class ParserATNSimulator: ATNSimulator { /// If the reach set could not be trivially determined, perform a closure /// operation on the intermediate set to compute its initial value. /// - if reach == nil { + var reach: ATNConfigSet + if let r = prepReach { + reach = r + } else { reach = ATNConfigSet(fullCtx) var closureBusy = Set() let treatEofAsEpsilon = (t == CommonToken.EOF) for config in intermediate.configs { - try closure(config, reach!, &closureBusy, false, fullCtx, treatEofAsEpsilon) + try closure(config, reach, &closureBusy, false, fullCtx, treatEofAsEpsilon) } } @@ -868,11 +870,11 @@ open class ParserATNSimulator: ATNSimulator { /// already guaranteed to meet this condition whether or not it's /// required. /// - reach = removeAllConfigsNotInRuleStopState(reach!, reach! === intermediate) + reach = removeAllConfigsNotInRuleStopState(reach, reach === intermediate) } /// - /// If skippedStopStates is not null, then it contains at least one + /// If skippedStopStates is not empty, then it contains at least one /// configuration. For full-context reach operations, these /// configurations reached the end of the start rule, in which case we /// only add them back to reach if no configuration during the current @@ -880,16 +882,9 @@ open class ParserATNSimulator: ATNSimulator { /// chooses an alternative matching the longest overall sequence when /// multiple alternatives are viable. /// - if let reach = reach { - if let skippedStopStates = skippedStopStates, (!fullCtx || !PredictionMode.hasConfigInRuleStopState(reach)) { - assert(!skippedStopStates.isEmpty, "Expected: !skippedStopStates.isEmpty()") - for c in skippedStopStates { - try! reach.add(c, &mergeCache) - } - } - - if reach.isEmpty() { - return nil + if !skippedStopStates.isEmpty, (!fullCtx || !PredictionMode.hasConfigInRuleStopState(reach)) { + for c in skippedStopStates { + try! reach.add(c, &mergeCache) } } return reach diff --git a/runtime/Swift/Sources/Antlr4/atn/ProfilingATNSimulator.swift b/runtime/Swift/Sources/Antlr4/atn/ProfilingATNSimulator.swift index 12f673f57c..cf067191c4 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ProfilingATNSimulator.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ProfilingATNSimulator.swift @@ -119,7 +119,7 @@ public class ProfilingATNSimulator: ParserATNSimulator { } override - internal func computeReachSet(_ closure: ATNConfigSet, _ t: Int, _ fullCtx: Bool) throws -> ATNConfigSet? { + internal func computeReachSet(_ closure: ATNConfigSet, _ t: Int, _ fullCtx: Bool) throws -> ATNConfigSet { if fullCtx { // this method is called after each time the input position advances // during full context prediction @@ -129,8 +129,7 @@ public class ProfilingATNSimulator: ParserATNSimulator { let reachConfigs = try super.computeReachSet(closure, t, fullCtx) if fullCtx { decisions[currentDecision].LL_ATNTransitions += 1 // count computation even if error - if reachConfigs != nil { - } else { + if reachConfigs.isEmpty() { // no reach on current lookahead symbol. ERROR. // TODO: does not handle delayed errors per getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule() decisions[currentDecision].errors.append( @@ -139,8 +138,7 @@ public class ProfilingATNSimulator: ParserATNSimulator { } } else { decisions[currentDecision].SLL_ATNTransitions += 1 - if reachConfigs != nil { - } else { + if reachConfigs.isEmpty() { // no reach on current lookahead symbol. ERROR. decisions[currentDecision].errors.append( ErrorInfo(currentDecision, closure, _input, _startIndex, _sllStopIndex, false) diff --git a/runtime/Swift/Sources/Antlr4/atn/RangeTransition.swift b/runtime/Swift/Sources/Antlr4/atn/RangeTransition.swift index 69dd39d82e..8c7f282731 100644 --- a/runtime/Swift/Sources/Antlr4/atn/RangeTransition.swift +++ b/runtime/Swift/Sources/Antlr4/atn/RangeTransition.swift @@ -22,7 +22,7 @@ public final class RangeTransition: Transition, CustomStringConvertible { } override - public func labelIntervalSet() -> IntervalSet? { + public func labelIntervalSet() -> IntervalSet { return IntervalSet.of(from, to) } diff --git a/runtime/Swift/Sources/Antlr4/atn/SetTransition.swift b/runtime/Swift/Sources/Antlr4/atn/SetTransition.swift index 54bdb4ed2b..78b8526fe5 100644 --- a/runtime/Swift/Sources/Antlr4/atn/SetTransition.swift +++ b/runtime/Swift/Sources/Antlr4/atn/SetTransition.swift @@ -26,7 +26,7 @@ public class SetTransition: Transition, CustomStringConvertible { } override - public func labelIntervalSet() -> IntervalSet? { + public func labelIntervalSet() -> IntervalSet { return set } diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Swift/Swift.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Swift/Swift.stg index 861348a330..677292979e 100755 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Swift/Swift.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Swift/Swift.stg @@ -945,7 +945,7 @@ _prevctx = _localctx >> recRuleSetPrevCtx() ::= << -if _parseListeners != nil { +if !_parseListeners.isEmpty { try triggerExitRuleEvent() } _prevctx = _localctx