1
1
mirror of https://github.com/anoma/juvix.git synced 2025-01-07 08:08:44 +03:00

[scoper] add module not in scope error

This commit is contained in:
Jan Mas Rovira 2022-02-17 13:40:19 +01:00
parent f3956f5fcd
commit e55680bfec
9 changed files with 81 additions and 63 deletions

View File

@ -1,4 +1,5 @@
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
module MiniJuvix.Syntax.Concrete.Name where module MiniJuvix.Syntax.Concrete.Name where
@ -26,18 +27,6 @@ instance HasLoc Symbol where
instance Hashable Symbol where instance Hashable Symbol where
hashWithSalt i Symbol {..} = hashWithSalt i _symbolText hashWithSalt i Symbol {..} = hashWithSalt i _symbolText
data QualifiedName = QualifiedName
{ qualifiedPath :: Path,
qualifiedSymbol :: Symbol
}
deriving stock (Show, Eq, Ord, Generic, Lift)
instance HasLoc QualifiedName where
getLoc QualifiedName {..} =
getLoc qualifiedPath <> getLoc qualifiedSymbol
instance Hashable QualifiedName
data Name data Name
= NameQualified QualifiedName = NameQualified QualifiedName
| NameUnqualified Symbol | NameUnqualified Symbol
@ -53,11 +42,25 @@ newtype Path = Path
} }
deriving stock (Show, Eq, Ord, Lift) deriving stock (Show, Eq, Ord, Lift)
data QualifiedName = QualifiedName
{ _qualifiedPath :: Path,
_qualifiedSymbol :: Symbol
}
deriving stock (Show, Eq, Ord, Generic, Lift)
instance HasLoc QualifiedName where
getLoc QualifiedName {..} =
getLoc _qualifiedPath <> getLoc _qualifiedSymbol
instance Hashable QualifiedName
instance HasLoc Path where instance HasLoc Path where
getLoc (Path p) = getLoc (NonEmpty.head p) <> getLoc (NonEmpty.last p) getLoc (Path p) = getLoc (NonEmpty.head p) <> getLoc (NonEmpty.last p)
deriving newtype instance Hashable Path deriving newtype instance Hashable Path
makeLenses ''QualifiedName
-- | A.B.C corresponds to TopModulePath [A,B] C -- | A.B.C corresponds to TopModulePath [A,B] C
data TopModulePath = TopModulePath data TopModulePath = TopModulePath
{ modulePathDir :: [Symbol], { modulePathDir :: [Symbol],
@ -86,5 +89,4 @@ topModulePathToFilePath' ext root mp = absPath
toPath :: Symbol -> FilePath toPath :: Symbol -> FilePath
toPath Symbol{..} = unpack _symbolText toPath Symbol{..} = unpack _symbolText
instance Hashable TopModulePath instance Hashable TopModulePath

View File

@ -20,10 +20,9 @@ data ScopeError
| ErrMultipleDeclarations MultipleDeclarations | ErrMultipleDeclarations MultipleDeclarations
| ErrLacksTypeSig LacksTypeSig | ErrLacksTypeSig LacksTypeSig
| ErrImportCycle ImportCycle | ErrImportCycle ImportCycle
| ErrOpenNotInScope QualifiedName
| ErrSymNotInScope NotInScope | ErrSymNotInScope NotInScope
| ErrQualSymNotInScope QualifiedName | ErrQualSymNotInScope QualifiedName
| ErrModuleNotInScope Name | ErrModuleNotInScope ModuleNotInScope
| ErrBindGroup BindGroupConflict | ErrBindGroup BindGroupConflict
| ErrDuplicateFixity DuplicateFixity | ErrDuplicateFixity DuplicateFixity
| ErrMultipleExport MultipleExportConflict | ErrMultipleExport MultipleExportConflict
@ -42,10 +41,9 @@ ppScopeError s = case s of
ErrMultipleDeclarations e -> ppError e ErrMultipleDeclarations e -> ppError e
ErrLacksTypeSig e -> ppError e ErrLacksTypeSig e -> ppError e
ErrImportCycle e -> ppError e ErrImportCycle e -> ppError e
ErrOpenNotInScope {} -> undefined
ErrSymNotInScope e -> ppError e ErrSymNotInScope e -> ppError e
ErrQualSymNotInScope {} -> undefined ErrQualSymNotInScope {} -> pretty (show s :: Text)
ErrModuleNotInScope {} -> undefined ErrModuleNotInScope e -> ppError e
ErrBindGroup e -> ppError e ErrBindGroup e -> ppError e
ErrDuplicateFixity e -> ppError e ErrDuplicateFixity e -> ppError e
ErrMultipleExport e -> ppError e ErrMultipleExport e -> ppError e

View File

@ -112,8 +112,9 @@ instance PrettyError DuplicateFixity where
instance PrettyError MultipleExportConflict where instance PrettyError MultipleExportConflict where
ppError MultipleExportConflict {..} = ppError MultipleExportConflict {..} =
"The symbol" <+> ppCode sym <+> "is exported multiple times in the module" <+> undefined "The symbol" <+> highlight (ppCode _multipleExportSymbol) <+> "is exported multiple times in the module"
where <+> ppCode _multipleExportModule
sym :: S.Symbol
sym = undefined instance PrettyError ModuleNotInScope where
e = NonEmpty.head _multipleExportEntries ppError ModuleNotInScope {..} =
"The module" <+> ppCode _moduleNotInScopeName <+> "is not in scope"

View File

@ -6,6 +6,7 @@ module MiniJuvix.Syntax.Concrete.Scoped.Error.Types (
import MiniJuvix.Prelude import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Language import MiniJuvix.Syntax.Concrete.Language
import MiniJuvix.Syntax.Concrete.Scoped.Scope import MiniJuvix.Syntax.Concrete.Scoped.Scope
import qualified MiniJuvix.Syntax.Concrete.Scoped.Name as S
data MultipleDeclarations = MultipleDeclarations { data MultipleDeclarations = MultipleDeclarations {
_multipleDeclEntry :: SymbolEntry, _multipleDeclEntry :: SymbolEntry,
@ -38,13 +39,6 @@ newtype ImportCycle = ImportCycle {
} }
deriving stock (Show) deriving stock (Show)
data NotInScope = NotInScope {
_notInScopeSymbol :: Symbol,
_notInScopeLocal :: LocalVars,
_notInScopeScope :: Scope
}
deriving stock (Show)
data BindGroupConflict = BindGroupConflict { data BindGroupConflict = BindGroupConflict {
_bindGroupFirst :: Symbol, _bindGroupFirst :: Symbol,
_bindGroupSecond :: Symbol _bindGroupSecond :: Symbol
@ -57,7 +51,21 @@ data DuplicateFixity = DuplicateFixity {
} }
deriving stock (Show) deriving stock (Show)
newtype MultipleExportConflict = MultipleExportConflict { data MultipleExportConflict = MultipleExportConflict {
_multipleExportModule :: S.AbsModulePath,
_multipleExportSymbol :: Symbol,
_multipleExportEntries :: NonEmpty SymbolEntry _multipleExportEntries :: NonEmpty SymbolEntry
} }
deriving stock (Show) deriving stock (Show)
data NotInScope = NotInScope {
_notInScopeSymbol :: Symbol,
_notInScopeLocal :: LocalVars,
_notInScopeScope :: Scope
}
deriving stock (Show)
newtype ModuleNotInScope = ModuleNotInScope {
_moduleNotInScopeName :: Name
}
deriving stock (Show)

View File

@ -9,6 +9,7 @@ import MiniJuvix.Prelude
import qualified Data.List.NonEmpty.Extra as NonEmpty import qualified Data.List.NonEmpty.Extra as NonEmpty
import Prettyprinter hiding (braces, parens) import Prettyprinter hiding (braces, parens)
import MiniJuvix.Syntax.Concrete.Scoped.Pretty.Ann import MiniJuvix.Syntax.Concrete.Scoped.Pretty.Ann
import MiniJuvix.Syntax.Concrete.Scoped.Name (AbsModulePath)
data Options = Options data Options = Options
{ {
@ -203,7 +204,9 @@ groupStatements = reverse . map reverse . uncurry cons . foldl' aux ([], [])
(StatementImport _, StatementImport _) -> True (StatementImport _, StatementImport _) -> True
(StatementImport i, StatementOpenModule o) -> case sing :: SStage s of (StatementImport i, StatementOpenModule o) -> case sing :: SStage s of
SParsed -> True SParsed -> True
SScoped -> S._nameId (modulePath (importModule i)) == S._nameId (openModuleName o) SScoped ->
S._nameId (modulePath (importModule i)) ==
S._nameId (openModuleName o)
(StatementImport _, _) -> False (StatementImport _, _) -> False
(StatementOpenModule {}, StatementOpenModule {}) -> True (StatementOpenModule {}, StatementOpenModule {}) -> True
(StatementOpenModule {}, _) -> False (StatementOpenModule {}, _) -> False
@ -280,6 +283,12 @@ instance SingI s => PrettyCode (InductiveParameter s) where
instance SingI s => PrettyCode [InductiveParameter s] where instance SingI s => PrettyCode [InductiveParameter s] where
ppCode = fmap hsep . mapM ppCode ppCode = fmap hsep . mapM ppCode
instance PrettyCode AbsModulePath where
ppCode S.AbsModulePath {..} = do
absLocalPath' <- mapM ppCode absLocalPath
absTopModulePath' <- ppCode absTopModulePath
return $ dotted (absTopModulePath' : absLocalPath')
ppInductiveParameters :: (SingI s, Members '[Reader Options] r) ppInductiveParameters :: (SingI s, Members '[Reader Options] r)
=> [InductiveParameter s] -> Sem r (Maybe (Doc Ann)) => [InductiveParameter s] -> Sem r (Maybe (Doc Ann))
ppInductiveParameters ps ppInductiveParameters ps
@ -355,7 +364,7 @@ dotted = concatWith (surround kwDot)
instance PrettyCode QualifiedName where instance PrettyCode QualifiedName where
ppCode QualifiedName {..} = do ppCode QualifiedName {..} = do
let symbols = pathParts qualifiedPath NonEmpty.|> qualifiedSymbol let symbols = pathParts _qualifiedPath NonEmpty.|> _qualifiedSymbol
dotted <$> mapM ppSymbol symbols dotted <$> mapM ppSymbol symbols
ppName :: forall s r. (SingI s, Members '[Reader Options] r) => NameType s -> Sem r (Doc Ann) ppName :: forall s r. (SingI s, Members '[Reader Options] r) => NameType s -> Sem r (Doc Ann)
@ -372,7 +381,7 @@ annDef nm = case sing :: SStage s of
SParsed -> id SParsed -> id
annSDef :: S.Name' n -> Doc Ann -> Doc Ann annSDef :: S.Name' n -> Doc Ann -> Doc Ann
annSDef nm = annotate (AnnDef (S.absTopModulePath (S._nameDefinedIn nm)) (S._nameId nm)) annSDef S.Name' {..} = annotate (AnnDef (S.absTopModulePath _nameDefinedIn) _nameId)
instance PrettyCode TopModulePath where instance PrettyCode TopModulePath where
ppCode TopModulePath {..} = ppCode TopModulePath {..} =
@ -708,22 +717,22 @@ instance HasFixity (ExpressionAtoms 'Parsed) where
getFixity = const Nothing getFixity = const Nothing
pinfixFixity :: PatternInfixApp -> Fixity pinfixFixity :: PatternInfixApp -> Fixity
pinfixFixity (PatternInfixApp _ op _) = case S._nameFixity op of pinfixFixity (PatternInfixApp _ op _) = case op ^. S.nameFixity of
S.NoFixity -> impossible S.NoFixity -> impossible
S.SomeFixity s -> s S.SomeFixity s -> s
ppostfixFixity :: PatternPostfixApp -> Fixity ppostfixFixity :: PatternPostfixApp -> Fixity
ppostfixFixity (PatternPostfixApp _ op) = case S._nameFixity op of ppostfixFixity (PatternPostfixApp _ op) = case op ^. S.nameFixity of
S.NoFixity -> impossible S.NoFixity -> impossible
S.SomeFixity s -> s S.SomeFixity s -> s
infixFixity :: InfixApplication -> Fixity infixFixity :: InfixApplication -> Fixity
infixFixity (InfixApplication _ op _) = case S._nameFixity op of infixFixity (InfixApplication _ op _) = case op ^. S.nameFixity of
S.NoFixity -> impossible S.NoFixity -> impossible
S.SomeFixity s -> s S.SomeFixity s -> s
postfixFixity :: PostfixApplication -> Fixity postfixFixity :: PostfixApplication -> Fixity
postfixFixity (PostfixApplication _ op) = case S._nameFixity op of postfixFixity (PostfixApplication _ op) = case op ^. S.nameFixity of
S.NoFixity -> impossible S.NoFixity -> impossible
S.SomeFixity s -> s S.SomeFixity s -> s

View File

@ -26,29 +26,10 @@ newtype SymbolInfo = SymbolInfo
type SymbolEntry = S.Name' () type SymbolEntry = S.Name' ()
-- data SymbolEntry = SymbolEntry -- data SymbolEntry' = SymbolEntry' {
-- { _symbolKind :: S.NameKind, -- _entryNameInfo :: NameInfo
-- _symbolDefinedIn :: S.AbsModulePath,
-- _symbolDefined :: Interval,
-- _symbolId :: S.NameId,
-- _symbolFixity :: S.NameFixity,
-- _symbolWhyInScope :: S.WhyInScope,
-- _symbolPublicAnn :: PublicAnn
-- } -- }
-- deriving stock (Show)
-- getSymbolKind :: SymbolEntry -> S.NameKind
-- getSymbolKind SymbolEntry {..} = fromSing _symbolKind
-- instance HasLoc SymbolEntry where
-- getLoc SymbolEntry {..} = case _symbolKind of
-- S.SKNameTopModule -> getLoc _symbolSymbol
-- S.SKNameAxiom -> getLoc _symbolSymbol
-- S.SKNameConstructor -> getLoc _symbolSymbol
-- S.SKNameInductive -> getLoc _symbolSymbol
-- S.SKNameFunction -> getLoc _symbolSymbol
-- S.SKNameLocal -> getLoc _symbolSymbol
-- S.SKNameLocalModule -> getLoc _symbolSymbol
-- | Symbols that a module exports -- | Symbols that a module exports
newtype ExportInfo = ExportInfo { newtype ExportInfo = ExportInfo {

View File

@ -315,7 +315,7 @@ entryToSName :: s -> SymbolEntry -> S.Name' s
entryToSName s S.Name' {..} = S.Name' {_nameConcrete = s, ..} entryToSName s S.Name' {..} = S.Name' {_nameConcrete = s, ..}
-- | We gather all symbols which have been defined or marked to be public in the given scope. -- | We gather all symbols which have been defined or marked to be public in the given scope.
exportScope :: forall r. Members '[Error ScopeError] r => Scope -> Sem r ExportInfo exportScope :: forall r. Members '[State Scope, Error ScopeError] r => Scope -> Sem r ExportInfo
exportScope Scope {..} = do exportScope Scope {..} = do
_exportSymbols <- getExportSymbols _exportSymbols <- getExportSymbols
return ExportInfo {..} return ExportInfo {..}
@ -332,7 +332,8 @@ exportScope Scope {..} = do
case filter shouldExport (toList _symbolInfo) of case filter shouldExport (toList _symbolInfo) of
[] -> return Nothing [] -> return Nothing
[e] -> return $ Just (s, e) [e] -> return $ Just (s, e)
(e:es) -> throw (ErrMultipleExport (MultipleExportConflict (e :| es))) (e:es) -> throw (ErrMultipleExport
(MultipleExportConflict _scopePath s (e :| es)))
readParseModule :: readParseModule ::
Members '[Error ScopeError, Reader ScopeParameters, Embed IO] r => Members '[Error ScopeError, Reader ScopeParameters, Embed IO] r =>
@ -542,7 +543,7 @@ lookupModuleSymbol n = do
[x] -> return $ entryToSName n x [x] -> return $ entryToSName n x
_ -> throw (ErrAmbiguousModuleSym es) _ -> throw (ErrAmbiguousModuleSym es)
where where
notInScope = throw (ErrModuleNotInScope n) notInScope = throw (ErrModuleNotInScope (ModuleNotInScope n))
(path, sym) = case n of (path, sym) = case n of
NameUnqualified s -> ([], s) NameUnqualified s -> ([], s)
NameQualified (QualifiedName (Path p) s) -> (toList p, s) NameQualified (QualifiedName (Path p) s) -> (toList p, s)

View File

@ -96,4 +96,11 @@ tests = [
case er of case er of
ErrMultipleExport {} -> Nothing ErrMultipleExport {} -> Nothing
_ -> wrongError _ -> wrongError
, NegTest "Module not in scope"
"."
"ModuleNotInScope.mjuvix" $ \er ->
case er of
ErrModuleNotInScope {} -> Nothing
_ -> wrongError
] ]

View File

@ -0,0 +1,11 @@
module ModuleNotInScope;
module A;
end;
axiom M : Type;
open M;
end;