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

Fix void_function_in_ternary incorrectly triggered with if statement #5674

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

u-abyss
Copy link
Contributor

@u-abyss u-abyss commented Jul 15, 2024

Fixes #5611

This PR corrects that VoidFunctionInTernaryConditionRule incorrectly triggered with if statement.
This new rule is triggered or not depending on the return type of the function.

@SwiftLintBot
Copy link

SwiftLintBot commented Jul 15, 2024

2 Warnings
⚠️ If this is a user-facing change, please include a CHANGELOG entry to credit yourself!
You can find it at CHANGELOG.md.
⚠️ This PR may need tests.
17 Messages
📖 Linting Aerial with this PR took 0.16s vs 0.16s on main (0% slower)
📖 Linting Alamofire with this PR took 0.16s vs 0.16s on main (0% slower)
📖 Linting Brave with this PR took 0.61s vs 0.61s on main (0% slower)
📖 Linting DuckDuckGo with this PR took 0.48s vs 0.48s on main (0% slower)
📖 Linting Firefox with this PR took 1.35s vs 1.37s on main (1% faster)
📖 Linting Kickstarter with this PR took 0.74s vs 0.74s on main (0% slower)
📖 Linting Moya with this PR took 0.12s vs 0.12s on main (0% slower)
📖 Linting NetNewsWire with this PR took 0.28s vs 0.28s on main (0% slower)
📖 Linting Nimble with this PR took 0.14s vs 0.14s on main (0% slower)
📖 Linting PocketCasts with this PR took 0.68s vs 0.65s on main (4% slower)
📖 Linting Quick with this PR took 0.12s vs 0.12s on main (0% slower)
📖 Linting Realm with this PR took 0.41s vs 0.41s on main (0% slower)
📖 Linting Sourcery with this PR took 0.27s vs 0.27s on main (0% slower)
📖 Linting Swift with this PR took 0.39s vs 0.39s on main (0% slower)
📖 Linting VLC with this PR took 0.19s vs 0.19s on main (0% slower)
📖 Linting Wire with this PR took 1.6s vs 1.58s on main (1% slower)
📖 Linting WordPress with this PR took 1.05s vs 1.03s on main (1% slower)

Here's an example of your CHANGELOG entry:

* Fix void_function_in_ternary incorrectly triggered with if statement.  
  [u-abyss](https://github.com/u-abyss)
  [#issue_number](https://github.com/realm/SwiftLint/issues/issue_number)

note: There are two invisible spaces after the entry's text.

Generated by 🚫 Danger

@u-abyss u-abyss force-pushed the fix/5611 branch 3 times, most recently from 529c862 to 337358f Compare September 10, 2024 10:00
@u-abyss u-abyss changed the title fix: void_function_in_ternary incorrectly triggered with if statement Fix void_function_in_ternary incorrectly triggered with if statement Sep 10, 2024
@u-abyss u-abyss marked this pull request as ready for review September 10, 2024 10:58
Copy link
Collaborator

@SimplyDanny SimplyDanny left a comment

Choose a reason for hiding this comment

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

Thanks taking up the issue!

The current implementation is very specific to implicit returns. However, if and switch expression can also appear as variable initializers and they can be nested into each other. I don't think the current solution addresses these cases, does it?

@u-abyss
Copy link
Contributor Author

u-abyss commented Oct 12, 2024

@SimplyDanny
Added handling of nested if and switch statements. I have a question.
I believe that when you initialize a variable in an if or switch expression, the compiler prevents you from writing a statement that returns void in it.
If there is an appropriate case for initializing a variable in an if or switch expression, I would appreciate it if you could let me know.

@SimplyDanny
Copy link
Collaborator

@SimplyDanny Added handling of nested if and switch statements. I have a question. I believe that when you initialize a variable in an if or switch expression, the compiler prevents you from writing a statement that returns void in it. If there is an appropriate case for initializing a variable in an if or switch expression, I would appreciate it if you could let me know.

Can you provide an example?

The code

func f(i: Int) -> Int {
  if i > 1 {
    let j = i - 1
    j
  } else {
    0
  }
}

wouldn't compile. There you need the return before j.

if true {
if true {
isTrue ↓? defaultValue() : defaultValue()
retun "True"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
retun "True"
return "True"

return targetSyntax
}
if let ifExprSyntax = targetSyntax?.as(IfExprSyntax.self) {
if ifExprSyntax.body.statements.last != codeBlockItem {
Copy link
Collaborator

Choose a reason for hiding this comment

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

What about else blocks?

// For codeBlockItem, recursively traverse it to determine if it is within its own FunctionDeclSyntax.
func getFunctionDeclSyntax(codeBlockItem: CodeBlockItemSyntax) -> FunctionDeclSyntax? {
let targetSyntax = codeBlockItem.parent?.parent?.parent?.parent
if let targetSyntax = targetSyntax?.as(FunctionDeclSyntax.self) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This covers only functions, but there are also the other cases which are checked above in the is...Return properties.

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.

void_function_in_ternary incorrectly triggered with if and switch expressions
3 participants