Remove use of deprecated String functions in StringExtension.

Remove some functions that are no longer used, and update the
rest to Swift 4's String API.  lastIndexOf changes to lastIndex(of: ),
matching the standard library naming conventions, and returns a
String.Index? instead of an Int.

Add an implementation of Substring.hasPrefix for Linux; this
is in the Apple standard library but not the Linux one.
https://bugs.swift.org/browse/SR-5627

Add unit tests for StringExtension.

Bump the Swift download for the Travis Linux tests from 4.0
to 4.0.2.  There is a bug in Substring.range(of:) in 4.0.0
(https://bugs.swift.org/browse/SR-5663) that we need to avoid.
This commit is contained in:
Ewan Mellor 2017-11-01 23:55:56 -07:00
parent 15a7b3be24
commit ba392be1af
No known key found for this signature in database
GPG Key ID: 7CE1C6BC9EC8645D
4 changed files with 57 additions and 51 deletions

View File

@ -6,7 +6,7 @@ set -euo pipefail
# here since environment variables doesn't pass
# across scripts
if [ $TRAVIS_OS_NAME == "linux" ]; then
export SWIFT_VERSION=swift-4.0
export SWIFT_VERSION=swift-4.0.2
export SWIFT_HOME=$(pwd)/swift/$SWIFT_VERSION-RELEASE-ubuntu14.04/usr/bin/
export PATH=$SWIFT_HOME:$PATH

View File

@ -85,9 +85,8 @@ public class ListTokenSource: TokenSource {
let lastToken = tokens[tokens.count - 1]
if let tokenText = lastToken.getText() {
let lastNewLine = tokenText.lastIndexOf("\n")
if lastNewLine >= 0 {
return tokenText.length - lastNewLine - 1
if let lastNewLine = tokenText.lastIndex(of: "\n") {
return tokenText.distance(from: lastNewLine, to: tokenText.endIndex) - 1
}
}
return (lastToken.getCharPositionInLine() +

View File

@ -6,62 +6,38 @@
import Foundation
//http://stackoverflow.com/questions/28182441/swift-how-to-get-substring-from-start-to-last-index-of-character
//https://github.com/williamFalcon/Bolt_Swift/blob/master/Bolt/BoltLibrary/String/String.swift
extension String {
var length: Int {
return self.characters.count
}
func indexOf(_ target: String) -> Int {
let range = self.range(of: target)
if let range = range {
return self.characters.distance(from: self.startIndex, to: range.lowerBound)
} else {
return -1
func lastIndex(of target: String) -> String.Index? {
if target.isEmpty {
return nil
}
}
func indexOf(_ target: String, startIndex: Int) -> Int {
let startRange = self.characters.index(self.startIndex, offsetBy: startIndex)
let range = self.range(of: target, options: .literal, range: startRange..<self.endIndex)
if let range = range {
return self.characters.distance(from: self.startIndex, to: range.lowerBound)
} else {
return -1
}
}
func lastIndexOf(_ target: String) -> Int {
var index = -1
var stepIndex = self.indexOf(target)
while stepIndex > -1 {
index = stepIndex
if stepIndex + target.length < self.length {
stepIndex = indexOf(target, startIndex: stepIndex + target.length)
} else {
stepIndex = -1
var result: String.Index? = nil
var substring = self[...]
while true {
guard let targetRange = substring.range(of: target) else {
return result
}
result = targetRange.lowerBound
let nextChar = substring.index(after: targetRange.lowerBound)
substring = self[nextChar...]
}
return index
}
subscript(integerIndex: Int) -> Character {
let index = characters.index(startIndex, offsetBy: integerIndex)
return self[index]
}
subscript(integerRange: Range<Int>) -> String {
let start = characters.index(startIndex, offsetBy: integerRange.lowerBound)
let end = characters.index(startIndex, offsetBy: integerRange.upperBound)
let start = index(startIndex, offsetBy: integerRange.lowerBound)
let end = index(startIndex, offsetBy: integerRange.upperBound)
let range = start ..< end
return String(self[range])
}
}
// Implement Substring.hasPrefix, which is not currently in the Linux stdlib.
// https://bugs.swift.org/browse/SR-5627
#if os(Linux)
extension Substring {
func hasPrefix(_ prefix: String) -> Bool {
return String(self).hasPrefix(prefix)
}
}
#endif

View File

@ -0,0 +1,31 @@
/// 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.
import Foundation
import XCTest
@testable import Antlr4
class StringExtensionTests: XCTestCase {
func testLastIndex() {
doLastIndexTest("", "", nil)
doLastIndexTest("a", "", nil)
doLastIndexTest("a", "a", 0)
doLastIndexTest("aba", "a", 2)
doLastIndexTest("aba", "b", 1)
doLastIndexTest("abc", "d", nil)
}
}
private func doLastIndexTest(_ str: String, _ target: String, _ expectedOffset: Int?) {
let expectedIdx: String.Index?
if let expectedOffset = expectedOffset {
expectedIdx = str.index(str.startIndex, offsetBy: expectedOffset)
}
else {
expectedIdx = nil
}
XCTAssertEqual(str.lastIndex(of: target), expectedIdx)
}