1
1
mirror of https://github.com/github/semantic.git synced 2024-11-28 10:15:55 +03:00

Use Statement exclusively for imperative semantics

This commit is contained in:
Timothy Clem 2018-05-30 17:06:32 -07:00
parent 40ea6d0767
commit 7e2c8eed3a
8 changed files with 80 additions and 63 deletions

View File

@ -34,8 +34,6 @@ import Data.Abstract.Name as X
import Data.Abstract.Package as Package
import Data.Abstract.Ref as X
import Data.Scientific (Scientific)
import Data.Semigroup.App
import Data.Semigroup.Foldable
import Data.Semigroup.Reducer hiding (unit)
import Data.Semilattice.Lower
import Data.Sum
@ -217,11 +215,6 @@ instance Apply Evaluatable fs => Evaluatable (Sum fs) where
instance Evaluatable s => Evaluatable (TermF s a) where
eval = eval . termFOut
-- | '[]' is treated as an imperative sequence of statements/declarations s.t.:
--
-- 1. Each statements effects on the store are accumulated;
-- 2. Each statement can affect the environment of later statements (e.g. by 'modify'-ing the environment); and
-- 3. Only the last statements return value is returned.
-- | '[]' uses the default eval. Use Data.Syntax.Statements if you need an imperative sequence.
instance Evaluatable [] where
-- 'nonEmpty' and 'foldMap1' enable us to return the last statements result instead of 'unit' for non-empty lists.
eval = maybe (pure (Rval unit)) (runApp . foldMap1 (App . subtermRef)) . nonEmpty
eval _ = throwResumable (Unspecialized ("Eval unspecialized for []"))

View File

