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

Fix retain cycles in the Swift runtime #2076

Merged
merged 12 commits into from
Oct 27, 2017
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
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ TokenStartColumnEquals(i) ::= <%self._tokenStartCharPositionInLine == <i>%>

ImportListener(X) ::= ""

GetExpectedTokenNames() ::= "try self.getExpectedTokens().toString(self.tokenNames)"
GetExpectedTokenNames() ::= "try self.getExpectedTokens().toString(self.getVocabulary())"

RuleInvocationStack() ::= "getRuleInvocationStack().description.replacingOccurrences(of: \"\\\"\", with: \"\")"

Expand Down
13 changes: 6 additions & 7 deletions runtime/Swift/Sources/Antlr4/BailErrorStrategy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ public class BailErrorStrategy: DefaultErrorStrategy {
/// original _org.antlr.v4.runtime.RecognitionException_.
///
override public func recover(_ recognizer: Parser, _ e: AnyObject) throws {
var context: ParserRuleContext? = recognizer.getContext()
while let contextWrap = context{
var context = recognizer.getContext()
while let contextWrap = context {
contextWrap.exception = e
context = (contextWrap.getParent() as? ParserRuleContext)
}

throw ANTLRException.recognition(e: e)
throw ANTLRException.recognition(e: e)
}

///
Expand All @@ -56,15 +56,14 @@ public class BailErrorStrategy: DefaultErrorStrategy {
///
override
public func recoverInline(_ recognizer: Parser) throws -> Token {
let e: InputMismatchException = try InputMismatchException(recognizer)
var context: ParserRuleContext? = recognizer.getContext()
let e = try InputMismatchException(recognizer)
var context = recognizer.getContext()
while let contextWrap = context {
contextWrap.exception = e
context = (contextWrap.getParent() as? ParserRuleContext)
}

throw ANTLRException.recognition(e: e)

throw ANTLRException.recognition(e: e)
}

///
Expand Down
37 changes: 16 additions & 21 deletions runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public class BufferedTokenStream: TokenStream {
let index = tokens.count - 1
throw ANTLRError.indexOutOfBounds(msg: "token index \(i) out of range 0..\(index)")
}
return tokens[i] //tokens[i]
return tokens[i]
}

///
Expand All @@ -202,7 +202,6 @@ public class BufferedTokenStream: TokenStream {
return subset
}

//TODO: LT(i)!.getType();
public func LA(_ i: Int) throws -> Int {
return try LT(i)!.getType()
}
Expand Down Expand Up @@ -273,11 +272,11 @@ public class BufferedTokenStream: TokenStream {
fetchedEOF = false
}

public func getTokens() -> Array<Token> {
public func getTokens() -> [Token] {
return tokens
}

public func getTokens(_ start: Int, _ stop: Int) throws -> Array<Token>? {
public func getTokens(_ start: Int, _ stop: Int) throws -> [Token]? {
return try getTokens(start, stop, nil)
}

Expand All @@ -286,40 +285,36 @@ public class BufferedTokenStream: TokenStream {
/// the token type BitSet. Return null if no tokens were found. This
/// method looks at both on and off channel tokens.
///
public func getTokens(_ start: Int, _ stop: Int, _ types: Set<Int>?) throws -> Array<Token>? {
public func getTokens(_ start: Int, _ stop: Int, _ types: Set<Int>?) throws -> [Token]? {
try lazyInit()
if start < 0 || stop >= tokens.count ||
stop < 0 || start >= tokens.count {
throw ANTLRError.indexOutOfBounds(msg: "start \(start) or stop \(stop) not in 0..\(tokens.count - 1)")
if start < 0 || start >= tokens.count ||
stop < 0 || stop >= tokens.count {
throw ANTLRError.indexOutOfBounds(msg: "start \(start) or stop \(stop) not in 0...\(tokens.count - 1)")

}
if start > stop {
return nil
}


var filteredTokens: Array<Token> = Array<Token>()
var filteredTokens = [Token]()
for i in start...stop {
let t: Token = tokens[i]
if let types = types , !types.contains(t.getType()) {
}else {
let t = tokens[i]
if let types = types, !types.contains(t.getType()) {
}
else {
filteredTokens.append(t)
}

}
if filteredTokens.isEmpty {
return nil
//filteredTokens = nil;
}
return filteredTokens
}

public func getTokens(_ start: Int, _ stop: Int, _ ttype: Int) throws -> Array<Token>? {
//TODO Set<Int> initialCapacity
var s: Set<Int> = Set<Int>()
public func getTokens(_ start: Int, _ stop: Int, _ ttype: Int) throws -> [Token]? {
var s = Set<Int>()
s.insert(ttype)
//s.append(ttype);
return try getTokens(start, stop, s)
return try getTokens(start, stop, s)
}

///
Expand Down Expand Up @@ -464,7 +459,7 @@ public class BufferedTokenStream: TokenStream {
}
}
}
if hidden.count == 0 {
if hidden.isEmpty {
return nil
}
return hidden
Expand Down
2 changes: 1 addition & 1 deletion runtime/Swift/Sources/Antlr4/CharStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ public protocol CharStream: IntStream {
/// - throws: _ANTLRError.unsupportedOperation_ if the stream does not support
/// getting the text of the specified interval
///
func getText(_ interval: Interval) -> String
func getText(_ interval: Interval) throws -> String
}
83 changes: 37 additions & 46 deletions runtime/Swift/Sources/Antlr4/CommonToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@


public class CommonToken: WritableToken {
///
/// An empty _org.antlr.v4.runtime.misc.Pair_ which is used as the default value of
/// _#source_ for tokens that do not have a source.
///
internal static let EMPTY_SOURCE: (TokenSource?, CharStream?) = (nil, nil)

///
/// This is the backing field for _#getType_ and _#setType_.
///
Expand All @@ -21,20 +15,20 @@ public class CommonToken: WritableToken {
///
/// This is the backing field for _#getLine_ and _#setLine_.
///
internal var line: Int = 0
internal var line = 0

///
/// This is the backing field for _#getCharPositionInLine_ and
/// _#setCharPositionInLine_.
///
internal var charPositionInLine: Int = -1
internal var charPositionInLine = -1
// set to invalid position

///
/// This is the backing field for _#getChannel_ and
/// _#setChannel_.
///
internal var channel: Int = DEFAULT_CHANNEL
internal var channel = DEFAULT_CHANNEL

///
/// This is the backing field for _#getTokenSource_ and
Expand All @@ -47,7 +41,7 @@ public class CommonToken: WritableToken {
/// _org.antlr.v4.runtime.misc.Pair_ containing these values.
///

internal var source: (TokenSource?, CharStream?)
internal let source: TokenSourceAndStream

///
/// This is the backing field for _#getText_ when the token text is
Expand All @@ -61,19 +55,19 @@ public class CommonToken: WritableToken {
/// This is the backing field for _#getTokenIndex_ and
/// _#setTokenIndex_.
///
internal var index: Int = -1
internal var index = -1

///
/// This is the backing field for _#getStartIndex_ and
/// _#setStartIndex_.
///
internal var start: Int = 0
internal var start = 0

///
/// This is the backing field for _#getStopIndex_ and
/// _#setStopIndex_.
///
internal var stop: Int = 0
internal var stop = 0

///
/// Constructs a new _org.antlr.v4.runtime.CommonToken_ with the specified token type.
Expand All @@ -85,16 +79,16 @@ public class CommonToken: WritableToken {

public init(_ type: Int) {
self.type = type
self.source = CommonToken.EMPTY_SOURCE
self.source = TokenSourceAndStream.EMPTY
}

public init(_ source: (TokenSource?, CharStream?), _ type: Int, _ channel: Int, _ start: Int, _ stop: Int) {
public init(_ source: TokenSourceAndStream, _ type: Int, _ channel: Int, _ start: Int, _ stop: Int) {
self.source = source
self.type = type
self.channel = channel
self.start = start
self.stop = stop
if let tsource = source.0 {
if let tsource = source.tokenSource {
self.line = tsource.getLine()
self.charPositionInLine = tsource.getCharPositionInLine()
}
Expand All @@ -111,20 +105,12 @@ public class CommonToken: WritableToken {
self.type = type
self.channel = CommonToken.DEFAULT_CHANNEL
self.text = text
self.source = CommonToken.EMPTY_SOURCE
self.source = TokenSourceAndStream.EMPTY
}

///
/// Constructs a new _org.antlr.v4.runtime.CommonToken_ as a copy of another _org.antlr.v4.runtime.Token_.
///
///
/// If `oldToken` is also a _org.antlr.v4.runtime.CommonToken_ instance, the newly
/// constructed token will share a reference to the _#text_ field and
/// the _org.antlr.v4.runtime.misc.Pair_ stored in _#source_. Otherwise, _#text_ will
/// be assigned the result of calling _#getText_, and _#source_
/// will be constructed from the result of _org.antlr.v4.runtime.Token#getTokenSource_ and
/// _org.antlr.v4.runtime.Token#getInputStream_.
///
///
/// - parameter oldToken: The token to copy.
///
public init(_ oldToken: Token) {
Expand All @@ -135,14 +121,8 @@ public class CommonToken: WritableToken {
channel = oldToken.getChannel()
start = oldToken.getStartIndex()
stop = oldToken.getStopIndex()

if oldToken is CommonToken {
text = (oldToken as! CommonToken).text
source = (oldToken as! CommonToken).source
} else {
text = oldToken.getText()
source = (oldToken.getTokenSource(), oldToken.getInputStream())
}
text = oldToken.getText()
source = oldToken.getTokenSourceAndStream()
}


Expand All @@ -157,14 +137,19 @@ public class CommonToken: WritableToken {


public func getText() -> String? {
if text != nil {
return text!
if let text = text {
return text
}

if let input = getInputStream() {
let n: Int = input.size()
let n = input.size()
if start < n && stop < n {
return input.getText(Interval.of(start, stop))
do {
return try input.getText(Interval.of(start, stop))
}
catch {
return nil
}
} else {
return "<EOF>"
}
Expand Down Expand Up @@ -247,23 +232,25 @@ public class CommonToken: WritableToken {


public func getTokenSource() -> TokenSource? {
return source.0
return source.tokenSource
}


public func getInputStream() -> CharStream? {
return source.1
return source.stream
}

public func getTokenSourceAndStream() -> TokenSourceAndStream {
return source
}

public var description: String {
return toString(nil)
}

public func toString(_ r: Recognizer<ATNSimulator>?) -> String {
var channelStr: String = ""
if channel > 0 {
channelStr = ",channel=\(channel)"
}
let channelStr = (channel > 0 ? ",channel=\(channel)" : "")

var txt: String
if let tokenText = getText() {
txt = tokenText.replacingOccurrences(of: "\n", with: "\\n")
Expand All @@ -272,12 +259,16 @@ public class CommonToken: WritableToken {
} else {
txt = "<no text>"
}
var typeString = "\(type)"
let typeString: String
if let r = r {
typeString = r.getVocabulary().getDisplayName(type);
typeString = r.getVocabulary().getDisplayName(type)
}
else {
typeString = "\(type)"
}
return "[@\(getTokenIndex()),\(start):\(stop)='\(txt)',<\(typeString)>\(channelStr),\(line):\(getCharPositionInLine())]"
}

public var visited: Bool {
get {
return _visited
Expand Down
15 changes: 7 additions & 8 deletions runtime/Swift/Sources/Antlr4/CommonTokenFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,17 @@ public class CommonTokenFactory: TokenFactory {
}


public func create(_ source: (TokenSource?, CharStream?), _ type: Int, _ text: String?,
public func create(_ source: TokenSourceAndStream, _ type: Int, _ text: String?,
_ channel: Int, _ start: Int, _ stop: Int,
_ line: Int, _ charPositionInLine: Int) -> Token {
let t: CommonToken = CommonToken(source, type, channel, start, stop)
let t = CommonToken(source, type, channel, start, stop)
t.setLine(line)
t.setCharPositionInLine(charPositionInLine)
if text != nil {
t.setText(text!)
} else {
if let cStream = source.1 , copyText {
t.setText(cStream.getText(Interval.of(start, stop)))
}
if let text = text {
t.setText(text)
}
else if let cStream = source.stream, copyText {
t.setText(try! cStream.getText(Interval.of(start, stop)))
}

return t
Expand Down
Loading