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

Exempt Immutable from UnnecessarilyFullyQualified #2236

Conversation

hisener
Copy link
Contributor

@hisener hisener commented Mar 14, 2021

UnnecessarilyFullyQualified flags the usage of fully qualified @Value.Immutable annotation from Immutables. We prefer the fully qualified name when @Value from spring-beans is used. So we need to suppress it in those cases.

import org.springframework.beans.factory.annotation.Value;

final class Demo { 
  Demo(@Value("some.property") String property) {}

  @SuppressWarnings("UnnecessarilyFullyQualified" /* Direct `@Immutable` import is confusing. */)
  @org.immutables.value.Value.Immutable
  abstract class AbstractType {}
}

The following report is generated without the suppression:

java.lang.AssertionError: Saw unexpected error on line 8. All errors:
/test/Test.java:8: warning: [UnnecessarilyFullyQualified] This fully qualified name is unambiguous to the compiler if imported.
  @org.immutables.value.Value.Immutable
                             ^
    (see https://errorprone.info/bugpattern/UnnecessarilyFullyQualified)
  Did you mean '@Immutable'?

However, using @Immutable can be confusing as there are many @Immutable annotations, e.g. javax.annotation.concurrent.Immutable, com.google.errorprone.annotations.Immutable, org.hibernate.annotations.Immutable, etc. For that reason, I think it makes sense to add Immutable to exempted names.

@google-cla google-cla bot added the cla: yes label Mar 14, 2021
@cushon
Copy link
Collaborator

cushon commented Sep 16, 2023

Thanks for the PR, and sorry for the very slow response.

In our codebase we're gradually moving towards standardizing oncom.google.errorprone.annotations.Immutable, and using imports and simple names vs. qualified names, so I'd like to have a way to preserve the UnnecessarilyFullyQualified findings for that use-case.

I also see the benefit of skipping them for projects that are mixing different Immutable annotations.

I see a couple ways forward here:

  • For the immutables annotation, I wondered about writing @Value.Immutable instead, @org.immutables.value.Value.Immutable. But it sounds like the preference in your code is to use the full qualified name, so maybe that wouldn't help?
  • Another option would be to add a flag to UnnecessarilyFullyQualified to make the list of exemptions configurable, and then you could pass e.g. -XepOpt:UnnecessarilyFullyQualified:ExemptedNames=Immutable

What do you think?

@hisener
Copy link
Contributor Author

hisener commented Sep 22, 2023

No worries.

Disclaimer: I created this issue over two years ago and am trying to remember the context. Also, I work for a different company, where we don't have this problem.

  • For the immutables annotation, I wondered about writing @Value.Immutable instead, @org.immutables.value.Value.Immutable. But it sounds like the preference in your code is to use the full qualified name, so maybe that wouldn't help?

I am not sure I understand the proposal here. Using @Value.Immutable is not possible when we already have the org.springframework.beans.factory.annotation.Value import, right? 👀 Or, do you mean adding org.immutables.value.Value.Immutable to the exempted name set?

@Stephan202
Copy link
Contributor

Disclaimer: I created this issue over two years ago and am trying to remember the context. Also, I work for a different company, where we don't have this problem.

I can report that the original company still has this issue. 😉

I guess an ExemptedNames flag would work. Another approach (which is more work but also more versatile and closer to the Picnic use case), would be to introduce an AdditionalTypes (name TBD) flag for the BadImport check, and have UnnecessarilyFullyQualified also respect that configuration. (Note that UnnecessarilyFullyQualified already has a dependency on BadImport, so this isn't too far-fetched.)

IIUC this way one could set -XepOpt:BadImport:AdditionalTypes=org.immutables.value.Value, which would then allow UnnecessarilyFullyQualified to suggest Value.Immutable if possible and remain silent otherwise.

@cushon
Copy link
Collaborator

cushon commented Sep 22, 2023

I am not sure I understand the proposal here. Using @Value.Immutable is not possible when we already have the org.springframework.beans.factory.annotation.Value import, right?

You're right--I was thinking about ways to avoid a clash with another Immutable annotation, not with Value.

Another approach (which is more work but also more versatile and closer to the Picnic use case), would be to introduce an AdditionalTypes (name TBD) flag for the BadImport check, and have UnnecessarilyFullyQualified also respect that configuration

That alternative SGTM, as long as UnnecessarilyFullyQualified and BadImport sharing heuristics it seems nice to keep them in sync with a shared flag.

@hisener
Copy link
Contributor Author

hisener commented Jan 1, 2024

Sorry for the delay; I created #4228 for the alternative approach Stephan suggested.

(Created a separate PR because I don't think I have write access to this branch anymore)

copybara-service bot pushed a commit that referenced this pull request Jan 2, 2024
Following the discussions in #2236, this PR introduces the `BadImport:BadEnclosingTypes` flag to disallow nested types of specified enclosing type.

This PR also takes the flag into account in `UnnecessarilyFullyQualified` to suggest importing `EnclosingType.NestedType` when possible.

For instance, when `-XepOpt:BadImport:BadEnclosingTypes=org.immutables.value.Value` is set, it would suggest the following:

```java
final class Test {
  @org.immutables.value.Value.Immutable
  abstract class AbstractType {}
}
```
->
```java
final class Test {
  @Value.Immutable
  abstract class AbstractType {}
}
```

Also, it won't require suppressing `UnnecessarilyFullyQualified` in the example in #2236.

```java
import org.springframework.beans.factory.annotation.Value;

final class Test {
  Demo(@value("some.property") String property) {}

  @org.immutables.value.Value.Immutable
  abstract class AbstractType {}
}
```

Closes #2236.

Fixes #4228

FUTURE_COPYBARA_INTEGRATE_REVIEW=#4228 from hisener:halil.sener/bad-import-bad-enclosing-types 67aa36d
PiperOrigin-RevId: 595179563
copybara-service bot pushed a commit that referenced this pull request Jan 12, 2024
Following the discussions in #2236, this PR introduces the `BadImport:BadEnclosingTypes` flag to disallow nested types of specified enclosing type.

This PR also takes the flag into account in `UnnecessarilyFullyQualified` to suggest importing `EnclosingType.NestedType` when possible.

For instance, when `-XepOpt:BadImport:BadEnclosingTypes=org.immutables.value.Value` is set, it would suggest the following:

```java
final class Test {
  @org.immutables.value.Value.Immutable
  abstract class AbstractType {}
}
```
->
```java
final class Test {
  @Value.Immutable
  abstract class AbstractType {}
}
```

Also, it won't require suppressing `UnnecessarilyFullyQualified` in the example in #2236.

```java
import org.springframework.beans.factory.annotation.Value;

final class Test {
  Demo(@value("some.property") String property) {}

  @org.immutables.value.Value.Immutable
  abstract class AbstractType {}
}
```

Closes #2236.

Fixes #4228

FUTURE_COPYBARA_INTEGRATE_REVIEW=#4228 from hisener:halil.sener/bad-import-bad-enclosing-types 67aa36d
PiperOrigin-RevId: 595179563
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants