Skip to content

[Sema] Warn for redundant access-level modifiers on setters or used in an extension. #18623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 6, 2018

Conversation

dingobye
Copy link
Contributor

@dingobye dingobye commented Aug 10, 2018

This patch adds warning for redundant access-level modifiers used in an extension.

This patch adds warnings for redundant access-level modifiers for two aspects: (1) used on members declared in an extension, and (2) used on property setters.

(1) For the following example, it produces a warning - 'public' modifier is redundant for instance method declared in a public extension.

 public extension SomeClass {
     public func foo() {}
+    ^~~~~~~
 }

(2) For instance below, it produces a warning - 'public(set)' modifier is redundant for a public property.

 public SomeClass {
     public public(set) var x: Int = 0
+           ^~~~~~~~~~~~
 }

In addition, it refines the diagnostics of access_control_ext_member_more issues, in case the fixit
could suggest redundant modifiers. Consider the example below, the existing fixit suggests replacing public by internal, which is indeed a redundant modifier. This patch changes the fixit from replacement to removal.

 internal extension SomeClass {
     public func foo() {}
     ^~~~~~
-    internal
 }

Moreover, the corresponding redundancy warnings in the existing code of Swift projects are also fixed. These include:

  • stdlib in the main Swift repo as fixed by this patch
  • swift-corelibs-foundation repo #1663
  • swift-corelibs-libdispatch repo #390
  • swift-corelibs-xctest repo #218
  • swiftpm repo #1746

Resolves SR-8453.

…sion.

This patch adds warning for redundant access-level modifiers
used in an extension. It also refines the diagnostics of
access_control_ext_member_more issues, in case the fixit
could suggest redundant modifiers.

Resolves: SR-8453.
@dingobye
Copy link
Contributor Author

@jrose-apple Hi Jordan, would you help review this, please?

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up, Ding! I have a few comments but the general approach seems reasonable.

public func extMemberPublic() {}
// CHECK-DAG: sil private @$S22accessibility_warnings12PublicStructV07extImplC033_5D2F2E026754A901C0FF90C404896D02LLyyF
private func extImplPublic() {}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't remove this; just add the expected diagnostics. It's still checking the SIL-level linkage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

public func apply<Result>(_ transform: ((Wrapped) -> Result)?) -> Result? {
return self.flatMap { value in
transform.map { $0(value) }
}
}

// expected-warning@+1 {{'public' modifier is redundant for instance method declared in a public extension}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this test isn't really about the access modifiers, it's probably better to just remove the public from the extension (both here and in test/Compatibility).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -1189,7 +1189,12 @@ ERROR(access_control_setter_more,none,
(AccessLevel, unsigned, AccessLevel))
WARNING(access_control_ext_member_more,none,
"declaring %select{%error|a fileprivate|an internal|a public|open}0 %1 in "
"%select{a private|a fileprivate|an internal|public|%error}2 extension",
"%select{a private|a fileprivate|an internal|a public|%error}2 extension",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this. :-)

