Add more swift 5.x support (#unavalaible mainly)

This commit is contained in:
kenji
2023-02-07 20:50:08 +01:00
parent c3b1317a77
commit a10662731b
8 changed files with 879 additions and 2 deletions

View File

@@ -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'
;

View File

@@ -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");

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

View 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

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

View File

File diff suppressed because it is too large Load Diff

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

View 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