@@ -69,42 +69,39 @@ type HsArrow pass = HsMultAnn pass
6969-- In this case a new argument would have to add its type between b and c in the signature.
7070plugin :: ParsedModule -> FileDiagnostic -> Either PluginError [(T. Text , [TextEdit ])]
7171plugin parsedModule fd
72- | Just (name , typ) <- matchVariableNotInScope fd = addArgumentAction parsedModule _range name typ
73- | Just (name , typ) <- matchFoundHoleIncludeUnderscore fd = addArgumentAction parsedModule _range name (Just typ)
72+ | Just (rdrName , typ) <- matchVariableNotInScope fd = addArgumentAction parsedModule _range rdrName typ
73+ | Just (rdrName , typ) <- matchFoundHole fd = addArgumentAction parsedModule _range rdrName (Just typ)
7474 | otherwise = pure []
7575 where
76- Diagnostic {_message, _range} = fdLspDiagnostic fd :: Diagnostic
76+ Diagnostic {_message, _range} = fdLspDiagnostic fd
7777
7878-- Given a name for the new binding, add a new pattern to the match in the last position,
7979-- returning how many patterns there were in this match prior to the transformation:
8080-- addArgToMatch "foo" `bar arg1 arg2 = ...`
8181-- => (`bar arg1 arg2 foo = ...`, 2)
82- addArgToMatch :: T. Text -> GenLocated l (Match GhcPs (LocatedA (HsExpr GhcPs ))) -> (GenLocated l (Match GhcPs (LocatedA (HsExpr GhcPs ))), Int )
82+ addArgToMatch :: RdrName -> GenLocated l (Match GhcPs (LocatedA (HsExpr GhcPs ))) -> (GenLocated l (Match GhcPs (LocatedA (HsExpr GhcPs ))), Int )
8383
8484-- NOTE: The code duplication within CPP clauses avoids a parse error with
8585-- `stylish-haskell`.
8686#if MIN_VERSION_ghc(9,11,0)
87- addArgToMatch name (L locMatch (Match xMatch ctxMatch (L l pats) rhs)) =
88- let unqualName = mkRdrUnqual $ mkVarOcc $ T. unpack name
89- newPat = L noAnnSrcSpanDP1 $ VarPat NoExtField $ L noAnn unqualName
87+ addArgToMatch unqualName (L locMatch (Match xMatch ctxMatch (L l pats) rhs)) =
88+ let newPat = L noAnnSrcSpanDP1 $ VarPat NoExtField $ L noAnn unqualName
9089 -- The intention is to move `= ...` (right-hand side with equals) to the right so there's 1 space between
9190 -- the newly added pattern and the rest
9291 indentRhs :: GRHSs GhcPs (LocatedA (HsExpr GhcPs )) -> GRHSs GhcPs (LocatedA (HsExpr GhcPs ))
9392 indentRhs rhs@ GRHSs {grhssGRHSs} = rhs {grhssGRHSs = fmap (`setEntryDP` (SameLine 1 )) grhssGRHSs }
9493 in (L locMatch (Match xMatch ctxMatch (L l (pats <> [newPat])) (indentRhs rhs)), Prelude. length pats)
9594#elif MIN_VERSION_ghc(9,9,0)
96- addArgToMatch name (L locMatch (Match xMatch ctxMatch pats rhs)) =
97- let unqualName = mkRdrUnqual $ mkVarOcc $ T. unpack name
98- newPat = L noAnnSrcSpanDP1 $ VarPat NoExtField $ L noAnn unqualName
95+ addArgToMatch unqualName (L locMatch (Match xMatch ctxMatch pats rhs)) =
96+ let newPat = L noAnnSrcSpanDP1 $ VarPat NoExtField $ L noAnn unqualName
9997 -- The intention is to move `= ...` (right-hand side with equals) to the right so there's 1 space between
10098 -- the newly added pattern and the rest
10199 indentRhs :: GRHSs GhcPs (LocatedA (HsExpr GhcPs )) -> GRHSs GhcPs (LocatedA (HsExpr GhcPs ))
102100 indentRhs rhs@ GRHSs {grhssGRHSs} = rhs {grhssGRHSs = fmap (`setEntryDP` (SameLine 1 )) grhssGRHSs }
103101 in (L locMatch (Match xMatch ctxMatch (pats <> [newPat]) (indentRhs rhs)), Prelude. length pats)
104102#else
105- addArgToMatch name (L locMatch (Match xMatch ctxMatch pats rhs)) =
106- let unqualName = mkRdrUnqual $ mkVarOcc $ T. unpack name
107- newPat = L (noAnnSrcSpanDP1 generatedSrcSpan) $ VarPat NoExtField (noLocA unqualName)
103+ addArgToMatch unqualName (L locMatch (Match xMatch ctxMatch pats rhs)) =
104+ let newPat = L (noAnnSrcSpanDP1 generatedSrcSpan) $ VarPat NoExtField (noLocA unqualName)
108105 indentRhs = id
109106 in (L locMatch (Match xMatch ctxMatch (pats <> [newPat]) (indentRhs rhs)), Prelude. length pats)
110107#endif
@@ -117,10 +114,10 @@ addArgToMatch name (L locMatch (Match xMatch ctxMatch pats rhs)) =
117114-- For example:
118115-- insertArg "new_pat" `foo bar baz = 1`
119116-- => (`foo bar baz new_pat = 1`, Just ("foo", 2))
120- appendFinalPatToMatches :: T. Text -> LHsDecl GhcPs -> TransformT (Either PluginError ) (LHsDecl GhcPs , Maybe (GenLocated SrcSpanAnnN RdrName , Int ))
121- appendFinalPatToMatches name = \ case
117+ appendFinalPatToMatches :: RdrName -> LHsDecl GhcPs -> TransformT (Either PluginError ) (LHsDecl GhcPs , Maybe (GenLocated SrcSpanAnnN RdrName , Int ))
118+ appendFinalPatToMatches rdrName = \ case
122119 (L locDecl (ValD xVal fun@ FunBind {fun_matches= mg,fun_id = idFunBind})) -> do
123- (mg', numPatsMay) <- modifyMgMatchesT' mg (pure . second Just . addArgToMatch name ) Nothing combineMatchNumPats
120+ (mg', numPatsMay) <- modifyMgMatchesT' mg (pure . second Just . addArgToMatch rdrName ) Nothing combineMatchNumPats
124121 numPats <- TransformT $ lift $ maybeToEither (PluginInternalError " Unexpected empty match group in HsDecl" ) numPatsMay
125122 let decl' = L locDecl (ValD xVal fun{fun_matches= mg'})
126123 pure (decl', Just (idFunBind, numPats))
@@ -143,8 +140,8 @@ appendFinalPatToMatches name = \case
143140-- foo () = new_def
144141--
145142-- TODO instead of inserting a typed hole; use GHC's suggested type from the error
146- addArgumentAction :: ParsedModule -> Range -> T. Text -> Maybe T. Text -> Either PluginError [(T. Text , [TextEdit ])]
147- addArgumentAction (ParsedModule _ moduleSrc _) range name _typ = do
143+ addArgumentAction :: ParsedModule -> Range -> RdrName -> Maybe Type -> Either PluginError [(T. Text , [TextEdit ])]
144+ addArgumentAction (ParsedModule _ moduleSrc _) range rdrName _typ = do
148145 (newSource, _, _) <- runTransformT $ do
149146 (moduleSrc', join -> matchedDeclNameMay) <- addNameAsLastArgOfMatchingDecl
150147#if MIN_VERSION_ghc(9,9,0)
@@ -153,17 +150,15 @@ addArgumentAction (ParsedModule _ moduleSrc _) range name _typ = do
153150 (makeDeltaAst moduleSrc)
154151#endif
155152 case matchedDeclNameMay of
156- Just (matchedDeclName, numPats) -> modifySigWithM (unLoc matchedDeclName) (addTyHoleToTySigArg numPats) moduleSrc'
157- Nothing -> pure moduleSrc'
153+ Just (matchedDeclName, numPats) -> modifySigWithM (unLoc matchedDeclName) (addTyHoleToTySigArg numPats) moduleSrc'
154+ Nothing -> pure moduleSrc'
158155 let diff = makeDiffTextEdit (T. pack $ exactPrint moduleSrc) (T. pack $ exactPrint newSource)
159- pure [(" Add argument ‘" <> definedName <> " ’ to function" , diff)]
156+ pure [(" Add argument ‘" <> labelName <> " ’ to function" , diff)]
160157 where
161158 addNameAsLastArgOfMatchingDecl = modifySmallestDeclWithM spanContainsRangeOrErr addNameAsLastArg
162- addNameAsLastArg = fmap (first (: [] )) . appendFinalPatToMatches definedName
163- definedName =
164- case T. stripPrefix " _" name of
165- Just n -> n
166- Nothing -> name
159+ addNameAsLastArg = fmap (first (: [] )) . appendFinalPatToMatches rdrName
160+ occName = rdrNameOcc rdrName
161+ labelName = T. pack $ occNameString occName
167162 spanContainsRangeOrErr = maybeToEither (PluginInternalError " SrcSpan was not valid range" ) . (`spanContainsRange` range)
168163
169164-- Transform an LHsType into a list of arguments and return type, to make transformations easier.
0 commit comments