Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit cd3494c

Browse files
committed
Add documentation for hsimport plugin
1 parent 3350686 commit cd3494c

File tree

1 file changed

+67
-10
lines changed

1 file changed

+67
-10
lines changed

src/Haskell/Ide/Engine/Plugin/HsImport.hs

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,35 @@ hsimportDescriptor plId = PluginDescriptor
4141
, pluginFormattingProvider = Nothing
4242
}
4343

44+
-- | Type of the symbol to import.
45+
-- Important to offer the correct import list, or hiding code action.
4446
data SymbolType
45-
= Symbol
46-
| Constructor
47-
| Type
47+
= Symbol -- ^ Symbol is a simple function
48+
| Constructor -- ^ Symbol is a constructor
49+
| Type -- ^ Symbol is a type
4850
deriving (Show, Eq, Generics.Generic, ToJSON, FromJSON)
4951

5052

5153
-- | What of the symbol should be taken.
54+
-- Import a simple symbol, or a value constructor.
5255
data SymbolKind
53-
= Only SymbolName -- ^ only the symbol should be taken
54-
| AllOf DatatypeName -- ^ all constructors or methods of the symbol should be taken: Symbol(..)
55-
| OneOf DatatypeName SymbolName -- ^ some constructors or methods of the symbol should be taken: Symbol(X, Y)
56+
= Only SymbolName -- ^ Only the symbol should be taken
57+
| OneOf DatatypeName SymbolName -- ^ Some constructors or methods of the symbol should be taken: Symbol(X)
58+
| AllOf DatatypeName -- ^ All constructors or methods of the symbol should be taken: Symbol(..)
5659
deriving (Show, Eq, Generics.Generic, ToJSON, FromJSON)
5760

58-
-- | The imported or from the import hidden symbol.
61+
-- | Disambiguates between an import action and an hiding action.
62+
-- Can be used to determine suggestion tpye from ghc-mod,
63+
-- e.g. whether ghc-mod suggests to hide an identifier or to import an identifier.
64+
-- Also important later, to know how the symbol shall be imported.
5965
data SymbolImport a
6066
= Import a -- ^ the symbol to import
6167
| Hiding a -- ^ the symbol to hide from the import
6268
deriving (Show, Eq, Generics.Generic, ToJSON, FromJSON)
6369

6470

71+
-- | Utility to retrieve the contents of the 'SymbolImport'.
72+
-- May never fail.
6573
extractSymbolImport :: SymbolImport a -> a
6674
extractSymbolImport (Hiding s) = s
6775
extractSymbolImport (Import s) = s
@@ -70,19 +78,26 @@ type ModuleName = T.Text
7078
type SymbolName = T.Text
7179
type DatatypeName = T.Text
7280

81+
-- | How to import a module.
82+
-- Can be used to express to import a whole module or only specific symbols
83+
-- from a module.
84+
-- Is used to either hide symbols from an import or use an import-list to
85+
-- import only a specific symbol.
7386
data ImportStyle
7487
= Simple -- ^ Import the whole module
7588
| Complex (SymbolImport SymbolKind) -- ^ Complex operation, import module hiding symbols or import only selected symbols.
7689
deriving (Show, Eq, Generics.Generic, ToJSON, FromJSON)
7790

91+
-- | Contains information about the diagnostic, the symbol ghc-mod
92+
-- complained about and what the kind of the symbol is and whether
93+
-- to import or hide the symbol as suggested by ghc-mod.
7894
data ImportDiagnostic = ImportDiagnostic
7995
{ diagnostic :: J.Diagnostic
8096
, term :: SymbolName
8197
, termType :: SymbolImport SymbolType
8298
}
8399
deriving (Show, Eq, Generics.Generic, ToJSON, FromJSON)
84100

85-
86101
-- | Import Parameters for Modules.
87102
-- Can be used to import every symbol from a module,
88103
-- or to import only a specific function from a module.
@@ -189,23 +204,31 @@ importModule uri impStyle modName =
189204
$ IdeResultOk (J.WorkspaceEdit newChanges newDocChanges)
190205
else return $ IdeResultOk (J.WorkspaceEdit mChanges mDocChanges)
191206

