File: nscoding.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (162 lines) | stat: -rw-r--r-- 7,707 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// RUN: %empty-directory(%t)

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -verify
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -disable-nskeyedarchiver-diagnostics 2>&1 | %FileCheck -check-prefix CHECK-NO-DIAGS %s
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -dump-ast -target %target-pre-stable-abi-triple > %t/old.ast

// RUN: %FileCheck --check-prefix=CHECK-OLD %s < %t/old.ast
// RUN: %FileCheck --check-prefix=NEGATIVE %s < %t/old.ast

// REQUIRES: objc_interop
// UNSUPPORTED: swift_only_stable_abi

// See also nscoding_stable_abi.swift, for the stable ABI deployment
// target test.

// CHECK-NO-DIAGS-NOT: NSCoding
// CHECK-NO-DIAGS-NOT: unstable

import Foundation

// Top-level classes
// NEGATIVE-NOT: class_decl{{.*}}"CodingA"{{.*}}@_staticInitializeObjCMetadata
class CodingA : NSObject, NSCoding {
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
  
}   // okay

// Nested classes
extension CodingA {
  // NEGATIVE-NOT: class_decl{{.*}}"NestedA"{{.*}}@_staticInitializeObjCMetadata
  class NestedA : NSObject, NSCoding { // expected-error{{nested class 'CodingA.NestedA' has an unstable name when archiving via 'NSCoding'}}
    // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCC8nscoding7CodingA7NestedA)}}
    // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
    required init(coder: NSCoder) { }
    func encode(coder: NSCoder) { }
  }

  class NestedB : NSObject {
    // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCC8nscoding7CodingA7NestedB)}}
    // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
    required init(coder: NSCoder) { }
    func encode(coder: NSCoder) { }
  }

  // NEGATIVE-NOT: class_decl{{.*}}"NestedC"{{.*}}@_staticInitializeObjCMetadata
  @objc(CodingA_NestedC)
  class NestedC : NSObject, NSCoding {
    required init(coder: NSCoder) { }
    func encode(coder: NSCoder) { }
  }

  // NEGATIVE-NOT: class_decl{{.*}}"NestedD"{{.*}}@_staticInitializeObjCMetadata
  @objc(CodingA_NestedD)
  class NestedD : NSObject {
    required init(coder: NSCoder) { }
    func encode(coder: NSCoder) { }
  }
}

extension CodingA.NestedB: NSCoding { // expected-error{{nested class 'CodingA.NestedB' has an unstable name when archiving via 'NSCoding'}}
}

extension CodingA.NestedD: NSCoding { // okay
}

// Generic classes
// NEGATIVE-NOT: class_decl{{.*}}"CodingB"{{.*}}@_staticInitializeObjCMetadata
class CodingB<T> : NSObject, NSCoding {
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
}

extension CodingB {
  class NestedA : NSObject, NSCoding {
    required init(coder: NSCoder) { }
    func encode(coder: NSCoder) { }
  }
}

// Fileprivate classes.
// NEGATIVE-NOT: class_decl{{.*}}"CodingC"{{.*}}@_staticInitializeObjCMetadata
fileprivate class CodingC : NSObject, NSCoding { // expected-error{{fileprivate class 'CodingC' has an unstable name when archiving via 'NSCoding'}}
  // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingC)}}
  // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
}

// Private classes
private class CodingD : NSObject, NSCoding { // expected-error{{private class 'CodingD' has an unstable name when archiving via 'NSCoding'}}
  // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingD)}}
  // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
}

// Local classes.
func someFunction() {
  class LocalCoding : NSObject, NSCoding { // expected-error{{local class 'LocalCoding' has an unstable name when archiving via 'NSCoding'}}
  // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCF8nscoding12someFunctionFT_T_L_11LocalCoding)}}
  // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
}
}

// Inherited conformances.
// NEGATIVE-NOT: class_decl{{.*}}"CodingE"{{.*}}@_staticInitializeObjCMetadata
class CodingE<T> : CodingB<T> {
  required init(coder: NSCoder) { super.init(coder: coder) }
  override func encode(coder: NSCoder) { }
}

// @objc suppressions
@objc(TheCodingF)
fileprivate class CodingF : NSObject, NSCoding {
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
}

@objc(TheCodingG)
private class CodingG : NSObject, NSCoding {
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
}

extension CodingB {
  // NEGATIVE-NOT: class_decl{{.*}}"GenericViaScope"{{.*}}@_staticInitializeObjCMetadata
  @objc(GenericViaScope) // expected-error {{generic subclasses of '@objc' classes cannot have an explicit '@objc' because they are not directly visible from Objective-C}}
  class GenericViaScope : NSObject { }
}

// Inference of @_staticInitializeObjCMetadata.
// NEGATIVE-NOT: class_decl{{.*}}"SubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
class SubclassOfCodingA : CodingA { }

// CHECK-OLD: class_decl{{.*}}"SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
// NEGATIVE-NEW-NOT: class_decl{{.*}}"SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
class SubclassOfCodingE : CodingE<Int> { }

// Do not warn when simply inheriting from classes that conform to NSCoding.
// The subclass may never be serialized. But do still infer static
// initialization, just in case.
// NEGATIVE-NOT: class_decl{{.*}}"PrivateSubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
private class PrivateSubclassOfCodingA : CodingA { }
// CHECK-OLD: class_decl{{.*}}"PrivateSubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
// NEGATIVE-NEW-NOT: class_decl{{.*}}"PrivateSubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
private class PrivateSubclassOfCodingE : CodingE<Int> { }

// But do warn when inherited through a protocol.
protocol AlsoNSCoding : NSCoding {}
private class CodingH : NSObject, AlsoNSCoding { // expected-error{{private class 'CodingH' has an unstable name when archiving via 'NSCoding'}}
  // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingH)}}
  // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
  required init(coder: NSCoder) { }
  func encode(coder: NSCoder) { }
}

// Don't allow one to write @_staticInitializeObjCMetadata!
@_staticInitializeObjCMetadata // expected-error{{unknown attribute '_staticInitializeObjCMetadata'}}
class DontAllowStaticInits { }