Skip to content

Commit

Permalink
refactor(renamer): ♻️ Change renamer to have the current module be _o…
Browse files Browse the repository at this point in the history
…ptional_

needed for unit tests to compile (when renaming specific expressions we don't have a whole module)
  • Loading branch information
bristermitten committed Jun 1, 2024
1 parent 9162419 commit 515f619
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 34 deletions.
72 changes: 41 additions & 31 deletions src/Elara/Rename.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ data RenameError
-- | The name that was unknown
(Located Name)
-- | The module we're renaming that the unknown name was referenced in
(Module 'Desugared)
(Maybe (Module 'Desugared))
-- | All known names
(Map name (NonEmpty (VarRef name)))
| AmbiguousVarName (Located Name) (NonEmpty (VarRef VarName))
Expand Down Expand Up @@ -101,35 +101,39 @@ instance ReportableError RenameError where
let namesMap = Map.mapKeys toName names
let allNames = maybe [] toList (fmap toName <<$>> Map.lookup (n ^. unlocated) namesMap)
let namesThatMightveBeenIntendedButNotImported =
case filter (not . isImportedBy m) allNames of
[] -> []
ns ->
[ Hint $
vsep
[ "This name is defined in the following modules, but none of them are imported:"
, hsep (punctuate comma (ns ^.. each % _As @"Global" % unlocated % qualifier % to pretty))
, "Try importing one of the modules."
]
]
let
prettyVarRef n@(Local{}) = pretty (toName $ view unlocated $ varRefVal n) <+> "(local variable)"
prettyVarRef (Global (Located _ (Qualified n m))) = pretty (toName n) <+> "(imported from" <+> pretty m <> ")"
possibleTypos =
let intendedText = nameText n
isTypo name = levenshtein (nameText name) intendedText < 3
typos =
Map.filterWithKey
(\k _ -> isTypo k)
(NonEmpty.filter (\x -> isImportedBy m (toName <$> x)) <$> namesMap)
in case join (Map.elems typos) of
case m of
Nothing -> []
Just m -> case filter (not . isImportedBy m) allNames of
[] -> []
ts ->
ns ->
[ Hint $
vsep
[ "You may have meant one of:"
, listToText (prettyVarRef <$> ts)
[ "This name is defined in the following modules, but none of them are imported:"
, hsep (punctuate comma (ns ^.. each % _As @"Global" % unlocated % qualifier % to pretty))
, "Try importing one of the modules."
]
]
let
prettyVarRef n@(Local{}) = pretty (toName $ view unlocated $ varRefVal n) <+> "(local variable)"
prettyVarRef (Global (Located _ (Qualified n m))) = pretty (toName n) <+> "(imported from" <+> pretty m <> ")"
possibleTypos = case m of
Nothing -> []
Just m ->
let intendedText = nameText n
isTypo name = levenshtein (nameText name) intendedText < 3
typos =
Map.filterWithKey
(\k _ -> isTypo k)
(NonEmpty.filter (\x -> isImportedBy m (toName <$> x)) <$> namesMap)
in case join (Map.elems typos) of
[] -> []
ts ->
[ Hint $
vsep
[ "You may have meant one of:"
, listToText (prettyVarRef <$> ts)
]
]

writeReport $
Err
Expand Down Expand Up @@ -216,7 +220,7 @@ type RenamePipelineEffects =
type Rename r = Members RenamePipelineEffects r
type InnerRename r =
( Members RenamePipelineEffects r
, Member (Reader (Module 'Desugared)) r -- the module we're renaming
, Member (Reader (Maybe (Module 'Desugared))) r -- the module we're renaming
)

runRenamePipeline ::
Expand Down Expand Up @@ -264,10 +268,16 @@ lookupGenericName _ _ (Located sr (MaybeQualified n (Just m))) = do
lookupGenericName lens ambiguousError (Located sr (MaybeQualified n Nothing)) = do
names' <- use' lens
m <- ask
case maybe [] (NonEmpty.filter ((m `isImportedBy`) . fmap toName)) (Map.lookup n names') of
[v] -> pure $ Located sr v
[] -> throw $ UnknownName (Located sr $ toName n) m names'
(x : xs) -> throw $ ambiguousError (Located sr $ toName n) (x :| xs)
case m of
Nothing ->
case Map.lookup n names' of
Nothing -> throw $ UnknownName (Located sr $ toName n) m names'
Just (v :| []) -> pure $ Located sr v
Just many -> throw $ ambiguousError (Located sr $ toName n) many
Just m -> case maybe [] (NonEmpty.filter ((m `isImportedBy`) . fmap toName)) (Map.lookup n names') of
[v] -> pure $ Located sr v
[] -> throw $ UnknownName (Located sr $ toName n) (Just m) names'
(x : xs) -> throw $ ambiguousError (Located sr $ toName n) (x :| xs)

lookupVarName :: InnerRename r => Located (MaybeQualified VarName) -> Sem r (Located (VarRef VarName))
lookupVarName = lookupGenericName (field' @"varNames") AmbiguousVarName
Expand Down Expand Up @@ -300,7 +310,7 @@ rename m = do
traverseOf_ (field' @"declarations" % each) (addDeclarationToContext False) m' -- add our own declarations to field' context
exposing' <- renameExposing (m' ^. field' @"name" % unlocated) (m' ^. field' @"exposing")
imports' <- traverse renameImport (m' ^. field' @"imports")
declarations' <- runReader m (traverse renameDeclaration (m' ^. field' @"declarations"))
declarations' <- runReader (Just m) (traverse renameDeclaration (m' ^. field' @"declarations"))
sorted <- sortDeclarations declarations'
pure (Module' (m' ^. field' @"name") exposing' imports' sorted)
)
Expand Down
10 changes: 8 additions & 2 deletions test/Infer/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import Polysemy.Log
import Polysemy.Reader (runReader)
import Polysemy.State (State)
import Print (showPretty)
import Test.HUnit (assertFailure)

pattern Forall' :: UniqueTyVar -> Domain -> Type () -> Type ()
pattern Forall' name domain t = Forall () () name domain t
Expand All @@ -65,7 +64,14 @@ inferFully source = finalisePipeline . runInferPipeline . runShuntPipeline . run
tokens <- readTokensWith fp (toString source)
parsed <- parsePipeline exprParser fp (toString source, tokens)
desugared <- runDesugarPipeline $ runDesugar $ desugarExpr parsed
renamed <- runRenamePipeline (createGraph []) primitiveRenameState (runReader Nothing $ renameExpr desugared)
renamed <-
runRenamePipeline
(createGraph [])
primitiveRenameState
( runReader (Nothing @(Module 'Desugared)) $
runReader (Nothing @(Declaration 'Desugared)) $
renameExpr desugared
)
shunted <- runReader mempty $ shuntExpr renamed
inferExpression shunted Nothing >>= completeInference

Expand Down
3 changes: 2 additions & 1 deletion test/Shunt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Common (diagShouldSucceed)
import Elara.AST.Generic
import Elara.AST.Generic.Instances ()
import Elara.AST.Generic.Pattern (functionCall, int, var)
import Elara.AST.Module
import Elara.AST.Name (OpName (..), Qualified (..), VarName (OperatorVarName))
import Elara.AST.Region (generatedLocated)
import Elara.AST.Select (LocatedAST (..), UnlocatedAST (UnlocatedShunted))
Expand Down Expand Up @@ -33,7 +34,7 @@ loadExpr source = finalisePipeline . runShuntPipeline . runRenamePipeline (creat
parsed <- parsePipeline exprParser fp (toString source, tokens)
desugared <- runDesugarPipeline $ runDesugar $ desugarExpr parsed

renamed <- runReader Nothing $ renameExpr desugared
renamed <- runReader Nothing $ runReader (Nothing :: Maybe (Module 'Desugared)) $ renameExpr desugared
runReader fakeOperatorTable $ fixExpr renamed

mkFakeVar :: OpName -> VarRef VarName
Expand Down

0 comments on commit 515f619

Please sign in to comment.