1
1
mirror of https://github.com/github/semantic.git synced 2025-01-03 04:51:57 +03:00

Use term to contextualize / post contextualize comments

This commit is contained in:
Rick Winfrey 2017-11-15 15:37:12 -08:00
parent 017b511469
commit 2cd1bc4f59

View File

@ -9,7 +9,7 @@ module Language.Go.Assignment
import Data.Functor (void)
import Data.List.NonEmpty (some1)
import Data.Record
import Data.Syntax (contextualize, emptyTerm, parseError, handleError, infixContext, makeTerm, makeTerm', makeTerm1)
import Data.Syntax (contextualize, emptyTerm, parseError, handleError, infixContext, makeTerm, makeTerm', makeTerm1, postContextualize)
import qualified Data.Syntax as Syntax
import Data.Syntax.Assignment hiding (Assignment, Error)
import qualified Data.Syntax.Assignment as Assignment
@ -101,9 +101,31 @@ type Syntax =
type Term = Term.Term (Union Syntax) (Record Location)
type Assignment = HasCallStack => Assignment.Assignment [] Grammar Term
-- Helpers
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: Assignment
-> Assignment
-> [Assignment.Assignment [] Grammar (Term -> Term -> Union Syntax Term)]
-> Assignment.Assignment [] Grammar (Union Syntax Term)
infixTerm = infixContext comment
-- | Match a series of terms or comments until a delimiter is matched
manyTermsTill :: Show b => Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar [Term]
manyTermsTill step end = manyTill (step <|> comment) end
-- | 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))
-- | Match a term and contextualize any comments preceeding or proceeding the term.
term :: Assignment -> Assignment
term term = contextualize comment (postContextualize comment term)
-- | Assignment from AST in Go's grammar onto a program in Go's syntax.
assignment :: Assignment
assignment = handleError $ makeTerm <$> symbol SourceFile <*> children (Syntax.Program <$> many expression) <|> parseError
assignment = handleError $ makeTerm <$> symbol SourceFile <*> children (Syntax.Program <$> manyTerm expression) <|> parseError
expression :: Assignment
expression = term (handleError (choice expressionChoices))
@ -193,13 +215,13 @@ expressionChoices =
]
identifiers :: Assignment
identifiers = mk <$> location <*> many identifier
identifiers = mk <$> location <*> manyTerm identifier
where
mk _ [a] = a
mk loc children = makeTerm loc children
expressions :: Assignment
expressions = mk <$> location <*> many expression
expressions = mk <$> location <*> manyTerm expression
where
mk _ [a] = a
mk loc children = makeTerm loc children
@ -234,10 +256,10 @@ imaginaryLiteral :: Assignment
imaginaryLiteral = makeTerm <$> symbol ImaginaryLiteral <*> (Literal.Complex <$> source)
literalValue :: Assignment
literalValue = makeTerm <$> symbol LiteralValue <*> children (many expression)
literalValue = makeTerm <$> symbol LiteralValue <*> children (manyTerm expression)
compositeLiteral :: Assignment
compositeLiteral = makeTerm <$> symbol CompositeLiteral <*> children (Literal.Composite <$> expression <*> expression)
compositeLiteral = makeTerm <$> symbol CompositeLiteral <*> children (Literal.Composite <$> term expression <*> term expression)
intLiteral :: Assignment
intLiteral = makeTerm <$> symbol IntLiteral <*> (Literal.Integer <$> source)
@ -261,7 +283,7 @@ packageIdentifier :: Assignment
packageIdentifier = makeTerm <$> symbol PackageIdentifier <*> (Syntax.Identifier <$> source)
parenthesizedType :: Assignment
parenthesizedType = makeTerm <$> symbol Grammar.ParenthesizedType <*> children (Go.Syntax.ParenthesizedType <$> expression)
parenthesizedType = makeTerm <$> symbol Grammar.ParenthesizedType <*> children (Go.Syntax.ParenthesizedType <$> term expression)
interpretedStringLiteral :: Assignment
interpretedStringLiteral = makeTerm <$> symbol InterpretedStringLiteral <*> (Literal.TextElement <$> source)
@ -276,41 +298,41 @@ runeLiteral = makeTerm <$> symbol Grammar.RuneLiteral <*> (Go.Syntax.RuneLiteral
-- Primitive Types
qualifiedType :: Assignment
qualifiedType = makeTerm <$> symbol QualifiedType <*> children (Expression.MemberAccess <$> expression <*> expression)
qualifiedType = makeTerm <$> symbol QualifiedType <*> children (Expression.MemberAccess <$> term expression <*> term expression)
arrayType :: Assignment
arrayType = makeTerm <$> symbol ArrayType <*> children (Type.Array . Just <$> expression <*> (expression <|> arrayType))
arrayType = makeTerm <$> symbol ArrayType <*> children (Type.Array . Just <$> term expression <*> (term expression <|> term arrayType))
implicitLengthArrayType :: Assignment
implicitLengthArrayType = makeTerm <$> symbol ImplicitLengthArrayType <*> children (Type.Array Nothing <$> expression)
implicitLengthArrayType = makeTerm <$> symbol ImplicitLengthArrayType <*> children (Type.Array Nothing <$> term expression)
functionType :: Assignment
functionType = makeTerm <$> symbol FunctionType <*> children (Type.Function <$> many parameters <*> returnType)
functionType = makeTerm <$> symbol FunctionType <*> children (Type.Function <$> manyTerm parameters <*> term returnType)
where
returnType = symbol Parameters *> children expressions <|> expression <|> emptyTerm
returnType = symbol Parameters *> children expressions <|> term expression <|> emptyTerm
sliceType :: Assignment
sliceType = makeTerm <$> symbol SliceType <*> children (Type.Slice <$> expression)
sliceType = makeTerm <$> symbol SliceType <*> children (Type.Slice <$> term expression)
channelType :: Assignment
channelType = (makeTerm <$> symbol ChannelType <*> children (token AnonLAngleMinus *> token AnonChan *> (Type.ReceiveChannel <$> expression)))
<|> (makeTerm <$> symbol ChannelType <*> children (token AnonChan *> token AnonLAngleMinus *> (Type.SendChannel <$> expression)))
<|> (makeTerm <$> symbol ChannelType <*> children (token AnonChan *> (Type.BiDirectionalChannel <$> expression)))
channelType = (makeTerm <$> symbol ChannelType <*> children (token AnonLAngleMinus *> token AnonChan *> (Type.ReceiveChannel <$> term expression)))
<|> (makeTerm <$> symbol ChannelType <*> children (token AnonChan *> token AnonLAngleMinus *> (Type.SendChannel <$> term expression)))
<|> (makeTerm <$> symbol ChannelType <*> children (token AnonChan *> (Type.BiDirectionalChannel <$> term expression)))
structType :: Assignment
structType = handleError $ makeTerm <$> symbol StructType <*> children (Declaration.Constructor <$> emptyTerm <*> many expression)
structType = handleError $ makeTerm <$> symbol StructType <*> children (Declaration.Constructor <$> emptyTerm <*> manyTerm expression)
interfaceType :: Assignment
interfaceType = handleError $ makeTerm <$> symbol InterfaceType <*> children (Type.Interface <$> many expression)
interfaceType = handleError $ makeTerm <$> symbol InterfaceType <*> children (Type.Interface <$> manyTerm expression)
mapType :: Assignment
mapType = handleError $ makeTerm <$> symbol MapType <*> children (Type.Map <$> expression <*> expression)
mapType = handleError $ makeTerm <$> symbol MapType <*> children (Type.Map <$> term expression <*> term expression)
pointerType :: Assignment
pointerType = handleError $ makeTerm <$> symbol PointerType <*> children (Type.Pointer <$> expression)
pointerType = handleError $ makeTerm <$> symbol PointerType <*> children (Type.Pointer <$> term expression)
fieldDeclaration :: Assignment
fieldDeclaration = mkFieldDeclarationWithTag <$> symbol FieldDeclaration <*> children ((,,) <$> (manyTermsTill expression (void (symbol TypeIdentifier)) <|> (many expression)) <*> optional expression <*> optional expression)
fieldDeclaration = mkFieldDeclarationWithTag <$> symbol FieldDeclaration <*> children ((,,) <$> (manyTermsTill expression (void (symbol TypeIdentifier)) <|> (manyTerm expression)) <*> optional (term expression) <*> optional (term expression))
where
mkFieldDeclarationWithTag loc (fields, (Just type'), (Just tag)) = makeTerm loc $ Go.Syntax.Field [type', tag] (makeTerm loc fields) --Type.Annotation (makeTerm loc (Type.Annotation (makeTerm loc fields) type')) tag
mkFieldDeclarationWithTag loc (fields, (Just type'), Nothing) = makeTerm loc $ Go.Syntax.Field [type'] (makeTerm loc fields)
@ -321,90 +343,90 @@ fieldDeclaration = mkFieldDeclarationWithTag <$> symbol FieldDeclaration <*> ch
-- Type Declarations
channelTypeDeclaration :: Assignment
channelTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> channelType)
channelTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term channelType)
functionTypeDeclaration :: Assignment
functionTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> functionType)
functionTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term functionType)
interfaceTypeDeclaration :: Assignment
interfaceTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> interfaceType)
interfaceTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term interfaceType)
mapTypeDeclaration :: Assignment
mapTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> mapType)
mapTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term mapType)
structTypeDeclaration :: Assignment
structTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> structType)
structTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term structType)
qualifiedTypeDeclaration :: Assignment
qualifiedTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> qualifiedType)
qualifiedTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term qualifiedType)
arrayTypeDeclaration :: Assignment
arrayTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> arrayType)
arrayTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term arrayType)
sliceTypeDeclaration :: Assignment
sliceTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> sliceType)
sliceTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term sliceType)
pointerTypeDeclaration :: Assignment
pointerTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> pointerType)
pointerTypeDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term pointerType)
typeAlias :: Assignment
typeAlias = makeTerm <$> symbol TypeAlias <*> children (Type.Alias <$> expression <*> expression)
typeAlias = makeTerm <$> symbol TypeAlias <*> children (Type.Alias <$> term expression <*> term expression)
typeIdentifierDeclaration :: Assignment
typeIdentifierDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> typeIdentifier <*> expression)
typeIdentifierDeclaration = makeTerm <$> symbol TypeSpec <*> children (Type.Annotation <$> term typeIdentifier <*> term expression)
typeDeclaration :: Assignment
typeDeclaration = handleError $ makeTerm <$> symbol TypeDeclaration <*> children (many ( arrayTypeDeclaration
<|> channelTypeDeclaration
<|> functionTypeDeclaration
<|> interfaceTypeDeclaration
<|> qualifiedTypeDeclaration
<|> pointerTypeDeclaration
<|> sliceTypeDeclaration
<|> structTypeDeclaration
<|> mapTypeDeclaration
<|> typeAlias
<|> typeIdentifierDeclaration ))
typeDeclaration = handleError $ makeTerm <$> symbol TypeDeclaration <*> children (manyTerm ( arrayTypeDeclaration
<|> channelTypeDeclaration
<|> functionTypeDeclaration
<|> interfaceTypeDeclaration
<|> qualifiedTypeDeclaration
<|> pointerTypeDeclaration
<|> sliceTypeDeclaration
<|> structTypeDeclaration
<|> mapTypeDeclaration
<|> typeAlias
<|> typeIdentifierDeclaration ))
-- Expressions
indexExpression :: Assignment
indexExpression = makeTerm <$> symbol IndexExpression <*> children (Expression.Subscript <$> expression <*> many expression)
indexExpression = makeTerm <$> symbol IndexExpression <*> children (Expression.Subscript <$> term expression <*> manyTerm expression)
sliceExpression :: Assignment
sliceExpression = makeTerm <$> symbol SliceExpression <*> children ( (Go.Syntax.Slice <$> expression <*> expression <*> expression <*> expression)
<|> (Go.Syntax.Slice <$> expression <*> emptyTerm <* symbol AnonColon <*> expression <* symbol AnonColon <*> expression)
<|> (Go.Syntax.Slice <$> expression <*> emptyTerm <* symbol AnonColon <*> expression <*> emptyTerm)
<|> (Go.Syntax.Slice <$> expression <*> expression <*> expression <*> emptyTerm)
<|> (Go.Syntax.Slice <$> expression <*> expression <*> emptyTerm <*> emptyTerm)
<|> (Go.Syntax.Slice <$> expression <*> emptyTerm <*> emptyTerm <*> emptyTerm))
sliceExpression = makeTerm <$> symbol SliceExpression <*> children ( (Go.Syntax.Slice <$> term expression <*> term expression <*> term expression <*> term expression)
<|> (Go.Syntax.Slice <$> term expression <*> emptyTerm <* symbol AnonColon <*> term expression <* symbol AnonColon <*> term expression)
<|> (Go.Syntax.Slice <$> term expression <*> emptyTerm <* symbol AnonColon <*> term expression <*> emptyTerm)
<|> (Go.Syntax.Slice <$> term expression <*> term expression <*> term expression <*> emptyTerm)
<|> (Go.Syntax.Slice <$> term expression <*> term expression <*> emptyTerm <*> emptyTerm)
<|> (Go.Syntax.Slice <$> term expression <*> emptyTerm <*> emptyTerm <*> emptyTerm))
parenthesizedExpression :: Assignment
parenthesizedExpression = symbol ParenthesizedExpression *> children expressions
parenthesizedExpression = symbol ParenthesizedExpression *> children (term expressions)
selectorExpression :: Assignment
selectorExpression = makeTerm <$> symbol SelectorExpression <*> children (Expression.MemberAccess <$> expression <*> expression)
selectorExpression = makeTerm <$> symbol SelectorExpression <*> children (Expression.MemberAccess <$> term expression <*> term expression)
typeAssertion :: Assignment
typeAssertion = makeTerm <$> symbol TypeAssertionExpression <*> children (Go.Syntax.TypeAssertion <$> expression <*> expression)
typeAssertion = makeTerm <$> symbol TypeAssertionExpression <*> children (Go.Syntax.TypeAssertion <$> term expression <*> term expression)
typeConversion :: Assignment
typeConversion = makeTerm <$> symbol TypeConversionExpression <*> children (Go.Syntax.TypeConversion <$> expression <*> expression)
typeConversion = makeTerm <$> symbol TypeConversionExpression <*> children (Go.Syntax.TypeConversion <$> term expression <*> term expression)
unaryExpression :: Assignment
unaryExpression = symbol UnaryExpression >>= \ location -> (notExpression location) <|> (unaryMinus location) <|> unaryPlus <|> unaryAmpersand <|> unaryReceive <|> unaryPointer <|> unaryComplement
where
notExpression location = makeTerm location . Expression.Not <$> children (symbol AnonBang *> expression)
unaryMinus location = makeTerm location . Expression.Negate <$> children (symbol AnonMinus *> expression)
notExpression location = makeTerm location . Expression.Not <$> children (symbol AnonBang *> term expression)
unaryMinus location = makeTerm location . Expression.Negate <$> children (symbol AnonMinus *> term expression)
unaryPlus = children (symbol AnonPlus *> expression)
unaryAmpersand = children (makeTerm <$> symbol AnonAmpersand <*> (Literal.Reference <$> expression))
unaryReceive = children (makeTerm <$> symbol AnonLAngleMinus <*> (Go.Syntax.Receive <$> emptyTerm <*> expression))
unaryPointer = children (makeTerm <$> symbol AnonStar <*> (Literal.Pointer <$> expression))
unaryComplement = children (makeTerm <$> symbol AnonCaret <*> (Expression.Complement <$> expression))
unaryAmpersand = children (makeTerm <$> symbol AnonAmpersand <*> (Literal.Reference <$> term expression))
unaryReceive = children (makeTerm <$> symbol AnonLAngleMinus <*> (Go.Syntax.Receive <$> emptyTerm <*> term expression))
unaryPointer = children (makeTerm <$> symbol AnonStar <*> (Literal.Pointer <$> term expression))
unaryComplement = children (makeTerm <$> symbol AnonCaret <*> (Expression.Complement <$> term expression))
binaryExpression :: Assignment
binaryExpression = makeTerm' <$> symbol BinaryExpression <*> children (infixTerm expression expression
binaryExpression = makeTerm' <$> symbol BinaryExpression <*> children (infixTerm expression (term expression)
[ (inj .) . Expression.Plus <$ symbol AnonPlus
, (inj .) . Expression.Minus <$ symbol AnonMinus
, (inj .) . Expression.Times <$ symbol AnonStar
@ -432,30 +454,30 @@ block :: Assignment
block = symbol Block *> children expressions
expressionCase :: Assignment
expressionCase = makeTerm <$> symbol ExpressionCase <*> (Statement.Pattern <$> children expressions <*> expressions)
expressionCase = makeTerm <$> symbol ExpressionCase <*> (Statement.Pattern <$> children (term expressions) <*> term expressions)
defaultCase :: Assignment
defaultCase = makeTerm <$> symbol DefaultCase <*> children (Go.Syntax.DefaultPattern <$> (expressions <|> emptyTerm))
defaultCase = makeTerm <$> symbol DefaultCase <*> children (Go.Syntax.DefaultPattern <$> (term expressions <|> emptyTerm))
defaultExpressionCase :: Assignment
defaultExpressionCase = makeTerm <$> symbol DefaultCase <*> (Go.Syntax.DefaultPattern <$ source <*> (expressions <|> emptyTerm))
defaultExpressionCase = makeTerm <$> symbol DefaultCase <*> (Go.Syntax.DefaultPattern <$ source <*> (term expressions <|> emptyTerm))
expressionCaseClause :: Assignment
expressionCaseClause = symbol ExpressionCaseClause *> children (expressionCase <|> defaultExpressionCase)
expressionCaseClause = symbol ExpressionCaseClause *> children (term expressionCase <|> term defaultExpressionCase)
expressionSwitchStatement :: Assignment
expressionSwitchStatement = makeTerm <$> symbol ExpressionSwitchStatement <*> children (Statement.Match <$> (makeTerm <$> location <*> manyTermsTill expression (void (symbol ExpressionCaseClause)) <|> emptyTerm) <*> expressions)
expressionSwitchStatement = makeTerm <$> symbol ExpressionSwitchStatement <*> children (Statement.Match <$> (makeTerm <$> location <*> manyTermsTill expression (void (symbol ExpressionCaseClause)) <|> emptyTerm) <*> term expressions)
typeSwitchStatement :: Assignment
typeSwitchStatement = makeTerm <$> symbol TypeSwitchStatement <*> children (Go.Syntax.TypeSwitch <$> _typeSwitchSubject <*> expressions)
typeSwitchStatement = makeTerm <$> symbol TypeSwitchStatement <*> children (Go.Syntax.TypeSwitch <$> term _typeSwitchSubject <*> term expressions)
where
_typeSwitchSubject = makeTerm <$> location <*> manyTermsTill expression (void (symbol TypeCaseClause))
typeSwitchGuard :: Assignment
typeSwitchGuard = makeTerm <$> symbol Grammar.TypeSwitchGuard <*> children (Go.Syntax.TypeSwitchGuard <$> expressions)
typeSwitchGuard = makeTerm <$> symbol Grammar.TypeSwitchGuard <*> children (Go.Syntax.TypeSwitchGuard <$> term expressions)
typeCaseClause :: Assignment
typeCaseClause = makeTerm <$> symbol TypeCaseClause <*> children (Statement.Pattern <$> expression <*> expressions)
typeCaseClause = makeTerm <$> symbol TypeCaseClause <*> children (Statement.Pattern <$> term expression <*> term expressions)
typeCase :: Assignment
typeCase = symbol TypeCase *> children expressions
@ -464,69 +486,69 @@ fallThroughStatement :: Assignment
fallThroughStatement = makeTerm <$> symbol FallthroughStatement <*> (Statement.Pattern <$> (makeTerm <$> location <*> (Syntax.Identifier <$> source)) <*> emptyTerm)
variadicArgument :: Assignment
variadicArgument = makeTerm <$> symbol VariadicArgument <*> children (Go.Syntax.Variadic <$> pure [] <*> expression)
variadicArgument = makeTerm <$> symbol VariadicArgument <*> children (Go.Syntax.Variadic <$> pure [] <*> term expression)
callExpression :: Assignment
callExpression = makeTerm <$> symbol CallExpression <*> children (Expression.Call <$> pure [] <*> expression <*> many expression <*> emptyTerm)
callExpression = makeTerm <$> symbol CallExpression <*> children (Expression.Call <$> pure [] <*> term expression <*> manyTerm expression <*> emptyTerm)
varDeclaration :: Assignment
varDeclaration = (symbol ConstDeclaration <|> symbol VarDeclaration) *> children expressions
varSpecification :: Assignment
varSpecification = makeTerm <$> (symbol ConstSpec <|> symbol VarSpec) <*> children (Statement.Assignment <$> pure [] <*> (annotatedLHS <|> identifiers) <*> expressions)
varSpecification = makeTerm <$> (symbol ConstSpec <|> symbol VarSpec) <*> children (Statement.Assignment <$> pure [] <*> (annotatedLHS <|> identifiers) <*> term expressions)
where
annotatedLHS = makeTerm <$> location <*> (Type.Annotation <$> (makeTerm <$> location <*> (manyTermsTill identifier (void (symbol TypeIdentifier)))) <*> expression)
annotatedLHS = makeTerm <$> location <*> (Type.Annotation <$> (makeTerm <$> location <*> (manyTermsTill identifier (void (symbol TypeIdentifier)))) <*> term expression)
expressionList :: Assignment
expressionList = symbol ExpressionList *> children expressions
expressionList = symbol ExpressionList *> children (term expressions)
functionDeclaration :: Assignment
functionDeclaration = mkTypedFunctionDeclaration <$> symbol FunctionDeclaration <*> children ((,,,) <$> expression <*> many parameters <*> optional (types <|> identifier <|> returnParameters) <*> optional block)
<|> mkTypedFunctionLiteral <$> symbol FuncLiteral <*> children ((,,,) <$> emptyTerm <*> many parameters <*> optional (types <|> identifier <|> returnParameters) <*> block)
functionDeclaration = mkTypedFunctionDeclaration <$> symbol FunctionDeclaration <*> children ((,,,) <$> term expression <*> manyTerm parameters <*> optional (term types <|> term identifier <|> term returnParameters) <*> optional (term block))
<|> mkTypedFunctionLiteral <$> symbol FuncLiteral <*> children ((,,,) <$> emptyTerm <*> manyTerm parameters <*> optional (term types <|> term identifier <|> term returnParameters) <*> term block)
where
mkTypedFunctionDeclaration loc (name', params', types', block') = makeTerm loc (Declaration.Function [(maybe (makeTerm loc Syntax.Empty) id types')] name' params' (maybe (makeTerm loc Syntax.Empty) id block'))
mkTypedFunctionLiteral loc (name', params', types', block') = makeTerm loc (Declaration.Function [(maybe (makeTerm loc Syntax.Empty) id types')] name' params' block')
returnParameters = makeTerm <$> symbol Parameters <*> children (many expression)
returnParameters = makeTerm <$> symbol Parameters <*> children (manyTerm expression)
variadicParameterDeclaration :: Assignment
variadicParameterDeclaration = mkVariadic <$> symbol VariadicParameterDeclaration <*> children ((,) <$> emptyTerm <*> expression)
<|> mkVariadic <$> symbol VariadicParameterDeclaration <*> children ((,) <$> expression <*> expression)
variadicParameterDeclaration = mkVariadic <$> symbol VariadicParameterDeclaration <*> children ((,) <$> emptyTerm <*> term expression)
<|> mkVariadic <$> symbol VariadicParameterDeclaration <*> children ((,) <$> term expression <*> term expression)
where
mkVariadic loc (identifier', typeIdentifier') = makeTerm loc (Go.Syntax.Variadic [typeIdentifier'] identifier')
importDeclaration :: Assignment
importDeclaration = makeTerm <$> symbol ImportDeclaration <*> children (Declaration.Import <$> many expression)
importDeclaration = makeTerm <$> symbol ImportDeclaration <*> children (Declaration.Import <$> manyTerm expression)
importSpec :: Assignment
importSpec = symbol ImportSpec *> children expressions
parameters :: Assignment
parameters = makeTerm <$> symbol Parameters <*> children (many expression)
parameters = makeTerm <$> symbol Parameters <*> children (manyTerm expression)
parameterDeclaration :: Assignment
parameterDeclaration = makeTerm <$> symbol ParameterDeclaration <*> children (many expression)
parameterDeclaration = makeTerm <$> symbol ParameterDeclaration <*> children (manyTerm expression)
methodDeclaration :: Assignment
methodDeclaration = mkTypedMethodDeclaration <$> symbol MethodDeclaration <*> children ((,,,,) <$> receiver <*> fieldIdentifier <*> many parameters <*> ((makeTerm <$> location <*> (manyTermsTill expression (void (symbol Block)))) <|> emptyTerm) <*> (block <|> emptyTerm))
methodDeclaration = mkTypedMethodDeclaration <$> symbol MethodDeclaration <*> children ((,,,,) <$> term receiver <*> term fieldIdentifier <*> manyTerm parameters <*> term ((makeTerm <$> location <*> (manyTermsTill expression (void (symbol Block)))) <|> emptyTerm) <*> term (block <|> emptyTerm))
where
receiver = symbol Parameters *> children ((symbol ParameterDeclaration *> children expressions) <|> expressions)
receiver = symbol Parameters *> children ((symbol ParameterDeclaration *> children (term expressions)) <|> term expressions)
mkTypedMethodDeclaration loc (receiver', name', parameters', type'', body') = makeTerm loc (Declaration.Method [type''] receiver' name' parameters' body')
methodSpec :: Assignment
methodSpec = mkMethodSpec <$> symbol MethodSpec <*> children ((,,,,) <$> empty <*> expression <*> parameters <*> (expression <|> parameters <|> emptyTerm) <*> empty)
methodSpec = mkMethodSpec <$> symbol MethodSpec <*> children ((,,,,) <$> empty <*> term expression <*> term parameters <*> (term expression <|> term parameters <|> term emptyTerm) <*> term empty)
where
empty = makeTerm <$> location <*> pure Syntax.Empty
mkMethodSpec loc (receiver', name', params, optionaltypeLiteral, body') = makeTerm loc $ Type.Annotation (mkMethod loc receiver' name' params body') optionaltypeLiteral
mkMethod loc empty' name' params empty'' = makeTerm loc $ Declaration.Method [] empty' name' (pure params) empty''
packageClause :: Assignment
packageClause = makeTerm <$> symbol PackageClause <*> children (Declaration.Module <$> expression <*> pure [])
packageClause = makeTerm <$> symbol PackageClause <*> children (Declaration.Module <$> term expression <*> pure [])
-- Statements
assignment' :: Assignment
assignment' = makeTerm' <$> symbol AssignmentStatement <*> children (infixTerm expressionList expressionList
assignment' = makeTerm' <$> symbol AssignmentStatement <*> children (infixTerm expressionList (term expressionList)
[ assign <$ symbol AnonEqual
, augmentedAssign Expression.Plus <$ symbol AnonPlusEqual
, augmentedAssign Expression.Minus <$ symbol AnonMinusEqual
@ -553,31 +575,31 @@ emptyStatement :: Assignment
emptyStatement = makeTerm <$> token EmptyStatement <*> (Statement.NoOp <$> emptyTerm)
shortVarDeclaration :: Assignment
shortVarDeclaration = makeTerm <$> symbol ShortVarDeclaration <*> children (Statement.Assignment <$> pure [] <*> expression <*> expression)
shortVarDeclaration = makeTerm <$> symbol ShortVarDeclaration <*> children (Statement.Assignment <$> pure [] <*> term expression <*> term expression)
sendStatement :: Assignment
sendStatement = makeTerm <$> symbol SendStatement <*> children (Go.Syntax.Send <$> expression <*> expression)
sendStatement = makeTerm <$> symbol SendStatement <*> children (Go.Syntax.Send <$> term expression <*> term expression)
breakStatement :: Assignment
breakStatement = makeTerm <$> symbol BreakStatement <*> children (Statement.Break <$> (labelName' <|> emptyTerm))
breakStatement = makeTerm <$> symbol BreakStatement <*> children (Statement.Break <$> (term labelName' <|> term emptyTerm))
continueStatement :: Assignment
continueStatement = makeTerm <$> symbol ContinueStatement <*> children (Statement.Continue <$> (labelName' <|> emptyTerm))
continueStatement = makeTerm <$> symbol ContinueStatement <*> children (Statement.Continue <$> (term labelName' <|> term emptyTerm))
decStatement :: Assignment
decStatement = makeTerm <$> symbol DecStatement <*> children (Statement.PostDecrement <$> expression)
decStatement = makeTerm <$> symbol DecStatement <*> children (Statement.PostDecrement <$> term expression)
deferStatement :: Assignment
deferStatement = makeTerm <$> symbol DeferStatement <*> children (Go.Syntax.Defer <$> expression)
deferStatement = makeTerm <$> symbol DeferStatement <*> children (Go.Syntax.Defer <$> term expression)
goStatement :: Assignment
goStatement = makeTerm <$> symbol GoStatement <*> children (Go.Syntax.Go <$> expression)
goStatement = makeTerm <$> symbol GoStatement <*> children (Go.Syntax.Go <$> term expression)
gotoStatement :: Assignment
gotoStatement = makeTerm <$> symbol GotoStatement <*> children (Statement.Goto <$> expression)
gotoStatement = makeTerm <$> symbol GotoStatement <*> children (Statement.Goto <$> term expression)
ifStatement :: Assignment
ifStatement = makeTerm <$> symbol IfStatement <*> children (Statement.If <$> (makeTerm <$> location <*> manyTermsTill expression (void (symbol Block))) <*> expression <*> (expression <|> emptyTerm))
ifStatement = makeTerm <$> symbol IfStatement <*> children (Statement.If <$> (makeTerm <$> location <*> manyTermsTill expression (void (symbol Block))) <*> term expression <*> (term expression <|> term emptyTerm))
ifInitializer :: Assignment
ifInitializer = symbol IfInitializer *> children expression
@ -586,62 +608,43 @@ elseClause :: Assignment
elseClause = symbol ElseClause *> children expression
forStatement :: Assignment
forStatement = mkForStatement <$> symbol ForStatement <*> children ((,) <$> (forClause <|> rangeClause <|> for <|> emptyClause) <*> expression)
forStatement = mkForStatement <$> symbol ForStatement <*> children ((,) <$> (forClause <|> rangeClause <|> for <|> emptyClause) <*> term expression)
where
mkForStatement loc ((constructor, a, b, c), block') = case (constructor :: [Char]) of
"forEach" -> makeTerm loc $ (Statement.ForEach a b block')
_ -> makeTerm loc $ (Statement.For a b c block')
emptyClause = children (("for",,,) <$> emptyTerm <*> emptyTerm <*> emptyTerm)
rangeClause = symbol RangeClause *> children ( (("forEach",,,) <$> expression <*> expression <*> emptyTerm)
<|> (("forEach",,,) <$> emptyTerm <*> expression <*> emptyTerm))
forClause = symbol ForClause *> children ( (("for",,,) <$> expression <*> expression <*> expression)
<|> (("for",,,) <$> expression <*> expression <*> emptyTerm)
<|> (("for",,,) <$> expression <*> emptyTerm <*> emptyTerm)
<|> (("for",,,) <$> emptyTerm <*> emptyTerm <*> emptyTerm))
for = ("for",,,) <$> emptyTerm <*> expression <*> emptyTerm
rangeClause = symbol RangeClause *> children ( (("forEach",,,) <$> term expression <*> term expression <*> emptyTerm)
<|> (("forEach",,,) <$> term emptyTerm <*> term expression <*> emptyTerm))
forClause = symbol ForClause *> children ( (("for",,,) <$> term expression <*> term expression <*> term expression)
<|> (("for",,,) <$> term expression <*> term expression <*> emptyTerm)
<|> (("for",,,) <$> term expression <*> emptyTerm <*> emptyTerm)
<|> (("for",,,) <$> term emptyTerm <*> emptyTerm <*> emptyTerm))
for = ("for",,,) <$> emptyTerm <*> term expression <*> emptyTerm
incStatement :: Assignment
incStatement = makeTerm <$> symbol IncStatement <*> children (Statement.PostIncrement <$> expression)
incStatement = makeTerm <$> symbol IncStatement <*> children (Statement.PostIncrement <$> term expression)
keyedElement :: Assignment
keyedElement = makeTerm <$> symbol KeyedElement <*> children (Literal.KeyValue <$> expression <*> expression)
keyedElement = makeTerm <$> symbol KeyedElement <*> children (Literal.KeyValue <$> term expression <*> term expression)
labelName' :: Assignment
labelName' = makeTerm <$> symbol LabelName <*> (Syntax.Identifier <$> source)
labelStatement' :: Assignment
labelStatement' = makeTerm <$> symbol LabelStatement <*> children (Go.Syntax.Label <$> expression <*> (expression <|> emptyTerm))
labelStatement' = makeTerm <$> symbol LabelStatement <*> children (Go.Syntax.Label <$> term expression <*> (term expression <|> emptyTerm))
returnStatement :: Assignment
returnStatement = makeTerm <$> symbol ReturnStatement <*> children (Statement.Return <$> (expression <|> emptyTerm))
returnStatement = makeTerm <$> symbol ReturnStatement <*> children (Statement.Return <$> (term expression <|> emptyTerm))
receiveStatement :: Assignment
receiveStatement = makeTerm <$> symbol ReceiveStatement <*> children ( (Go.Syntax.Receive <$> expression <*> expression)
<|> (Go.Syntax.Receive <$> emptyTerm <*> expression))
receiveStatement = makeTerm <$> symbol ReceiveStatement <*> children ( (Go.Syntax.Receive <$> term expression <*> term expression)
<|> (Go.Syntax.Receive <$> emptyTerm <*> term expression))
selectStatement :: Assignment
selectStatement = makeTerm <$> symbol SelectStatement <*> children (Go.Syntax.Select <$> expressions)
selectStatement = makeTerm <$> symbol SelectStatement <*> children (Go.Syntax.Select <$> term expressions)
communicationClause :: Assignment
communicationClause = makeTerm <$> symbol CommunicationClause <*> children (Statement.Pattern <$> (communicationCase <|> defaultCase) <*> expressions)
communicationClause = makeTerm <$> symbol CommunicationClause <*> children (Statement.Pattern <$> (term communicationCase <|> term defaultCase) <*> term expressions)
where
communicationCase = symbol CommunicationCase *> children expression
-- Helpers
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: HasCallStack
=> Assignment
-> Assignment
-> [Assignment.Assignment [] Grammar (Term -> Term -> Union Syntax Term)]
-> Assignment.Assignment [] Grammar (Union Syntax Term)
infixTerm = infixContext comment
-- | Match a term optionally preceded by comment(s), or a sequence of comments if the term is not present.
term :: Assignment -> Assignment
term term = contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm)
-- | Match a series of terms or comments until a delimiter is matched
manyTermsTill :: Show b => Assignment.Assignment [] Grammar Term -> Assignment.Assignment [] Grammar b -> Assignment.Assignment [] Grammar [Term]
manyTermsTill step end = manyTill (step <|> comment) end