Skip to content

Commit 5052daa

Browse files
authored
Merge pull request #64446 from apple/es-kw
Allow `package(set)` at the top level decl site
2 parents 2e92542 + 2ca5156 commit 5052daa

File tree

3 files changed

+157
-6
lines changed

3 files changed

+157
-6
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4886,6 +4886,50 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
48864886
if (Tok.isContextualKeyword("macro") && Tok2.is(tok::identifier))
48874887
return true;
48884888

4889+
if (Tok.isContextualKeyword("package")) {
4890+
// If `case` is the next token after `return package` statement,
4891+
// E.g.
4892+
// switch package {
4893+
// case .x: return package
4894+
// case .y: return nil
4895+
// }
4896+
// currently it errors (this is also true for `open`).
4897+
//
4898+
// If a non-contextual keyword was used in the above example, this
4899+
// function hits the line from above:
4900+
// ```
4901+
// if (!Tok.isContextualDeclKeyword())
4902+
// return false;
4903+
// ```
4904+
// thus we return false here as well, i.e. treat it as a non-contextual
4905+
// keyword.
4906+
if (Tok2.getKind() == tok::kw_case)
4907+
return false;
4908+
4909+
// Handle 'package(set)' access modifier
4910+
auto DAK = DeclAttribute::getAttrKindFromString(Tok.getText());
4911+
if (DAK != DAK_Count && DeclAttribute::isDeclModifier(DAK)) {
4912+
BacktrackingScope backtrack(*this);
4913+
// First consume `package`
4914+
consumeToken();
4915+
// Eat paren after modifier name; e.g. `package(set)`, similar to
4916+
// `private(set)` described above in the `if (Tok.isKeyword())` block
4917+
if (consumeIf(tok::l_paren)) {
4918+
while (Tok.isNot(tok::r_brace, tok::eof, tok::pound_endif)) {
4919+
if (consumeIf(tok::r_paren))
4920+
break;
4921+
// If we found the start of a decl while trying to skip over the
4922+
// paren, then we have something incomplete like 'package('. Return
4923+
// true for better recovery.
4924+
if (isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false))
4925+
return true;
4926+
skipSingle();
4927+
}
4928+
}
4929+
return isStartOfSwiftDecl(/*allowPoundIfAttributes=*/false);
4930+
}
4931+
}
4932+
48894933
// If the next token is obviously not the start of a decl, bail early.
48904934
if (!isKeywordPossibleDeclStart(Context.LangOpts, Tok2))
48914935
return false;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %t/main.swift -package-name myPkg
5+
// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %t/A.swift -package-name myPkg
6+
// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %t/B.swift -package-name myPkg
7+
// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %t/D.swift -package-name myPkg
8+
// RUN: not %target-swift-frontend-typecheck -verify -disable-availability-checking %t/C.swift -package-name myPkg 2>&1 | %FileCheck %s
9+
10+
//--- main.swift
11+
package(set) public var a: String // should pass when `package` modifier is used at top level decls
12+
public package(set) var b: String
13+
package let c: Int
14+
package var d: Int
15+
package func f() {}
16+
package func package() {}
17+
package()
18+
19+
//--- A.swift
20+
package class package { // package can be a type name
21+
package init() {}
22+
package var package: String? // package can be a var name
23+
}
24+
25+
package class pkg {
26+
package init() {}
27+
package func package() {} // package can be a func name
28+
package func package(arg: Int) {}
29+
package func package(_ arg: Double) {}
30+
}
31+
32+
public class MyClass {
33+
var myVar1: package = package()
34+
var myVar2: pkg = pkg()
35+
func myFunc() {
36+
_ = myVar1.package
37+
myVar2.package()
38+
myVar2.package(arg: 1)
39+
myVar2.package(2.0)
40+
}
41+
}
42+
43+
//--- B.swift
44+
public class Foo {
45+
package(set) public var x: String?
46+
public package(set) var y: Int?
47+
}
48+
49+
//--- C.swift
50+
public class Bar {
51+
package package(set) package: String? // CHECK: warning: 'package(set)' modifier is redundant for a package var
52+
package(set) package package: String? // CHECK: warning: 'package(set)' modifier is redundant for a package var
53+
}
54+
55+
//--- D.swift
56+
enum MyColor {
57+
case red, green, blue
58+
}
59+
let packages: [MyColor] = [MyColor.red, MyColor.blue].compactMap { package in
60+
switch package {
61+
case .blue: return package // Should not error when `case` follows the `package` contextual keyword
62+
case .red: return package
63+
default: return nil
64+
}
65+
}
66+

test/attr/accessibility.swift

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,10 @@ fileprivate(set)
3535
public
3636
var customSetter2 = 0
3737

38-
// FIXME: rdar://104931420 folowing should not error
39-
// expected-error @+2{{cannot find 'package' in scope}}{{none}}
40-
// expected-error @+1{{cannot find 'set' in scope; did you mean 'Set'?}}{{9-12=Set}}
4138
package(set)
4239
public
4340
var customSetter3 = 0
4441

45-
// FIXME: rdar://104931420 folowing should not error
46-
// expected-error @+1{{expected expression}}
4742
public
4843
package(set)
4944
var customSetter4 = 0
@@ -66,6 +61,14 @@ public(set) // expected-error {{duplicate modifier}}
6661
private // expected-error {{duplicate modifier}}
6762
var customSetterDuplicateAttrsAllAround = 0
6863