diag.fixItReplace(attr->getLocation(), fixItString.drop_back());
if (shouldNotReplace) {
// Remove the attribute if replacement is not preferred.
diag.fixItRemove(attr->getRange());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test with public(set)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I extended the solution to also produce warnings for redundant access modifiers on setters.

ValueDecl *VD,
AccessLevel desiredAccess,
bool isForSetter = false,
bool shouldNotReplace = false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: "shouldNotReplace" doesn't tell us what to do instead. Maybe "shouldUseDefaultAccess" or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, shouldUseDefaultAccess sounds better!

@dingobye
Copy link
Contributor Author

dingobye commented Aug 11, 2018

Thank you for your feedback, Jordan! I updated the code as you suggested.

In addition, this update produces a warning for the following case:

'fileprivate' modifier is redundant for instance method declared in a private (equivalent to fileprivate) extension

 private extension SomeClass {
     fileprivate func foo() {}
+    ^~~~~~~~~~~~
 }

My earlier solution didn't report any warning for such cases. I think it more appropriate to warn, since it makes the entire redundancy checking comprehensive and consistent.

@dingobye dingobye changed the title [Sema] Warn when redundant access-level modifier is added in an extension [Sema] Warn for redundant access-level modifiers on setters or used in an extension. Aug 11, 2018
modifier is used in an extension. In addition, add warnings
for access modifier redundancy on property setters; and
address comments from Jordan Rose.
@jrose-apple
Copy link
Contributor

I think that's consistent, yes. We warn if the access is greater and if the access is the same, so it makes sense to also handle "written greater but effectively the same".

@jrose-apple
Copy link
Contributor

@swift-ci Please test

@swift-ci

This comment has been minimized.

@swift-ci

This comment has been minimized.

@dingobye
Copy link
Contributor Author

dingobye commented Aug 14, 2018

Thank you for the reply, Jordan!

I had stdlib compiled with this patch, and got flooded by a number of such warnings for redundant modifiers in extension. Below is the brief statistics, among which 588 are public, 2 are internal, and the rest 2 are fileprivate.

Source Count
public/SDK/AppKit 16
public/SDK/CloudKit 2
public/SDK/CoreGraphics 4
public/SDK/Dispatch 202
public/SDK/Foundation 230
public/SDK/Intents 4
public/SDK/XCTest 4
public/core 130
TOTAL 592

Should all those warnings be fixed before landing this PR?

@jrose-apple
Copy link
Contributor

Ooh, good thing to check. I should have looked at that first. Yes, we should definitely fix all those, but I can see Dispatch, Foundation, and XCTest all having different preferences from the rest (as the three teams who manage corelibs equivalents for their libraries). @mwwa, @phausler / @millenomi, and @briancroom, would you prefer to standardize on

public extension X {
  func foo()
}

or

extension X {
  public func foo()
}

for your respective projects?

@phausler
Copy link
Contributor

Personally I prefer the latter because it enforces knowingly making things public

@dingobye
Copy link
Contributor Author

Thank you, Philippe! I updated the code to fix the Foundation part as per your preference. Let's wait for advice from @mwwa and @briancroom.

@mwwa
Copy link
Contributor

mwwa commented Aug 15, 2018

I'm also happy with @phausler's preference, seems reasonable. We'll need to perform the equivalent fixes in corelibs-dispatch too.

dingobye pushed a commit to dingobye/swift-corelibs-foundation that referenced this pull request Aug 16, 2018
dingobye pushed a commit to dingobye/swift-corelibs-libdispatch that referenced this pull request Aug 16, 2018
dingobye added a commit to dingobye/swift-corelibs-foundation that referenced this pull request Aug 16, 2018
dingobye added a commit to dingobye/swift-corelibs-libdispatch that referenced this pull request Aug 16, 2018
@dingobye
Copy link
Contributor Author

Thanks for your inputs, Matt! I updated the code for the Dispatch part, and submitted a PR for relevant fixes in the corelibs-libdispatch repo.

aciidgh pushed a commit to swiftlang/swift-package-manager that referenced this pull request Aug 16, 2018
parkera pushed a commit to swiftlang/swift-corelibs-foundation that referenced this pull request Aug 28, 2018
@dingobye
Copy link
Contributor Author

dingobye commented Sep 4, 2018

@jrose-apple Hi Jordan, thanks for your all time support, and now all relevant projects have been prepared to embrace this patch. Would you help finalise this, please?

@jrose-apple
Copy link
Contributor

Ah, I thought we were still waiting on XCTest. I missed that Stuart already took care of that.

@swift-ci Please test

@dingobye
Copy link
Contributor Author

dingobye commented Sep 4, 2018

Yes, Stuart helped XCTest earlier.

The last one we were waiting for was libdispatch, which was merged just hours ago. Thanks to Kim!

@swift-ci
Copy link
Contributor

swift-ci commented Sep 5, 2018

Build failed
Swift Test Linux Platform
Git Sha - d5d17fa

@jrose-apple
Copy link
Contributor

@swift-ci Please test Linux

@jrose-apple jrose-apple merged commit 5dace22 into swiftlang:master Sep 6, 2018
@jrose-apple
Copy link
Contributor

Thanks for all your work here!

ktopley-apple pushed a commit to swiftlang/swift-corelibs-libdispatch that referenced this pull request Dec 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants