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

Upgrade to new version of lsp libraries #2494

Merged
merged 7 commits into from
Dec 29, 2021
Merged

Upgrade to new version of lsp libraries #2494

merged 7 commits into from
Dec 29, 2021

Conversation

michaelpj
Copy link
Collaborator

@michaelpj michaelpj commented Dec 16, 2021

Don't look here (except @jneira), just for CI.

This branch has the new version pulled in by source-repository-package. We could merge it that way, or we could wait until we do a lsp release, which is desirable anyway.

@michaelpj
Copy link
Collaborator Author

I'll squash all these and tidy up before merging, once this works.

@jneira
Copy link
Member

jneira commented Dec 17, 2021

I would release LSP and changing this to use it before merge, as final sanity check over the released version (the bump of hackage index could change the behaviour)

@jneira
Copy link
Member

jneira commented Dec 17, 2021

wow

Exception: 

Row number out of bounds: 2644896934/0 

CallStack (from HasCallStack): 

error, called at test/exe/Main.hs:6383:26 in main:Main 

Exception thrown while showing test case: 

Row number out of bounds: 2644896934/0 

CallStack (from HasCallStack): 

error, called at test/exe/Main.hs:6383:26 in main:Main

@jneira
Copy link
Member

jneira commented Dec 17, 2021

2644896934

Obviusly that exceeds the max bound for Word32/Int32: 2147483647

@michaelpj
Copy link
Collaborator Author

Exciting.

@jneira
Copy link
Member

jneira commented Dec 17, 2021

It is due to quickcheck using arbitrary instances for a numeric type bigger than Word32:

, adjustOption (\(QuickCheckTests i) -> QuickCheckTests (max 1000 i)) $ testGroup "properties"
[ testProperty "fromCurrent r t <=< toCurrent r t" $ do
-- Note that it is important to use suchThatMap on all values at once
-- instead of only using it on the position. Otherwise you can get
-- into situations where there is no position that can be mapped back
-- for the edit which will result in QuickCheck looping forever.
let gen = do
rope <- genRope
range <- genRange rope
PrintableText replacement <- arbitrary
oldPos <- genPosition rope
pure (range, replacement, oldPos)
forAll
(suchThatMap gen
(\(range, replacement, oldPos) -> positionResultToMaybe $ (range, replacement, oldPos,) <$> toCurrent range replacement oldPos)) $
\(range, replacement, oldPos, newPos) ->
fromCurrent range replacement newPos === PositionExact oldPos
, testProperty "toCurrent r t <=< fromCurrent r t" $ do
let gen = do
rope <- genRope
range <- genRange rope
PrintableText replacement <- arbitrary
let newRope = applyChange rope (TextDocumentContentChangeEvent (Just range) Nothing replacement)
newPos <- genPosition newRope
pure (range, replacement, newPos)
forAll
(suchThatMap gen
(\(range, replacement, newPos) -> positionResultToMaybe $ (range, replacement, newPos,) <$> fromCurrent range replacement newPos)) $
\(range, replacement, newPos, oldPos) ->
toCurrent range replacement oldPos === PositionExact newPos
]

@jneira
Copy link
Member

jneira commented Dec 17, 2021

I think i have a fix

@jneira
Copy link
Member

jneira commented Dec 17, 2021

Why do you want runtime errors from dynamic types if you can have them with pesky type classes? :-P

@michaelpj
Copy link
Collaborator Author

Hang on, I'm fixing a bunch of these.

@michaelpj
Copy link
Collaborator Author

I did a different fix, oops 😅

@michaelpj
Copy link
Collaborator Author

Releasing the lock for a bit now!

Honestly, the fromIntegral :: Int -> Word32 conversions are kind of dodgy. Maybe we should use some function that checks, or rounds to 0 or something.

@michaelpj
Copy link
Collaborator Author

I also wonder about having an IntegralPosition pattern synonym or something.

@jneira
Copy link
Member

jneira commented Dec 17, 2021

Releasing the lock for a bit now!

Honestly, the fromIntegral :: Int -> Word32 conversions are kind of dodgy. Maybe we should use some function that checks, or rounds to 0 or something.

well i checked manually the inputs for nthLine to ensure they were always in (0, maxBound :: Word32) and not sure what would be the sensible option, i guess we will want round for some and error for others 🤷

@michaelpj
Copy link
Collaborator Author

It's not nthLine that I'm worried about. e.g there was a test that maybe some CPP preprocessor errors come back from GHC with column -1, which just wraps 😱 There are lots of conversions everywhere we make a Postion...

@jneira
Copy link
Member

