Skip to content

Commit

Permalink
Merge pull request avh4#748 from emmabastas/new-parser-2021-refactor
Browse files Browse the repository at this point in the history
Misc refactors to the Elm compiler's parser integration code
  • Loading branch information
avh4 committed Aug 21, 2021
2 parents a424c87 + 8bbb6ad commit 7bd05db
Show file tree
Hide file tree
Showing 27 changed files with 395 additions and 657 deletions.
5 changes: 0 additions & 5 deletions elm-format-lib/elm-format-lib.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ common common-options
Parse.Number
Parse.Parse
Parse.ParsecAdapter
Parse.ParsecAdapter.Message
Parse.Pattern
Parse.Primitives
Parse.State
Expand Down Expand Up @@ -117,9 +116,7 @@ library
ElmVersion
Parse.Markdown
Reporting.Annotation
Reporting.Annotation.New
Reporting.Error.Syntax
Reporting.Region
Reporting.Result


Expand Down Expand Up @@ -147,9 +144,7 @@ test-suite efl-tests
ElmVersion
Parse.Markdown
Reporting.Annotation
Reporting.Annotation.New
Reporting.Error.Syntax
Reporting.Region
Reporting.Result

other-modules:
Expand Down
6 changes: 3 additions & 3 deletions elm-format-lib/src/ElmFormat/AST/PatternMatching.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module ElmFormat.AST.PatternMatching where
import ElmFormat.AST.Shared
import AST.V0_16
import AST.Structure
import Reporting.Annotation (Located(A))
import Reporting.Annotation (Located(At))
import Data.Indexed as I


Expand All @@ -23,12 +23,12 @@ matchType ::
, ASTNS Located ns 'TypeNK
)
matchType [] typ = ( [], typ )
matchType (pat : restPat) (I.Fix (A region (FunctionType (C eol typ) restTyp multiline))) =
matchType (pat : restPat) (I.Fix (At region (FunctionType (C eol typ) restTyp multiline))) =
let
nextTyp =
case toCommentedList restTyp of
[ (C _ single) ] -> single
( (C (_, _, eol2) first) : rest ) -> I.Fix $ A region $ FunctionType (C eol2 first) (Sequence rest) multiline
( (C (_, _, eol2) first) : rest ) -> I.Fix $ At region $ FunctionType (C eol2 first) (Sequence rest) multiline

( pats, retType ) =
matchType restPat nextTyp
Expand Down
31 changes: 14 additions & 17 deletions elm-format-lib/src/ElmFormat/AST/PublicAST/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ module ElmFormat.AST.PublicAST.Core
, module AST.V0_16
, module AST.Structure
, module Reporting.Annotation
, module Reporting.Region
, module Data.Coapplicative
, module ElmFormat.AST.PublicAST.MaybeF
, module ElmFormat.AST.PublicAST.Config
Expand All @@ -39,10 +38,8 @@ import qualified AST.V0_16 as AST
import qualified AST.Module as AST
import qualified AST.Listing as AST
import Data.Indexed as I
import Reporting.Annotation (Located(A))
import qualified Reporting.Annotation
import Reporting.Region (Region)
import qualified Reporting.Region as Region
import Reporting.Annotation (Located, Region, Position)
import qualified Reporting.Annotation as A
import Data.Coapplicative
import qualified Data.List as List
import qualified Data.Text as Text
Expand Down Expand Up @@ -189,25 +186,25 @@ instance (FromJSON a) => FromJSON (LocatedIfRequested a) where

instance ToPairs a => ToJSON (Located a) where
toJSON = undefined
toEncoding (A region a) =
toEncoding (A.At region a) =
pairs (toPairs a <> "sourceLocation" .= region)


