-
Notifications
You must be signed in to change notification settings - Fork 97
Conversation
Just curious, would this involve parsing those things out of GHC's stringy output? |
@@ -132,7 +132,8 @@ suggestAction contents Diagnostic{_range=_range@Range{..},..} | |||
| "Valid hole fits include" `T.isInfixOf` _message = let | |||
findSuggestedHoleFits :: T.Text -> [T.Text] | |||
findSuggestedHoleFits = extractFitNames . selectLinesWithFits . dropPreceding . T.lines | |||
proposeHoleFit name = ("replace hole with " <> name, [TextEdit _range name]) | |||
proposeHoleFit name = ("replace hole `" <> holeName <> "` with " <> name, [TextEdit _range name]) | |||
holeName = T.strip $ last $ T.splitOn ":" $ head . T.splitOn "::" $ head $ filter ("Found hole" `T.isInfixOf`) $ T.lines _message |
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'm not at all proud of the pattern matching in places like holeName
and surroundings. Any hints on how to do a better job of pattern matching on Text
would be most welcome.
(oh, oops, this is a PR, not a feature request) |
@mitchellwrosen yes, it involves parsing crap out of the GHC error message, which is sad, but effective. We turn on Unicode all the time to slightly reduce the amount of surface area we have to cover. We are also working with someone who is writing an error messages as ADT proposal, so as of GHC 8.12 or so we hope to avoid this string parsing. |
Which probably explains the mismatch I had in quotes between the action name that I generate, and the action name that I have to search for in the test.
So for 8.6 and 8.4 we're stuck with string parsing ... and I'm guessing that some subtle differences between the crap that 8.4 and 8.6 spit out are responsible for the CI failures that have shown up. So now I have to get |
d1d3dbb
to
0eccd2e
Compare
Given that parsing text is central to writing these actions, should we use some parser combinator library? If so, which one? |
It's unclear if a parsing library makes it easier or harder. It probably makes it more demanding about the precise layout, which may not be what we want. But someone would need to try it to know. |
But at least there's no upfront objection to adding a parsing library as a dependency? |
Not from me. If the code looks better or more robust after it sounds like a good idea. I believe attoparsec would be the "default" parser lib nowadays |
0eccd2e
to
91eb2a2
Compare
All the CI checks now pass, but the implementation simply comments out two tests which work on GHC 8.6 but fail on 8.4, because the latter doesn't provide hints about local bindings. Is there a way of excluding these tests on GHC 8.4 only, without resorting to CPP? |
91eb2a2
to
4908400
Compare
@ndmitchell btw, who's working on error messages as an ADT? I had some thoughts about it after digging through the GHC code a bit so would be interested to know what's planned. |
@hsenag @bgamari and @alpmestan I think (but I might be wrong) |
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.
Looks great thank you, the version checks need to be fixed (not your fault, I only added the new macro after you’ve opened this PR) but apart from that it looks great!
|
||
suggestAction _ _ = [] | ||
|
||
topOfHoleFitsMarker = if versionBranch compilerVersion >= [8,6] |
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.
versionBranch
isn’t going to work when compiling against ghc-lib
. I’ve added a MIN_GHC_API_VERSION
macro in #73 which should always be used for checking the GHC API version.
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.
OK, but this requires CPP, and CI rejected my first attempt because it used CPP, which hlint didn't like. Do I have to permit CPP for this module somewhere?
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.
We have a whitelist of modules that are allowed to use CPP
to make people a bit more cautious when using it. This is definitely a valid usecase, so you can just add your module to the whitelist https://github.com/digital-asset/ghcide/blob/7133f4192f8d11908e5fb4c3f52ca3af54a23459/.hlint.yaml#L78
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.
How do I add the test Main
to this whitelist?
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 believe that Main
should do the trick?
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.
Hm not sure why this doesn’t work, maybe @ndmitchell has an idea?
edit: looks like you figured it out.
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'm struggling to get CPP to work in Main.hs
of the tests:
It works in CodeAction.hs
, and I've done exactly the same in Main.hs
AFAICT, that is:
Add
{-# LANGUAGE CPP #-}
#include "ghc-api-version.h"
at the top, then
#if MIN_GHC_API_VERSION(8,6,0)
I did need to add include-dirs: include
to test-suite ghcide-tests
in ghcide.cabal
, for the #include
to work at all in Main.hs
.
Now I get:
$ cabal v2-test -w ghc-8.6.4
Build profile: -w ghc-8.6.4 -O1
In order, the following will be built (use -v for more details):
- ghcide-0.0.2 (test:ghcide-tests) (file test/exe/Main.hs changed)
Preprocessing test suite 'ghcide-tests' for ghcide-0.0.2..
Building test suite 'ghcide-tests' for ghcide-0.0.2..
test/exe/Main.hs:507:0: error:
error: missing binary operator before token "("
#if MIN_GHC_API_VERSION(8,6,0)
|
507 | #if MIN_GHC_API_VERSION(8,6,0)
| ^
test/exe/Main.hs:521:0: error:
error: missing binary operator before token "("
#if MIN_GHC_API_VERSION(8,6,0)
|
521 | #if MIN_GHC_API_VERSION(8,6,0)
| ^
`cc' failed in phase `C pre-processor'. (Exit code: 1)
What am I missing?
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.
Oh I see what’s going on here. We rely on the MIN_VERSION
pragmas which only exist if you depend on ghc
which the test suite does not atm. Not quite sure what a nice solution would be but for now, just adding a dependency on ghc
is not that bad.
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.
Thanks, that solves the problem.
Where shall I document the ghc-dependence in the tests? Comment in the cabal file itself?
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.
Yeah I think a comment in the cabal file should be sufficient, thank you!
test/exe/Main.hs
Outdated
, check "replace hole `_c` with globalInt" | ||
"_a" "_b" "_c" | ||
"_a" "_b" "globalInt" | ||
] <> if versionBranch compilerVersion < [8,6] then [] else |
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.
Same here, this should also use MIN_GHC_API_VERSION
.
As for nicer ways of doing the string matching, I’m definitely not opposed to using a parser library (but I would prefer Definitely not something for this PR but if someone wants to give it a shot I’d certainly be interested in whether it ends up being cleaner (I hope it does). |
Useful if more than one hole appears on the same line. Not so useful if both of these holes are just `_` rather than `_name` (or more than one hole on the same line has the same `_name`): In which case perhaps some numbers could be attached to the action titles, to distinguish the holes. But I suspect that this would not be worth the effort.
These test hints about local bindings, whic GHC 8.4 does not provide.
510f478
to
cec1323
Compare
cec1323
to
cebaadb
Compare
It seems to have passed CI, though I am confused by the hlint output, which includes stuff like:
|
Ah, it looks like we need to pass |
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.
Thanks a lot @jacg!
Correct, Ben and I have been discussing various approaches for this and I will in fact soon write a proposal for a design that we settled on with lots of useful inputs from Richard Eisenberg and Neil (Mitchell). One of its goals will be to make the life of IDE-style tooling devs a lot easier, essentially doing away with the need to parse GHC's messages, instead getting good old Haskell values to manipulate, inspect, use and print. I can perhaps ping the ghcide team and you Ganesh, once I have something in a reviewable state, if some of you would like to give some feedback. |
* Add code action for filling type holes * Incorporate hole name into action title Useful if more than one hole appears on the same line. Not so useful if both of these holes are just `_` rather than `_name` (or more than one hole on the same line has the same `_name`): In which case perhaps some numbers could be attached to the action titles, to distinguish the holes. But I suspect that this would not be worth the effort. * Add tests for fill-type-hole actions * Disable two tests on GHC 8.4 These test hints about local bindings, whic GHC 8.4 does not provide. * Replace compilerVersion with new MIN_GHC_API_VERSION macro
* Add code action for filling type holes * Incorporate hole name into action title Useful if more than one hole appears on the same line. Not so useful if both of these holes are just `_` rather than `_name` (or more than one hole on the same line has the same `_name`): In which case perhaps some numbers could be attached to the action titles, to distinguish the holes. But I suspect that this would not be worth the effort. * Add tests for fill-type-hole actions * Disable two tests on GHC 8.4 These test hints about local bindings, whic GHC 8.4 does not provide. * Replace compilerVersion with new MIN_GHC_API_VERSION macro
* Add code action for filling type holes * Incorporate hole name into action title Useful if more than one hole appears on the same line. Not so useful if both of these holes are just `_` rather than `_name` (or more than one hole on the same line has the same `_name`): In which case perhaps some numbers could be attached to the action titles, to distinguish the holes. But I suspect that this would not be worth the effort. * Add tests for fill-type-hole actions * Disable two tests on GHC 8.4 These test hints about local bindings, whic GHC 8.4 does not provide. * Replace compilerVersion with new MIN_GHC_API_VERSION macro
Add code actions which replace typed holes, using GHC's "Relevant bindings include" hints.