@ -30,12 +30,6 @@ makeTerm a = makeTerm' a . inject
makeTerm' :: (HasCallStack, Semigroup a, Foldable f) => a -> f (Term f a) -> Term f a
makeTerm' a f = termIn (sconcat (a :| (termAnnotation <$> toList f))) f
-- | Lift syntax and an annotation into a term, injecting the syntax into a union & ensuring the annotation encompasses all children. Removes extra structure if term is a list of a single item.
makeTerm'' :: (HasCallStack, f :< fs, Semigroup a, Apply Foldable fs, Foldable f) => a -> f (Term (Sum fs) a) -> Term (Sum fs) a
makeTerm'' a children = case toList children of
[x] -> x
_ -> makeTerm' a (inject children)
-- | Lift non-empty syntax into a term, injecting the syntax into a union & appending all subterms.annotations to make the new terms annotation.
makeTerm1 :: (HasCallStack, f :< fs, Semigroup a, Apply Foldable fs) => f (Term (Sum fs) a) -> Term (Sum fs) a
makeTerm1 = makeTerm1' . inject
@ -46,11 +40,26 @@ makeTerm1' f = case toList f of
a : _ -> makeTerm' (termAnnotation a) f
_ -> error "makeTerm1': empty structure"
-- FIXME: I think this might be an anti-pattern.
-- | Lift syntax and an annotation into a term, injecting the syntax into a union & ensuring the annotation encompasses all children. Removes extra structure if term is a list of a single item.
makeStatementTerm :: (HasCallStack, f :< fs, Statements :< fs, Semigroup a, Apply Foldable fs, Foldable f) => a -> f (Term (Sum fs) a) -> Term (Sum fs) a
makeStatementTerm a children = case toList children of
[x] -> x
xs -> makeTerm' a (inject (Statements xs))
-- | Construct an empty term at the current position.
emptyTerm :: (HasCallStack, Empty :< fs, Apply Foldable fs) => Assignment.Assignment ast grammar (Term (Sum fs) (Record Location))
emptyTerm = makeTerm . startLocation <$> Assignment.location <*> pure Empty
where startLocation ann = Range (start (getField ann)) (start (getField ann)) :. Span (spanStart (getField ann)) (spanStart (getField ann)) :. Nil
-- | Construct zero or more Statements.
manyStatements :: (Enum grammar, Eq1 ast, Ix grammar, Show grammar) => Assignment.Assignment ast grammar (Term f a) -> Assignment.Assignment ast grammar (Statements (Term f a))
manyStatements expr = Exts.fromList <$> (many expr)
-- | Construct an empty list of Statements.
emptyStatements :: Assignment.Assignment ast grammar (Statements (Term f a))
emptyStatements = pure (Exts.fromList [])
-- | Catch assignment errors into an error term.
handleError :: (HasCallStack, Error :< fs, Enum grammar, Eq1 ast, Ix grammar, Show grammar, Apply Foldable fs) => Assignment.Assignment ast grammar (Term (Sum fs) (Record Location)) -> Assignment.Assignment ast grammar (Term (Sum fs) (Record Location))
handleError = flip catchError (\ err -> makeTerm <$> Assignment.location <*> pure (errorSyntax (either id show <$> err) []) <* Assignment.source)
@ -132,6 +141,10 @@ instance Evaluatable Program where
eval (Program statements) = eval statements
-- | Imperative sequence of statements/declarations
--
-- 1. Each statements effects on the store are accumulated;
-- 2. Each statement can affect the environment of later statements (e.g. by 'modify'-ing the environment); and
-- 3. Only the last statements return value is returned.
newtype Statements a = Statements [a]
deriving (Diffable, Eq, Foldable, Functor, Generic1, Hashable1, Mergeable, Ord, Show, Traversable, FreeVariables1, Declarations1, ToJSONFields1)
@ -140,6 +153,11 @@ instance Ord1 Statements where liftCompare = genericLiftCompare
instance Show1 Statements where liftShowsPrec = genericLiftShowsPrec
instance ToJSON1 Statements
-- | Imperative sequence of statements is evaluated s.t:
--
-- 1. Each statements effects on the store are accumulated;
-- 2. Each statement can affect the environment of later statements (e.g. by 'modify'-ing the environment); and
-- 3. Only the last statements return value is returned.
instance Evaluatable Statements where
eval (Statements xs) = maybe (pure (Rval unit)) (runApp . foldMap1 (App . subtermRef)) (nonEmpty xs)
@ -148,6 +166,7 @@ instance Exts.IsList (Statements a) where
fromList = Statements
toList (Statements xs) = xs
-- | An accessibility modifier, e.g. private, public, protected, etc.
newtype AccessibilityModifier a = AccessibilityModifier ByteString
deriving (Diffable, Eq, Foldable, Functor, Generic1, Hashable1, Mergeable, Ord, Show, Traversable, FreeVariables1, Declarations1, ToJSONFields1)

View File

