Fix ModifyCollectionInEnhancedForLoop#34972
Conversation
|
BUILD SUCCESSFUL in 35s |
| } finally { | ||
| lock.unlock(); | ||
| } | ||
| throw new IllegalStateException("Gradle user home directory scoped services have already been released."); |
There was a problem hiding this comment.
Is this still needed? Feels a little off, only working in combination with the return in L:132.
Since loop is actually an stream, this might not be mandatory anymore.
There was a problem hiding this comment.
Isn't it for the break condition on L:124?
There was a problem hiding this comment.
i mean everything is kind of the preset for the last line. Test again demanding this having the need for ifElse as implemented in new fashion way of java featuring streaming api.
| break; | ||
| } | ||
| services.count--; | ||
| if (services.count == 0 && (servicesForHomeDir.size() > 1 || System.getProperty(REUSE_USER_HOME_SERVICES, "true").equals("false"))) { |
There was a problem hiding this comment.
Assuming count is the SSOT, meaning it’s not shared, we don’t need to decrement it but can simply check for 1 instead.
Assuming 0 would just be true, when having a value of 1 before decrement, therefore can just check for 1 and the logic remains the same, right? Adding +1 to the equation should work out.
There was a problem hiding this comment.
I don't feel confident enough to change this logic. Let's leave it as is, just refactor it
There was a problem hiding this comment.
Nothing has changed, right?
Its just doing the decrementation operation right before access, instead of dedicating a whole separate line. This might feel a bit niche or new to some developers, but it’s equally effective and logically the same.
The tests fail on missing incrementation case, which shows that this is simply a refactoring, not a logic change.
The result is identical, since performing the math operation before or after access only changes syntax — not behavior — as the tests confirm.
There was a problem hiding this comment.
We may misunderstand each other.
I'm ok with if (--services.count.... I'm not ok with checking against 1.
There was a problem hiding this comment.
Actually, this is a difference I did not recognize before. Assuming a test blind spot, we should ensure that incrementation and decrementation are fully covered.
ov7a
left a comment
There was a problem hiding this comment.
Thank you for your contribution!
| } finally { | ||
| lock.unlock(); | ||
| } | ||
| throw new IllegalStateException("Gradle user home directory scoped services have already been released."); |
There was a problem hiding this comment.
Isn't it for the break condition on L:124?
| break; | ||
| } | ||
| services.count--; | ||
| if (services.count == 0 && (servicesForHomeDir.size() > 1 || System.getProperty(REUSE_USER_HOME_SERVICES, "true").equals("false"))) { |
There was a problem hiding this comment.
I don't feel confident enough to change this logic. Let's leave it as is, just refactor it
|
@bot-gradle test APT |
This comment has been minimized.
This comment has been minimized.
|
The following builds have passed: |
| break; | ||
| } | ||
| services.count--; | ||
| if (services.count == 0 && (servicesForHomeDir.size() > 1 || System.getProperty(REUSE_USER_HOME_SERVICES, "true").equals("false"))) { |
There was a problem hiding this comment.
Nothing has changed, right?
Its just doing the decrementation operation right before access, instead of dedicating a whole separate line. This might feel a bit niche or new to some developers, but it’s equally effective and logically the same.
The tests fail on missing incrementation case, which shows that this is simply a refactoring, not a logic change.
The result is identical, since performing the math operation before or after access only changes syntax — not behavior — as the tests confirm.
| } finally { | ||
| lock.unlock(); | ||
| } | ||
| throw new IllegalStateException("Gradle user home directory scoped services have already been released."); |
There was a problem hiding this comment.
i mean everything is kind of the preset for the last line. Test again demanding this having the need for ifElse as implemented in new fashion way of java featuring streaming api.
| @@ -180,8 +284,7 @@ class DefaultGradleUserHomeScopeServiceRegistryTest extends Specification { | |||
| homeDirServices.release(services) | |||
|
|
|||
| then: | |||
| def e = thrown(IllegalStateException) | |||
| e.message == 'Gradle user home directory scoped services have already been released.' | |||
There was a problem hiding this comment.
Is the exception needed, or can we just stay silent here, since the new all-in-one filter would pass through the non-early-exit case due to the functional style?
There was a problem hiding this comment.
❌ The exception is required. Please revert this change
| then: "count should be decremented only once" | ||
| initialCount == 1 | ||
| countAfterFirstRelease == 0 | ||
| countAfterSecondRelease == -1 |
There was a problem hiding this comment.
is this the right intend? having now full coverage/contro
| 100% (3/3) | 100% (12/12) | 100% (54/54) | 100% (18/18) |
|---|
There was a problem hiding this comment.
countAfterSecondRelease == -1
is this the right intend?
No, the original code would throw an IllegalStateException. Please preserve that behaviour
| // unboxing and boxing does the trick | ||
| boolean value = options.get(key); | ||
| options.put(key, value); | ||
| options.compute(key, (k, value) -> value); // unboxing and boxing does the trick. |
There was a problem hiding this comment.
This does not do a unbox and re-box. Also, this is still a "modification", so it's not really solving the issue, even though it removes the warning. This could potentially be a false-negative from ErrorProne. I would just make a copy of the key set instead, for (String key : ImmutableSet.copyOf(options.keySet())).
There was a problem hiding this comment.
yes sorry, then need to suppress suggesion: Can be replaced with single 'Map.compute' method call .
When inlining the field assuming this is equivalent leads to; Can be replaced with single 'Map.replaceAll' method call
leading to:
| options.compute(key, (k, value) -> value); // unboxing and boxing does the trick. | |
| options.replaceAll((k, v) -> v); |
is this any good?
There was a problem hiding this comment.
No, because again, that does not do an unbox and re-box, which is the whole reason for the call in the first place. options.replaceAll((k, v) -> (boolean) v); should work for that, or perhaps we should be explicit and use options.replaceAll((k, v) -> v ? Boolean.TRUE : Boolean.FALSE);. This prevents a warning from IntelliJ as well.
There was a problem hiding this comment.
integrated your draft thanks.
kindly request feedback.
ov7a
left a comment
There was a problem hiding this comment.
Thanks for covering this code with tests!
❌ Please keep trowing the IllegalStateException on multiple releases to preserve the original behavior
| then: "count should be decremented only once" | ||
| initialCount == 1 | ||
| countAfterFirstRelease == 0 | ||
| countAfterSecondRelease == -1 |
There was a problem hiding this comment.
countAfterSecondRelease == -1
is this the right intend?
No, the original code would throw an IllegalStateException. Please preserve that behaviour
| @@ -180,8 +284,7 @@ class DefaultGradleUserHomeScopeServiceRegistryTest extends Specification { | |||
| homeDirServices.release(services) | |||
|
|
|||
| then: | |||
| def e = thrown(IllegalStateException) | |||
| e.message == 'Gradle user home directory scoped services have already been released.' | |||
There was a problem hiding this comment.
❌ The exception is required. Please revert this change
Signed-off-by: Vincent Potucek <vpotucek@me.com>

Context
Contributor Checklist
<subproject>/src/integTest) to verify changes from a user perspective.<subproject>/src/test) to verify logic../gradlew sanityCheck../gradlew <changed-subproject>:quickTest.Reviewing cheatsheet
Before merging the PR, comments starting with
BUILD SUCCESSFUL in 10m 47s