Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Swift] reduce Optionals in APIs #3621

Merged
merged 9 commits into from
Apr 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)")
Expand All @@ -397,28 +397,28 @@ 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)")
}

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
let to = tokenIndex - 1
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 {
Expand All @@ -431,9 +431,6 @@ public class BufferedTokenStream: TokenStream {
}
}
}
if hidden.isEmpty {
return nil
}
return hidden
}

Expand Down Expand Up @@ -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()))
}

///
Expand Down
51 changes: 17 additions & 34 deletions runtime/Swift/Sources/Antlr4/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
///
/// - SeeAlso: #addParseListener
///
public var _parseListeners: Array<ParseTreeListener>?
public var _parseListeners: Array<ParseTreeListener> = []

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

public func getParseListeners() -> [ParseTreeListener] {
return _parseListeners ?? [ParseTreeListener]()
return _parseListeners
}

///
Expand Down Expand Up @@ -314,11 +314,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
/// - Parameter listener: the listener to add
///
public func addParseListener(_ listener: ParseTreeListener) {
if _parseListeners == nil {
_parseListeners = [ParseTreeListener]()
}

_parseListeners!.append(listener)
_parseListeners.append(listener)
}

///
Expand All @@ -333,16 +329,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
///

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 })
}

///
Expand All @@ -351,7 +338,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
/// - SeeAlso: #addParseListener
///
public func removeParseListeners() {
_parseListeners = nil
_parseListeners = []
}

///
Expand All @@ -360,7 +347,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
/// - 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)
Expand All @@ -375,7 +362,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
///
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)
Expand Down Expand Up @@ -542,24 +529,20 @@ open class Parser: Recognizer<ParserATNSimulator> {
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)
}
}
}
Expand Down Expand Up @@ -611,7 +594,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
}
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)
Expand All @@ -629,7 +612,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
}
}
_ctx = localctx
if _parseListeners != nil {
if !_parseListeners.isEmpty {
try triggerEnterRuleEvent()
}
}
Expand Down Expand Up @@ -664,7 +647,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
_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
}
}
Expand All @@ -684,7 +667,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
_ctx!.addChild(previous)
}

if _parseListeners != nil {
if !_parseListeners.isEmpty {
try triggerEnterRuleEvent() // simulates rule entry for left-recursive rules
}
}
Expand All @@ -695,7 +678,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
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
Expand Down
41 changes: 16 additions & 25 deletions runtime/Swift/Sources/Antlr4/ParserRuleContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
}
}
}
Expand All @@ -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) {
Expand All @@ -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<T: ParseTree>(_ 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?
Expand All @@ -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?
Expand All @@ -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
Expand All @@ -217,20 +211,17 @@ open class ParserRuleContext: RuleContext {
}

open func getRuleContexts<T: ParserRuleContext>(_ 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
Expand Down
38 changes: 37 additions & 1 deletion runtime/Swift/Sources/Antlr4/TokenStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 &lt;= 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)
}
}
4 changes: 2 additions & 2 deletions runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
}


Expand Down
Loading