ghc-mod icon indicating copy to clipboard operation
ghc-mod copied to clipboard

adding ghcjs type inference to ghc-mod

Open nrolland opened this issue 8 years ago • 19 comments

Hi,

Luite added some support for retrieving ghc-mod kind of information from GHCJS project here (commit 1) (single GHCJS entry point refactor)

A file containing GHCJS specific code

{-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-}
{-# LANGUAGE JavaScriptFFI, CPP #-}

module Main where

import qualified GHCJS.Types   as T
import GHCJS.Foreign
import Data.JSString

foreign import javascript safe  "console.log($1);"
    printThis       :: T.JSString -> IO ()


main :: IO ()
main = printThis "Hello World" 

can then be queried

$ ./ghc-mod/.stack-work/dist/x86_64-osx/Cabal-1.22.4.0/build/ghc-mod/ghc-mod  type helloWorldJS.hs 15 20
15 18 15 31 "JSString"
15 8 15 31 "IO ()"
15 1 15 31 "IO ()"

whereas it currently fails with

$ ghc-mod type helloWorldJS.hs 15 20
EXCEPTION: types:
           Could not find module ‘GHCJS.Types’
           Perhaps you meant GHC.Types (from ghc-prim-0.4.0.0)
           Use -v to see a list of the files searched for.
           Could not find module ‘GHCJS.Foreign’
           Perhaps you meant GHC.Foreign (from base-4.8.1.0)
           Use -v to see a list of the files searched for.
           Could not find module ‘Data.JSString’
           Perhaps you meant Data.String (from base-4.8.1.0)
           Use -v to see a list of the files searched for.

This works on a particular file, with hard coded instructions. How would it be best integrated in ghc-mod ?

nrolland avatar Oct 13 '15 15:10 nrolland

Oh boy, I knew this request would come in at some point ;)

I really don't know enough about ghcjs to be able to say what needs doing exactly.

So essentially we can just link against ghcjs instead of ghc, replace a few references to ghc* programs here and there and we should be fine, right? right, that's what it looks like fork you linked is doing. cabal-helper might need some hacks too? Not sure how much of this Cabal abstracts away from us.

If @luite were to say submit a WIP PR I'd be happy to point out the bits that need changing for integration hint hint.

Just to say this is also going to make the problem with ghc-mod having to be compiled agains just the right version/variant of ghc much more problematic so we'll probably want to look at https://github.com/kazu-yamamoto/ghc-mod/issues/615 as well.

DanielG avatar Oct 13 '15 19:10 DanielG

I used my tachyon drive to go two days back in time and do a proof of concept to show how the GHC API should be set up for GHCJS and also pushed a change to the GHCJS library to make it easier and more future proof. Code here:

https://github.com/luite/ghc-mod/tree/ghcjs-support-hack

There is no front end, this hardcodes GHCJS, if a package has been configured for GHC instead, the package ids will be unknown. I guess some code to specify the preferred compiler and also detect any configured compiler flavour should be added.

luite avatar Oct 13 '15 19:10 luite

Just to be clear, pretty much everything is still GHC, the ghc package is still needed, but the session is changed to use the GHCJS compilation settings, which means different default package db locations, overriding foreign import checking (with the JavaScriptFFI extension enabled) and some changes in baked in types.

I don't know if there are other things that break here, but the basics seem to work with this patch.

luite avatar Oct 13 '15 19:10 luite

What needs to be done for this patch to be integrated in ghc-mod?

meditans avatar Mar 10 '16 11:03 meditans

ghc-mod would need to know whether to typecheck a project with ghc or with ghcjs. I think this would mean either adding the logic to detect the configured compiler for a project, or perhaps some command line option to specify one.

luite avatar Mar 10 '16 18:03 luite

Oh that's no problem at all we can derive that from cabal's setup-config. The problem is more architectural since a ghc-mod built using ghc but linked against ghcjs would only work with ghcjs projects and we currently don't have a way to switch compilers. See https://github.com/DanielG/ghc-mod/issues/615

DanielG avatar Mar 10 '16 19:03 DanielG

@DanielG the alternative is littering GHC code with equivalent to ghcjs code using undefined and pragma. switching binary once is a very mild operation in comparison

nrolland avatar Mar 10 '16 22:03 nrolland

Oh yeah sure, I'm not suggesting we link against ghc and ghcjs at the same time. I'm merely pointing out that we don't have any dispatch logic anywhere to handle this sort of compiler switch gracefully.

DanielG avatar Mar 11 '16 12:03 DanielG

yeah, that's nothing given the upshot. just switch the binary by hand once. it'd be nice to have https://github.com/DanielG/ghc-mod/issues/615, but one can do without and is a separate issue

nrolland avatar Mar 11 '16 14:03 nrolland

I suppose but that's just not a very nice user experience.

Anyways in the meantime I see no reason we can't at least add support for this so feel free to shoot a PR and we can discuss the nitty gritty there.

