-
-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add fix for correct placement of import (#2100) #2116
Conversation
Looks like the 8.6.5 build needs some compatibility fix:
The usual recommendation is to |
Ah ok, that extra import wasn't needed at all so, I'll update it tomorrow. |
a425a85
to
ed384f6
Compare
I removed that extra 'HasSrcSpan' import, but actually just checking now I noticed I'll have to amend the expected value of some of the older import tests too, as there's a few of them failing now because of the different behaviour - I can do this tomorrow. |
-- | Finds the next valid position for inserting a new import declaration | ||
-- If the file already has existing imports it will be inserted under the last of these, | ||
-- it is assumed that the existing last import declaration is in a valid position | ||
-- If the file does not have existing imports, but has a (module ... where) declaration, | ||
-- the new import will be inserted directly under this declaration (accounting for explicit exports) | ||
-- If the file has neither existing imports nor a module declaration, | ||
-- the import will be inserted at line zero if there are no pragmas, | ||
-- otherwise inserted one line after the last file-header pragma |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-- | Finds the next valid position for inserting a new import declaration | |
-- If the file already has existing imports it will be inserted under the last of these, | |
-- it is assumed that the existing last import declaration is in a valid position | |
-- If the file does not have existing imports, but has a (module ... where) declaration, | |
-- the new import will be inserted directly under this declaration (accounting for explicit exports) | |
-- If the file has neither existing imports nor a module declaration, | |
-- the import will be inserted at line zero if there are no pragmas, | |
-- otherwise inserted one line after the last file-header pragma | |
-- | Finds the next valid position for inserting a new import declaration | |
-- * If the file already has existing imports it will be inserted under the last of these, | |
-- it is assumed that the existing last import declaration is in a valid position | |
-- * If the file does not have existing imports, but has a (module ... where) declaration, | |
-- the new import will be inserted directly under this declaration (accounting for explicit exports) | |
-- * If the file has neither existing imports nor a module declaration, | |
-- the import will be inserted at line zero if there are no pragmas, | |
-- * otherwise inserted one line after the last file-header pragma |
-- | Insert the import under the Module declaration exports if they exist, otherwise just under the module declaration | ||
-- If no module declaration exists, then no exports will exist either, in that case | ||
-- insert the import after any file-header pragmas or at position zero if there are no pragmas |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-- | Insert the import under the Module declaration exports if they exist, otherwise just under the module declaration | |
-- If no module declaration exists, then no exports will exist either, in that case | |
-- insert the import after any file-header pragmas or at position zero if there are no pragmas | |
-- | Insert the import under the Module declaration exports if they exist, otherwise just under the module declaration. | |
-- If no module declaration exists, then no exports will exist either, in that case | |
-- insert the import after any file-header pragmas or at position zero if there are no pragmas |
@@ -209,7 +209,7 @@ extendImportHandler' ideState ExtendImport {..} | |||
it = case thingParent of | |||
Nothing -> newThing | |||
Just p -> p <> "(" <> newThing <> ")" | |||
t <- liftMaybe $ snd <$> newImportToEdit n (astA ps) | |||
t <- liftMaybe $ snd <$> newImportToEdit n (astA ps) "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this do the right thing if the module has a module name but no imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you mean, because of the empty string? I think it will be fine for that case as if the module has a name but no imports the new import will be added directly under the module declaration via the 'hsmodName' type, or via 'hsmodExports' if the declaration contains explicit exports.
But it would be an issue actually when the module has neither a module name nor imports - in that case it relies on the 'fileContents' argument when calling 'findNextPragmaPosition', but if it's just getting an empty string from there it won't always be accurate.
I guess calling 'GetFileContents' earlier in the "extendImportHandler'" function, and then having (fromMaybe "" contents) in the line you highlighted should cover that case? I can check this evening and add a test too.
ed384f6
to
400baf4
Compare
Looks like there are some Windows specific test failures related to newlines:
|
Oh ok, so just after the new import it's getting '\n' but expecting '\r\n', I'll have a look this evening. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than the failing tests, this looks good to me. Thanks again @nini-faroux !
c696970
to
bd0d817
Compare
I think it should be ok for the windows tests now too. No worries! let me know if there's any issues with it. Thanks for the help @pepeiborra and @jneira |
hlint is sad:
|
i think it is caused by some hlint change, i ve tried to fix it with 6e9d0bb |
I just released a new version of HLint that had this new hint added. |
* Remove HasSrcSpan import * Amend extendImportHandler' function * Amend old import tests * Adapt tests for windows newline issue
228a05b
to
1b3c4f9
Compare
hi, I added a fix for the import placement issue. (#2100)
So, the way it worked previously was to use the 'HsModule' type to find the next import position. Specifically it had two cases, when there's no existing imports in the file it would use the 'hsmodDecls' field, with type [LHsDecl name], and otherwise it would use 'hsmodImports', with type [LImportDecl name]'.
In the first case (hsmodDecls) the position would be one above the first element in that list, and this worked fine in general unless there was something above it which wasn't included in the list, like the comment in the example in the issue.
So for the fix, firstly it's changed to use the 'hsmodName' and 'hsmodExports' fields in 'HsModule' instead of 'hsmodDecls' to calculate the position in the case that the file included a 'module ... where' declaration, with no existing imports in the file. So in this case the new import will be added directly under the module declaration.
But in the case where there is no module declaration and no existing imports I used the same logic as in the pragma plugin, basically the import will be one under the last file-header pragma or else at the very top. I needed to change a few functions to do this, just to pass down the Text version of the file contents, as there wasn't enough information in the 'HsModule' type to manage it otherwise.
I left the other case, where there are existing imports in the file the way it was, as I think inserting the next import directly underneath the last existing import is a sensible thing to do. This would only be a problem I guess if the user has placed the existing import in the wrong place themselves, or if there's another bug that does that.
I also added a good few tests, I hope it covers most of the cases!