@ -9,7 +9,7 @@ module Language.Go.Assignment
import Assigning.Assignment hiding (Assignment, Error)
import Data.Abstract.Name (name)
import Data.Record
import Data.Syntax (contextualize, emptyTerm, parseError, handleError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1)
import Data.Syntax (contextualize, emptyStatements, emptyTerm, handleError, infixContext, makeTerm, makeTerm', makeStatementTerm, makeTerm1, parseError)
import Language.Go.Grammar as Grammar
import Language.Go.Syntax as Go.Syntax
import Language.Go.Type as Go.Type
@ -209,10 +209,10 @@ types =
]
identifiers :: Assignment
identifiers = makeTerm'' <$> location <*> manyTerm identifier
identifiers = makeStatementTerm <$> location <*> manyTerm identifier
expressions :: Assignment
expressions = makeTerm'' <$> location <*> manyTerm expression
expressions = makeStatementTerm <$> location <*> manyTerm expression
-- Literals
@ -384,7 +384,7 @@ functionDeclaration = makeTerm <$> (symbol FunctionDeclaration <|> symbol FuncL
returnParameters = makeTerm <$> symbol ParameterList <*> children (manyTerm expression)
importDeclaration :: Assignment
importDeclaration = makeTerm'' <$> symbol ImportDeclaration <*> children (manyTerm (importSpec <|> importSpecList))
importDeclaration = makeStatementTerm <$> symbol ImportDeclaration <*> children (manyTerm (importSpec <|> importSpecList))
where
-- `import . "lib/Math"`
dotImport = inject <$> (flip Go.Syntax.Import <$> dot <*> importFromPath)
@ -401,7 +401,7 @@ importDeclaration = makeTerm'' <$> symbol ImportDeclaration <*> children (manyTe
dot = makeTerm <$> symbol Dot <*> (Literal.TextElement <$> source)
underscore = makeTerm <$> symbol BlankIdentifier <*> (Literal.TextElement <$> source)
importSpec = makeTerm' <$> symbol ImportSpec <*> children (sideEffectImport <|> dotImport <|> namedImport <|> plainImport)
importSpecList = makeTerm <$> symbol ImportSpecList <*> children (manyTerm (importSpec <|> comment))
importSpecList = makeTerm <$> symbol ImportSpecList <*> children (manyStatements (importSpec <|> comment))
importFromPath = symbol InterpretedStringLiteral *> (importPath <$> source)
indexExpression :: Assignment
@ -609,9 +609,6 @@ manyTerm = many . term
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
manyStatements expr = fromList <$> (manyTerm expr)
emptyStatements :: Assignment.Assignment [] Grammar (Syntax.Statements Term)
emptyStatements = pure (fromList [])
-- | Match a term and contextualize any comments preceeding or proceeding the term.
term :: Assignment -> Assignment
term term' = contextualize comment term' <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm)

View File

@ -9,7 +9,7 @@ module Language.Haskell.Assignment
import Assigning.Assignment hiding (Assignment, Error)
import Data.Record
import Data.Sum
import Data.Syntax (emptyTerm, handleError, parseError, makeTerm, makeTerm'', contextualize, postContextualize)
import Data.Syntax (emptyTerm, handleError, parseError, makeTerm, contextualize, postContextualize)
import Language.Haskell.Grammar as Grammar
import qualified Assigning.Assignment as Assignment
import qualified Data.Abstract.Name as Name
@ -48,7 +48,7 @@ module' = makeTerm
expressions :: Assignment
expressions = makeTerm'' <$> location <*> many expression
expressions = makeTerm <$> location <*> many expression
expression :: Assignment
expression = term (handleError (choice expressionChoices))

View File

@ -117,6 +117,7 @@ type Syntax = '[
, Syntax.ScalarType
, Syntax.ShellCommand
, Syntax.SimpleVariable
, Syntax.Statements
, Syntax.Static
, Syntax.Text
, Syntax.TraitDeclaration
@ -390,12 +391,12 @@ scalarType :: Assignment
scalarType = makeTerm <$> symbol ScalarType <*> (Syntax.ScalarType <$> source)
compoundStatement :: Assignment
compoundStatement = makeTerm <$> symbol CompoundStatement <*> children (manyTerm statement)
compoundStatement = makeTerm <$> symbol CompoundStatement <*> children (manyStatements statement)
objectCreationExpression :: Assignment
objectCreationExpression = (makeTerm <$> symbol ObjectCreationExpression <*> children (Expression.New <$> ((:) <$> term classTypeDesignator <*> (arguments <|> pure []))))
<|> (makeTerm <$> symbol ObjectCreationExpression <*> children (makeAnonClass <$ token AnonNew <* token AnonClass <*> emptyTerm <*> (arguments <|> pure []) <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyTerm classMemberDeclaration)))
<|> (makeTerm <$> symbol ObjectCreationExpression <*> children (makeAnonClass <$ token AnonNew <* token AnonClass <*> emptyTerm <*> (arguments <|> pure []) <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyStatements classMemberDeclaration)))
where makeAnonClass identifier args baseClause interfaceClause declarations = Declaration.Class [] identifier (args <> [baseClause, interfaceClause]) declarations
classMemberDeclaration :: Assignment
@ -602,7 +603,7 @@ functionDefinition = makeTerm <$> symbol FunctionDefinition <*> children (makeFu
makeFunction identifier parameters returnType statement = Declaration.Function [returnType] identifier parameters statement
classDeclaration :: Assignment
classDeclaration = makeTerm <$> symbol ClassDeclaration <*> children (makeClass <$> (term classModifier <|> emptyTerm) <*> term name <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyTerm classMemberDeclaration))
classDeclaration = makeTerm <$> symbol ClassDeclaration <*> children (makeClass <$> (term classModifier <|> emptyTerm) <*> term name <*> (term classBaseClause <|> emptyTerm) <*> (term classInterfaceClause <|> emptyTerm) <*> (makeTerm <$> location <*> manyStatements classMemberDeclaration))
where
makeClass modifier name baseClause interfaceClause declarations = Declaration.Class [modifier] name [baseClause, interfaceClause] declarations
@ -734,7 +735,7 @@ functionStaticDeclaration :: Assignment
functionStaticDeclaration = makeTerm <$> symbol FunctionStaticDeclaration <*> children (Declaration.VariableDeclaration <$> manyTerm staticVariableDeclaration)
staticVariableDeclaration :: Assignment
staticVariableDeclaration = makeTerm <$> symbol StaticVariableDeclaration <*> children (Statement.Assignment <$> pure [] <*> term variableName <*> (term expression <|> emptyTerm))
staticVariableDeclaration = makeTerm <$> symbol StaticVariableDeclaration <*> children (Statement.Assignment [] <$> term variableName <*> (term expression <|> emptyTerm))
comment :: Assignment
comment = makeTerm <$> symbol Comment <*> (Comment.Comment <$> source)
@ -767,6 +768,9 @@ someTerm = fmap NonEmpty.toList . someTerm'
someTerm' :: Assignment -> Assignment.Assignment [] Grammar (NonEmpty Term)
someTerm' = NonEmpty.some1 . commentedTerm
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
manyStatements expr = fromList <$> (manyTerm expr)
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: Assignment
-> Assignment