instance ToJSON Region where
toJSON = undefined
toEncoding region =
toEncoding (A.Region start end) =
pairs $ mconcat
[ "start" .= Region.start region
, "end" .= Region.end region
[ "start" .= start
, "end" .= end
]


instance ToJSON Region.Position where
instance ToJSON A.Position where
toJSON = undefined
toEncoding pos =
toEncoding (A.Position row col) =
pairs $ mconcat
[ "line" .= Region.line pos
, "col" .= Region.column pos
[ "line" .= row
, "col" .= col
]


Expand Down Expand Up @@ -482,11 +479,11 @@ instance (FromJSON (f a)) => FromJSON (MaybeF f a) where
--


nowhere :: Region.Position
nowhere :: A.Position
nowhere =
Region.Position 0 0
A.Position 0 0


noRegion :: a -> Reporting.Annotation.Located a
noRegion :: a -> Located a
noRegion =
Reporting.Annotation.at nowhere nowhere
A.at nowhere nowhere
5 changes: 3 additions & 2 deletions elm-format-lib/src/ElmFormat/AST/PublicAST/Expression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import qualified Data.Maybe as Maybe
import ElmFormat.AST.PublicAST.Pattern
import ElmFormat.AST.PublicAST.Type
import ElmFormat.AST.PublicAST.Comment
import Reporting.Annotation (Located(At))
import Data.Maybe (mapMaybe, fromMaybe)
import Data.Text (Text)
import qualified Data.Either as Either
Expand Down Expand Up @@ -49,7 +50,7 @@ mkLetDeclarations config decls =
let
toDefBuilder :: ASTNS1 Located [UppercaseIdentifier] 'LetDeclarationNK -> DefinitionBuilder LetDeclaration
toDefBuilder = \case
AST.LetCommonDeclaration (I.Fix (A _ def)) ->
AST.LetCommonDeclaration (I.Fix (At _ def)) ->
Right def

AST.LetComment comment ->
Expand Down Expand Up @@ -716,7 +717,7 @@ mkDefinitions config fromDef items =
merge :: DefinitionBuilder a -> Maybe a
merge decl =
case decl of
Right (AST.Definition (I.Fix (A _ pat)) args comments expr) ->
Right (AST.Definition (I.Fix (At _ pat)) args comments expr) ->
let
annotation =
case pat of
Expand Down
9 changes: 5 additions & 4 deletions elm-format-lib/src/ElmFormat/AST/PublicAST/Module.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ElmFormat.AST.PublicAST.Core
import ElmFormat.AST.PublicAST.Comment
import ElmFormat.AST.PublicAST.Expression
import ElmFormat.AST.PublicAST.Type
import Reporting.Annotation (Located(At))
import qualified AST.V0_16 as AST
import qualified AST.Module as AST
import qualified AST.Listing as AST
Expand Down Expand Up @@ -140,16 +141,16 @@ data TopLevelStructure
| TODO_TopLevelStructure String

fromTopLevelStructures :: Config -> ASTNS Located [UppercaseIdentifier] 'TopLevelNK -> List (MaybeF LocatedIfRequested TopLevelStructure)
fromTopLevelStructures config (I.Fix (A _ (AST.TopLevel decls))) =
fromTopLevelStructures config (I.Fix (At _ (AST.TopLevel decls))) =
let
toDefBuilder :: AST.TopLevelStructure
(ASTNS Located [UppercaseIdentifier] 'TopLevelDeclarationNK) -> MaybeF LocatedIfRequested (DefinitionBuilder TopLevelStructure)
toDefBuilder decl =
case fmap I.unFix decl of
AST.Entry (A region entry) ->
JustF $ fromLocated config $ A region $
AST.Entry (At region entry) ->
JustF $ fromLocated config $ At region $
case entry of
AST.CommonDeclaration (I.Fix (A _ def)) ->
AST.CommonDeclaration (I.Fix (At _ def)) ->
Right def

AST.TypeAlias c1 (C (c2, c3) (AST.NameWithArgs name args)) (C c4 t) ->
Expand Down
11 changes: 5 additions & 6 deletions elm-format-lib/src/ElmFormat/Render/Box.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ import qualified ElmFormat.Render.ElmStructure as ElmStructure
import qualified ElmFormat.Render.Markdown
import qualified ElmVersion
import qualified Parse.Parse as Parse
import qualified Reporting.Annotation as RA
import qualified Reporting.Region as Region
import qualified Reporting.Annotation as A
import qualified Reporting.Result as Result
import Text.Printf (printf)

Expand Down Expand Up @@ -1715,14 +1714,14 @@ formatRange_0_17 elmVersion importInfo left right multiline =
, line $ punc "]"
]

nowhere :: Region.Position
nowhere :: A.Position
nowhere =
Region.Position 0 0
A.Position 0 0


noRegion :: a -> RA.Located a
noRegion :: a -> A.Located a
noRegion =
RA.at nowhere nowhere
A.at nowhere nowhere

formatRange_0_18 ::
Coapplicative annf =>
Expand Down
14 changes: 7 additions & 7 deletions elm-format-lib/src/Parse/Expression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Data.Coapplicative
import qualified Data.Indexed as I
import Data.Maybe (fromMaybe)

import Parse.ParsecAdapter hiding (newline, spaces)
import Parse.ParsecAdapter
import qualified Parse.Binop as Binop
import Parse.Helpers
import Parse.Common
Expand Down Expand Up @@ -157,10 +157,10 @@ head' (a:_) = Just a
appExpr :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'ExpressionNK)
appExpr elmVersion =
expecting "an expression" $
do start <- getMyPosition
do start <- getPosition
(t, initialTermMultiline) <- trackNewline (term elmVersion)
ts <- constrainedSpacePrefix (term elmVersion)
end <- getMyPosition
end <- getPosition
return $
case ts of
[] ->
Expand Down Expand Up @@ -291,13 +291,13 @@ letExpr :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'Expressio
letExpr elmVersion =
fmap I.Fix $ addLocation $
do try (reserved elmVersion "let")
A.A cal commentsAfterLet' <- addLocation whitespace
let commentsAfterLet = fmap (I.Fix . A.A cal . LetComment) commentsAfterLet'
A.At cal commentsAfterLet' <- addLocation whitespace
let commentsAfterLet = fmap (I.Fix . A.At cal . LetComment) commentsAfterLet'
defs <-
block $
do def <- fmap I.Fix $ addLocation $ fmap (LetCommonDeclaration . I.Fix) $ addLocation (typeAnnotation elmVersion TypeAnnotation <|> definition elmVersion Definition)
A.A cad commentsAfterDef' <- addLocation whitespace
let commentsAfterDef = fmap (I.Fix . A.A cad . LetComment) commentsAfterDef'
A.At cad commentsAfterDef' <- addLocation whitespace
let commentsAfterDef = fmap (I.Fix . A.At cad . LetComment) commentsAfterDef'
return (def : commentsAfterDef)
_ <- reserved elmVersion "in"
bodyComments <- whitespace
Expand Down
47 changes: 21 additions & 26 deletions elm-format-lib/src/Parse/Helpers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import qualified Parse.State as State
import Parse.Comments
import Parse.IParser
import Parse.Whitespace
import qualified Parse.Primitives as EP
import qualified Parse.Primitives as P
import qualified Parse.ParsecAdapter as Parsec
import qualified Reporting.Annotation as A
import qualified Reporting.Error.Syntax as Syntax
import qualified Reporting.Region as R


reserveds :: [String]
Expand All @@ -42,14 +42,14 @@ expecting = flip (<?>)

-- SETUP

iParse :: IParser a -> String -> Either ParseError a
iParse :: IParser a -> String -> Either ParsecError a
iParse =
iParseWithState "" State.init
iParseWithState State.init


iParseWithState :: SourceName -> State.State -> IParser a -> String -> Either ParseError a
iParseWithState sourceName state aParser input =
runIndent sourceName $ runParserT aParser state sourceName input
iParseWithState :: State.State -> IParser a -> String -> Either ParsecError a
iParseWithState state aParser input =
runIndent $ runParserT aParser state input


-- VARIABLES
Expand Down Expand Up @@ -98,7 +98,7 @@ makeVar :: ElmVersion -> IParser Char -> IParser String
makeVar elmVersion firstChar =
do variable <- (:) <$> firstChar <*> many (innerVarChar elmVersion)
if variable `elem` reserveds
then fail (Syntax.keyword variable)
then parserFail $ parseError (Message (Syntax.keyword variable))
else return variable


Expand Down Expand Up @@ -290,11 +290,11 @@ keyValue parseSep parseKey parseVal =
)


separated :: IParser sep -> IParser e -> IParser (Either e (R.Region, C0Eol e, Sequence e, Bool))
separated :: IParser sep -> IParser e -> IParser (Either e (A.Region, C0Eol e, Sequence e, Bool))
separated sep expr' =
let
subparser =
do start <- getMyPosition
do start <- Parsec.getPosition
t1 <- expr'
arrow <- optionMaybe $ try ((,) <$> restOfLine <*> whitespace <* sep)
case arrow of
Expand All @@ -303,11 +303,11 @@ separated sep expr' =
Just (eolT1, preArrow) ->
do postArrow <- whitespace
t2 <- separated sep expr'
end <- getMyPosition
end <- Parsec.getPosition
case t2 of
Right (_, C eolT2 t2', Sequence ts, _) ->
return $ \multiline -> Right
( R.Region start end
( A.Region start end
, C eolT1 t1
, Sequence (C (preArrow, postArrow, eolT2) t2' : ts)
, multiline
Expand All @@ -316,7 +316,7 @@ separated sep expr' =
do
eol <- restOfLine
return $ \multiline -> Right
( R.Region start end
( A.Region start end
, C eolT1 t1
, Sequence [ C (preArrow, postArrow, eol) t2' ]
, multiline)
Expand Down Expand Up @@ -459,28 +459,23 @@ surround'' leftDelim rightDelim inner =

-- HELPERS FOR EXPRESSIONS

getMyPosition :: IParser R.Position
getMyPosition =
R.fromSourcePos <$> getPosition


addLocation :: IParser a -> IParser (A.Located a)
addLocation expr =
do (start, e, end) <- located expr
return (A.at start end e)


located :: IParser a -> IParser (R.Position, a, R.Position)
located :: IParser a -> IParser (A.Position, a, A.Position)
located parser =
do start <- getMyPosition
do start <- Parsec.getPosition
value <- parser
end <- getMyPosition
end <- Parsec.getPosition
return (start, value, end)


accessible :: ElmVersion -> IParser (FixAST A.Located typeRef ctorRef varRef 'ExpressionNK) -> IParser (FixAST A.Located typeRef ctorRef varRef 'ExpressionNK)
accessible elmVersion exprParser =
do start <- getMyPosition
do start <- Parsec.getPosition
rootExpr <- exprParser
access <- optionMaybe (try dot <?> "a field access like .name")

Expand All @@ -491,7 +486,7 @@ accessible elmVersion exprParser =
Just _ ->
accessible elmVersion $
do v <- lowVar elmVersion
end <- getMyPosition
end <- Parsec.getPosition
return $ I.Fix $ A.at start end $ Access rootExpr v


Expand All @@ -516,9 +511,9 @@ commentedKeyword elmVersion word parser =
-- continuation is called instead of the empty continuation.
failure :: String -> IParser String
failure msg =
EP.Parser $ \s _ _ cerr _ ->
P.Parser $ \s _ _ cerr _ ->
let
(EP.Parser p) = fail msg
(P.Parser p) = parserFail $ parseError (Message msg)
in
-- This looks really unsound, but `p` which was created with `fail` will
-- only ever call the empty error continuation (which in this case
Expand Down Expand Up @@ -570,4 +565,4 @@ processAs processor s =
where
calloutParser :: String -> IParser a -> IParser a
calloutParser inp p =
either (fail . show) return (iParse p inp)
either (parserFail . const . const) return (iParse p inp)
4 changes: 2 additions & 2 deletions elm-format-lib/src/Parse/IParser.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Parse.IParser where

import Parse.Primitives (Parser)
import Parse.ParsecAdapter (ParseError)
import Reporting.Error.Syntax (ParsecError)


type IParser a = Parser ParseError a
type IParser a = Parser ParsecError a
Loading

0 comments on commit 7bd05db

Please sign in to comment.