DanielG avatar Mar 11 '16 18:03 DanielG

Sure but who knows how many people want that feature ? Not knowing the amount of interest, why would someone spend effort on this and not something else. that's a typical example where https://github.com/DanielG/ghc-mod/issues/676 would help

nrolland avatar Mar 13 '16 11:03 nrolland

Well how about you create a new issue titled "Poll: Add ghcjs support to ghc-mod" and post a link to that to reddit and maybe haskell-cafe and just let people comment on it? I still don't see why we need another forum type thing to do this. I mean github even has thumbs up and down buttons now that don't count as comments.

DanielG avatar Mar 13 '16 11:03 DanielG

sure we could do that. But baring such a system of vote we just don't know

nrolland avatar Mar 13 '16 21:03 nrolland

@DanielG could you point out what would be the simplest (from the perspective of the implementer) way to get ghc-mod to work with ghcjs, even if this means swapping binaries? I'd like to think about it when I have a couple of days.

As for the issue in general, @nrolland, I think this is one of the best new features ghc-mod could provide (there is also a ghci-js in the recent versions of ghcjs, so the dream would be to get equal tooling).

meditans avatar Apr 18 '16 14:04 meditans

I dunno you'd have to ask @luite, I see no reason not to use that patch as a basis though if it works. Actually looking at it now I think I didn't realize before that ghcjs is an additional dependency rather than a replacement for ghc proper. @luite am I right in assuming ghcjs itself links against ghc? If so this should actually all be rather easy and not even require any bin-switching. We can just add a Cabal flag to ghc-mod to turn the ghcjs dependency on and off and compile it in or not depending.

So with that in mind we just have to solve, at runtime, the problem of which session bringup to use for a project. I suppose we can add a commandline flag --ghcjs, --with-compiler=ghcjs for the general case (plain and cabal-sandbox project types) and autodetect logic for Cabal projects (I think that should cover both Stack and just-Cabal).

For the autodetection all that needs to be done is adding support for getting information out of the compiler field from LocalBuildInfo to cabal-helper which should be trivial to implement (CompilerFlavor is the relevant field in there so we can differentiate between GHC and GHCJS).

Oh! Actually. I already did that:

cabal-helper-wrapper . dist compiler-version
[Just (ChResponseVersion "GHC" (Version {versionBranch = [7,10,3], versionTags = []}))]

http://hackage.haskell.org/package/cabal-helper-0.6.3.1/docs/Distribution-Helper.html#v:compilerVersion

So really all that needs to be done is adding the hookup logic in ghc-mod: https://github.com/DanielG/ghc-mod/blob/master/Language/Haskell/GhcMod/CabalHelper.hs

It wont fit in right away since currently it only has a concept of per-component information but it should be easy to add this check nonetheless.

DanielG avatar Apr 19 '16 11:04 DanielG

@meditans The only issue, as laid out previously here in #676, is that we don't know how many people are interested in this functionality. for all we know, people might be ready to pay to have that done. It's been a concern since at least 2014 https://github.com/ghcjs/ghcjs/issues/271 and people are still asking : 24days ago https://github.com/DanielG/ghc-mod/issues/782 ) 11 days ago http://stackoverflow.com/questions/37173514/does-ghc-mod-support-ghcjs

Having a way to jauge the importance of a feature, like uservoice or anything similar, is crucial to start organizing

nrolland avatar May 24 '16 13:05 nrolland

Will this be implemented?

michaelmesser avatar Jul 31 '16 22:07 michaelmesser

During MuniHac me and @meditans figured out that in addition to what I said above we need to have cabal-helper handle using either Distribution.Simple.GHC or Distribution.Simple.GHCJS to get the rendered options (and maybe other things) though both use Distribution.Simple.GHC.Internal so exactly how much needs to be changed still remains to be seen.

Other than that the only change to ghc-mod's dealing with GHC that needs to happen would be around https://github.com/DanielG/ghc-mod/blob/master/Language/Haskell/GhcMod/Target.hs#L173 where the DynFlags are initialized.

Furthermore @luite suggested that we should just treat ghcjs as a separate compiler "version" for the purpose of co-installing a ghcjs version of ghc-mod with a regular GHC one even though ghcjs is built on top of GHC itself so technically we could support ghcjs and regular GHC in one executable. This is due to the possibility of a temporary fork of the GHC library happening as needed to move ghcjs forward though the overall plan is to upstream it into GHC eventually.

DanielG avatar Sep 04 '16 18:09 DanielG

FYI the coinstall stuff has moved moved forward since my last post here, see https://github.com/DanielG/ghc-mod/issues/615#issuecomment-309964717. It's time for someone interested in this feature to start thinking about how to detect and dispatch to the correct ghc-mod copy so this can be taken into account in the design of the GHC-version-detecting dispatcher/wrapper.

DanielG avatar Jun 21 '17 05:06 DanielG