207+
-- | Convert the import style arguments into HsImport arguments.
208+
-- Takes an input and an output file as well as a module name.
192209
importStyleToHsImportArgs
193210
:: FilePath -> FilePath -> ModuleName -> ImportStyle -> HsImport.HsImportArgs
194211
importStyleToHsImportArgs input output modName style =
195-
let defaultArgs =
212+
let defaultArgs = -- Default args, must be set every time.
196213
HsImport.defaultArgs { HsImport.moduleName = T.unpack modName
197214
, HsImport.inputSrcFile = input
198215
, HsImport.outputSrcFile = output
199216
}
217+
218+
kindToArgs :: SymbolKind -> HsImport.HsImportArgs
200219
kindToArgs kind = case kind of
220+
-- Only import a single symbol e.g. Data.Text (isPrefixOf)
201221
Only sym -> defaultArgs { HsImport.symbolName = T.unpack sym }
222+
-- Import a constructor e.g. Data.Mabye (Maybe(Just))
202223
OneOf dt sym -> defaultArgs { HsImport.symbolName = T.unpack dt
203224
, HsImport.with = [T.unpack sym]
204225
}
226+
-- Import all constructors e.g. Data.Maybe (Maybe(..))
205227
AllOf dt -> defaultArgs { HsImport.symbolName = T.unpack dt
206228
, HsImport.all = True
207229
}
208230
in case style of
231+
-- If the import style is simple, import thw whole module
209232
Simple -> defaultArgs
210233
Complex s -> case s of
211234
Hiding kind -> kindToArgs kind {- TODO: wait for hsimport version bump -}
@@ -289,13 +312,22 @@ codeActionProvider plId docId _ context = do
289312
where
290313
importListActions :: [IdeM (Maybe J.CodeAction)]
291314
importListActions = case searchStyle of
315+
-- If the search has been relaxed by a custom function,
316+
-- we cant know how much the search query has been altered
317+
-- and how close the result terms are to the initial diagnostic.
318+
-- Thus, we cant offer more specific imports.
292319
Relax _ -> []
293320
_ -> catMaybes
294321
$ case extractSymbolImport $ termType impDiagnostic of
322+
-- If the term to import is a simple symbol, such as a function,
323+
-- import only this function
295324
Symbol
296325
-> [ mkImportAction moduleName impDiagnostic . Just . Only
297326
<$> symName (term impDiagnostic)
298327
]
328+
-- Constructors can be imported in two ways, either all
329+
-- constructors of a type or only a subset.
330+
-- We can only import a single constructor at a time though.
299331
Constructor
300332
-> [ mkImportAction moduleName impDiagnostic . Just . AllOf
301333
<$> datatypeName (term impDiagnostic)
@@ -304,22 +336,43 @@ codeActionProvider plId docId _ context = do
304336
<$> datatypeName (term impDiagnostic)
305337
<*> symName (term impDiagnostic)
306338
]
339+
-- If we are looking for a type, import it as just a symbol
307340
Type
308341
-> [ mkImportAction moduleName impDiagnostic . Just . Only
309342
<$> symName (term impDiagnostic)]
310343

344+
-- | All code actions that may be available
345+
-- Currently, omits all
311346
codeActions :: [IdeM (Maybe J.CodeAction)]
312347
codeActions = case termType impDiagnostic of
313-
Hiding _ -> []
348+
Hiding _ -> [] {- If we are hiding an import, we can not import
349+
a module hiding everything from it. -}
314350
Import _ -> [mkImportAction moduleName impDiagnostic Nothing]
351+
-- ^ Simple import, import the whole module
315352
++ importListActions
316353

354+
-- | Retrieve the function signature of a term such as
355+
-- >>> signatureOf "take :: Int -> [a] -> [a]"
356+
-- Just " Int -> [a] -> [a]"
317357
signatureOf :: T.Text -> Maybe T.Text
318358
signatureOf sig = do
319359
let parts = T.splitOn "::" sig
320360
typeSig <- S.tailMay parts
321361
S.headMay typeSig
322362

363+
-- | Retrieve the datatype name of a Constructor.
364+
--
365+
-- >>> datatypeName "Null :: Data.Aeson.Internal.Types.Value"
366+
-- Just "Value"
367+
--
368+
-- >>> datatypeName "take :: Int -> [a] -> [a]" -- Not a constructor
369+
-- Just "[a]"
370+
--
371+
-- >>> datatypeName "Just :: a -> Maybe a"
372+
-- Just "Maybe"
373+
--
374+
-- Thus, the result of this function only makes sense,
375+
-- if the symbol kind of the diagnostic term is of type 'Constructor'
323376
datatypeName :: T.Text -> Maybe T.Text
324377
datatypeName sig = do
325378
sig_ <- signatureOf sig
@@ -330,6 +383,10 @@ codeActionProvider plId docId _ context = do
330383
let qualifiedDtNameParts = T.splitOn "." qualifiedDtName
331384
S.lastMay qualifiedDtNameParts
332385

386+
-- | Name of a symbol. May contain a function signature.
387+
--
388+
-- >>> symName "take :: Int -> [a] -> [a]"
389+
-- Just "take"
333390
symName :: T.Text -> Maybe SymbolName
334391
symName = S.headMay . T.words
335392

0 commit comments

Comments
 (0)