Add more swift 5.x support (#unavalaible mainly)
This commit is contained in:
@@ -156,7 +156,7 @@ whereExpression: expression ;
|
||||
|
||||
// GRAMMAR OF AN AVAILABILITY CONDITION
|
||||
|
||||
availabilityCondition: '#available' '(' availabilityArguments ')' ;
|
||||
availabilityCondition: '#available' | '#unavailable' '(' availabilityArguments ')' ;
|
||||
availabilityArguments: availabilityArgument (',' availabilityArguments)* ;
|
||||
availabilityArgument: platformName platformVersion | '*' ;
|
||||
platformName: 'iOS' | 'iOSApplicationExtension' | 'OSX' | 'OSXApplicationExtension' | 'watchOS'
|
||||
@@ -934,7 +934,7 @@ keyword :
|
||||
// Keywords used in patterns
|
||||
| '_'
|
||||
// Keywords that begin with a number sign (#)
|
||||
| '#available' | '#colorLiteral' | '#column' | '#else' | '#elseif' | '#endif' | '#file' | 'fileLiteral' | '#function'
|
||||
| '#available' | '#unavailable' | '#colorLiteral' | '#column' | '#else' | '#elseif' | '#endif' | '#file' | 'fileLiteral' | '#function'
|
||||
| '#if' | 'imageLiteral' | '#line' | '#selector'
|
||||
;
|
||||
|
||||
|
@@ -47,6 +47,21 @@ public class SwiftTokenizerTest extends CpdTextComparisonTest {
|
||||
doTest("Swift5.2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwift53() {
|
||||
doTest("Swift5.3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwift55() {
|
||||
doTest("Swift5.5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwift56() {
|
||||
doTest("Swift5.6");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackoverflowOnLongLiteral() {
|
||||
doTest("Issue628");
|
||||
|
13
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.3.swift
vendored
Normal file
13
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.3.swift
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// file for supporting swift 5.2 changes : https://github.com/apple/swift/blob/master/CHANGELOG.md#swift-53
|
||||
|
||||
// https://github.com/apple/swift/issues/54108
|
||||
struct Container {
|
||||
static let defaultKey = 0
|
||||
|
||||
var dictionary = [defaultKey:0]
|
||||
|
||||
mutating func incrementValue(at key: Int) {
|
||||
let defaultValue = dictionary[Container.defaultKey]!
|
||||
dictionary[key, default: defaultValue] += 1
|
||||
}
|
||||
}
|
59
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.3.txt
vendored
Normal file
59
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.3.txt
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
[Image] or [Truncated image[ Bcol Ecol
|
||||
L4
|
||||
[struct] 1 6
|
||||
[Container] 8 16
|
||||
[{] 18 18
|
||||
L5
|
||||
[static] 3 8
|
||||
[let] 10 12
|
||||
[defaultKey] 14 23
|
||||
[=] 25 25
|
||||
[0] 27 27
|
||||
L7
|
||||
[var] 3 5
|
||||
[dictionary] 7 16
|
||||
[=] 18 18
|
||||
[\[] 20 20
|
||||
[defaultKey] 21 30
|
||||
[:] 31 31
|
||||
[0] 32 32
|
||||
[\]] 33 33
|
||||
L9
|
||||
[mutating] 3 10
|
||||
[func] 12 15
|
||||
[incrementValue] 17 30
|
||||
[(] 31 31
|
||||
[at] 32 33
|
||||
[key] 35 37
|
||||
[:] 38 38
|
||||
[Int] 40 42
|
||||
[)] 43 43
|
||||
[{] 45 45
|
||||
L10
|
||||
[let] 5 7
|
||||
[defaultValue] 9 20
|
||||
[=] 22 22
|
||||
[dictionary] 24 33
|
||||
[\[] 34 34
|
||||
[Container] 35 43
|
||||
[.] 44 44
|
||||
[defaultKey] 45 54
|
||||
[\]] 55 55
|
||||
[!] 56 56
|
||||
L11
|
||||
[dictionary] 5 14
|
||||
[\[] 15 15
|
||||
[key] 16 18
|
||||
[,] 19 19
|
||||
[default] 21 27
|
||||
[:] 28 28
|
||||
[defaultValue] 30 41
|
||||
[\]] 42 42
|
||||
[+] 44 44
|
||||
[=] 45 45
|
||||
[1] 47 47
|
||||
L12
|
||||
[}] 3 3
|
||||
L13
|
||||
[}] 1 1
|
||||
EOF
|
142
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.5.swift
vendored
Normal file
142
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.5.swift
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
// file for supporting swift 5.2 changes : https://github.com/apple/swift/blob/master/CHANGELOG.md#swift-55
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0313-actor-isolation-control.md
|
||||
actor MyActor {
|
||||
func f() { }
|
||||
}
|
||||
|
||||
func g(actor: isolated MyActor) {
|
||||
actor.f() // okay, this code is always executing on "actor"
|
||||
}
|
||||
|
||||
func h(actor: MyActor) async {
|
||||
g(actor: actor) // error, call must be asynchronous
|
||||
await g(actor: actor) // okay, hops to "actor" before calling g
|
||||
}
|
||||
|
||||
// https://github.com/apple/swift/issues/57081
|
||||
struct Box<T> {
|
||||
// previously interpreted as a return type of Box<T>, ignoring the <Int> part;
|
||||
// now we diagnose an error with a fix-it suggesting replacing `Self` with `Box`
|
||||
static func makeBox() -> Self<Int> {...}
|
||||
}
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0311-task-locals.md
|
||||
struct TraceID {
|
||||
@TaskLocal
|
||||
static var current: TraceID?
|
||||
}
|
||||
|
||||
func printTraceID() {
|
||||
if let traceID = TraceID.current {
|
||||
print("\(traceID)")
|
||||
} else {
|
||||
print("nil")
|
||||
}
|
||||
}
|
||||
|
||||
func run() async {
|
||||
printTraceID() // prints: nil
|
||||
TraceID.$current.withValue("1234-5678") {
|
||||
printTraceID() // prints: 1234-5678
|
||||
inner() // prints: 1234-5678
|
||||
}
|
||||
printTraceID() // prints: nil
|
||||
}
|
||||
|
||||
func inner() {
|
||||
// if called from a context in which the task-local value
|
||||
// was bound, it will print it (or 'nil' otherwise)
|
||||
printTraceID()
|
||||
}
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0316-global-actors.md
|
||||
|
||||
@globalActor
|
||||
struct DatabaseActor {
|
||||
actor ActorType { }
|
||||
|
||||
static let shared: ActorType = ActorType()
|
||||
}
|
||||
|
||||
@DatabaseActor func queryDB(query: Query) throws -> QueryResult
|
||||
|
||||
func runQuery(queryString: String) async throws -> QueryResult {
|
||||
let query = try Query(parsing: queryString)
|
||||
return try await queryDB(query: query) // 'await' because this implicitly hops to DatabaseActor.shared
|
||||
}
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0313-actor-isolation-control.md
|
||||
actor Account: Hashable {
|
||||
let idNumber: Int
|
||||
var balance: Double
|
||||
|
||||
nonisolated func hash(into hasher: inout Hasher) { // okay, non-isolated satisfies synchronous requirement
|
||||
hasher.combine(idNumber) // okay, can reference idNumber from outside the let
|
||||
hasher.combine(balance) // error: cannot synchronously access actor-isolated property
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0300-continuation.md
|
||||
struct MyValue {
|
||||
}
|
||||
|
||||
struct MyStruct {
|
||||
subscript(a: MyValue.Type) -> Int { get { ... } }
|
||||
}
|
||||
|
||||
func test(obj: MyStruct) {
|
||||
let _ = obj[MyValue]
|
||||
}
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md
|
||||
class BankAccount: FinancialAccount {
|
||||
var manager: AccountManager?
|
||||
|
||||
var lastTransaction: Transaction {
|
||||
get async throws {
|
||||
guard manager != nil else { throw BankError.notInYourFavor }
|
||||
return await manager!.getLastTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
subscript(_ day: Date) -> [Transaction] {
|
||||
get async {
|
||||
return await manager?.getTransactions(onDay: day) ?? []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol FinancialAccount {
|
||||
associatedtype T
|
||||
var lastTransaction: T { get async throws }
|
||||
subscript(_ day: Date) -> [T] { get async }
|
||||
}
|
||||
|
||||
extension BankAccount {
|
||||
func meetsTransactionLimit(_ limit: Amount) async -> Bool {
|
||||
return try! await self.lastTransaction.amount < limit
|
||||
// ^~~~~~~~~~~~~~~~ this access is async & throws
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func hadWithdrawalOn(_ day: Date, from acct: BankAccount) async -> Bool {
|
||||
return await !acct[day].allSatisfy { $0.amount >= Amount.zero }
|
||||
// ^~~~~~~~~ this access is async
|
||||
}
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0306-actors.md
|
||||
|
||||
actor Counter {
|
||||
var value = 0
|
||||
|
||||
func increment() {
|
||||
value = value + 1
|
||||
}
|
||||
}
|
||||
|
||||
func useCounter(counter: Counter) async {
|
||||
print(await counter.value) // interaction must be async
|
||||
await counter.increment() // interaction must be async
|
||||
}
|
596
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.5.txt
vendored
Normal file
596
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.5.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
13
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.6.swift
vendored
Normal file
13
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.6.swift
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// file for supporting swift 5.6 changes : https://github.com/apple/swift/blob/master/CHANGELOG.md#swift-56
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0315-placeholder-types.md
|
||||
let dict: [_: String] = [0: "zero", 1: "one", 2: "two"]
|
||||
|
||||
// https://github.com/apple/swift-evolution/blob/main/proposals/0290-negative-availability.md
|
||||
if #unavailable(iOS 15.0) {
|
||||
// Old functionality
|
||||
} else {
|
||||
// iOS 15 functionality
|
||||
}
|
||||
|
||||
|
39
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.6.txt
vendored
Normal file
39
pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.6.txt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
[Image] or [Truncated image[ Bcol Ecol
|
||||
L4
|
||||
[let] 1 3
|
||||
[dict] 5 8
|
||||
[:] 9 9
|
||||
[\[] 11 11
|
||||
[_] 12 12
|
||||
[:] 13 13
|
||||
[String] 15 20
|
||||
[\]] 21 21
|
||||
[=] 23 23
|
||||
[\[] 25 25
|
||||
[0] 26 26
|
||||
[:] 27 27
|
||||
["zero"] 29 34
|
||||
[,] 35 35
|
||||
[1] 37 37
|
||||
[:] 38 38
|
||||
["one"] 40 44
|
||||
[,] 45 45
|
||||
[2] 47 47
|
||||
[:] 48 48
|
||||
["two"] 50 54
|
||||
[\]] 55 55
|
||||
L7
|
||||
[if] 1 2
|
||||
[#unavailable] 4 15
|
||||
[(] 16 16
|
||||
[iOS] 17 19
|
||||
[15.0] 21 24
|
||||
[)] 25 25
|
||||
[{] 27 27
|
||||
L9
|
||||
[}] 1 1
|
||||
[else] 3 6
|
||||
[{] 8 8
|
||||
L11
|
||||
[}] 1 1
|
||||
EOF
|
Reference in New Issue
Block a user