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

Fixed returns doc for init methods issue-557 #739

Merged
merged 1 commit into from Aug 23, 2016
Merged

Fixed returns doc for init methods issue-557 #739

merged 1 commit into from Aug 23, 2016

Conversation

mohpor
Copy link
Contributor

@mohpor mohpor commented Aug 2, 2016

Related to #557
There might be a better solution, but this pull request does the job, simple and easy.

@codecov-io
Copy link

codecov-io commented Aug 2, 2016

Current coverage is 89.39% (diff: 50.00%)

Merging #739 into master will decrease coverage by 0.12%

@@             master       #739   diff @@
==========================================
  Files            77         77          
  Lines          2633       2640     +7   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits           2357       2360     +3   
- Misses          276        280     +4   
  Partials          0          0          

Powered by Codecov. Last update 8389aa2...c7d0cf0

@@ -51,7 +51,9 @@ func declarationReturns(declaration: String, kind: SwiftDeclarationKind? = nil)
guard let outsideBracesMatch = matchOutsideBraces(declaration) else {
return false
}

if declaration.containsString("init(") {
Copy link
Contributor

@freak4pc freak4pc Aug 2, 2016

Choose a reason for hiding this comment

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

This is dangerous, Consider a declaration of sorts:
actionPerformFinit()
This would still match this case incorrectly.

I think something like this would be better for this "Simple" style solution but I'm still not totally sure if checking for a string match is the best solution regardless. I think it could work for now if @jpsim thinks this is proper.

Even though this might break for required init or override init ?

guard !declaration.hasPrefix("init(") else {
    return true
}

Copy link
Contributor Author

@mohpor mohpor Aug 2, 2016

Choose a reason for hiding this comment

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

@freak4pc You are right, should've considered the constant string more carefully.

  • I'm not that familiar with the project to be honest, and I wasn't aware that the declaration string would be something like: public convince init() or plain init(), that's why I didn't go for the hasPrefix, but I see your point and I think a leading space could help!
  • I decided against the guard usage instead of if because the guidelines I'm following, prohibits using guards for case testing and this is clearly testing against different scenarios, but, if SwiftLint suggests I should use guard, by all means!
  • The very next line of code uses the same technique for checking if a function returns (by checking the existence of ->), granted, that is very much unique in Swift's grammar, but then again so is init(), don't you agree? And with this logic what would become of a function with the following syntax: func runAndExit() -> Never { /* ... */ } in Swift 3?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the beginning space solution should be good :)

I'm also not familiar enough with SourceKitten so im not sure if includes the ACL etc but it should be considered in my opinion.

About guard/if, As far as I know, the guidelines SwiftLint follows, do suggest using guard to return early.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the guideline suggestion. That's very helpful. Wilco. :)

@jpsim
Copy link
Collaborator

jpsim commented Aug 2, 2016

This wouldn't work for failable initializers (init?). You should check if the declaration is a SwiftDeclarationKind.FunctionConstructor instead.

@Grubas7
Copy link

Grubas7 commented Aug 2, 2016

@jpsim Agree, I tried this solution but kind is never equal to .FunctionConstructor.
For code:

class TestClass: NSObject {

    /**
     Description about TestClass
     - parameter string: a super string
     - returns: a new class
     */
    override init() {
        super.init()
    }
}

returns .FunctionMethodInstance. I don't know why whole dictionary doesn't contain . FunctionConstructor value.

@jpsim
Copy link
Collaborator

jpsim commented Aug 2, 2016

Ah, interesting. That may be resolved later in the lexer than what's available to SourceKit.

@mohpor could you at least update this to support both init and init? please?

@mohpor
Copy link
Contributor Author

mohpor commented Aug 3, 2016

@jpsim Thanks for the heads up.
I have updated the checking mechanism to support failable initializers as well, made it a separate function, and moved checking to bail out of checking earlier.

The point here IMHO is that, a - returns: documentation for constructors should be optional. Because a constructor has a very specific job. To force the existence of returns doc makes documentation verbose. That being said, there are cases where you want to explain something about the constructor's job (especially in case of failable ones), that should be possible too, so I guess a returns doc for constructors should be optional, not mandatory, nor prohibited.

P.S.: I tried using regex to match the initializer syntax but I failed miserably!
Here is the regex code I was trying to use:

func declarationIsContructor(declaration: String) -> Bool {
    return regex("\\sinit\\?*\\(.*\\)").numberOfMatchesInString(declaration, options: [], range: NSRange(location: 0, length: declaration.characters.count)) > 0
}

But I couldn't make it work! It wouldn't match init() or init?() no matter what!

@freak4pc
Copy link
Contributor

freak4pc commented Aug 3, 2016

For the regex thing, this should work if you're interested in doing it
(.*)init(\\?)?\\((.*)\\)

Regex in Swift is painful though.

Here's a short Playground test:
image

@freak4pc
Copy link
Contributor

freak4pc commented Aug 3, 2016

