This repository was archived by the owner on Jan 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 95
Enhancements to top-level signatures #232
Merged
Merged
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b221936
Try adding a dependency on TypeCheck
serras a2771d9
Show warning regardless of the status of -Wall
serras f042cff
Try diagnostics after type checking, again
serras 4541807
Use `useE` instead of `use_` to not get a `BadDependency` error
serras 3a3a020
Degrade information about signatures if not present in user options
serras 4614474
Fix tests
serras 83733c8
Better suggested signatures for polymorphic bindings
serras 122128e
Remove old comment
serras File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ module Development.IDE.LSP.CodeAction | |
import Language.Haskell.LSP.Types | ||
import Development.IDE.GHC.Compat | ||
import Development.IDE.Core.Rules | ||
import Development.IDE.Core.RuleTypes | ||
import Development.IDE.Core.Shake | ||
import Development.IDE.LSP.Server | ||
import Development.IDE.Types.Location | ||
|
@@ -53,14 +54,16 @@ codeLens | |
-> CodeLensParams | ||
-> IO (List CodeLens) | ||
codeLens _lsp ideState CodeLensParams{_textDocument=TextDocumentIdentifier uri} = do | ||
diag <- getDiagnostics ideState | ||
-- diag <- getDiagnostics ideState | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like this line can be removed? |
||
case uriToFilePath' uri of | ||
Just (toNormalizedFilePath -> filePath) -> do | ||
_ <- runAction ideState $ use_ TypeCheck filePath | ||
serras marked this conversation as resolved.
Show resolved
Hide resolved
|
||
diag <- getDiagnostics ideState | ||
pure $ List | ||
[ CodeLens _range (Just (Command title "typesignature.add" (Just $ List [toJSON edit]))) Nothing | ||
| (dFile, dDiag@Diagnostic{_range=_range@Range{..},..}) <- diag | ||
, dFile == filePath | ||
, (title, tedit) <- suggestTopLevelBinding False dDiag | ||
, (title, tedit) <- suggestSignature False dDiag | ||
, let edit = WorkspaceEdit (Just $ Map.singleton uri $ List tedit) Nothing | ||
] | ||
Nothing -> pure $ List [] | ||
|
@@ -177,12 +180,12 @@ suggestAction contents diag@Diagnostic{_range=_range@Range{..},..} | |
extractFitNames = map (T.strip . head . T.splitOn " :: ") | ||
in map proposeHoleFit $ nubOrd $ findSuggestedHoleFits _message | ||
|
||
| tlb@[_] <- suggestTopLevelBinding True diag = tlb | ||
| tlb@[_] <- suggestSignature True diag = tlb | ||
|
||
suggestAction _ _ = [] | ||
|
||
suggestTopLevelBinding :: Bool -> Diagnostic -> [(T.Text, [TextEdit])] | ||
suggestTopLevelBinding isQuickFix Diagnostic{_range=_range@Range{..},..} | ||
suggestSignature :: Bool -> Diagnostic -> [(T.Text, [TextEdit])] | ||
suggestSignature isQuickFix Diagnostic{_range=_range@Range{..},..} | ||
| "Top-level binding with no type signature" `T.isInfixOf` _message = let | ||
filterNewlines = T.concat . T.lines | ||
unifySpaces = T.unwords . T.words | ||
|
@@ -192,7 +195,18 @@ suggestTopLevelBinding isQuickFix Diagnostic{_range=_range@Range{..},..} | |
title = if isQuickFix then "add signature: " <> signature else signature | ||
action = TextEdit beforeLine $ signature <> "\n" | ||
in [(title, [action])] | ||
suggestTopLevelBinding _ _ = [] | ||
suggestSignature isQuickFix Diagnostic{_range=_range@Range{..},..} | ||
| "Polymorphic local binding with no type signature" `T.isInfixOf` _message = let | ||
filterNewlines = T.concat . T.lines | ||
unifySpaces = T.unwords . T.words | ||
signature = T.takeWhile (\x -> x/='*' && x/='•') | ||
$ T.strip $ unifySpaces $ last $ T.splitOn "type signature: " $ filterNewlines _message | ||
startOfLine = Position (_line _start) (_character _start) | ||
beforeLine = Range startOfLine startOfLine | ||
title = if isQuickFix then "add signature: " <> signature else signature | ||
action = TextEdit beforeLine $ signature <> "\n" <> T.replicate (_character _start) " " | ||
in [(title, [action])] | ||
suggestSignature _ _ = [] | ||
|
||
topOfHoleFitsMarker :: T.Text | ||
topOfHoleFitsMarker = | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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’ve brought this up a couple of times before but I really dislike the idea of enabling warnings by default. If users care about these warnings, they should enable them in their cabal file. I don’t want to see a bunch of warnings in my IDE that I haven’t enabled. If we manage to make this work such that we only show the codelenses by default but not the warnings, I could be convinced that this is fine but given that the codelenses are based on diagnostics this doesn’t seem trivial and I think the complexity of trying to make this work is probably not worth it.
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 am happy both ways. I can attempt to write something which remembers whether these warning were already in effect at the beginning, so that we can filter out diagnostics if needed. But I agree: it might be quite complicated.
@ndmitchell you seemed to have an idea of how to achieve this in #231. Any suggestions?
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.
Code which doesn't have a warning is more likely to have top-level signatures omitted, and more likely to benefit from having them as code lenses, since I see them as helpful docs, rather than a mechanism to easily add them. I separately think that turning on some warnings in the IDE vs compiler is reasonable, but see that as unrelated to this patch.
I'm not convinced the code is that complex. You turn on the warning always, but demote the warning to an info if errMsgReason is missing top level signatures. At some point (if we want) we ditch info level diagnostics before sending them to the LSP client. A few lines here, a few lines (that will be generally useful) in the diagnostic sending code.
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 am admittedly a bit biased here, I don’t recall the last time I worked on a project that didn’t have these warnings enabled and that seems to be quite common in the ecosystem in general, so I’m somewhat hesitant to add any complexity (even if it’s probably not too much) to cater to that usecase.
That said, the argument that we’ll need this for other warnings eventually that are less popular is compelling so I’m fine with adding it.
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.
None of my projects have it turned on :)
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.
That’s your loss
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.
My loss is not getting to work with you awesome guys every day anymore!
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.
🤗
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.
It took a while, but finally I managed to "degrade" warnings about missing signatures to info level if they were not explicitly enabled by the user. They look great in VSCode, since they are shown with a blue underline.