From 167a3b8808c9fb6c1bad4e47016b517105ab0b54 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 10 Nov 2017 15:15:47 -0800 Subject: [PATCH] [Swift] Remove Recognizer.tokenTypeMapCache and .ruleIndexMapCache. Remove Recognizer.tokenTypeMapCache and .ruleIndexMapCache. These were easily replaced in Swift with lazy vars. The input to these two caches are fixed fields on the Recognizer (the Vocabulary and rule names respectively) so a lazy var suffices. Note that these differed compared with the Java runtime -- they are declared as static in Java and therefore the caches are shared across all recognizer instances, but the Swift runtime had them as Recognizer instance variables, which meant that at most we had a cache with one entry which got destroyed along with the parser. Regardless, using lazy vars is still simpler. This removes the only usage of ArrayWrapper in the Swift runtime, so delete that too. --- runtime/Swift/Sources/Antlr4/Recognizer.swift | 69 ++++++-------- .../Sources/Antlr4/misc/ArrayWrapper.swift | 91 ------------------- 2 files changed, 26 insertions(+), 134 deletions(-) delete mode 100644 runtime/Swift/Sources/Antlr4/misc/ArrayWrapper.swift diff --git a/runtime/Swift/Sources/Antlr4/Recognizer.swift b/runtime/Swift/Sources/Antlr4/Recognizer.swift index 6b3c60088..7604c5882 100644 --- a/runtime/Swift/Sources/Antlr4/Recognizer.swift +++ b/runtime/Swift/Sources/Antlr4/Recognizer.swift @@ -19,26 +19,11 @@ public protocol RecognizerProtocol { open class Recognizer: RecognizerProtocol { - //TODO: WeakKeyDictionary NSMapTable Dictionary MapTable> - private let tokenTypeMapCache = HashMap() - - private let ruleIndexMapCache = HashMap, [String : Int]>() - private var _listeners: [ANTLRErrorListener] = [ConsoleErrorListener.INSTANCE] public var _interp: ATNInterpreter! private var _stateNumber = -1 - - /// - /// mutex for tokenTypeMapCache updates - /// - private let tokenTypeMapCacheMutex = Mutex() - - /// - /// mutex for ruleIndexMapCacheMutex updates - /// - private let ruleIndexMapCacheMutex = Mutex() open func getRuleNames() -> [String] { fatalError(#function + " must be overridden") @@ -59,30 +44,30 @@ open class Recognizer: RecognizerProtocol { /// /// Used for XPath and tree pattern compilation. /// - public func getTokenTypeMap() -> [String : Int] { + public func getTokenTypeMap() -> [String: Int] { + return tokenTypeMap + } + + public lazy var tokenTypeMap: [String: Int] = { let vocabulary = getVocabulary() - var result = tokenTypeMapCache[vocabulary] - tokenTypeMapCacheMutex.synchronized { [unowned self] in - if result == nil { - result = [String : Int]() - let length = self.getATN().maxTokenType - for i in 0...length { - if let literalName = vocabulary.getLiteralName(i) { - result![literalName] = i - } - if let symbolicName = vocabulary.getSymbolicName(i) { - result![symbolicName] = i - } - } + var result = [String: Int]() + let length = getATN().maxTokenType + for i in 0...length { + if let literalName = vocabulary.getLiteralName(i) { + result[literalName] = i + } - result!["EOF"] = CommonToken.EOF - - self.tokenTypeMapCache[vocabulary] = result! + if let symbolicName = vocabulary.getSymbolicName(i) { + result[symbolicName] = i } } - return result! - } + + result["EOF"] = CommonToken.EOF + + return result + }() + /// /// Get a map from rule names to rule indexes. @@ -90,17 +75,15 @@ open class Recognizer: RecognizerProtocol { /// Used for XPath and tree pattern compilation. /// public func getRuleIndexMap() -> [String : Int] { - let ruleNames = getRuleNames() - - let result = ruleIndexMapCache[ArrayWrapper(ruleNames)] - ruleIndexMapCacheMutex.synchronized { [unowned self] in - if result == nil { - self.ruleIndexMapCache[ArrayWrapper(ruleNames)] = Utils.toMap(ruleNames) - } - } - return result! + return ruleIndexMap } + public lazy var ruleIndexMap: [String: Int] = { + let ruleNames = getRuleNames() + return Utils.toMap(ruleNames) + }() + + public func getTokenType(_ tokenName: String) -> Int { return getTokenTypeMap()[tokenName] ?? CommonToken.INVALID_TYPE } diff --git a/runtime/Swift/Sources/Antlr4/misc/ArrayWrapper.swift b/runtime/Swift/Sources/Antlr4/misc/ArrayWrapper.swift deleted file mode 100644 index 5d5a68b88..000000000 --- a/runtime/Swift/Sources/Antlr4/misc/ArrayWrapper.swift +++ /dev/null @@ -1,91 +0,0 @@ -/// -/// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. -/// Use of this file is governed by the BSD 3-clause license that -/// can be found in the LICENSE.txt file in the project root. -/// - -// -// ArrayWrapper.swift -// Antlr4 -// -// Created by janyou on 16/6/21. -// - -import Foundation - -public final class ArrayWrapper: ExpressibleByArrayLiteral, Hashable { - public var array: Array - public init(slice: ArraySlice) { - array = Array() - for element in slice { - array.append(element) - } - } - public init(_ elements: T...) { - array = Array() - for element in elements { - array.append(element) - } - - } - public init(_ elements: [T]) { - array = elements - } - public init(count: Int, repeatedValue: T) { - array = Array(repeating: repeatedValue, count: count) - } - - public init(arrayLiteral elements: T...) { - array = Array() - for element in elements { - array.append(element) - } - } - public subscript(index: Int) -> T { - get { - return array[index] - } - set { - array[index] = newValue - } - } - public subscript(subRange: Range) -> ArrayWrapper { - return ArrayWrapper(slice: array[subRange]) - } - public var count: Int { return array.count } - - public var hashValue: Int { - if count == 0 { - return 0 - } - - var result = 1 - - for element in array { - result = 31 &* result &+ element.hashValue - } - return result - } - -} - -public func == (lhs: ArrayWrapper, rhs: ArrayWrapper) -> Bool { - if lhs === rhs { - return true - } - - if lhs.count != rhs.count { - return false - } - - let length = lhs.count - for i in 0..