Skip to content

Commit

Permalink
Add dangling judoc error (#2099)
Browse files Browse the repository at this point in the history
  • Loading branch information
janmasrovira authored May 16, 2023
1 parent 3ed30dd commit d135f74
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 20 deletions.
6 changes: 3 additions & 3 deletions src/Juvix/Compiler/Concrete/Data/Highlight/PrettyJudoc.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ ppDoc :: Members '[Reader Options] r => Scoped.AName -> Maybe Internal.Expressio
ppDoc n ty j = do
n' <- ppScoped n
ty' <- fmap ((n' <+> kwColon) <+>) <$> mapM ppInternal ty
j' <- join <$> mapM ppJudoc j
j' <- mapM ppJudoc j
return $
case (ty', j') of
(Just jty', Just jj') -> return (jty' <+> line <> line <> jj')
_ -> ty' <|> j'

ppJudoc :: forall r. Members '[Reader Options] r => Judoc 'Scoped -> Sem r (Maybe (Doc CodeAnn))
ppJudoc :: forall r. Members '[Reader Options] r => Judoc 'Scoped -> Sem r (Doc CodeAnn)
ppJudoc (Judoc bs) = do
void (ask @Options) -- to suppress redundant constraint warning
mapM ppBlocks (nonEmpty bs)
ppBlocks bs
where
ppBlocks :: NonEmpty (JudocBlock 'Scoped) -> Sem r (Doc CodeAnn)
ppBlocks = fmap vsep2 . mapM ppBlock
Expand Down
12 changes: 6 additions & 6 deletions src/Juvix/Compiler/Concrete/Language.hs
Original file line number Diff line number Diff line change
Expand Up @@ -888,9 +888,9 @@ data ExpressionAtoms (s :: Stage) = ExpressionAtoms
}