View File

@ -10,7 +10,7 @@ module Language.Python.Assignment
import Assigning.Assignment hiding (Assignment, Error)
import Data.Abstract.Name (name)
import Data.Record
import Data.Syntax (contextualize, emptyTerm, handleError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1, parseError, postContextualize)
import Data.Syntax (contextualize, emptyTerm, handleError, infixContext, makeTerm, makeTerm', makeStatementTerm, makeTerm1, parseError, postContextualize)
import GHC.Stack
import Language.Python.Grammar as Grammar
import Language.Python.Syntax as Python.Syntax
@ -82,6 +82,7 @@ type Syntax =
, Syntax.Error
, Syntax.Identifier
, Syntax.Program
, Syntax.Statements
, Type.Annotation
, []
]
@ -91,7 +92,7 @@ type Assignment = HasCallStack => Assignment.Assignment [] Grammar Term
-- | Assignment from AST in Python's grammar onto a program in Python's syntax.
assignment :: Assignment
assignment = handleError $ makeTerm <$> symbol Module <*> children (Syntax.Program <$> manyStatements expression) <|> parseError
assignment = handleError $ makeTerm <$> symbol Module <*> children (Syntax.Program . fromList <$> manyTerm expression) <|> parseError
expression :: Assignment
expression = handleError (choice expressionChoices)
@ -163,14 +164,15 @@ expressionChoices =
, yield
]
expressions :: Assignment
expressions = makeTerm'' <$> location <*> manyTerm expression
expressions = makeStatementTerm <$> location <*> manyTerm expression
expressionStatement :: Assignment
expressionStatement = makeTerm'' <$> symbol ExpressionStatement <*> children (someTerm expression)
expressionStatement = makeStatementTerm <$> symbol ExpressionStatement <*> children (someTerm expression)
expressionList :: Assignment
expressionList = makeTerm'' <$> symbol ExpressionList <*> children (someTerm expression)
expressionList = makeStatementTerm <$> symbol ExpressionList <*> children (someTerm expression)
listSplat :: Assignment
listSplat = makeTerm <$> symbol ListSplat <*> (Syntax.Identifier . name <$> source)
@ -241,7 +243,7 @@ functionDefinition =
makeFunctionDeclaration loc (functionName', functionParameters, ty, functionBody) = makeTerm loc $ Type.Annotation (makeTerm loc $ Declaration.Function [] functionName' functionParameters functionBody) (fromMaybe (makeTerm loc Syntax.Empty) ty)
classDefinition :: Assignment
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class <$> pure [] <*> term expression <*> argumentList <*> expressions)
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class [] <$> term expression <*> argumentList <*> expressions)
where argumentList = symbol ArgumentList *> children (manyTerm expression)
<|> pure []
@ -360,7 +362,7 @@ comment :: Assignment
comment = makeTerm <$> symbol Comment <*> (Comment.Comment <$> source)
import' :: Assignment
import' = makeTerm'' <$> symbol ImportStatement <*> children (manyTerm (aliasedImport <|> plainImport))
import' = makeStatementTerm <$> symbol ImportStatement <*> children (manyTerm (aliasedImport <|> plainImport))
<|> makeTerm <$> symbol ImportFromStatement <*> children (Python.Syntax.Import <$> importPath <*> (wildcard <|> some (aliasImportSymbol <|> importSymbol)))
where
-- `import a as b`
@ -385,7 +387,7 @@ import' = makeTerm'' <$> symbol ImportStatement <*> children (manyTerm (aliase
makeNameAliasPair from Nothing = (from, from)
assertStatement :: Assignment
assertStatement = makeTerm <$> symbol AssertStatement <*> children (Expression.Call <$> pure [] <*> (makeTerm <$> symbol AnonAssert <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
assertStatement = makeTerm <$> symbol AssertStatement <*> children (Expression.Call [] <$> (makeTerm <$> symbol AnonAssert <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
printStatement :: Assignment
printStatement = do
@ -399,19 +401,19 @@ printStatement = do
printCallTerm location identifier = makeTerm location <$> (Expression.Call [] identifier <$> manyTerm expression <*> emptyTerm)
nonlocalStatement :: Assignment
nonlocalStatement = makeTerm <$> symbol NonlocalStatement <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> symbol AnonNonlocal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
nonlocalStatement = makeTerm <$> symbol NonlocalStatement <*> children (Expression.Call [] <$> term (makeTerm <$> symbol AnonNonlocal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
globalStatement :: Assignment
globalStatement = makeTerm <$> symbol GlobalStatement <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> symbol AnonGlobal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
globalStatement = makeTerm <$> symbol GlobalStatement <*> children (Expression.Call [] <$> term (makeTerm <$> symbol AnonGlobal <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
await :: Assignment
await = makeTerm <$> symbol Await <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> symbol AnonAwait <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
await = makeTerm <$> symbol Await <*> children (Expression.Call [] <$> term (makeTerm <$> symbol AnonAwait <*> (Syntax.Identifier . name <$> source)) <*> manyTerm expression <*> emptyTerm)
returnStatement :: Assignment
returnStatement = makeTerm <$> symbol ReturnStatement <*> children (Statement.Return <$> term (expressionList <|> emptyTerm))
deleteStatement :: Assignment
deleteStatement = makeTerm <$> symbol DeleteStatement <*> children (Expression.Call <$> pure [] <*> term deleteIdentifier <* symbol ExpressionList <*> children (manyTerm expression) <*> emptyTerm)
deleteStatement = makeTerm <$> symbol DeleteStatement <*> children (Expression.Call [] <$> term deleteIdentifier <* symbol ExpressionList <*> children (manyTerm expression) <*> emptyTerm)
where deleteIdentifier = makeTerm <$> symbol AnonDel <*> (Syntax.Identifier . name <$> source)
raiseStatement :: Assignment
@ -423,7 +425,7 @@ ifStatement = makeTerm <$> symbol IfStatement <*> children (Statement.If <$> ter
makeElif (loc, makeIf) rest = makeTerm loc (makeIf rest)
execStatement :: Assignment
execStatement = makeTerm <$> symbol ExecStatement <*> children (Expression.Call <$> pure [] <*> term (makeTerm <$> location <*> (Syntax.Identifier . name <$> source)) <*> manyTerm (string <|> expression) <*> emptyTerm)
execStatement = makeTerm <$> symbol ExecStatement <*> children (Expression.Call [] <$> term (makeTerm <$> location <*> (Syntax.Identifier . name <$> source)) <*> manyTerm (string <|> expression) <*> emptyTerm)
passStatement :: Assignment
passStatement = makeTerm <$> symbol PassStatement <*> (Statement.NoOp <$> emptyTerm <* advance)
@ -447,7 +449,7 @@ slice = makeTerm <$> symbol Slice <*> children
<*> (term expression <|> emptyTerm))
call :: Assignment
call = makeTerm <$> symbol Call <*> children (Expression.Call <$> pure [] <*> term (identifier <|> expression) <*> (symbol ArgumentList *> children (manyTerm expression) <|> someTerm comprehension) <*> emptyTerm)
call = makeTerm <$> symbol Call <*> children (Expression.Call [] <$> term (identifier <|> expression) <*> (symbol ArgumentList *> children (manyTerm expression) <|> someTerm comprehension) <*> emptyTerm)
boolean :: Assignment
boolean = makeTerm <$> token Grammar.True <*> pure Literal.true
@ -476,6 +478,7 @@ conditionalExpression = makeTerm <$> symbol ConditionalExpression <*> children (
-- Helpers
-- | Match a term optionally preceded by comment(s), or a sequence of comments if the term is not present.
manyTerm :: Assignment -> Assignment.Assignment [] Grammar [Term]
manyTerm term = many (contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm))
@ -486,7 +489,6 @@ someTerm term = some (contextualize comment term <|> makeTerm1 <$> (Syntax.Conte
term :: Assignment -> Assignment
term term = contextualize comment (postContextualize comment term)
-- | Match a left-associated infix chain of terms, optionally followed by comments. Like 'chainl1' but assigning comment nodes automatically.
chainl1Term :: Assignment -> Assignment.Assignment [] Grammar (Term -> Term -> Term) -> Assignment
chainl1Term expr op = postContextualize (comment <|> symbol AnonLambda *> empty) expr `chainl1` op
@ -495,9 +497,6 @@ chainl1Term expr op = postContextualize (comment <|> symbol AnonLambda *> empty)
manyTermsTill :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar [Term]
manyTermsTill step end = manyTill (step <|> comment) end
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
manyStatements expr = fromList <$> (manyTerm expr)
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: HasCallStack
=> Assignment

View File

@ -10,7 +10,19 @@ import Assigning.Assignment hiding (Assignment, Error)
import Data.Abstract.Name (name)
import Data.List (elem)
import Data.Record
import Data.Syntax (contextualize, postContextualize, emptyTerm, parseError, handleError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1)
import Data.Syntax
( contextualize
, emptyTerm
, handleError
, infixContext
, makeTerm
, makeTerm'
, makeTerm1
, makeStatementTerm
, manyStatements
, parseError
, postContextualize
)
import Language.Ruby.Grammar as Grammar
import qualified Assigning.Assignment as Assignment
import Data.Sum
@ -146,10 +158,10 @@ expressionChoices =
mk s construct = makeTerm <$> symbol s <*> children ((construct .) . fromMaybe <$> emptyTerm <*> optional (symbol ArgumentList *> children expressions))
expressions :: Assignment
expressions = makeTerm'' <$> location <*> many expression
expressions = makeStatementTerm <$> location <*> many expression
parenthesizedExpressions :: Assignment
parenthesizedExpressions = makeTerm'' <$> symbol ParenthesizedStatements <*> children (many expression)
parenthesizedExpressions = makeTerm <$> symbol ParenthesizedStatements <*> children (manyStatements expression)
withExtendedScope :: Assignment' a -> Assignment' a
withExtendedScope inner = do
@ -262,9 +274,8 @@ parameter = postContextualize comment (term uncontextualizedParameter)
optionalParameter = symbol OptionalParameter *> children (lhsIdent <* expression)
method :: Assignment
method = makeTerm <$> symbol Method <*> (withNewScope . children) (Declaration.Method <$> pure [] <*> emptyTerm <*> methodSelector <*> params <*> expressions')
method = makeTerm <$> symbol Method <*> (withNewScope . children) (Declaration.Method <$> pure [] <*> emptyTerm <*> methodSelector <*> params <*> expressions)
where params = symbol MethodParameters *> children (many parameter) <|> pure []
expressions' = makeTerm <$> location <*> many expression
singletonMethod :: Assignment
singletonMethod = makeTerm <$> symbol SingletonMethod <*> (withNewScope . children) (Declaration.Method <$> pure [] <*> expression <*> methodSelector <*> params <*> expressions)
@ -493,11 +504,8 @@ term term = contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> som
where heredocEnd = makeTerm <$> symbol HeredocEnd <*> (Literal.TextElement <$> source)
-- | Match a series of terms or comments until a delimiter is matched.
manyTermsTill :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar [Term]
manyTermsTill step end = manyTill (step <|> comment) end
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
manyStatements expr = fromList <$> (many expr)
manyTermsTill :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
manyTermsTill step end = fromList <$> manyTill (step <|> comment) end
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: HasCallStack

View File

@ -11,7 +11,7 @@ import Data.Abstract.Name (name)
import qualified Assigning.Assignment as Assignment
import Data.Record
import Data.Sum
import Data.Syntax (emptyTerm, handleError, parseError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1, contextualize, postContextualize)
import Data.Syntax (emptyTerm, emptyStatements, handleError, parseError, infixContext, makeTerm, makeTerm', makeStatementTerm, makeTerm1, contextualize, postContextualize)
import qualified Data.Syntax as Syntax
import qualified Data.Syntax.Comment as Comment
import qualified Data.Syntax.Declaration as Declaration
@ -558,10 +558,10 @@ constructorTy :: Assignment
constructorTy = makeTerm <$> symbol ConstructorType <*> children (TypeScript.Syntax.Constructor <$> (fromMaybe <$> emptyTerm <*> optional (term typeParameters)) <*> formalParameters <*> term ty)
statementBlock :: Assignment
statementBlock = makeTerm <$> symbol StatementBlock <*> children (manyTerm statement)
statementBlock = makeTerm <$> symbol StatementBlock <*> children (manyStatements statement)
classBodyStatements :: Assignment
classBodyStatements = makeTerm'' <$> symbol ClassBody <*> children (contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> (concat <$> many ((\as b -> as ++ [b]) <$> manyTerm decorator <*> term (methodDefinition <|> publicFieldDefinition <|> methodSignature <|> indexSignature <|> abstractMethodSignature))) <*> many comment))
classBodyStatements = makeStatementTerm <$> symbol ClassBody <*> children (contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> (concat <$> many ((\as b -> as ++ [b]) <$> manyTerm decorator <*> term (methodDefinition <|> publicFieldDefinition <|> methodSignature <|> indexSignature <|> abstractMethodSignature))) <*> many comment))
where
contextualize' (cs, formalParams) = case nonEmpty cs of
Just cs -> toList cs ++ formalParams
@ -863,9 +863,6 @@ manyTerm term = many (contextualize comment term <|> makeTerm1 <$> (Syntax.Conte
manyStatements :: Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar (Syntax.Statements Term)
manyStatements expr = fromList <$> (manyTerm expr)
emptyStatements :: Assignment.Assignment [] Grammar (Syntax.Statements Term)
emptyStatements = pure (fromList [])
term :: Assignment -> Assignment
term term = contextualize comment (postContextualize comment term)