Skip to content

Commit 445192e

Browse files
Kobayashimergify[bot]
Kobayashi
andauthored
refactor selection range plugin (#3003)
* update Gitpod config * update nix shellHook & docs * install pre-commit hook * add kokobd as code owner to .gitpod.* * add gen-hie to Gitpod * add tools for doc * remove .pre-commit-config.yaml from .gitignore * set vscode formatter to stylish-haskell in Gitpod * refactor selection range plugin * refine selection range * add CodeKind to CodeRange * rename hls-selection-range-plugin to hls-code-range-plugin * update docs about selection range * cleanup RuleTypes.hs * add the missing bang pattern * fix subRange * add some unit tests to CodeRange.Rules * add tests for removeInterleaving * add even more tests * fix extra sources Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent b747aa0 commit 445192e

File tree

30 files changed

+762
-351
lines changed

30 files changed

+762
-351
lines changed

.github/workflows/hackage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
"hls-refine-imports-plugin", "hls-rename-plugin", "hls-retrie-plugin",
3737
"hls-splice-plugin", "hls-tactics-plugin",
3838
"hls-call-hierarchy-plugin", "hls-alternate-number-format-plugin",
39-
"hls-qualify-imported-names-plugin", "hls-selection-range-plugin",
39+
"hls-qualify-imported-names-plugin", "hls-code-range-plugin",
4040
"haskell-language-server"]
4141
ghc: [ "9.0.2"
4242
, "8.10.7"

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ jobs:
236236
run: cabal test hls-qualify-imported-names-plugin --test-options="$TEST_OPTS" || cabal test hls-qualify-imported-names-plugin --test-options="$TEST_OPTS" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-qualify-imported-names-plugin --test-options="$TEST_OPTS"
237237

238238
- if: matrix.test
239-
name: Test hls-selection-range-plugin test suite
240-
run: cabal test hls-selection-range-plugin --test-options="$TEST_OPTS" || cabal test hls-selection-range-plugin --test-options="$TEST_OPTS" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-selection-range-plugin --test-options="$TEST_OPTS"
239+
name: Test hls-code-range-plugin test suite
240+
run: cabal test hls-code-range-plugin --test-options="$TEST_OPTS" || cabal test hls-code-range-plugin --test-options="$TEST_OPTS" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-code-range-plugin --test-options="$TEST_OPTS"
241241

242242
- if: matrix.test
243243
name: Test hls-change-type-signature test suite

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/plugins/hls-refine-imports-plugin
2626
/plugins/hls-rename-plugin @OliverMadine
2727
/plugins/hls-retrie-plugin @pepeiborra
28-
/plugins/hls-selection-range-plugin @kokobd
28+
/plugins/hls-code-range-plugin @kokobd
2929
/plugins/hls-splice-plugin @konn
3030
/plugins/hls-stylish-haskell-plugin @Ailrun
3131
/plugins/hls-tactics-plugin @isovector

cabal.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ packages:
2626
./plugins/hls-call-hierarchy-plugin
2727
./plugins/hls-alternate-number-format-plugin
2828
./plugins/hls-qualify-imported-names-plugin
29-
./plugins/hls-selection-range-plugin
29+
./plugins/hls-code-range-plugin
3030
./plugins/hls-change-type-signature-plugin
3131
./plugins/hls-gadt-plugin
3232

docs/features.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,13 @@ Shows module name matching file path, and applies it with a click.
317317

318318
## Selection range
319319

320-
Provided by: `hls-selection-range-plugin`
320+
Provided by: `hls-code-range-plugin`
321321

322322
Provides haskell specific
323-
[shrink/expand selection](https://code.visualstudio.com/docs/editor/codebasics#shrinkexpand-selection)
323+
[shrink/expand selection](https://code.visualstudio.com/docs/editor/codebasics#_shrinkexpand-selection)
324324
support.
325325

326-
![Selection range demo](https://user-images.githubusercontent.com/16440269/150301502-4c002605-9f8d-43f5-86d3-28846942c4ff.mov)
326+
![Selection range demo](https://user-images.githubusercontent.com/16440269/177240833-7dc8fe39-b446-477e-b5b1-7fc303608d4f.gif)
327327

328328
## Rename
329329

docs/supported-versions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Sometimes a plugin will be supported in the pre-built binaries but not in a HLS
6868
| `hls-splice-plugin` | 9.2 |
6969
| `hls-stylish-haskell-plugin` | |
7070
| `hls-tactics-plugin` | 9.2 |
71-
| `hls-selection-range-plugin` | |
71+
| `hls-code-range-plugin` | |
7272
| `hls-gadt-plugin` | |
7373

7474
### Using deprecated GHC versions

exe/Plugins.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ import qualified Ide.Plugin.Splice as Splice
7676
import qualified Ide.Plugin.AlternateNumberFormat as AlternateNumberFormat
7777
#endif
7878

79-
#if selectionRange
80-
import Ide.Plugin.SelectionRange as SelectionRange
79+
#if codeRange
80+
import qualified Ide.Plugin.CodeRange as CodeRange
8181
#endif
8282

8383
#if changeTypeSignature
@@ -190,8 +190,8 @@ idePlugins recorder includeExamples = pluginDescToIdePlugins allPlugins
190190
#if alternateNumberFormat
191191
AlternateNumberFormat.descriptor pluginRecorder :
192192
#endif
193-
#if selectionRange
194-
SelectionRange.descriptor "selectionRange" :
193+
#if codeRange
194+
CodeRange.descriptor pluginRecorder "codeRange" :
195195
#endif
196196
#if changeTypeSignature
197197
ChangeTypeSignature.descriptor :

ghcide/src/Development/IDE/Core/RuleTypes.hs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import Development.IDE.Types.HscEnvEq (HscEnvEq)
3535
import Development.IDE.Types.KnownTargets
3636
import GHC.Generics (Generic)
3737

38-
import qualified Data.Binary as B
3938
import Data.ByteString (ByteString)
4039
import Data.Text (Text)
4140
import Development.IDE.Import.FindImports (ArtifactsLocation)
@@ -173,17 +172,17 @@ tmrModSummary :: TcModuleResult -> ModSummary
173172
tmrModSummary = pm_mod_summary . tmrParsed
174173

175174
data HiFileResult = HiFileResult
176-
{ hirModSummary :: !ModSummary
175+
{ hirModSummary :: !ModSummary
177176
-- Bang patterns here are important to stop the result retaining
178177
-- a reference to a typechecked module
179-
, hirModIface :: !ModIface
180-
, hirModDetails :: ModDetails
178+
, hirModIface :: !ModIface
179+
, hirModDetails :: ModDetails
181180
-- ^ Populated lazily
182-
, hirIfaceFp :: !ByteString
181+
, hirIfaceFp :: !ByteString
183182
-- ^ Fingerprint for the ModIface
184183
, hirRuntimeModules :: !(ModuleEnv ByteString)
185184
-- ^ same as tmrRuntimeModules
186-
, hirCoreFp :: !(Maybe (CoreFile, ByteString))
185+
, hirCoreFp :: !(Maybe (CoreFile, ByteString))
187186
-- ^ If we wrote a core file for this module, then its contents (lazily deserialised)
188187
-- along with its hash
189188
}
@@ -445,7 +444,7 @@ newtype GhcSessionDeps = GhcSessionDeps_
445444

446445
instance Show GhcSessionDeps where
447446
show (GhcSessionDeps_ False) = "GhcSessionDeps"
448-
show (GhcSessionDeps_ True) = "GhcSessionDepsFull"
447+
show (GhcSessionDeps_ True) = "GhcSessionDepsFull"
449448

450449
pattern GhcSessionDeps :: GhcSessionDeps
451450
pattern GhcSessionDeps = GhcSessionDeps_ False

ghcide/src/Development/IDE/GHC/Compat.hs

Lines changed: 108 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,14 @@ module Development.IDE.GHC.Compat(
3232
myCoreToStgExpr,
3333
#endif
3434

35+
FastStringCompat,
3536
nodeInfo',
3637
getNodeIds,
37-
nodeInfoFromSource,
38+
sourceNodeInfo,
39+
generatedNodeInfo,
40+
simpleNodeInfoCompat,
3841
isAnnotationInNodeInfo,
42+
nodeAnnotations,
3943
mkAstNode,
4044
combineRealSrcSpans,
4145

@@ -94,7 +98,6 @@ module Development.IDE.GHC.Compat(
9498
module UniqSet,
9599
module UniqDFM,
96100
getDependentMods,
97-
diffBinds,
98101
flattenBinds,
99102
mkRnEnv2,
100103
emptyInScopeSet,
@@ -113,6 +116,7 @@ module Development.IDE.GHC.Compat(
113116
#endif
114117
) where
115118

119+
import Data.Bifunctor
116120
import Development.IDE.GHC.Compat.Core
117121
import Development.IDE.GHC.Compat.Env
118122
import Development.IDE.GHC.Compat.ExactPrint
@@ -125,58 +129,74 @@ import Development.IDE.GHC.Compat.Units
125129
import Development.IDE.GHC.Compat.Util
126130
import GHC hiding (HasSrcSpan,
127131
ModLocation,
128-
RealSrcSpan, getLoc,
129-
lookupName, exprType)
132+
RealSrcSpan, exprType,
133+
getLoc, lookupName)
134+
135+
import Data.Coerce (coerce)
136+
import Data.String (IsString (fromString))
137+
138+
130139
#if MIN_VERSION_ghc(9,0,0)
131-
import GHC.Driver.Hooks (hscCompileCoreExprHook)
132-
import GHC.Core (CoreExpr, CoreProgram, Unfolding(..), noUnfolding, flattenBinds)
133-
import qualified GHC.Core.Opt.Pipeline as GHC
134-
import GHC.Core.Tidy (tidyExpr)
135-
import GHC.Types.Var.Env (emptyTidyEnv, mkRnEnv2, emptyInScopeSet)
136-
import qualified GHC.CoreToStg.Prep as GHC
137-
import GHC.CoreToStg.Prep (corePrepPgm)
138-
import GHC.Core.Lint (lintInteractiveExpr)
140+
import GHC.Core.Lint (lintInteractiveExpr)
141+
import qualified GHC.Core.Opt.Pipeline as GHC
142+
import GHC.Core.Tidy (tidyExpr)
143+
import GHC.CoreToStg.Prep (corePrepPgm)
144+
import qualified GHC.CoreToStg.Prep as GHC
145+
import GHC.Driver.Hooks (hscCompileCoreExprHook)
139146
#if MIN_VERSION_ghc(9,2,0)
140-
import GHC.Unit.Home.ModInfo (lookupHpt, HomePackageTable)
141-
import GHC.Runtime.Context (icInteractiveModule)
142-
import GHC.Unit.Module.Deps (Dependencies(dep_mods))
143-
import GHC.Linker.Types (isObjectLinkable)
144-
import GHC.Linker.Loader (loadExpr)
147+
import GHC.Linker.Loader (loadExpr)
148+
import GHC.Linker.Types (isObjectLinkable)
149+
import GHC.Runtime.Context (icInteractiveModule)
150+
import GHC.Unit.Home.ModInfo (HomePackageTable,
151+
lookupHpt)
152+
import GHC.Unit.Module.Deps (Dependencies (dep_mods))
145153
#else
146-
import GHC.CoreToByteCode (coreExprToBCOs)
147-
import GHC.Driver.Types (Dependencies(dep_mods), icInteractiveModule, lookupHpt, HomePackageTable)
148-
import GHC.Runtime.Linker (linkExpr)
149-
#endif
150-
import GHC.ByteCode.Asm (bcoFreeNames)
151-
import GHC.Types.Annotations (Annotation(..), AnnTarget(ModuleTarget), extendAnnEnvList)
152-
import GHC.Types.Unique.DSet as UniqDSet
153-
import GHC.Types.Unique.Set as UniqSet
154-
import GHC.Types.Unique.DFM as UniqDFM
154+
import GHC.CoreToByteCode (coreExprToBCOs)
155+
import GHC.Driver.Types (Dependencies (dep_mods),
156+
HomePackageTable,
157+
icInteractiveModule,
158+
lookupHpt)
159+
import GHC.Runtime.Linker (linkExpr)
160+
#endif
161+
import GHC.ByteCode.Asm (bcoFreeNames)
162+
import GHC.Types.Annotations (AnnTarget (ModuleTarget),
163+
Annotation (..),
164+
extendAnnEnvList)
165+
import GHC.Types.Unique.DFM as UniqDFM
166+
import GHC.Types.Unique.DSet as UniqDSet
167+
import GHC.Types.Unique.Set as UniqSet
155168
#else
156-
import Hooks (hscCompileCoreExprHook)
157-
import CoreSyn (CoreExpr, flattenBinds, Unfolding(..), noUnfolding)
158-
import qualified SimplCore as GHC
159-
import CoreTidy (tidyExpr)
160-
import VarEnv (emptyTidyEnv, mkRnEnv2, emptyInScopeSet)
161-
import CorePrep (corePrepExpr, corePrepPgm)
162-
import CoreLint (lintInteractiveExpr)
163-
import ByteCodeGen (coreExprToBCOs)
164-
import HscTypes (icInteractiveModule, HomePackageTable, lookupHpt, Dependencies(dep_mods))
165-
import Linker (linkExpr)
166-
import ByteCodeAsm (bcoFreeNames)
167-
import Annotations (Annotation(..), AnnTarget(ModuleTarget), extendAnnEnvList)
168-
import UniqDSet
169-
import UniqSet
170-
import UniqDFM
169+
import Annotations (AnnTarget (ModuleTarget),
170+
Annotation (..),
171+
extendAnnEnvList)
172+
import ByteCodeAsm (bcoFreeNames)
173+
import ByteCodeGen (coreExprToBCOs)
174+
import CoreLint (lintInteractiveExpr)
175+
import CorePrep (corePrepExpr,
176+
corePrepPgm)
177+
import CoreSyn (CoreExpr,
178+
Unfolding (..),
179+
flattenBinds,
180+
noUnfolding)
181+
import CoreTidy (tidyExpr)
182+
import Hooks (hscCompileCoreExprHook)
183+
import Linker (linkExpr)
184+
import qualified SimplCore as GHC
185+
import UniqDFM
186+
import UniqDSet
187+
import UniqSet
188+
import VarEnv (emptyInScopeSet,
189+
emptyTidyEnv, mkRnEnv2)
171190
#endif
172191

173192
#if MIN_VERSION_ghc(9,0,0)
193+
import GHC.Core
174194
import GHC.Data.StringBuffer
175195
import GHC.Driver.Session hiding (ExposePackage)
176196
import qualified GHC.Types.SrcLoc as SrcLoc
197+
import GHC.Types.Var.Env
177198
import GHC.Utils.Error
178199
#if MIN_VERSION_ghc(9,2,0)
179-
import Data.Bifunctor
180200
import GHC.Driver.Env as Env
181201
import GHC.Unit.Module.ModIface
182202
import GHC.Unit.Module.ModSummary
@@ -209,41 +229,32 @@ import System.IO
209229

210230
import Compat.HieAst (enrichHie)
211231
import Compat.HieBin
212-
import Compat.HieTypes
232+
import Compat.HieTypes hiding (nodeAnnotations)
233+
import qualified Compat.HieTypes as GHC (nodeAnnotations)
213234
import Compat.HieUtils
214235
import qualified Data.ByteString as BS
215236
import Data.IORef
216237

217238
import Data.List (foldl')
218239
import qualified Data.Map as Map
219-
import qualified Data.Set as Set
220-
221-
#if MIN_VERSION_ghc(9,0,0)
222240
import qualified Data.Set as S
223-
#endif
224241

225242
#if !MIN_VERSION_ghc(8,10,0)
226243
import Bag (unitBag)
227244
#endif
228245

229246
#if MIN_VERSION_ghc(9,2,0)
230-
import GHC.Types.CostCentre
231-
import GHC.Stg.Syntax
232-
import GHC.Types.IPE
233-
import GHC.Stg.Syntax
234-
import GHC.Types.IPE
235-
import GHC.Types.CostCentre
236-
import GHC.Core
237-
import GHC.Builtin.Uniques
238-
import GHC.Runtime.Interpreter
239-
import GHC.StgToByteCode
240-
import GHC.Stg.Pipeline
241-
import GHC.ByteCode.Types
242-
import GHC.Linker.Loader (loadDecls)
243-
import GHC.Data.Maybe
244-
import GHC.CoreToStg
245-
import GHC.Core.Utils
246-
import GHC.Types.Var.Env
247+
import GHC.Builtin.Uniques
248+
import GHC.ByteCode.Types
249+
import GHC.CoreToStg
250+
import GHC.Data.Maybe
251+
import GHC.Linker.Loader (loadDecls)
252+
import GHC.Runtime.Interpreter
253+
import GHC.Stg.Pipeline
254+
import GHC.Stg.Syntax
255+
import GHC.StgToByteCode
256+
import GHC.Types.CostCentre
257+
import GHC.Types.IPE
247258
#endif
248259

249260
type ModIfaceAnnotation = Annotation
@@ -506,11 +517,18 @@ nodeInfo' = nodeInfo
506517
-- unhelpfulSpanFS = id
507518
#endif
508519

509-
nodeInfoFromSource :: HieAST a -> Maybe (NodeInfo a)
520+
sourceNodeInfo :: HieAST a -> Maybe (NodeInfo a)
521+
#if MIN_VERSION_ghc(9,0,0)
522+
sourceNodeInfo = Map.lookup SourceInfo . getSourcedNodeInfo . sourcedNodeInfo
523+
#else
524+
sourceNodeInfo = Just . nodeInfo
525+
#endif
526+
527+
generatedNodeInfo :: HieAST a -> Maybe (NodeInfo a)
510528
#if MIN_VERSION_ghc(9,0,0)
511-
nodeInfoFromSource = Map.lookup SourceInfo . getSourcedNodeInfo . sourcedNodeInfo
529+
generatedNodeInfo = Map.lookup GeneratedInfo . getSourcedNodeInfo . sourcedNodeInfo
512530
#else
513-
nodeInfoFromSource = Just . nodeInfo
531+
generatedNodeInfo = sourceNodeInfo -- before ghc 9.0, we don't distinguish the source
514532
#endif
515533

516534
data GhcVersion
@@ -553,11 +571,31 @@ runPp =
553571
const SysTools.runPp
554572
#endif
555573

556-
isAnnotationInNodeInfo :: (FastString, FastString) -> NodeInfo a -> Bool
574+
simpleNodeInfoCompat :: FastStringCompat -> FastStringCompat -> NodeInfo a
575+
simpleNodeInfoCompat ctor typ = simpleNodeInfo (coerce ctor) (coerce typ)
576+
577+
isAnnotationInNodeInfo :: (FastStringCompat, FastStringCompat) -> NodeInfo a -> Bool
578+
isAnnotationInNodeInfo p = S.member p . nodeAnnotations
579+
580+
nodeAnnotations :: NodeInfo a -> S.Set (FastStringCompat, FastStringCompat)
581+
#if MIN_VERSION_ghc(9,2,0)
582+
nodeAnnotations = S.map (\(NodeAnnotation ctor typ) -> (coerce ctor, coerce typ)) . GHC.nodeAnnotations
583+
#else
584+
nodeAnnotations = S.map (bimap coerce coerce) . GHC.nodeAnnotations
585+
#endif
586+
587+
#if MIN_VERSION_ghc(9,2,0)
588+
newtype FastStringCompat = FastStringCompat LexicalFastString
589+
#else
590+
newtype FastStringCompat = FastStringCompat FastString
591+
#endif
592+
deriving (Show, Eq, Ord)
593+
594+
instance IsString FastStringCompat where
557595
#if MIN_VERSION_ghc(9,2,0)
558-
isAnnotationInNodeInfo (ctor, typ) = Set.member (NodeAnnotation ctor typ) . nodeAnnotations
596+
fromString = FastStringCompat . LexicalFastString . fromString
559597
#else
560-
isAnnotationInNodeInfo p = Set.member p . nodeAnnotations
598+
fromString = FastStringCompat . fromString
561599
#endif
562600

563601
mkAstNode :: NodeInfo a -> Span -> [HieAST a] -> HieAST a

0 commit comments

Comments
 (0)