About your whitespace issue,
Xcode -> Preferences -> Text Editing -> Automatically trim trailing whitespace, including whitespace-only lines

;-)

@mohpor
Copy link
Contributor Author

mohpor commented Aug 3, 2016

The regex you've mentioned would match performinit() too. The leading space should be mandatory I think. a better approach would be to start from the beginning and move from there, check if there is any character and if not a whitespace, then check that before init there is a whitespace. That makes for a relatively complex regex.

P.S.: Strangely enough, the regex I have provided before works in playground but fails in action! I will take a closer look at this.

P.P.S: thanks a lot for guiding me through that vicious trailing white space, it's been bugging me for too long. 👍

@mohpor
Copy link
Contributor Author

mohpor commented Aug 3, 2016

The correct regex I think is something like this: ^((.+)?\s+)?init\?*\(.*\) do you find any caveats whit this @freak4pc ?

@freak4pc
Copy link
Contributor

freak4pc commented Aug 3, 2016

Nothing that I can notice, it looks good here with ^((.+)?\\s+)?init\\?*\\(.*\\)

image

@mohpor
Copy link
Contributor Author

mohpor commented Aug 3, 2016

Worked like a charm!

@mohpor
Copy link
Contributor Author

mohpor commented Aug 6, 2016

@jpsim do you need anything to add to this one?

@mohpor
Copy link
Contributor Author

mohpor commented Aug 14, 2016

It's been 8 days! Any news?

@Grubas7
Copy link

Grubas7 commented Aug 18, 2016

@mohpor Could you make optional - returns: for constructors, update CHANGELOG.md and squash your commits?

@mohpor
Copy link
Contributor Author

mohpor commented Aug 20, 2016

@Grubas7 I have updated the CHANGELOG.md.
I thought my commits would be squashed by the admin who will merge this pull request. Am I wrong?

@Grubas7
Copy link

Grubas7 commented Aug 20, 2016

@mohpor Yeap, you're right. I forgot about this option on GitHub :)

@@ -20,11 +20,15 @@
[bootstraponline](https://github.com/bootstraponline)
[#689](https://github.com/realm/SwiftLint/issues/689)

* Made `- returns:` doc optional for constructors.
Copy link
Collaborator

Choose a reason for hiding this comment

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

missing two trailing spaces as indicated in https://github.com/realm/SwiftLint/blob/master/CONTRIBUTING.md#tracking-changes

I'd also prefer if you replaced the word "constructors" with "initializers" because constructors also include the family of static functions that return Self and this doesn't apply to that.

@jpsim
Copy link
Collaborator

jpsim commented Aug 21, 2016

@mohpor thanks for your work on this, and sorry for the delay on reviewing this. I just had a few minor comments. Could you please address them, then I think this can be merged.

@mohpor
Copy link
Contributor Author

mohpor commented Aug 22, 2016

@jpsim Done.

P.S.: My branch has conflicts now. Should I do anything?

@freak4pc
Copy link
Contributor

@mohpor you'll probably have to rebase against master

@mohpor
Copy link
Contributor Author

mohpor commented Aug 22, 2016

@freak4pc Thanks again. You're the man.

@mohpor
Copy link
Contributor Author

mohpor commented Aug 22, 2016

Hmmmm, rebasing made everyone's commits into this one. I guess I need to close this commit, make a clean, one commit PR instead. Do you agree @freak4pc @jpsim ?

@jpsim
Copy link
Collaborator

jpsim commented Aug 22, 2016

Hmmmm, rebasing made everyone's commits into this one. I guess I need to close this commit, make a clean, one commit PR instead.

You don't need to close this PR, you can rebase (correctly) and force-push to the same branch.

Signed-off-by: M. Porooshani <porooshani@gmail.com>
@mohpor
Copy link
Contributor Author

mohpor commented Aug 23, 2016

@jpsim Sorry for the mixup, I have re-rebased and squashed my commits.
It seems like a simple merge but I learned a ton.
I should thank @freak4pc for his advices too, very helpful.

@freak4pc
Copy link
Contributor

Anytime. Thanks for your consistent help on this PR! @mohpor

@jpsim jpsim merged commit e8dc451 into realm:master Aug 23, 2016
@jpsim
Copy link
Collaborator

jpsim commented Aug 23, 2016

🎉 congrats for landing this @mohpor

@mohpor mohpor deleted the InitReturnDoc branch August 24, 2016 04:05
@Grubas7
Copy link

Grubas7 commented Aug 31, 2016

This bug is still valid for implicitly unwrapped optional, eg:
init!()

@jpsim
Copy link
Collaborator

jpsim commented Aug 31, 2016

huh, forgot it was possible to make initializers like that.

@mohpor
Copy link
Contributor Author

mohpor commented Aug 31, 2016

Whoops,
Will make a PR soon.

@mohpor
Copy link
Contributor Author

mohpor commented Sep 2, 2016

Checkout #804

@norio-nomura
Copy link
Collaborator

We can make initializers generic.

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.

None yet

6 participants