newtype Judoc (s :: Stage) = Judoc
{ _block :: [JudocBlock s]
{ _block :: NonEmpty (JudocBlock s)
}
deriving newtype (Semigroup, Monoid)
deriving newtype (Semigroup)

deriving stock instance (Show (ExpressionType s), Show (SymbolType s)) => Show (Judoc s)

Expand Down Expand Up @@ -1170,12 +1170,9 @@ getLocExpressionType = case sing :: SStage s of
SParsed -> getLoc
SScoped -> getLoc

getJudocLoc :: Judoc s -> Maybe Interval
getJudocLoc = fmap getLocSpan . nonEmpty . (^. block)

instance SingI s => HasLoc (TypeSignature s) where
getLoc TypeSignature {..} =
(_sigDoc >>= getJudocLoc)
(getLoc <$> _sigDoc)
?<> (getLoc <$> _sigPragmas)
?<> (getLoc <$> _sigBuiltin)
?<> (getLoc <$> _sigTerminating)
Expand All @@ -1185,6 +1182,9 @@ instance SingI s => HasLoc (TypeSignature s) where
instance HasLoc (Example s) where
getLoc e = e ^. exampleLoc

instance HasLoc (Judoc s) where
getLoc (Judoc j) = getLocSpan j

instance HasLoc (JudocBlock s) where
getLoc = \case
JudocParagraph ls -> getLocSpan ls
Expand Down
2 changes: 1 addition & 1 deletion src/Juvix/Compiler/Concrete/Print/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ instance PrettyPrint (JudocParagraphLine 'Scoped) where

instance PrettyPrint (Judoc 'Scoped) where
ppCode :: forall r. Members '[ExactPrint, Reader Options] r => Judoc 'Scoped -> Sem r ()
ppCode (Judoc blocks) = sequenceWith paragraphSep (map ppCode blocks) >> line
ppCode (Judoc blocks) = sequenceWith paragraphSep (fmap ppCode blocks) >> line
where
paragraphSep :: Sem r ()
paragraphSep = line >> noLoc P.ppJudocStart >> line
Expand Down
32 changes: 22 additions & 10 deletions src/Juvix/Compiler/Concrete/Translation/FromSource.hs
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,25 @@ statement :: (Members '[Files, Error ParserError, PathResolver, InfoTableBuilder
statement = P.label "<top level statement>" $ do
void (optional stashJudoc)
void (optional stashPragmas)
(StatementOperator <$> operatorSyntaxDef)
<|> (StatementOpenModule <$> openModule)
<|> (StatementImport <$> import_)
<|> (StatementInductive <$> inductiveDef Nothing)
<|> (StatementModule <$> moduleDef)
<|> (StatementAxiom <$> axiomDef Nothing)
<|> builtinStatement
<|> ( either StatementTypeSignature StatementFunctionClause
ms <-
optional
( StatementOperator <$> operatorSyntaxDef
<|> StatementOpenModule <$> openModule
<|> StatementImport <$> import_
<|> StatementInductive <$> inductiveDef Nothing
<|> StatementModule <$> moduleDef
<|> StatementAxiom <$> axiomDef Nothing
<|> builtinStatement
<|> either StatementTypeSignature StatementFunctionClause
<$> auxTypeSigFunClause
)
)
case ms of
Just s -> return s
Nothing -> do
mj <- peekJudoc
case mj of
Nothing -> P.failure Nothing mempty
Just j -> P.lift . throw . ErrDanglingJudoc . DanglingJudoc $ j

stashPragmas :: forall r. (Members '[InfoTableBuilder, PragmasStash, NameIdGen] r) => ParsecS r ()
stashPragmas = do
Expand All @@ -276,7 +285,7 @@ stashJudoc = do
P.lift (modify (<> Just b))
where
judocBlocks :: ParsecS r (Judoc 'Parsed)
judocBlocks = Judoc <$> some judocBlock
judocBlocks = Judoc <$> some1 judocBlock

judocBlock :: ParsecS r (JudocBlock 'Parsed)
judocBlock = do
Expand Down Expand Up @@ -519,6 +528,9 @@ universe = do
Just (lvl, i') -> Universe (Just lvl) (i <> i')
)

peekJudoc :: (Member JudocStash r) => ParsecS r (Maybe (Judoc 'Parsed))
peekJudoc = P.lift get

getJudoc :: (Member JudocStash r) => ParsecS r (Maybe (Judoc 'Parsed))
getJudoc = P.lift $ do
j <- get
Expand Down
22 changes: 22 additions & 0 deletions src/Juvix/Parser/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ data ParserError
| ErrTopModulePath TopModulePathError
| ErrWrongTopModuleName WrongTopModuleName
| ErrStdinOrFile StdinOrFileError
| ErrDanglingJudoc DanglingJudoc
deriving stock (Show)

instance ToGenericError ParserError where
Expand All @@ -22,6 +23,7 @@ instance ToGenericError ParserError where
ErrTopModulePath e -> genericError e
ErrWrongTopModuleName e -> genericError e
ErrStdinOrFile e -> genericError e
ErrDanglingJudoc e -> genericError e

instance Pretty MegaparsecError where
pretty (MegaparsecError b) = pretty (M.errorBundlePretty b)
Expand Down Expand Up @@ -114,3 +116,23 @@ instance ToGenericError StdinOrFileError where
_genericErrorMessage = prettyError "Neither JUVIX_FILE_OR_PROJECT nor --stdin option is choosen",
_genericErrorIntervals = []
}

newtype DanglingJudoc = DanglingJudoc
{ _danglingJudoc :: Judoc 'Parsed
}
deriving stock (Show)

instance ToGenericError DanglingJudoc where
genericError :: Member (Reader GenericOptions) r => DanglingJudoc -> Sem r GenericError
genericError DanglingJudoc {..} = do
opts <- fromGenericOptions <$> ask
let msg = "Dangling judoc comment:\n" <+> ppCode opts _danglingJudoc
return
GenericError
{ _genericErrorLoc = i,
_genericErrorMessage = AnsiText msg,
_genericErrorIntervals = [i]
}
where
i :: Interval
i = getLoc _danglingJudoc
8 changes: 8 additions & 0 deletions test/Parsing/Negative.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,13 @@ filesErrorTests =
$ \case
ErrTopModulePath
TopModulePathError {_topModulePathError = ErrMissingModule {}} -> Nothing
_ -> wrongError,
negTest
"Dangling Judoc comment"
$(mkRelDir ".")
$(mkRelFile "DanglingJudoc.juvix")
$ \case
ErrDanglingJudoc
DanglingJudoc {} -> Nothing
_ -> wrongError
]
5 changes: 5 additions & 0 deletions tests/negative/DanglingJudoc.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module DanglingJudoc;

axiom A : Type;

--- hello

0 comments on commit d135f74

Please sign in to comment.