FrigoEU / psc-ide-vim

Vim plugin for psc-ide
96 stars 36 forks source link

Can't get inferred type of declarations in current module #122

Closed andreasthoelke closed 6 years ago

andreasthoelke commented 7 years ago

After updating to the newest versions of psc-ide-vim, purescript@0.11.7 and pulp@12.0.1, I’m no longer able to use Ptype.

When I create a fresh project with pulp init, I can run :Pload and :Prebuild successfully, but if I run :Ptype main in Main.purs I get “No type information found for main”. (:Ptype log works fine on the other hand/ gets me the type of the imported log function)

Debug output when running :Ptype main:

purescript#ide#callSync: command: {"params": {"file": "/Users/andreas.thoelke/Documents/purescript/hello1/src/Main.purs", "type": "import"}, "command": "list"}

purescript#ide#callSync: trying to reach server again s:callFn: response: "{\"result\":{\"moduleName\":\"Main\",\"imports\":[{\"importType\":\"implicit\",\"module\":\"Prelude\"},{\"importType\":\"explicit\",\"identifiers\":[\"Eff\"],\"module\":\"Control.Monad.Eff\"},{\"importType\":\"explicit\",\"identifiers\":[\"CONSOLE\",\"log\"],\"module\":\"Control.Monad.Eff.Console\"}]},\"resultType\":\"success\"}\n"

PSCIDE purescript#ide#import#listImports result: {'result': {'moduleName': 'Main', 'imports': [{'module': 'Prelude', 'importType': 'implicit'}, {'module': 'Control.Monad.Eff', 'identifiers': ['Eff'], 'importType': 'explicit'}, {'module': 'Control.Monad.Eff.Console', 'identifiers': ['CONSOLE', 'log'], 'importType': 'explicit'}]}, 'resultType': 'success'}

PSCIDE s:getType currentModule: Main purescript#ide#call: command: {"params": {"currentModule": "Main", "search": "main", "filters": [{"filter": "modules", "params": {"modules": ["Prelude"]}}]}, "command": "type"} s:callFn: response: ["{\"result\":[],\"resultType\":\"success\"}", ""] purescript#ide#callSync: command: {"params": {"file": "/Users/andreas.tho...ts/purescript/hello1/src/Main.purs", "type": "import"}, "command": "list"} purescript#ide#callSync: trying to reach server again s:callFn: response: "{\"result\":{\"moduleName\":\"Main\",\"imports\":[{\...\"module\":\"Control.Monad.Eff.Console\"}]},\"resultType\":\"success\"}\n"

PSCIDE purescript#ide#import#listImports result: {'result': {'moduleName'... ['CONSOLE', 'log'], 'importType': 'explicit'}]}, 'resultType': 'success'}

PSCIDE s:getType currentModule: Main purescript#ide#call: command: {"params": {"currentModule": "Main", "searc... "Control.Monad.Eff", "Control.Monad.Eff.Console"]}}]}, "command": "type"}

s:callFn: response: ["{\"result\":[],\"resultType\":\"success\"}", ""] purs ide: no type information found for main

andreasthoelke commented 6 years ago

I've looked into this a bit more.

If I call :call PSCIDEtype('main', v:false), I get this in the logs:

s:getType currentModule: Main purescript#ide#call: command: {"params": {"currentModule": "Main", "search": "main", "filters": [{"filter": "modules", "params": {"modules": ["Prelude", "Control.Monad.Eff", "Control.Monad.Eff.Console"]}}]}, "command": "type"}

s:callFn: response: ["{\"result\":[],\"resultType\":\"success\"}", ""] purs ide: no type information found for main

It seems that purs ide needs the current module (Main in this case) to be included in the filter - modules list, while currently it's missing: {"modules": ["Prelude", "Control.Monad.Eff", "Control.Monad.Eff.Console"]}.

I could think of two ways to fix this in the s:getType function:

  1. Add the current module to the modules list here: https://github.com/FrigoEU/psc-ide-vim/blob/23bf302de91181d409fb988ce372ab703b119bc5/ftplugin/purescript_pscide.vim#L699

  2. Don't pass a filter to the type command, when PSCIDEtype is called with filterModules = v:false, e.g.: purescript#ide#callSync( {'command': 'type', 'params': {'search': 'main', 'filters': [], 'currentModule': 'Main'}, }, '', 0, ) ).

I noticed that, when using Ptype, s:getType get's called with filterModules = v:true first, which produces a filter - modules list of merely [Prelude]. As this will fail to return a type for the main function, s:getType will be called again, this time with filterModules = v:false.

I'm probably getting this wrong, but from what I can see, using {"modules": ["Main", "Prelude", "Control.Monad.Eff", "Control.Monad.Eff.Console"]} would make sense for s:getType/filterModules = v:true and using no filter ('filters': []) would make sense for s:getType/filterModules = v:false.

I changed s:getType accordingly:

function! s:getType(ident, filterModules, cb)
  let currentModule = purescript#ide#utils#currentModule()

  if a:filterModules
    let [ident, qualifier] = purescript#ide#utils#splitQualifier(a:ident)
    let imports = purescript#ide#import#listImports(currentModule, qualifier, "")
    let modules = map(copy(imports), {key, val -> val["module"]})
    let filters = [purescript#ide#utils#modulesFilter( add(modules, currentModule) )]
  else
    let filters = []
  endif

  call purescript#ide#utils#debug('PSCIDE s:getType currentModule: ' . currentModule, 3)

  call purescript#ide#call(
    \ { 'command': 'type'
    \ , 'params':
    \     { 'search': ident
    \     , 'filters': filters
    \     , 'currentModule': currentModule
    \     }
    \ },
    \  'Failed to get type info for: ' . a:ident,
    \ 0,
    \ {resp -> a:cb(resp)}
    \ )
endfunction

Things seem to work with a small project/at first glance then.

andreasthoelke commented 6 years ago

@kRITZCREEK sent a reference to the emacs equivalent of s:getType in Slack:

https://github.com/epost/psc-ide-emacs/blob/633b07b238aff51dc4b95a75c67910a18ba28da1/psc-ide.el#L625-L661

However I can't spot where this includes the current module in the filter modules list either. So I guess I'm still confused about this: When I run a type command like this:

purescript#ide#callSync( {'command': 'type',
                                         \'params': {'search': 'main',
                                         \           'filters': [{"filter": "modules", "params": {"modules": ["Prelude", "Control.Monad.Eff", "Control.Monad.Eff.Console"]}}],
                                         \           'currentModule': 'Main'}, }, '', 0, ) )

I don't get the type of main. If however I add Main to "modules": ["Main", "Prelude".., the command does return the type of main.

On a related note, I can see that the emacs implementation adds Prim to the filter modules:

https://github.com/epost/psc-ide-emacs/blob/633b07b238aff51dc4b95a75c67910a18ba28da1/psc-ide.el#L651

But I can't see what effect this has: Running 'search': 'true' does not yield a type, while a declaration test = true and 'search': 'test' returns Boolean regardless of whether Prim is in "modules": ["Prim",.. or not.

andreasthoelke commented 6 years ago

113 is the same issue. I somehow overlooked this before.

coot commented 6 years ago

Lets just add the current module to the list.