Skip to content

Delete duplicate imports. #150

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

Merged
merged 1 commit into from
Feb 25, 2020

Conversation

dylansturg
Copy link
Contributor

The criteria for deletion is:

  • Has an identical path, excluding whitespace, as an existing import
  • No more than 1 of the matching imports have a trailing comment

The trailing comment rule is necessary because it's impossible to safely combine multiple trailing comments such that they all stay grouped to the relevant import. Leading comments are safe to combine, because OrderedImports keeps multiple lines of leading comments grouped to the next import. Rather than trying to keep the trailing comments on 1 line together or promote 1 trailing comment to a leading comment, it's safer to raise the diagnostic and keep both imports.

@allevato
Copy link
Member

What happens if someone has this?

import Foo
@testable import Foo

and is the result different than if they had this?

@testable import Foo
import Foo

I guess there are two questions here:

  1. Is that valid, or does the compiler complain (at Sema time) if you import the same module both testably and non-testably; I don't know off the top of my head what happens here.
  2. Does order matter here, or do we need to prioritize them in some way?

I suppose the same thing could happen for other attributes that aren't technically supported yet, like @_exported or @_implementationOnly.

Now that I've written that last sentence, maybe the right thing to do for attributed imports is not to deduplicate them at all; that way we don't have to deal with which attributes "semantically override" the others.

Can you add a test or two that covers these cases?

@SDGGiesbrecht
Copy link
Contributor

What happens if someone has this?

import Foo
@testable import Foo

and is the result different than if they had this?

@testable import Foo
import Foo

Last I checked, the compiler mistook the second for having already been covered by the first and skipped it. The second example was actually testable; the first actually wasn’t. But that is probably a bug. I first ran into it when I wrote something like this...

import Module
@testable import struct Module.Structure

...and nothing was testable, but I changed it to...

@testable import struct Module.Structure
import Module

...and only the structure was testable, but everything was available. That had been my original intention.

@dylansturg dylansturg force-pushed the nuke_duplicate_imports branch from 7fb2fbe to bb84022 Compare February 25, 2020 21:20
The criteria for deletion is:
- Has an identical path, excluding whitespace, as an existing import
- No more than 1 of the matching imports have a trailing comment

The trailing comment rule is necessary because it's impossible to safely combine multiple trailing comments such that they all stay grouped to the relevant import. Leading comments are safe to combine, because OrderedImports keeps multiple lines of leading comments grouped to the next import. Rather than trying to keep the trailing comments on 1 line together or promote 1 trailing comment to a leading comment, it's safer to raise the diagnostic and keep both imports.
@dylansturg dylansturg force-pushed the nuke_duplicate_imports branch from bb84022 to 7324c20 Compare February 25, 2020 21:26
@dylansturg
Copy link
Contributor Author

I guess there are two questions here:

  1. Is that valid, or does the compiler complain (at Sema time) if you import the same module both testably and non-testably; I don't know off the top of my head what happens here.

It looks like this is fine, at least from a compilation perspective and doesn't even raise a warning. Based on the comments from @SDGGiesbrecht, we might want to reconsider the fact that @testable imports are always sorted below other imports.

  1. Does order matter here, or do we need to prioritize them in some way?

It sounds like order does matter, again based on the previous comment.

Now that I've written that last sentence, maybe the right thing to do for attributed imports is not to deduplicate them at all; that way we don't have to deal with which attributes "semantically override" the others.

I agree. I've updated the implementation to consider all pieces of the import decl: the attributes, modifiers, kind, and path for de-duplication.

Interestingly, we have special handling for the @testable attribute but imports with any other attribute are treated as "regular" imports and are sorted based on the import path disregarding attributes. We might want to consider some additional effort to support the order requirements of @testable import and how to handle unrecognized attributes (keep mixing them in with regular imports? group by attribute?).

@allevato
Copy link
Member

Based on the comments from @SDGGiesbrecht, we might want to reconsider the fact that @testable imports are always sorted below other imports.

Yeah, as much as I don't want to have us worry too much about questionably-defined behavior, if order matters in that situation, then our current behavior for @testable would break that code without an ignore directive.

Let's merge this for now and then consider what to do for @testable imports long-term.

@allevato allevato merged commit 9cbfbcb into swiftlang:master Feb 25, 2020
@dylansturg dylansturg deleted the nuke_duplicate_imports branch February 26, 2020 22:08
aaditya-chandrasekhar pushed a commit to val-verde/swift-format that referenced this pull request May 20, 2021
…able declaration code blocks (swiftlang#150)

* Omit initializer expression if closure or function call to ensure reasonable declaration code blocks.

Resolves swiftlang#138

* Add changelog entry for swiftlang#150
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.

3 participants