Skip to content

Commit ce2b68e

Browse files
DougGregoreeckstein
authored andcommitted
Make diagnostics for NSCoding classes with unstable names more discouraging.
The diagnostic regarding NSCoding classes with unstable names can be suppressed by adding @objc (the preferred solution for new code) or @NSKeyedArchiveLegacy (for existing archives). Provide those as Fix-Its, in that order. (Thanks, Jordan!)
1 parent 32bcf19 commit ce2b68e

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,11 +1220,14 @@ WARNING(nscoding_unstable_mangled_name_warn,none,
12201220
"%select{private|fileprivate|nested|local|generic}0 class %1 has an "
12211221
"unstable name when archiving via 'NSCoding'",
12221222
(unsigned, Type))
1223-
NOTE(add_nskeyedarchivelegacy_attr,none,
1224-
"add the '@NSKeyedArchiveLegacy' attribute to specify the class name "
1225-
"used for archiving", ())
1223+
NOTE(unstable_mangled_name_add_objc,none,
1224+
"for new classes, add '@objc' to specify a unique, prefixed Objective-C "
1225+
"runtime name", ())
1226+
NOTE(unstable_mangled_name_add_nskeyedarchivelegacy,none,
1227+
"for compatibility with existing archives, use '@NSKeyedArchiveLegacy' "
1228+
"to record the Swift 3 mangled name", ())
12261229
ERROR(attr_nskeyedarchivelegacy_generic,none,
1227-
"@NSKeyedArchiveLegacy attribute cannot be applied to generic class %0",
1230+
"'@NSKeyedArchiveLegacy' cannot be applied to generic class %0",
12281231
(Type))
12291232

12301233
// Generic types

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5944,10 +5944,15 @@ void TypeChecker::checkConformancesInContext(DeclContext *dc,
59445944
: diag::nscoding_unstable_mangled_name,
59455945
*kind, classDecl->TypeDecl::getDeclaredInterfaceType());
59465946
if (isFixable) {
5947-
diagnose(classDecl, diag::add_nskeyedarchivelegacy_attr)
5948-
.fixItInsert(
5949-
classDecl->getAttributeInsertionLoc(/*forModifier=*/false),
5950-
"@NSKeyedArchiveLegacy(\"<#class archival name#>\")");
5947+
auto insertionLoc =
5948+
classDecl->getAttributeInsertionLoc(/*forModifier=*/false);
5949+
diagnose(classDecl, diag::unstable_mangled_name_add_objc)
5950+
.fixItInsert(insertionLoc,
5951+
"@objc(<#Objective-C class name#>)");
5952+
diagnose(classDecl,
5953+
diag::unstable_mangled_name_add_nskeyedarchivelegacy)
5954+
.fixItInsert(insertionLoc,
5955+
"@NSKeyedArchiveLegacy(\"<#class archival name#>\")");
59515956
}
59525957
}
59535958

