rikvdkleij / intellij-haskell

IntelliJ plugin for Haskell
https://rikvdkleij.github.io/intellij-haskell/
Apache License 2.0
1.32k stars 94 forks source link

Extract variable/function #414

Open sir4ur0n opened 5 years ago

sir4ur0n commented 5 years ago

Kind of similar (or subset of) #85 : it would be reaaaaaaaaaaally good to be able to extract variable/function.

These features are amazingly useful in Java development and would be, too, in Haskell.

Ideas:

Note the option for function extraction would be useless if we had an option to add signature to an existing function.

Is such a thing possible?

rikvdkleij commented 5 years ago

Note the option for function extraction would be useless if we had an option to add signature to an existing function.

I do not understand this remark, there is an option to add type signature to function but it depends on -Wall

rikvdkleij commented 5 years ago

I think something is doable by selection an expression and extracting that to a function.

The biggest issue is that (what I already mentioned a couple of times in issues) is that the parser is not layout sensitive. So for example, a where clause is not identifiable. cc @ice1000

rikvdkleij commented 5 years ago

I do not understand this remark, there is an option to add type signature to function but it depends on -Wall

It is possible to make this a action which is always available when function has no type signature.

sir4ur0n commented 5 years ago

I do not understand this remark, there is an option to add type signature to function but it depends on -Wall

This is not enough. This also provides a quickfix for top-level bindings. It doesn't provide a way to add type info on bindings inside let or where bindings. It also doesn't provide the feature for packages with configuration -fno-warn-missing-signatures (which is common for test package).

foo :: Integer
foo =
  -- How do I add type information for a?
  let a = 42
   in a

{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
test_foo = testProperty "Foo" $ \a -> 
  -- How do I add type information for b?
  let b = SUT.myFunction a
   in b === 42
rikvdkleij commented 5 years ago

It doesn't provide a way to add type info on bindings inside let or where bindings.

That's not possible with the current parser.

rikvdkleij commented 5 years ago

So, I think it is possible to select an expression and extract that to a function.

See com.intellij.refactoring.actions.ExtractMethodAction and com.intellij.refactoring.extractMethod.ExtractMethodHandler

@Sir4ur0n Maybe you can implement this?

sir4ur0n commented 5 years ago

Thanks for the pointers, I'll try to take a look in the coming days. I hope the Intellij API for method/variable extraction is better documented than test creation/navigation one 😢

ice1000 commented 5 years ago

I have to say with the current parser, extract method refactoring is almost impossible. I hope I'm wrong and I'm looking forward to see a nice implementation.

rikvdkleij commented 5 years ago

I hope the Intellij API for method/variable extraction is better documented than test creation/navigation one 😢

Sorry to say no, you have to look the code.

rikvdkleij commented 5 years ago

I have to say with the current parser, extract method refactoring is almost impossible.

I think it is only doable by selecting an expression.

sir4ur0n commented 5 years ago

It seems that part of the problem is: nothing is parsed as a PsiExpression by the parser. Everythin is just a PsiElement. ExtractMethodHandler expects the part being extracted to be a PsiExpression (which kind of makes sense). Any idea why the parser doesn't parse anything as a PsiExpression? Is it something that could be added/enhanced in the parser? No clue how the parsing bit works, sorry.

ice1000 commented 5 years ago

PsiExpression is Java specific

ice1000 commented 5 years ago

Is it something that could be added/enhanced in the parser? No clue how the parsing bit works, sorry.

There's HaskellExpression