Skip to content
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

Implemented super call rule (#803) #809

Merged
merged 17 commits into from
Oct 20, 2016

Conversation

angelolloqui
Copy link
Contributor

@angelolloqui angelolloqui commented Sep 7, 2016

PR for issue #803

It basically looks for methods in the whitelist (and marked as overriden) and checks that there is exactly one super call somewhere in its implementation.

The rule comes with a custom provider that allows configuring the list of methods to include or exclude. The default configuration comes with the most common methods in Cocoa.

Example only checking 2 custom methods:

overridden_super_call:
  severity: warning
  excluded: *
  included: 
    - testMethod1()
    - testMethod2(_:)

@angelolloqui
Copy link
Contributor Author

Current predefined list of included methods:

var defaultIncluded = [
        //NSObject
        "awakeFromNib()",
        "prepareForInterfaceBuilder()",
        //UIViewController
        "transitionCoordinator()",
        "viewDidLoad()",
        "viewWillAppear(_:)",
        "viewWillDisappear(_:)",
        "viewDidAppear(_:)",
        "viewDidDisappear(_:)",
        "addChildViewController(_:)",
        "removeFromParentViewController()",
        "transition(from:to:duration:options:animations:completion:)",
        "transitionFromViewController(_:toViewController:duration:options:animations:completion:)",
        "didReceiveMemoryWarning()",
        "encodeRestorableState(with:)",
        "encodeRestorableStateWithCoder(_:)",
        "decodeRestorableState(with:)",
        "decodeRestorableStateWithCoder(_:)",
        "setEditing(_:animated:)",
        //UIView
        "updateConstraints()",
        "prepareForReuse()",
        //UICollectionViewLayout
        "invalidateLayout()",
        "invalidateLayout(with:)",
        "invalidateLayoutWithContext(_:)",
        //XCTestCase
        "tearDown()",
        "setUp()"
    ]

@codecov-io
Copy link

codecov-io commented Sep 26, 2016

Current coverage is 84.08% (diff: 86.99%)

Merging #809 into master will increase coverage by 0.08%

@@             master       #809   diff @@
==========================================
  Files           102        104     +2   
  Lines          4105       4228   +123   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits           3448       3555   +107   
- Misses          657        673    +16   
  Partials          0          0          

Powered by Codecov. Last update 3ecefe9...6161c9b

Copy link
Collaborator

@norio-nomura norio-nomura left a comment

Choose a reason for hiding this comment

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

Sorry for late reviews, and thanks for doing this!
Looks mostly good other than my feedbacks.

@@ -6,6 +6,10 @@

##### Enhancements

* Add `SuperCallRule` Opt-In rule that warns against overriden methods not calling to super in well known cases (ex: `viewWillAppear`).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you please wrap at 80 characters?

import Foundation

public struct SuperCallConfiguration: RuleConfiguration, Equatable {
var defaultIncluded = [
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorting this list by class+name alphabetically would be helpful.

var excluded: [String] = []
var included: [String] = ["*"]

public var consoleDescription: String {
Copy link
Collaborator

Choose a reason for hiding this comment

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

consoleDescription is used on swiftlint rules.

+--------------------------------+--------+-------------+------------------------+--------------------------------------------------+
| identifier                     | opt-in | correctable | enabled in your config | configuration                                    |
+--------------------------------+--------+-------------+------------------------+--------------------------------------------------+
| closing_brace                  | no     | yes         | yes                    | warning                                          |
…
| overridden_super_call          | yes    | no          | yes                    | warning, excluded: [[]], included: [["*"]]       |

The existence of defaultIncluded is not represented here.
Are there any idea for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you expect to see all the method list? It will pollute the table but I think it can be done easily. I am using * to reference the default list, so I can just return the evaluated list on:

 public var consoleDescription: String {
        return severityConfiguration.consoleDescription +
            ", excluded: [\(excluded)]" +
            ", included: [\(included)]"
    }

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, never mind. 👍

"invalidateLayoutWithContext(_:)",
//XCTestCase
"tearDown()",
"setUp()"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are there any documentation XCTestCase .tearDown() and XCTestCase .setUp() require calling super?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is indeed not mentioned for XCTestCase but as @marcelofabri comments, it is just there in the templates and assumed in all Apple test example code I have seen so far. We could remove it if you want, although I think since this is an Opt-In rule and it is configurable, I would leave it there as a good practice.

"\t\tself.method()\n" +
"\t}\n" +
"}\n",
]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you please add multiple calling to super triggering example?

Copy link
Collaborator

@norio-nomura norio-nomura left a comment

Choose a reason for hiding this comment

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

I guess the false negative pattern needs to be fixed.

var excluded: [String] = []
var included: [String] = ["*"]

public var consoleDescription: String {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, never mind. 👍

return severityConfiguration.severity
}

public var resolvedMethodNames: [String] {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess we would not need to re-create resolvedMethodNames on every calling.
Can we change this to initialize once on first calling?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍


guard let offset = dictionary["key.bodyoffset"] as? Int64,
let name = dictionary["key.name"] as? String,
let substructure = dictionary["key.substructure"] as? [SourceKitRepresentable]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I found false negative pattern:

class ViewController: UIViewController {
    override func didReceiveMemoryWarning() {
    }
}

that does not have "key.substructure".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ouch! thanks for pointing this out! I will check it out ASAP

@angelolloqui
Copy link
Contributor Author

Take a look now... 1 thing I am not sure if should be changed is that the rule id is overridden_super_call but the class implementing is SuperCallRule. If you want consistency, which name do you think makes more sense? maybe the first one?

@norio-nomura
Copy link
Collaborator

maybe the first one?

👍

@angelolloqui
Copy link
Contributor Author

Renamed! Let's hope this now is good enough :)

@norio-nomura norio-nomura merged commit 8b65811 into realm:master Oct 20, 2016
@norio-nomura
Copy link
Collaborator

Thanks! 🙏

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.

4 participants