test/decl/protocol/conforms/nscoding.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ class CodingA : NSObject, NSCoding {
1717
// Nested classes
1818
extension CodingA {
1919
class NestedA : NSObject, NSCoding { // expected-error{{nested class 'CodingA.NestedA' has an unstable name when archiving via 'NSCoding'}}
20-
// expected-note@-1{{add the '@NSKeyedArchiveLegacy' attribute to specify the class name used for archiving}}{{3-3=@NSKeyedArchiveLegacy("<#class archival name#>")}}
20+
// expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#Objective-C class name#>)}}
21+
// expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiveLegacy' to record the Swift 3 mangled name}}{{3-3=@NSKeyedArchiveLegacy("<#class archival name#>")}}
2122
required init(coder: NSCoder) { }
2223
func encode(coder: NSCoder) { }
2324
}
2425

2526
class NestedB : NSObject {
26-
// expected-note@-1{{add the '@NSKeyedArchiveLegacy' attribute to specify the class name used for archiving}}{{3-3=@NSKeyedArchiveLegacy("<#class archival name#>")}}
27+
// expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#Objective-C class name#>)}}
28+
// expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiveLegacy' to record the Swift 3 mangled name}}{{3-3=@NSKeyedArchiveLegacy("<#class archival name#>")}}
2729
required init(coder: NSCoder) { }
2830
func encode(coder: NSCoder) { }
2931
}
@@ -62,22 +64,25 @@ extension CodingB {
6264

6365
// Fileprivate classes.
6466
fileprivate class CodingC : NSObject, NSCoding { // expected-error{{fileprivate class 'CodingC' has an unstable name when archiving via 'NSCoding'}}
65-
// expected-note@-1{{add the '@NSKeyedArchiveLegacy' attribute to specify the class name used for archiving}}{{1-1=@NSKeyedArchiveLegacy("<#class archival name#>")}}
67+
// expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#Objective-C class name#>)}}
68+
// expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiveLegacy' to record the Swift 3 mangled name}}{{1-1=@NSKeyedArchiveLegacy("<#class archival name#>")}}
6669
required init(coder: NSCoder) { }
6770
func encode(coder: NSCoder) { }
6871
}
6972

7073
// Private classes
7174
private class CodingD : NSObject, NSCoding { // expected-error{{private class 'CodingD' has an unstable name when archiving via 'NSCoding'}}
72-
// expected-note@-1{{add the '@NSKeyedArchiveLegacy' attribute to specify the class name used for archiving}}{{1-1=@NSKeyedArchiveLegacy("<#class archival name#>")}}
75+
// expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#Objective-C class name#>)}}
76+
// expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiveLegacy' to record the Swift 3 mangled name}}{{1-1=@NSKeyedArchiveLegacy("<#class archival name#>")}}
7377
required init(coder: NSCoder) { }
7478
func encode(coder: NSCoder) { }
7579
}
7680

7781
// Local classes.
7882
func someFunction() {
7983
class LocalCoding : NSObject, NSCoding { // expected-error{{local class 'LocalCoding' has an unstable name when archiving via 'NSCoding'}}
80-
// expected-note@-1{{add the '@NSKeyedArchiveLegacy' attribute to specify the class name used for archiving}}{{3-3=@NSKeyedArchiveLegacy("<#class archival name#>")}}
84+
// expected-note@-1{{for new classes, add '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#Objective-C class name#>)}}
85+
// expected-note@-2{{for compatibility with existing archives, use '@NSKeyedArchiveLegacy' to record the Swift 3 mangled name}}{{3-3=@NSKeyedArchiveLegacy("<#class archival name#>")}}
8186
required init(coder: NSCoder) { }
8287
func encode(coder: NSCoder) { }
8388
}
@@ -114,11 +119,11 @@ private class CodingG : NSObject, NSCoding {
114119
@NSKeyedArchiveLegacy("TheCodingG") // expected-error{{@NSKeyedArchiveLegacy may only be used on 'class' declarations}}
115120
struct Foo { }
116121

117-
@NSKeyedArchiveLegacy("TheCodingG") // expected-error{{@NSKeyedArchiveLegacy attribute cannot be applied to generic class 'Bar<T>'}}
122+
@NSKeyedArchiveLegacy("TheCodingG") // expected-error{{'@NSKeyedArchiveLegacy' cannot be applied to generic class 'Bar<T>'}}
118123
class Bar<T> : NSObject { }
119124

120125
extension CodingB {
121-
@NSKeyedArchiveLegacy("GenericViaParent") // expected-error{{@NSKeyedArchiveLegacy attribute cannot be applied to generic class 'CodingB<T>.GenericViaParent'}}
126+
@NSKeyedArchiveLegacy("GenericViaParent") // expected-error{{'@NSKeyedArchiveLegacy' cannot be applied to generic class 'CodingB<T>.GenericViaParent'}}
122127
class GenericViaParent : NSObject { }
123128
}
124129

0 commit comments

Comments
 (0)