64+
private(set) // expected-note {{modifier already specified here}}
65+
package(set) // expected-error {{duplicate modifier}}
66+
var customSetterDuplicateAttr2 = 0
67+
68+
package(set) // expected-note {{modifier already specified here}}
69+
public(set) // expected-error {{duplicate modifier}}
70+
public var customSetterDuplicateAttr3 = 0
71+
6972
private(get) // expected-error{{expected 'set' as subject of 'private' modifier}}
7073
var invalidSubject = 0
7174

@@ -75,6 +78,13 @@ var invalidSubject2 = 0
7578
private(a bunch of random tokens) // expected-error{{expected 'set' as subject of 'private' modifier}} expected-error{{expected declaration}}
7679
var invalidSubject3 = 0
7780

81+
82+
package(get) // expected-error{{expected 'set' as subject of 'package' modifier}}
83+
var invalidSubject4 = 0
84+
85+
package(42) // expected-error{{expected 'set' as subject of 'package' modifier}}
86+
var invalidSubject5 = 0
87+
7888
private(set // expected-error{{expected ')' in 'private' modifier}}
7989
var unterminatedSubject = 0
8090

@@ -132,7 +142,9 @@ private protocol TestProtocol {
132142
public(set) func publicSetFunc() {} // expected-error {{'public' modifier cannot be applied to this declaration}} {{1-13=}}
133143

134144
public(set) var defaultVis = 0 // expected-error {{internal variable cannot have a public setter}}
135-
145+
package(set) var defaultVisPkg = 0 // expected-error {{internal variable cannot have a package setter}}
146+
package(set) package var defaultVisPkgPkg = 0 // expected-warning {{'package(set)' modifier is redundant for a package var}}
147+
package(set) public var defaultVisPkgOK = 0 // OK
136148
internal(set) private var privateVis = 0 // expected-error {{private variable cannot have an internal setter}}
137149
private(set) var defaultVisOK = 0
138150
private(set) public var publicVis = 0
@@ -144,8 +156,15 @@ private(set) var computedRW: Int {
144156
get { return 42 }
145157
set { }
146158
}
159+
160+
package(set) public var computedPkg: Int { // expected-error {{'package(set)' modifier cannot be applied to read-only variables}} {{1-14=}}
161+
return 42
162+
}
163+
147164
private(set) let constant = 42 // expected-error {{'private(set)' modifier cannot be applied to constants}} {{1-14=}}
148165

166+
package(set) public let constantPkg = 42 // expected-error {{'package(set)' modifier cannot be applied to constants}} {{1-14=}}
167+
149168
public struct Properties {
150169
private(set) var stored = 42
151170
private(set) var computed: Int { // expected-error {{'private(set)' modifier cannot be applied to read-only properties}} {{3-16=}}
@@ -155,14 +174,30 @@ public struct Properties {
155174
get { return 42 }
156175
set { }
157176
}
177+
178+
package(set) public var computedRWPkg: Int {
179+
get { return 42 }
180+
set { }
181+
}
182+
183+
public package(set) var computedR: Int { // expected-error {{'package(set)' modifier cannot be applied to read-only properties}} {{10-23=}}
184+
return 42
185+
}
186+
158187
private(set) let constant = 42 // expected-error {{'private(set)' modifier cannot be applied to read-only properties}} {{3-16=}}
188+
package(set) public let constantPkg = 42 // expected-error {{'package(set)' modifier cannot be applied to read-only properties}} {{3-16=}}
189+
package(set) var defaultVisPkg = 42 // expected-error {{internal property cannot have a package setter}}
159190
public(set) var defaultVis = 0 // expected-error {{internal property cannot have a public setter}}
160191
open(set) var defaultVis2 = 0 // expected-error {{internal property cannot have an open setter}}
161192

162193
public(set) subscript(a a: Int) -> Int { // expected-error {{internal subscript cannot have a public setter}}
163194
get { return 0 }
164195
set {}
165196
}
197+
package(set) subscript(p p: Int) -> Int { // expected-error {{internal subscript cannot have a package setter}}
198+
get { return 0 }
199+
set {}
200+
}
166201
internal(set) private subscript(b b: Int) -> Int { // expected-error {{private subscript cannot have an internal setter}}
167202
get { return 0 }
168203
set {}
@@ -180,6 +215,10 @@ public struct Properties {
180215
}
181216

182217
private extension Properties {
218+
package(set) var extPropPkg: Int { // expected-error {{private property cannot have a package setter}}
219+
get { return 42 }
220+
set { }
221+
}
183222
public(set) var extProp: Int { // expected-error {{private property cannot have a public setter}}
184223
get { return 42 }
185224
set { }
@@ -198,11 +237,13 @@ private(set) extension Properties : EmptyProto2 {} // expected-error {{'private'
198237
package protocol EmptyProto3 {}
199238
package protocol EmptyProto4 {}
200239
public protocol EmptyProto5 {}
240+
public protocol EmptyProto6 {}
201241

202242
private extension Properties : EmptyProto3 {} // expected-error {{'private' modifier cannot be used with extensions that declare protocol conformances}} {{1-9=}}
203243
private(set) extension Properties : EmptyProto4 {} // expected-error {{'private' modifier cannot be applied to this declaration}} {{1-14=}}
204244

205245
package extension Properties : EmptyProto5 {} // expected-error {{'package' modifier cannot be used with extensions that declare protocol conformances}} {{1-9=}}
246+
package(set) extension Properties : EmptyProto6 {} // expected-error {{'package' modifier cannot be applied to this declaration}} {{1-14=}}
206247

207248
public struct PublicStruct {}
208249
package struct PackageStruct {} // expected-note * {{declared here}}

0 commit comments

Comments
 (0)