jneira commented Dec 17, 2021

Ugh so ghc can return negative values as i vaguely remebered 🤦

@michaelpj
Copy link
Collaborator Author

In some ways this is good though: I believe technically a lsp client could simply have refused to parse a message where the position had a negative value, now we're forced to deal with it earlier.

@michaelpj
Copy link
Collaborator Author

Tests seem to pass... windows builds hanging (?) as usual.

@jneira
Copy link
Member

jneira commented Dec 17, 2021

the stack build is failing due to unused imports:

haskell-language-server > /root/build/test/functional/TypeDefinition.hs:7:1: error: [-Wunused-imports, -Werror=unused-imports] haskell-language-server > The import of ‘Data.Word’ is redundant haskell-language-server > except perhaps to import instances from ‘Data.Word’ haskell-language-server > To import instances alone, use: import Data.Word() haskell-language-server > | haskell-language-server > 7 | import Data.Word haskell-language-server > | ^^^^^^^^^^^^^^^^ haskell-language-server > -- While building package haskell-language-server-1.5.1.0 (scroll up to its section to see the error) using: /root/.stack/setup-exe-cache/x86_64-linux/Cabal-simple_mPHDZzAJ_3.2.1.0_ghc-8.10.6 --builddir=.stack-work/dist/x86_64-linux/Cabal-3.2.1.0 build lib:haskell-language-server exe:haskell-language-server exe:haskell-language-server-wrapper test:func-test test:wrapper-test --ghc-options " -fdiagnostics-color=always" Process exited with code: ExitFailure 1 Exited with code exit status 1 

@michaelpj
Copy link
Collaborator Author

We fail on unused imports in some builds but not others? oy vey.

@jneira
Copy link
Member

jneira commented Dec 17, 2021

ya inconsistent, I would make cabal ones stricter

@@ -79,7 +79,7 @@ realSrcSpanToRange real =

realSrcLocToPosition :: RealSrcLoc -> Position
realSrcLocToPosition real =
Position (srcLocLine real - 1) (srcLocCol real - 1)
Position (fromIntegral $ srcLocLine real - 1) (fromIntegral $ srcLocCol real - 1)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will currently wrap. Should we do something else here? Like take max 0 first?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah not sure if we have another sensible alternative?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. I think either let it wrap or max with 0.

-- In the lsp spec from 3.16 Position takes a uinteger,
-- where uinteger is 0 - 2^31 - 1. lsp-types currently has the type of line
-- as Int. So instead of using `maxBound :: Int` we hardcode the maxBound of
-- uinteger. 2 ^ 31 - 1 == 2147483647
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh. I think this means I got it wrong: uinteger according to the LSP specification is not, in fact a 32-bit unsigned integer, but a 31-bit unsigned integer. Presumably because it's actually a 32-bit signed integer that they just restrict to be positive. Terrible. I don't even know what to do about that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made them an issue: microsoft/language-server-protocol#1394

But in the short term this kind of sucks...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I can go back and use a custom type instead of Word32 in lsp, sigh.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, but we can go ahead with this lsp version? or you want to redefine the type in lso before the release
I guess we can continue using the hardcoded maxBound?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice not to release a version of lsp that disruptively requires people to change their code and then doesn't even fix the problem :(

I think the best thing might be to change to a custom type in lsp indeed. It shouldn't affect this PR too much. Either that or we should just revert the change in lsp.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm but if we use UInt31 in LSP with all the required intances, including from integral, would no be matter of replacing Word32 with UInt31 here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's basically it. I just need to do it. I'll try and find time tomorrow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe with a more generic name like LSPUInt? not sure if the data type could even change in the spec but I can imagine it could be bigger

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cabal-ghc901.project Outdated Show resolved Hide resolved
@jneira
Copy link
Member

jneira commented Dec 24, 2021

So this needs the change to use the new UInt31 from lsp

@michaelpj
Copy link
Collaborator Author

Yes, and I was going to try and remove the dependent-map dependency from lsp and then we could do a release.

@Bodigrim
Copy link
Contributor

Yes, and I was going to try and remove the dependent-map dependency from lsp and then we could do a release.

haskell/lsp#384 awaits for review.

@jneira
Copy link
Member

jneira commented Dec 28, 2021

I have the stack.yamls changed to use a recent commit and they works here #2551

michaelpj and others added 4 commits December 28, 2021 17:37
This is not only for faster completions.
 It's also needed to have semi-fresh completions after editing.
This is specially important for the first completion request of a file - without this change there are no  completions available at all
useful to synchonize on these events in tests
Copy link
Member

