@@ -12,11 +12,9 @@ module Development.IDE.Plugin.Completions.Context
1212 ) where
1313
1414import Control.DeepSeq (NFData (.. ), rwhnf )
15- import Control.Monad (join )
1615import Data.Hashable (Hashable )
17- import Data.List (maximumBy , singleton )
18- import Data.Maybe (catMaybes , mapMaybe ,
19- maybeToList )
16+ import Data.List (maximumBy )
17+ import Data.Maybe (catMaybes , mapMaybe )
2018import Data.Ord (Down (.. ), comparing )
2119import qualified Data.Text as T
2220import Development.IDE
@@ -38,10 +36,11 @@ data Context
3836 ImportListContext T. Text
3937 | -- | import hiding context with module name.
4038 ImportHidingContext T. Text
41- | -- | List of exported identifiers from the current module.
42- ExportContext
4339 | -- | Top-level context, with context groups indicating what would be valid
44- -- in that top-level context. NB: An empty list denotes _all_ contexts
40+ -- in that top-level context.
41+ --
42+ -- NB: An empty list denotes _all_ contexts, this occurs in splices which
43+ -- overlap with the top-level declaration snippets while typing.
4544 TopContext [ContextGroup ]
4645 | -- | Unsupported context, a placeholder context where we give up being smart
4746 -- and show all known symbols.
@@ -61,7 +60,6 @@ instance Pretty Context where
6160 ImportContext mod -> " import context " <> pretty mod
6261 ImportListContext mod -> " import explicit context " <> pretty mod
6362 ImportHidingContext mod -> " import hiding context " <> pretty mod
64- ExportContext -> " export context"
6563 TopContext cg -> " top context " <> pretty cg
6664 DefaultContext -> " unknown context"
6765
@@ -88,15 +86,6 @@ data ContextChunk = Chunk
8886 , items :: [(Range , Context )]
8987 }
9088
91- -- | Build a single 'Chunk' from a flat list of entries, or 'ChunkEnd' if empty.
92- singleChunk :: ContextGroup -> [(Range , Context )] -> ContextMap
93- singleChunk _ [] = ContextMap mempty
94- singleChunk group items = ContextMap $ singleton $ Chunk
95- (minimum (map (_start . fst ) items))
96- (maximum (map (_end . fst ) items))
97- group
98- items
99-
10089-- | Build lazy 'ContextChunk' by processing @n@ source items at a time.
10190groupedChunks :: Int -> ContextGroup -> (a -> Maybe Range ) -> (a -> [(Range , Context )]) -> [a ] -> ContextMap
10291groupedChunks n group getPos getRanges xs = ContextMap $ go xs
@@ -126,21 +115,16 @@ instance NFData ContextMap where rnf = rwhnf
126115-- as a Shake rule.
127116getContextMap :: ParsedModule -> ContextMap
128117getContextMap pm =
129- singleChunk HeaderGroup exportEntry
130- <> groupedChunks 10 ImportGroup rangeOf importEntry hsmodImports
118+ groupedChunks 10 ImportGroup rangeOf importEntry hsmodImports
131119 <> groupedChunks 10 DeclarationGroup rangeOf declEntry hsmodDecls
132120 where
133- HsModule {hsmodExports, hsmodImports, hsmodDecls} =
121+ HsModule {hsmodImports, hsmodDecls} =
134122 unLoc (pm_parsed_source pm)
135123
136124 rangeOf :: HasLoc (Anno a ) => XRec GhcPs a -> Maybe Range
137125 rangeOf (L (locA -> ss) _) = srcSpanToRange ss
138126 fromSpan context ss = (,context) <$> rangeOf ss
139127
140- -- Export list -> ExportContext
141- exportEntry :: [(Range , Context )]
142- exportEntry = maybeToList $ join $ fmap (fromSpan ExportContext ) hsmodExports
143-
144128 importEntry :: LImportDecl GhcPs -> [(Range , Context )]
145129 importEntry decl@ (L _ impDecl) =
146130 let modName = T. pack $ moduleNameString $ unLoc $ ideclName impDecl
@@ -210,7 +194,7 @@ getContextMap pm =
210194-- query position are forced; later chunks remain as unevaluated thunks.
211195getContext :: ContextMap -> PositionResult Position -> Context
212196getContext (ContextMap chunks) pos =
213- case searchChunks chunks of
197+ case searchChunks True chunks of
214198 ([] , [] ) -> TopContext []
215199 (groups, [] ) -> TopContext groups
216200 (_, xs) -> snd $ maximumBy (comparing (\ (Range s e, _) -> (s, Down e))) xs
@@ -222,12 +206,12 @@ getContext (ContextMap chunks) pos =
222206 dominates :: (Range , Context ) -> Bool
223207 dominates (Range s e, _) = s <= qLo && qHi <= e
224208
225- searchChunks :: [ContextChunk ] -> ([ContextGroup ], [(Range , Context )])
226- searchChunks [] = ([] , [] )
227- searchChunks (Chunk cLo cHi group items : rest)
209+ searchChunks :: Bool -> [ContextChunk ] -> ([ContextGroup ], [(Range , Context )])
210+ searchChunks _ [] = ([] , [] )
211+ searchChunks firstChunk (Chunk cLo cHi group items : rest)
228212 | -- query is past this chunk
229- qLo > cHi = searchChunks rest
213+ qLo > cHi = searchChunks False rest
230214 | -- query is before this chunk
231- qHi < cLo = ([] , [] )
215+ qHi < cLo = (if firstChunk then [ HeaderGroup ] else [] , [] )
232216 -- this chunk is relevant, emit the group and all relevant intervals
233- | otherwise = ([group], filter dominates items) <> searchChunks rest
217+ | otherwise = ([group], filter dominates items) <> searchChunks False rest
0 commit comments