@jneira jneira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm many thanks for working on this

@jneira
Copy link
Member

jneira commented Dec 28, 2021

9.0.1 is not picking the new index state

Warning: Requested index-state 2021-12-29T12:30:08Z is newer than 

'hackage.haskell.org'! Falling back to older state (2021-12-24T16:25:00Z).

🤔

@michaelpj
Copy link
Collaborator Author

Yeah, it seems like it's not calling cabal update and I don't know why. #2536 removed a bunch of cabal update calls which seems suspicious.

@michaelpj michaelpj marked this pull request as ready for review December 28, 2021 17:58
@michaelpj michaelpj changed the title WIP: upgrade to new version of lsp libraries Upgrade to new version of lsp libraries Dec 28, 2021
@jneira
Copy link
Member

jneira commented Dec 28, 2021

ugh we removed it cause the Haskell action seemed to do it, but maybe not in all cases
/cc @Anton-Latukha

@jneira
Copy link
Member

jneira commented Dec 28, 2021

hmm, is it related with the lsp changes? maybe with the drop of dependent-sum?


src/Ide/Types.hs:302:37: error:
Error:     • Could not deduce (GEq SMethod) arising from a use of ‘geq’
      from the context: PluginMethod a
        bound by a pattern with constructor:
                   IdeMethod :: forall (m :: Method 'FromClient 'Request).
                                PluginMethod m =>
                                SMethod m -> IdeMethod m,
                 in an equation for ‘geq’
        at src/Ide/Types.hs:302:8-18
      or from: PluginMethod b
        bound by a pattern with constructor:
                   IdeMethod :: forall (m :: Method 'FromClient 'Request).
                                PluginMethod m =>
                                SMethod m -> IdeMethod m,
                 in an equation for ‘geq’
        at src/Ide/Types.hs:302:22-32
    • In the expression: geq a b
      In an equation for ‘geq’: geq (IdeMethod a) (IdeMethod b) = geq a b
      In the instance declaration for ‘GEq IdeMethod’
    |
302 |   geq (IdeMethod a) (IdeMethod b) = geq a b
    |                                     ^^^^^^^

@Bodigrim
Copy link
Contributor

@jneira try cabal update now?

@Anton-Latukha
Copy link
Collaborator

Anton-Latukha commented Dec 28, 2021

#2494 (comment)

Yes.

I pretty much was wondering when Action particularly runs update. But there is too much layers I do not know enough info to say particularly. If to believe if switch in https://github.com/haskell/actions/blob/a64ac8cca0d4aec4e3fd4a5fbc9ae3c4953e20aa/setup/src/setup-haskell.ts#L75, if (!opts.stack.enable) await exec('cabal update'); implies it runs when stack is not in use & we declare that explicitly. But Action also does not say anything when it updates, does not produces the index-state information.
Then Action code & process as a whole, I know GitHub Actions infrastructure does some caching, but it is not known (for proprietary reasons) when & how. But also index updates happen rarely & it is rare for index-state needed to be required which is after update. So was wondering is it safe to remove additional update or not, but in complex cases with have small consequences I tend to believe the code. And I honestly did not had another way to model & test all this process but to try it, so that is on me.

Also after all this only today noted that Action does not use the latest ghcup, so I do not know enough about how haskell/actions/setup works, and it also seems to stay unmaintained.

We also had the typo that borked (which is seen in) the freeze caching key structure #2549 (comment) (but thankfully we made so everything falls-back into the simpler procedure in that case).

In any case, if there is now some kind of error - it probably may be the rm of update & I do not have particular feels about it the other way, just wanted to shave a step from the config & the CI runs. Sorry for the inconvinience.

@jneira
Copy link
Member

jneira commented Dec 29, 2021

@jneira try cabal update now?

after merging master CI succeeded, not sure why (have to take a deeper look)

@jneira jneira merged commit 7518a3a into master Dec 29, 2021
drsooch pushed a commit to drsooch/haskell-language-server that referenced this pull request Dec 29, 2021
* Update to latest version of lsp libraries

* Compute completions on kick

This is not only for faster completions.
 It's also needed to have semi-fresh completions after editing.
This is specially important for the first completion request of a file - without this change there are no  completions available at all

* Emit LSP custom messages on kick start/finish

useful to synchonize on these events in tests

* Fix completions tests after haskell/lsp#376

* Restore cabal update with comments

* Use new lsp in stack 9.0.1

Co-authored-by: Pepe Iborra <[email protected]>
Co-authored-by: jneira <[email protected]>

fix merge failure
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.

5 participants