1
1
mirror of https://github.com/github/semantic.git synced 2024-12-25 07:55:12 +03:00

Merge branch 'master' into gitparsing

This commit is contained in:
Patrick Thomson 2019-06-10 12:19:37 -04:00 committed by GitHub
commit aa02a62f76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 1418 additions and 652 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
Dockerfile

9
.gitmodules vendored
View File

@ -1,12 +1,3 @@
[submodule "vendor/hspec-expectations-pretty-diff"]
path = vendor/hspec-expectations-pretty-diff
url = https://github.com/rewinfrey/hspec-expectations-pretty-diff
[submodule "vendor/haskell-tree-sitter"]
path = vendor/haskell-tree-sitter
url = https://github.com/tree-sitter/haskell-tree-sitter.git
[submodule "vendor/proto3-suite"]
path = vendor/proto3-suite
url = https://github.com/joshvera/proto3-suite.git
[submodule "vendor/proto3-wire"]
path = vendor/proto3-wire
url = https://github.com/joshvera/proto3-wire.git

View File

@ -39,8 +39,6 @@
name: Eta reduce
within:
- Language.Go.Assignment
- Language.MiniPython.Assignment
- Language.MiniRuby.Assignment
- Language.PHP.Assignment
- Language.Python.Assignment
- Language.Ruby.Assignment

View File

@ -35,3 +35,10 @@ install:
script:
- cabal new-build -j semantic-core semantic:exe:semantic
- cabal new-test semantic:test semantic-core:spec
- cabal new-run semantic:parse-examples
# Any branch linked with a pull request will be built, as well as the non-PR
# branches listed below:
branches:
only:
- master

View File

@ -19,7 +19,7 @@ Please note that this project is released with a [Contributor Code of Conduct][c
0. Create a new branch: `git checkout -b my-branch-name`
0. Make your change, add tests, and make sure the tests still pass
0. Push to your fork and [submit a pull request][pr]
0. Pat your self on the back and wait for your pull request to be reviewed and merged.
0. Pat yourself on the back and wait for your pull request to be reviewed and merged.
Here are a few things you can do that will increase the likelihood of your pull request being accepted:
@ -28,6 +28,8 @@ Here are a few things you can do that will increase the likelihood of your pull
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
Please be aware that contributions to Semantic may multiple cycles of code review—we are grateful for all community involvement, but because Semantic powers real systems, we must maintain a high standard of code quality. For reasons of compatibility with production uses of Semantic within GitHub, we may also reject or require modifications to changes that would affect these systems. We may also reject patches that don't fit with our vision of the project; should this be the case, we will be clear about our rationale.
## Resources
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)

36
Dockerfile Normal file
View File

@ -0,0 +1,36 @@
FROM haskell:8.6 as build
WORKDIR /build
RUN cabal new-update
# Build our upstream dependencies after copying in only enough to tell cabal
# what they are. This will make these layers cache better even as we change the
# code of semantic itself.
COPY semantic.cabal .
COPY cabal.project .
COPY semantic-core/semantic-core.cabal ./semantic-core/
COPY vendor ./vendor
RUN cabal new-build --only-dependencies
# Once the dependencies are built, copy in the rest of the code and compile
# semantic itself.
COPY . /build
RUN cabal new-build semantic:exe:semantic
# A fake `install` target until we can get `cabal new-install` to work
RUN cp $(find dist-newstyle -name semantic -type f -perm -u=x) /usr/local/bin/semantic
# Create a fresh image containing only the compiled CLI program, so that the
# image isn't bulked up by all of the extra build state.
FROM debian:stretch-slim
RUN apt-get update && \
apt-get install -y \
libgmp10 \
&& \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
COPY --from=build /usr/local/bin/semantic /usr/local/bin/semantic
ENTRYPOINT ["/usr/local/bin/semantic"]

View File

@ -118,7 +118,7 @@ cabal new-run semantic -- --help
Architecturally, `semantic`:
1. Reads blobs.
2. Generates parse trees for those blobs with [tree-sitter][tree-sitter] (an incremental parsing system for programmings tools).
2. Generates parse trees for those blobs with [tree-sitter][tree-sitter] (an incremental parsing system for programming tools).
3. Assigns those trees into a generalized representation of syntax.
4. Performs analysis, computes diffs, or just returns parse trees.
5. Renders output in one of many supported formats.

View File

@ -1,3 +1,16 @@
packages: vendor/* vendor/proto3-suite vendor/haskell-tree-sitter/languages/* semantic.cabal semantic-core/semantic-core.cabal
packages: vendor/* vendor/haskell-tree-sitter/languages/* . semantic-core
package proto3-suite
source-repository-package
type: git
location: https://github.com/joshvera/proto3-suite.git
tag: 83f3352f0c7c94ea091e6087f60692eda9991fae
source-repository-package
type: git
location: https://github.com/joshvera/proto3-wire.git
tag: 84664e22f01beb67870368f1f88ada5d0ad01f56
source-repository-package
type: git
location: https://github.com/rewinfrey/hspec-expectations-pretty-diff
tag: 94af5871c24ba319f7f72fefa53c1a4d074c9a29

View File

@ -48,10 +48,13 @@ clone_repo "$python_examples/certbot" certbot/certbot bb8222200a8cbd39a3ce9584ce
ts_examples="$dir/typescript/vendor/tree-sitter-typescript/examples"
clone_repo "$ts_examples/desktop" desktop/desktop d1324f56d02dd9afca5d2e9da545905a7d41d671
# Java examples are disabled because the assignment code is not yet
# robust and for reasons of CI celerity.
java_examples="$dir/java/vendor/tree-sitter-java/examples"
clone_repo "$java_examples/elasticsearch" elastic/elasticsearch 4d62640bf116af7e825d89c7319a39c3f2f325b4
clone_repo "$java_examples/guava" google/guava e24fddc5fff7fd36d33ea38737b6606a7e476845
clone_repo "$java_examples/RxJava" ReactiveX/RxJava 8a6bf14fc9a61f7c1c0016ca217be02ca86211d2
# clone_repo "$java_examples/elasticsearch" elastic/elasticsearch 4d62640bf116af7e825d89c7319a39c3f2f325b4
# clone_repo "$java_examples/guava" google/guava e24fddc5fff7fd36d33ea38737b6606a7e476845
# clone_repo "$java_examples/RxJava" ReactiveX/RxJava 8a6bf14fc9a61f7c1c0016ca217be02ca86211d2
clone_repo "$ts_examples/npm" npm/npm ee147fbbca6f2707d3b16f4fa78f4c4606b2d9b1

View File

@ -35,7 +35,7 @@ library
-- other-modules:
-- other-extensions:
build-depends: algebraic-graphs ^>= 0.3
, base >= 4.11 && < 5
, base >= 4.12 && < 5
, containers ^>= 0.6
, directory ^>= 1.3
, filepath ^>= 1.4

View File

@ -41,7 +41,7 @@ common haskell
-- as caret-operator bounds relative to a version in Stackage.
-- These are currently pinned to lts-13.13.
common dependencies
build-depends: base >= 4.8 && < 5
build-depends: base >= 4.12 && < 5
, aeson ^>= 1.4.2.0
, algebraic-graphs ^>= 0.3
, async ^>= 2.2.1
@ -199,17 +199,17 @@ library
, Language.Haskell.Syntax.Type
, Language.JSON.Assignment
, Language.JSON.PrettyPrint
, Language.MiniRuby.Assignment
, Language.MiniPython.Assignment
, Language.Ruby.Assignment
, Language.Ruby.PrettyPrint
, Language.Ruby.Syntax
, Language.TSX.Assignment
, Language.TSX.Syntax
, Language.TSX.Syntax.JSX
, Language.TypeScript.Assignment
, Language.TypeScript.Resolution
, Language.TypeScript.Syntax
, Language.TypeScript.Syntax.Import
, Language.TypeScript.Syntax.JavaScript
, Language.TypeScript.Syntax.JSX
, Language.TypeScript.Syntax.TypeScript
, Language.TypeScript.Syntax.Types
, Language.PHP.Assignment
@ -273,7 +273,7 @@ library
-- Custom Prelude
, Prologue
build-depends: base >= 4.8 && < 5
build-depends: base >= 4.12 && < 5
, ansi-terminal ^>= 0.8.2
, array ^>= 0.5.3.0
, attoparsec ^>= 0.13.2.2
@ -320,6 +320,7 @@ library
, tree-sitter-python
, tree-sitter-ruby
, tree-sitter-typescript
, tree-sitter-tsx
, tree-sitter-java
ghc-options: -Wall -Wmissing-export-lists -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -fno-warn-name-shadowing -j
if flag(release)

View File

@ -22,6 +22,7 @@ import qualified Language.Markdown.Syntax as Markdown
import qualified Language.PHP.Syntax as PHP
import qualified Language.Python.Syntax as Python
import qualified Language.Ruby.Syntax as Ruby
import qualified Language.TSX.Syntax as TSX
import qualified Language.TypeScript.Syntax as TypeScript
import Data.Quieterm
@ -454,25 +455,26 @@ instance AccessControls1 Ruby.LowPrecedenceOr
instance AccessControls1 Ruby.Module
instance AccessControls1 Ruby.ZSuper
instance AccessControls1 TSX.JsxElement
instance AccessControls1 TSX.JsxOpeningElement
instance AccessControls1 TSX.JsxSelfClosingElement
instance AccessControls1 TSX.JsxAttribute
instance AccessControls1 TSX.JsxNamespaceName
instance AccessControls1 TSX.JsxText
instance AccessControls1 TSX.JsxExpression
instance AccessControls1 TSX.JsxClosingElement
instance AccessControls1 TSX.JsxFragment
instance AccessControls1 TypeScript.AnnotatedExpression
instance AccessControls1 TypeScript.JavaScriptRequire
instance AccessControls1 TypeScript.Debugger
instance AccessControls1 TypeScript.Super
instance AccessControls1 TypeScript.Undefined
instance AccessControls1 TypeScript.With
instance AccessControls1 TypeScript.JsxElement
instance AccessControls1 TypeScript.JsxOpeningElement
instance AccessControls1 TypeScript.JsxSelfClosingElement
instance AccessControls1 TypeScript.JsxAttribute
instance AccessControls1 TypeScript.OptionalParameter
instance AccessControls1 TypeScript.RequiredParameter
instance AccessControls1 TypeScript.RestParameter
instance AccessControls1 TypeScript.JsxNamespaceName
instance AccessControls1 TypeScript.JsxText
instance AccessControls1 TypeScript.JsxExpression
instance AccessControls1 TypeScript.JsxClosingElement
instance AccessControls1 TypeScript.ImplementsClause
instance AccessControls1 TypeScript.JsxFragment
instance AccessControls1 TypeScript.Import
instance AccessControls1 TypeScript.QualifiedAliasedImport
instance AccessControls1 TypeScript.QualifiedExportFrom

View File

@ -163,6 +163,8 @@ instance HasPrelude 'Ruby where
defineClass (Declaration (X.name "Object")) [] $ do
defineBuiltIn (Declaration $ X.name "inspect") Default Public Show
instance HasPrelude 'TSX
instance HasPrelude 'TypeScript where
definePrelude _ = do
defineSelf

View File

@ -36,6 +36,7 @@ data Language
| Ruby
| TypeScript
| PHP
| TSX
deriving (Eq, Generic, Ord, Read, Show, Bounded, Hashable, ToJSON, Named, Enum, MessageField, NFData)
class SLanguage (lang :: Language) where
@ -129,7 +130,7 @@ languageForType mediaType = case mediaType of
".go" -> Go
".js" -> JavaScript
".ts" -> TypeScript
".tsx" -> TypeScript
".tsx" -> TSX
".jsx" -> JSX
".py" -> Python
".php" -> PHP
@ -144,7 +145,9 @@ extensionsForLanguage language = case language of
PHP -> [".php"]
Python -> [".py"]
Ruby -> [".rb"]
TypeScript -> [".ts", ".tsx", ".d.tsx"]
TypeScript -> [".ts"]
TSX -> [".tsx", ".d.tsx"]
JSX -> [".jsx"]
_ -> []
-- | Return a language based on a FilePath's extension, or Nothing if extension is not found or not supported.

View File

@ -1,160 +0,0 @@
{-# LANGUAGE DataKinds, RankNTypes, TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} -- FIXME
module Language.MiniPython.Assignment
(
-- Small version of Python to enable internal framework development.
assignment
, Syntax
, Grammar
, Term
) where
import Assigning.Assignment hiding (Assignment, Error)
import qualified Assigning.Assignment as Assignment
import Data.Abstract.Name (name)
import Data.Sum
import Data.Syntax
( contextualize
, emptyTerm
, handleError
, infixContext
, makeTerm
, makeTerm'
, makeTerm''
, makeTerm1
, parseError
, postContextualize
)
import qualified Data.Syntax as Syntax
import qualified Data.Syntax.Comment as Comment
import qualified Data.Syntax.Declaration as Declaration
import qualified Data.Syntax.Expression as Expression
import qualified Data.Syntax.Literal as Literal
import qualified Data.Syntax.Statement as Statement
import qualified Data.Syntax.Type as Type
import qualified Data.Term as Term
import Prologue
import TreeSitter.Python as Grammar
-- | The type of Python syntax.
type Syntax =
'[ Declaration.Function
, Expression.Call
, Expression.Minus
, Expression.Plus
, Expression.Times
, Literal.Integer
, Literal.Boolean
, Literal.TextElement
, Statement.If
, Statement.Return
, Statement.Statements
, Syntax.Context
, Syntax.Empty
, Syntax.Error
, Syntax.Identifier
, Type.Annotation
, Comment.Comment
, []
]
type Term = Term.Term (Sum Syntax) Location
type Assignment = Assignment.Assignment [] Grammar
-- | Assignment from AST in Python's grammar onto a program in Python's syntax.
assignment :: Assignment Term
assignment = handleError $ makeTerm <$> symbol Module <*> children (Statement.Statements <$> manyTerm expression) <|> parseError
expression :: Assignment Term
expression = handleError (choice expressionChoices)
expressionChoices :: [Assignment Term]
expressionChoices =
[ binaryOperator
, boolean
, call
, expressionStatement
, functionDefinition
, identifier
, integer
, string
, returnStatement
, ifStatement
]
-- NOTE: Important that we don't flatten out the Imperative for single item lists
expressions :: Assignment Term
expressions = makeTerm <$> location <*> manyTerm expression
expressionStatement :: Assignment Term
expressionStatement = makeTerm'' <$> symbol ExpressionStatement <*> children (someTerm expression)
expressionList :: Assignment Term
expressionList = makeTerm'' <$> symbol ExpressionList <*> children (someTerm expression)
functionDefinition :: Assignment Term
functionDefinition =
makeFunctionDeclaration <$> symbol FunctionDefinition <*> children ((,,,) <$> term expression <* symbol Parameters <*> children (manyTerm expression) <*> optional (symbol Type *> children (term expression)) <*> expressions)
<|> makeFunctionDeclaration <$> (symbol Lambda' <|> symbol Lambda) <*> children ((,,,) <$ token AnonLambda <*> emptyTerm <*> (symbol LambdaParameters *> children (manyTerm expression) <|> pure []) <*> optional (symbol Type *> children (term expression)) <*> expressions)
where
makeFunctionDeclaration loc (functionName', functionParameters, ty, functionBody)
= let fn = makeTerm loc (Declaration.Function [] functionName' functionParameters functionBody)
in maybe fn (makeTerm loc . Type.Annotation fn) ty
binaryOperator :: Assignment Term
binaryOperator = makeTerm' <$> symbol BinaryOperator <*> children (infixTerm expression (term expression)
[ (inject .) . Expression.Plus <$ symbol AnonPlus
, (inject .) . Expression.Minus <$ symbol AnonMinus
, (inject .) . Expression.Times <$ symbol AnonStar
])
identifier :: Assignment Term
identifier = makeTerm <$> (symbol Identifier <|> symbol DottedName) <*> (Syntax.Identifier . name <$> source)
integer :: Assignment Term
integer = makeTerm <$> symbol Integer <*> (Literal.Integer <$> source)
string :: Assignment Term
string = makeTerm <$> symbol String <*> (Literal.TextElement <$> source)
comment :: Assignment Term
comment = makeTerm <$> symbol Comment <*> (Comment.Comment <$> source)
returnStatement :: Assignment Term
returnStatement = makeTerm <$> symbol ReturnStatement <*> children (Statement.Return <$> term (expressionList <|> emptyTerm))
call :: Assignment Term
call = makeTerm <$> symbol Call <*> children (Expression.Call [] <$> term (identifier <|> expression) <*> (symbol ArgumentList *> children (manyTerm expression)) <*> emptyTerm)
boolean :: Assignment Term
boolean = makeTerm <$> token Grammar.True <*> pure Literal.true
<|> makeTerm <$> token Grammar.False <*> pure Literal.false
ifStatement :: Assignment Term
ifStatement = makeTerm <$> symbol IfStatement <*> children (Statement.If <$> term expression <*> term (makeTerm <$> location <*> manyTermsTill expression (void (symbol ElseClause) <|> void (symbol ElifClause) <|> eof)) <*> (flip (foldr makeElif) <$> many elifClause <*> (symbol ElseClause *> children expressions <|> emptyTerm)))
where elifClause = (,) <$> symbol ElifClause <*> children (Statement.If <$> term expression <*> expressions)
makeElif (loc, makeIf) rest = makeTerm loc (makeIf rest)
-- Helpers
-- | Match a term optionally preceded by comment(s), or a sequence of comments if the term is not present.
manyTerm :: Assignment Term -> Assignment [Term]
manyTerm term = many (contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm))
someTerm :: Assignment Term -> Assignment [Term]
someTerm term = some (contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm))
term :: Assignment Term -> Assignment Term
term term = contextualize comment (postContextualize comment term)
-- | Match a series of terms or comments until a delimiter is matched.
manyTermsTill :: Assignment Term -> Assignment b -> Assignment [Term]
manyTermsTill step end = manyTill (step <|> comment) end
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: Assignment Term
-> Assignment Term
-> [Assignment (Term -> Term -> Sum Syntax Term)]
-> Assignment (Sum Syntax Term)
infixTerm = infixContext comment

View File

@ -1,220 +0,0 @@
{-# LANGUAGE DataKinds, RankNTypes, TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} -- FIXME
module Language.MiniRuby.Assignment
(
-- Small version of Ruby to enable internal framework development.
assignment
, Syntax
, Term
) where
import Assigning.Assignment hiding (Assignment, Error)
import qualified Assigning.Assignment as Assignment
import Data.Abstract.Name (name)
import qualified Data.Abstract.ScopeGraph as ScopeGraph (AccessControl(..))
import Data.List (elem)
import Data.Sum
import Data.Syntax
( contextualize
, emptyTerm
, handleError
, infixContext
, makeTerm
, makeTerm'
, makeTerm''
, makeTerm1
, parseError
, postContextualize
)
import qualified Data.Syntax as Syntax
import qualified Data.Syntax.Comment as Comment
import qualified Data.Syntax.Declaration as Declaration
import qualified Data.Syntax.Expression as Expression
import qualified Data.Syntax.Literal as Literal
import qualified Data.Syntax.Statement as Statement
import qualified Data.Term as Term
import qualified Language.Ruby.Syntax as Ruby.Syntax
import Prologue hiding (for)
import TreeSitter.Ruby as Grammar
-- | Small version of Ruby syntax for testing the code rewriting pipeline.
type Syntax =
'[ Comment.Comment
, Declaration.Function
, Declaration.Method
, Expression.Minus
, Expression.Plus
, Expression.Times
, Ruby.Syntax.Send
, Statement.Statements
, Syntax.Context
, Syntax.Empty
, Syntax.Error
, Syntax.Identifier
, Literal.Integer
, []
]
type Term = Term.Term (Sum Syntax) Location
type Assignment = Assignment.Assignment [] Grammar
assignment :: Assignment Term
assignment = handleError $ makeTerm <$> symbol Program <*> children (Statement.Statements <$> many expression) <|> parseError
expression :: Assignment Term
expression = term . handleError $
choice [ binary
, identifier
, number
, method
, methodCall
, parenthesizedExpressions ]
-- NOTE: Important that we don't flatten out the Imperative for single item lists
expressions :: Assignment Term
expressions = makeTerm <$> location <*> many expression
parenthesizedExpressions :: Assignment Term
parenthesizedExpressions = makeTerm'' <$> symbol ParenthesizedStatements <*> children (many expression)
number :: Assignment Term
number = makeTerm <$> symbol Grammar.Integer <*> (Literal.Integer <$> source)
identifier :: Assignment Term
identifier =
vcallOrLocal
<|> mk Constant
<|> mk InstanceVariable
<|> mk ClassVariable
<|> mk GlobalVariable
<|> mk Operator
<|> mk Super
<|> mk Setter
<|> mk SplatArgument
<|> mk HashSplatArgument
<|> mk BlockArgument
<|> mk Uninterpreted
where
mk s = makeTerm <$> symbol s <*> (Syntax.Identifier . name <$> source)
vcallOrLocal = do
(loc, ident, locals) <- identWithLocals
let identTerm = makeTerm loc (Syntax.Identifier (name ident))
if ident `elem` locals
then pure identTerm
else pure $ makeTerm loc (Ruby.Syntax.Send Nothing (Just identTerm) [] Nothing)
method :: Assignment Term
method = makeTerm <$> symbol Method <*> (withNewScope . children) (Declaration.Method [] <$> emptyTerm <*> methodSelector <*> params <*> expressions' <*> pure accessibility)
where params = symbol MethodParameters *> children (many parameter) <|> pure []
expressions' = makeTerm <$> location <*> many expression
accessibility = ScopeGraph.Public
methodSelector :: Assignment Term
methodSelector = makeTerm <$> symbols <*> (Syntax.Identifier <$> (name <$> source))
where
symbols = symbol Identifier
<|> symbol Constant
<|> symbol Operator
<|> symbol Setter
<|> symbol Super -- TODO(@charliesome): super calls are *not* method calls and need to be assigned into their own syntax terms
parameter :: Assignment Term
parameter = postContextualize comment (term uncontextualizedParameter)
where
uncontextualizedParameter =
lhsIdent
<|> splatParameter
<|> hashSplatParameter
<|> blockParameter
<|> keywordParameter
<|> optionalParameter
<|> makeTerm <$> symbol DestructuredParameter <*> children (many parameter)
-- splat and hash splat arguments can be unnamed. we don't currently
-- support unnamed arguments in the term syntax, so the use of emptyTerm
-- here is a huge hack. what we should be able to do is return a Nothing
-- for the argument name for splats and hash splats. TODO fix me:
mkSplat s = symbol s *> children (lhsIdent <|> emptyTerm)
splatParameter = mkSplat SplatParameter
hashSplatParameter = mkSplat HashSplatParameter
blockParameter = symbol BlockParameter *> children lhsIdent
-- we don't yet care about default expressions for optional (including
-- keyword) parameters, but we need to match on them to prevent errors:
keywordParameter = symbol KeywordParameter *> children (lhsIdent <* optional expression)
optionalParameter = symbol OptionalParameter *> children (lhsIdent <* expression)
lhsIdent :: Assignment Term
lhsIdent = do
(loc, ident, locals) <- identWithLocals
putLocals (ident : locals)
pure $ makeTerm loc (Syntax.Identifier (name ident))
methodCall :: Assignment Term
methodCall = makeTerm' <$> symbol MethodCall <*> children send -- (require <|> load <|> send)
where
send = inject <$> ((regularCall <|> funcCall <|> scopeCall <|> dotCall) <*> optional block)
funcCall = Ruby.Syntax.Send Nothing <$> selector <*> args
regularCall = symbol Call *> children (Ruby.Syntax.Send <$> (Just <$> expression) <*> selector) <*> args
scopeCall = symbol ScopeResolution *> children (Ruby.Syntax.Send <$> (Just <$> expression) <*> selector) <*> args
dotCall = symbol Call *> children (Ruby.Syntax.Send <$> (Just <$> term expression) <*> pure Nothing <*> args)
selector = Just <$> term methodSelector
-- require = inject <$> (symbol Identifier *> do
-- s <- rawSource
-- guard (s `elem` ["require", "require_relative"])
-- Ruby.Syntax.Require (s == "require_relative") <$> nameExpression)
-- load = inject <$ symbol Identifier <*> do
-- s <- rawSource
-- guard (s == "load")
-- (symbol ArgumentList <|> symbol ArgumentListWithParens) *> children (Ruby.Syntax.Load <$> expression <*> optional expression)
-- nameExpression = (symbol ArgumentList <|> symbol ArgumentListWithParens) *> children expression
args :: Assignment [Term]
args = (symbol ArgumentList <|> symbol ArgumentListWithParens) *> children (many expression) <|> many expression
block :: Assignment Term
block = makeTerm <$> symbol DoBlock <*> scopedBlockChildren
<|> makeTerm <$> symbol Block <*> scopedBlockChildren
where scopedBlockChildren = withExtendedScope blockChildren
blockChildren = children (Declaration.Function [] <$> emptyTerm <*> params <*> expressions)
params = symbol BlockParameters *> children (many parameter) <|> pure []
binary :: Assignment Term
binary = makeTerm' <$> symbol Binary <*> children (infixTerm expression expression
[ (inject .) . Expression.Plus <$ symbol AnonPlus
, (inject .) . Expression.Minus <$ symbol AnonMinus'
, (inject .) . Expression.Times <$ symbol AnonStar'
])
comment :: Assignment Term
comment = makeTerm <$> symbol Comment <*> (Comment.Comment <$> source)
term :: Assignment Term -> Assignment Term
term term = contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm)
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: Assignment Term
-> Assignment Term
-> [Assignment (Term -> Term -> Sum Syntax Term)]
-> Assignment (Sum Syntax Term)
infixTerm = infixContext comment
withExtendedScope :: Assignment a -> Assignment a
withExtendedScope inner = do
locals <- getLocals
result <- inner
putLocals locals
pure result
withNewScope :: Assignment a -> Assignment a
withNewScope inner = withExtendedScope $ do
putLocals []
inner
identWithLocals :: Assignment (Location, Text, [Text])
identWithLocals = do
loc <- symbol Identifier
-- source advances, so it's important we call getLocals first
locals <- getLocals
ident <- source
pure (loc, ident, locals)

View File

@ -136,6 +136,7 @@ expressionChoices =
, assignment'
, await
, binaryOperator
, block
, boolean
, booleanOperator
, breakStatement
@ -198,6 +199,12 @@ expressionChoices =
expressions :: Assignment Term
expressions = makeTerm'' <$> location <*> manyTerm expression
block :: Assignment Term
block = symbol Block *> children (makeTerm'' <$> location <*> manyTerm expression)
block' :: Assignment Term
block' = symbol Block *> children (makeTerm <$> location <*> manyTerm expression)
expressionStatement :: Assignment Term
expressionStatement = makeTerm'' <$> symbol ExpressionStatement <*> children (someTerm expression)
@ -233,31 +240,28 @@ argumentList :: Assignment Term
argumentList = symbol ArgumentList *> children expressions
withStatement :: Assignment Term
withStatement = mk <$> symbol WithStatement <*> children (someTerm with)
withStatement = symbol WithStatement *> children (flip (foldr make) <$> some withItem <*> term block')
where
mk _ [child] = child
mk l children = makeTerm l children
with = makeTerm <$> location <*> (withItem <*> term (makeTerm <$> location <*> manyTermsTill expression (void (symbol WithItem) <|> eof)))
withItem = symbol WithItem *> children (flip Statement.Let <$> term expression <*> term (expression <|> emptyTerm))
<|> flip Statement.Let <$> term expression <*> emptyTerm
make (val, name) = makeTerm1 . Statement.Let name val
withItem = symbol WithItem *> children ((,) <$> term expression <*> term (expression <|> emptyTerm))
forStatement :: Assignment Term
forStatement = symbol ForStatement >>= \ loc -> children (make loc <$> (symbol Variables *> children expressions) <*> term expressionList <*> (makeTerm <$> location <*> manyTermsTill expression (void (symbol ElseClause) <|> eof)) <*> optional (symbol ElseClause *> children expressions))
forStatement = symbol ForStatement >>= \ loc -> children (make loc <$> (symbol Variables *> children expressions) <*> term expressionList <*> term block' <*> optional (symbol ElseClause *> children expressions))
where
make loc binding subject body forElseClause = case forElseClause of
Nothing -> makeTerm loc (Statement.ForEach binding subject body)
Just a -> makeTerm loc (Statement.Else (makeTerm loc $ Statement.ForEach binding subject body) a)
whileStatement :: Assignment Term
whileStatement = symbol WhileStatement >>= \ loc -> children (make loc <$> term expression <*> (makeTerm <$> location <*> manyTermsTill expression (void (symbol ElseClause) <|> eof)) <*> optional (symbol ElseClause *> children expressions))
whileStatement = symbol WhileStatement >>= \ loc -> children (make loc <$> term expression <*> term block <*> optional (symbol ElseClause *> children expressions))
where
make loc whileCondition whileBody whileElseClause = case whileElseClause of
Nothing -> makeTerm loc (Statement.While whileCondition whileBody)
Just a -> makeTerm loc (Statement.Else (makeTerm loc $ Statement.While whileCondition whileBody) a)
tryStatement :: Assignment Term
tryStatement = makeTerm <$> symbol TryStatement <*> children (Statement.Try <$> term expression <*> manyTerm (expression <|> elseClause))
where elseClause = makeTerm <$> symbol ElseClause <*> children (Statement.Else <$> emptyTerm <*> expressions)
tryStatement = makeTerm <$> symbol TryStatement <*> children (Statement.Try <$> term block <*> manyTerm (expression <|> elseClause))
where elseClause = makeTerm <$> symbol ElseClause <*> children (Statement.Else <$> emptyTerm <*> term block)
exceptClause :: Assignment Term
exceptClause = makeTerm <$> symbol ExceptClause <*> children
@ -275,7 +279,7 @@ functionParam = (makeParameter <$> location <*> identifier)
functionDefinition :: Assignment Term
functionDefinition =
makeFunctionDeclaration <$> symbol FunctionDefinition <*> children ((,,,) <$> term expression <* symbol Parameters <*> children (manyTerm functionParam) <*> optional (symbol Type *> children (term expression)) <*> expressions')
makeFunctionDeclaration <$> symbol FunctionDefinition <*> children ((,,,) <$> term expression <* symbol Parameters <*> children (manyTerm functionParam) <*> optional (symbol Type *> children (term expression)) <*> term block')
<|> makeFunctionDeclaration <$> (symbol Lambda' <|> symbol Lambda) <*> children ((,,,) <$ token AnonLambda <*> emptyTerm <*> (symbol LambdaParameters *> children (manyTerm expression) <|> pure []) <*> optional (symbol Type *> children (term expression)) <*> expressions')
where
expressions' = makeTerm <$> location <*> manyTerm expression
@ -284,9 +288,8 @@ functionDefinition =
in maybe fn (makeTerm loc . Type.Annotation fn) ty
classDefinition :: Assignment Term
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class [] <$> term expression <*> argumentList <*> expressions')
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class [] <$> term expression <*> argumentList <*> term block')
where
expressions' = makeTerm <$> location <*> manyTerm expression
argumentList = symbol ArgumentList *> children (manyTerm expression)
<|> pure []
@ -466,8 +469,8 @@ ifStatement :: Assignment Term
ifStatement = makeTerm <$> symbol IfStatement <*> children if'
where
if' = Statement.If <$> term expression <*> thenClause <*> (elseClause <|> emptyTerm)
thenClause = makeTerm <$> location <*> manyTermsTill expression (void (symbol ElseClause) <|> void (symbol ElifClause) <|> eof)
elseClause = makeTerm <$> location <*> many (comment <|> elif <|> else')
thenClause = makeTerm'' <$> location <*> manyTermsTill expression (void (symbol ElseClause) <|> void (symbol ElifClause) <|> eof)
elseClause = makeTerm'' <$> location <*> many (comment <|> elif <|> else')
elif = makeTerm <$> symbol ElifClause <*> children if'
else' = symbol ElseClause *> children expressions

View File

@ -266,7 +266,7 @@ literal =
(children (inject . Literal.String <$> some (interpolation <|> escapeSequence)) <|> inject . Literal.TextElement <$> source)
symbol' :: Assignment Term
symbol' = makeTerm' <$> (symbol Symbol <|> symbol Symbol' <|> symbol Symbol'' <|> symbol BareSymbol) <*>
symbol' = makeTerm' <$> (symbol Symbol <|> symbol Symbol' <|> symbol BareSymbol) <*>
(children (inject . Literal.Symbol <$> some interpolation) <|> inject . Literal.SymbolElement <$> source)
interpolation :: Assignment Term
@ -517,7 +517,7 @@ binary = makeTerm' <$> symbol Binary <*> children (infixTerm expression expressi
, (inject .) . Expression.Minus <$ (symbol AnonMinus <|> symbol AnonMinus' <|> symbol AnonMinus'')
, (inject .) . Expression.Times <$ (symbol AnonStar <|> symbol AnonStar')
, (inject .) . Expression.Power <$ symbol AnonStarStar
, (inject .) . Expression.DividedBy <$ (symbol AnonSlash <|> symbol AnonSlash' <|> symbol AnonSlash'')
, (inject .) . Expression.DividedBy <$ (symbol AnonSlash <|> symbol AnonSlash')
, (inject .) . Expression.Modulo <$ symbol AnonPercent
, (inject .) . Expression.And <$ symbol AnonAmpersandAmpersand
, (inject .) . Ruby.Syntax.LowPrecedenceAnd <$ symbol AnonAnd

View File

@ -0,0 +1,971 @@
{-# LANGUAGE DataKinds, RankNTypes, TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} -- FIXME
module Language.TSX.Assignment
( assignment
, Syntax
, Grammar
, Term
) where
import Assigning.Assignment hiding (Assignment, Error)
import Data.Abstract.Name (name)
import qualified Data.Abstract.ScopeGraph as ScopeGraph (AccessControl(..))
import qualified Assigning.Assignment as Assignment
import Data.Sum
import Data.Syntax
( contextualize
, emptyTerm
, handleError
, infixContext
, makeTerm
, makeTerm'
, makeTerm''
, makeTerm1
, parseError
, postContextualize
)
import qualified Data.Syntax as Syntax
import qualified Data.Syntax.Comment as Comment
import qualified Data.Syntax.Declaration as Declaration
import qualified Data.Syntax.Expression as Expression
import qualified Data.Syntax.Literal as Literal
import qualified Data.Syntax.Statement as Statement
import qualified Data.Syntax.Type as Type
import qualified Data.Term as Term
import qualified Language.TSX.Syntax as TSX.Syntax
import qualified Language.TypeScript.Resolution as TypeScript.Resolution
import Prologue
import TreeSitter.TSX as Grammar
-- | The type of TSX syntax.
type Syntax = '[
Comment.Comment
, Comment.HashBang
, Declaration.Class
, Declaration.Function
, Declaration.Method
, Declaration.MethodSignature
, Declaration.InterfaceDeclaration
, Declaration.PublicFieldDefinition
, Declaration.VariableDeclaration
, Declaration.TypeAlias
, Expression.Plus
, Expression.Minus
, Expression.Times
, Expression.DividedBy
, Expression.Modulo
, Expression.Power
, Expression.Negate
, Expression.FloorDivision
, Expression.BAnd
, Expression.BOr
, Expression.BXOr
, Expression.LShift
, Expression.RShift
, Expression.UnsignedRShift
, Expression.Complement
, Expression.And
, Expression.Not
, Expression.Or
, Expression.XOr
, Expression.Call
, Expression.Cast
, Expression.LessThan
, Expression.LessThanEqual
, Expression.GreaterThan
, Expression.GreaterThanEqual
, Expression.Equal
, Expression.StrictEqual
, Expression.Comparison
, Expression.Enumeration
, Expression.MemberAccess
, Expression.NonNullExpression
, Expression.ScopeResolution
, Expression.SequenceExpression
, Expression.Subscript
, Expression.Member
, Expression.Delete
, Expression.Void
, Expression.Typeof
, Expression.InstanceOf
, Expression.New
, Expression.Await
, Expression.This
, Literal.Array
, Literal.Boolean
, Literal.Float
, Literal.Hash
, Literal.Integer
, Literal.KeyValue
, Literal.Null
, Literal.String
, Literal.TextElement
, Literal.Regex
, Statement.Assignment
, Statement.Break
, Statement.Catch
, Statement.Continue
, Statement.DoWhile
, Statement.Else
, Statement.Finally
, Statement.For
, Statement.ForEach
, Statement.If
, Statement.Match
, Statement.Pattern
, Statement.Retry
, Statement.Return
, Statement.ScopeEntry
, Statement.ScopeExit
, Statement.Statements
, Statement.Throw
, Statement.Try
, Statement.While
, Statement.Yield
, Syntax.AccessibilityModifier
, Syntax.Empty
, Syntax.Error
, Syntax.Identifier
, Syntax.Context
, Type.Readonly
, Type.TypeParameters
, TSX.Syntax.TypeParameter
, TSX.Syntax.Constraint
, TSX.Syntax.ParenthesizedType
, TSX.Syntax.DefaultType
, TSX.Syntax.PredefinedType
, TSX.Syntax.TypeIdentifier
, TSX.Syntax.NestedIdentifier
, TSX.Syntax.NestedTypeIdentifier
, TSX.Syntax.GenericType
, TSX.Syntax.TypeArguments
, TSX.Syntax.TypePredicate
, TSX.Syntax.CallSignature
, TSX.Syntax.ConstructSignature
, TSX.Syntax.ArrayType
, TSX.Syntax.LookupType
, TSX.Syntax.FlowMaybeType
, TSX.Syntax.TypeQuery
, TSX.Syntax.IndexTypeQuery
, TSX.Syntax.ThisType
, TSX.Syntax.ExistentialType
, TSX.Syntax.AbstractMethodSignature
, TSX.Syntax.IndexSignature
, TSX.Syntax.ObjectType
, TSX.Syntax.LiteralType
, TSX.Syntax.Union
, TSX.Syntax.Intersection
, TSX.Syntax.Module
, TSX.Syntax.InternalModule
, TSX.Syntax.FunctionType
, TSX.Syntax.Tuple
, TSX.Syntax.Constructor
, TSX.Syntax.TypeAssertion
, TSX.Syntax.ImportAlias
, TSX.Syntax.Debugger
, TSX.Syntax.ShorthandPropertyIdentifier
, TSX.Syntax.Super
, TSX.Syntax.Undefined
, TSX.Syntax.ClassHeritage
, TSX.Syntax.AbstractClass
, TSX.Syntax.ImplementsClause
, TSX.Syntax.JsxElement
, TSX.Syntax.JsxSelfClosingElement
, TSX.Syntax.JsxOpeningElement
, TSX.Syntax.JsxText
, TSX.Syntax.JsxClosingElement
, TSX.Syntax.JsxExpression
, TSX.Syntax.JsxAttribute
, TSX.Syntax.JsxFragment
, TSX.Syntax.JsxNamespaceName
, TSX.Syntax.OptionalParameter
, TSX.Syntax.RequiredParameter
, TSX.Syntax.RestParameter
, TSX.Syntax.PropertySignature
, TSX.Syntax.AmbientDeclaration
, TSX.Syntax.EnumDeclaration
, TSX.Syntax.ExtendsClause
, TSX.Syntax.AmbientFunction
, TSX.Syntax.ImportRequireClause
, TSX.Syntax.ImportClause
, TSX.Syntax.LabeledStatement
, TSX.Syntax.Annotation
, TSX.Syntax.With
, TSX.Syntax.ForOf
, TSX.Syntax.Update
, TSX.Syntax.ComputedPropertyName
, TSX.Syntax.Decorator
, TSX.Syntax.Import
, TSX.Syntax.QualifiedAliasedImport
, TSX.Syntax.SideEffectImport
, TSX.Syntax.DefaultExport
, TSX.Syntax.QualifiedExport
, TSX.Syntax.QualifiedExportFrom
, TSX.Syntax.JavaScriptRequire
, []
, Statement.StatementBlock
, TSX.Syntax.MetaProperty
, TSX.Syntax.AnnotatedExpression
]
type Term = Term.Term (Sum Syntax) Location
type Assignment = Assignment.Assignment [] Grammar
-- | Assignment from AST in TSXs grammar onto a program in TSXs syntax.
assignment :: Assignment Term
assignment = handleError $ makeTerm <$> symbol Program <*> children (Statement.Statements <$> manyTerm statement) <|> parseError
expression :: Assignment Term
expression = handleError everything
where
everything = choice [
asExpression,
nonNullExpression',
importAlias',
internalModule,
super,
object,
array,
jsxElement',
jsxFragment,
class',
anonymousClass,
function,
arrowFunction,
assignmentExpression,
augmentedAssignmentExpression,
awaitExpression,
unaryExpression,
binaryExpression,
ternaryExpression,
updateExpression,
callExpression,
memberExpression,
newExpression,
parenthesizedExpression,
subscriptExpression,
yieldExpression,
this,
number,
string,
templateString,
regex,
true,
false,
null',
undefined',
identifier
]
undefined' :: Assignment Term
undefined' = makeTerm <$> symbol Grammar.Undefined <*> (TSX.Syntax.Undefined <$ rawSource)
assignmentExpression :: Assignment Term
assignmentExpression = makeTerm <$> symbol AssignmentExpression <*> children (Statement.Assignment [] <$> term (memberExpression <|> subscriptExpression <|> identifier <|> destructuringPattern) <*> expression)
augmentedAssignmentExpression :: Assignment Term
augmentedAssignmentExpression = makeTerm' <$> symbol AugmentedAssignmentExpression <*> children (infixTerm (memberExpression <|> subscriptExpression <|> identifier <|> destructuringPattern) (term expression) [
assign Expression.Plus <$ symbol AnonPlusEqual
, assign Expression.Minus <$ symbol AnonMinusEqual
, assign Expression.Times <$ symbol AnonStarEqual
, assign Expression.DividedBy <$ symbol AnonSlashEqual
, assign Expression.Modulo <$ symbol AnonPercentEqual
, assign Expression.BXOr <$ symbol AnonCaretEqual
, assign Expression.BAnd <$ symbol AnonAmpersandEqual
, assign Expression.RShift <$ symbol AnonRAngleRAngleEqual
, assign Expression.LShift <$ symbol AnonLAngleLAngleEqual
, assign Expression.UnsignedRShift <$ symbol AnonRAngleRAngleRAngleEqual
, assign Expression.LShift <$ symbol AnonLAngleLAngleEqual
, assign Expression.BOr <$ symbol AnonPipeEqual ])
where assign :: (f :< Syntax) => (Term -> Term -> f Term) -> Term -> Term -> Sum Syntax Term
assign c l r = inject (Statement.Assignment [] l (makeTerm1 (c l r)))
awaitExpression :: Assignment Term
awaitExpression = makeTerm <$> symbol Grammar.AwaitExpression <*> children (Expression.Await <$> term expression)
unaryExpression :: Assignment Term
unaryExpression = symbol Grammar.UnaryExpression >>= \ loc ->
makeTerm loc . Expression.Not <$> children (symbol AnonBang *> term expression)
<|> makeTerm loc . Expression.Complement <$> children (symbol AnonTilde *> term expression)
<|> makeTerm loc . Expression.Negate <$> children ((symbol AnonMinus <|> symbol AnonPlus) *> term expression)
<|> makeTerm loc . Expression.Typeof <$> children (symbol AnonTypeof *> term expression)
<|> makeTerm loc . Expression.Void <$> children (symbol AnonVoid *> term expression)
<|> makeTerm loc . Expression.Delete <$> children (symbol AnonDelete *> term expression)
ternaryExpression :: Assignment Term
ternaryExpression = makeTerm <$> symbol Grammar.TernaryExpression <*> children (Statement.If <$> term expression <*> term expression <*> term expression)
memberExpression :: Assignment Term
memberExpression = makeTerm <$> (symbol Grammar.MemberExpression <|> symbol Grammar.MemberExpression') <*> children (Expression.MemberAccess <$> term expression <*> propertyIdentifier)
newExpression :: Assignment Term
newExpression = makeTerm <$> symbol Grammar.NewExpression <*> children (Expression.New <$> term constructableExpression <*> (typeArguments' <|> emptyTerm) <*> (arguments <|> pure []))
constructableExpression :: Assignment Term
constructableExpression = choice [
this
, identifier
, number
, string
, templateString
, regex
, true
, false
, null'
, undefined'
, object
, array
, function
, arrowFunction
, class'
, anonymousClass
, parenthesizedExpression
, subscriptExpression
, memberExpression
, metaProperty
, newExpression
]
metaProperty :: Assignment Term
metaProperty = makeTerm <$> symbol Grammar.MetaProperty <*> (TSX.Syntax.MetaProperty <$ rawSource)
updateExpression :: Assignment Term
updateExpression = makeTerm <$> symbol Grammar.UpdateExpression <*> children (TSX.Syntax.Update <$> term expression)
yieldExpression :: Assignment Term
yieldExpression = makeTerm <$> symbol Grammar.YieldExpression <*> children (Statement.Yield <$> term (expression <|> emptyTerm))
this :: Assignment Term
this = makeTerm <$> symbol Grammar.This <*> (Expression.This <$ rawSource)
regex :: Assignment Term
regex = makeTerm <$> symbol Grammar.Regex <*> (Literal.Regex <$> source)
null' :: Assignment Term
null' = makeTerm <$> symbol Null <*> (Literal.Null <$ rawSource)
anonymousClass :: Assignment Term
anonymousClass = makeTerm <$> symbol Grammar.AnonymousClass <*> children (Declaration.Class [] <$> emptyTerm <*> (classHeritage' <|> pure []) <*> classBodyStatements)
abstractClass :: Assignment Term
abstractClass = makeTerm <$> symbol Grammar.AbstractClass <*> children (TSX.Syntax.AbstractClass <$> term typeIdentifier <*> (term typeParameters <|> emptyTerm) <*> (classHeritage' <|> pure []) <*> classBodyStatements)
abstractMethodSignature :: Assignment Term
abstractMethodSignature = makeSignature <$> symbol Grammar.AbstractMethodSignature <*> children ((,,) <$> accessibilityModifier' <*> term propertyName <*> callSignatureParts)
where makeSignature loc (modifier, propertyName, (typeParams, params, annotation)) = makeTerm loc (TSX.Syntax.AbstractMethodSignature [typeParams, annotation] propertyName params modifier)
classHeritage' :: Assignment [Term]
classHeritage' = symbol Grammar.ClassHeritage *> children ((mappend `on` toList) <$> optional (term extendsClause) <*> optional (term implementsClause'))
extendsClause :: Assignment Term
extendsClause = makeTerm <$> symbol Grammar.ExtendsClause <*> children (TSX.Syntax.ExtendsClause <$> manyTerm (typeReference <|> expression))
typeReference :: Assignment Term
typeReference = typeIdentifier <|> nestedTypeIdentifier <|> genericType
implementsClause' :: Assignment Term
implementsClause' = makeTerm <$> symbol Grammar.ImplementsClause <*> children (TSX.Syntax.ImplementsClause <$> manyTerm ty)
super :: Assignment Term
super = makeTerm <$> symbol Grammar.Super <*> (TSX.Syntax.Super <$ rawSource)
asExpression :: Assignment Term
asExpression = makeTerm <$> symbol AsExpression <*> children (Expression.Cast <$> term expression <*> term (ty <|> templateString))
templateString :: Assignment Term
templateString = makeTerm <$> symbol TemplateString <*> children (Literal.String <$> manyTerm templateSubstitution)
templateSubstitution :: Assignment Term
templateSubstitution = symbol TemplateSubstitution *> children (term expressions)
nonNullExpression' :: Assignment Term
nonNullExpression' = makeTerm <$> symbol Grammar.NonNullExpression <*> children (Expression.NonNullExpression <$> term expression)
importAlias' :: Assignment Term
importAlias' = makeTerm <$> symbol Grammar.ImportAlias <*> children (TSX.Syntax.ImportAlias <$> term identifier <*> term (identifier <|> nestedIdentifier))
number :: Assignment Term
number = makeTerm <$> symbol Grammar.Number <*> (Literal.Float <$> source)
string :: Assignment Term
string = makeTerm <$> symbol Grammar.String <*> (Literal.TextElement <$> source)
true :: Assignment Term
true = makeTerm <$> symbol Grammar.True <*> (Literal.true <$ rawSource)
false :: Assignment Term
false = makeTerm <$> symbol Grammar.False <*> (Literal.false <$ rawSource)
identifier :: Assignment Term
identifier = makeTerm <$> symbol Identifier <*> (Syntax.Identifier . name <$> source)
class' :: Assignment Term
class' = makeClass <$> symbol Class <*> children ((,,,,) <$> manyTerm decorator <*> term typeIdentifier <*> (symbol TypeParameters *> children (manyTerm typeParameter') <|> pure []) <*> (classHeritage' <|> pure []) <*> classBodyStatements)
where makeClass loc (decorators, expression, typeParams, classHeritage, statements) = makeTerm loc (Declaration.Class (decorators <> typeParams) expression classHeritage statements)
object :: Assignment Term
object = makeTerm <$> (symbol Object <|> symbol ObjectPattern) <*> children (Literal.Hash <$> manyTerm (pair <|> spreadElement <|> methodDefinition <|> assignmentPattern <|> shorthandPropertyIdentifier))
array :: Assignment Term
array = makeTerm <$> (symbol Array <|> symbol ArrayPattern) <*> children (Literal.Array <$> manyTerm (expression <|> spreadElement))
jsxElement' :: Assignment Term
jsxElement' = choice [ jsxElement, jsxSelfClosingElement ]
jsxElement :: Assignment Term
jsxElement = makeTerm <$> symbol Grammar.JsxElement <*> children (TSX.Syntax.JsxElement <$> term jsxOpeningElement' <*> manyTerm jsxChild <*> term jsxClosingElement')
jsxFragment :: Assignment Term
jsxFragment = makeTerm <$> symbol Grammar.JsxFragment <*> children (TSX.Syntax.JsxFragment <$> manyTerm jsxChild)
jsxChild :: Assignment Term
jsxChild = choice [ jsxElement', jsxExpression', jsxText ]
jsxSelfClosingElement :: Assignment Term
jsxSelfClosingElement = makeTerm <$> symbol Grammar.JsxSelfClosingElement <*> children (TSX.Syntax.JsxSelfClosingElement <$> term jsxElementName <*> manyTerm jsxAttribute')
jsxAttribute' :: Assignment Term
jsxAttribute' = jsxAttribute <|> jsxExpression'
jsxOpeningElement' :: Assignment Term
jsxOpeningElement' = makeTerm <$> symbol Grammar.JsxOpeningElement <*> children (TSX.Syntax.JsxOpeningElement <$> term jsxElementName <*> manyTerm jsxAttribute')
jsxElementName :: Assignment Term
jsxElementName = choice [ identifier, nestedIdentifier, jsxNamespaceName ]
jsxNamespaceName :: Assignment Term
jsxNamespaceName = makeTerm <$> symbol Grammar.JsxNamespaceName <*> children (TSX.Syntax.JsxNamespaceName <$> identifier <*> identifier)
jsxExpression' :: Assignment Term
jsxExpression' = makeTerm <$> symbol Grammar.JsxExpression <*> children (TSX.Syntax.JsxExpression <$> term (expressions <|> spreadElement <|> emptyTerm))
jsxText :: Assignment Term
jsxText = makeTerm <$> symbol Grammar.JsxText <*> (TSX.Syntax.JsxText <$> source)
jsxClosingElement' :: Assignment Term
jsxClosingElement' = makeTerm <$> symbol Grammar.JsxClosingElement <*> children (TSX.Syntax.JsxClosingElement <$> term jsxElementName)
jsxAttribute :: Assignment Term
jsxAttribute = makeTerm <$> symbol Grammar.JsxAttribute <*> children (TSX.Syntax.JsxAttribute <$> term (propertyIdentifier <|> jsxNamespaceName) <*> (term jsxAttributeValue <|> emptyTerm))
where jsxAttributeValue = choice [ string, jsxExpression', jsxElement', jsxFragment ]
propertyIdentifier :: Assignment Term
propertyIdentifier = makeTerm <$> symbol PropertyIdentifier <*> (Syntax.Identifier . name <$> source)
sequenceExpression :: Assignment Term
sequenceExpression = makeTerm <$> symbol Grammar.SequenceExpression <*> children (Expression.SequenceExpression <$> term expression <*> term expressions)
expressions :: Assignment Term
expressions = annotatedExpression <|> expression <|> sequenceExpression
annotatedExpression :: Assignment Term
annotatedExpression = mkAnnotated <$> location <*> expression <*> typeAnnotation'
where mkAnnotated loc expr ann = makeTerm loc (TSX.Syntax.AnnotatedExpression expr ann)
parameter :: Assignment Term
parameter = requiredParameter
<|> restParameter
<|> optionalParameter
accessibilityModifier' :: Assignment ScopeGraph.AccessControl
accessibilityModifier' = (symbol AccessibilityModifier >> children (public <|> protected <|> private)) <|> default'
where public = symbol AnonPublic >> pure ScopeGraph.Public
protected = symbol AnonProtected >> pure ScopeGraph.Protected
private = symbol AnonPrivate >> pure ScopeGraph.Private
default' = pure ScopeGraph.Public
destructuringPattern :: Assignment Term
destructuringPattern = object <|> array
spreadElement :: Assignment Term
spreadElement = symbol SpreadElement *> children (term expression)
readonly' :: Assignment Term
readonly' = makeTerm <$> symbol Readonly <*> (Type.Readonly <$ rawSource)
methodDefinition :: Assignment Term
methodDefinition = makeMethod <$>
symbol MethodDefinition
<*> children ((,,,,,) <$> accessibilityModifier' <*> (term readonly' <|> emptyTerm) <*> emptyTerm <*> term propertyName <*> callSignatureParts <*> term statementBlock)
where
makeMethod loc (modifier, readonly, receiver, propertyName', (typeParameters', params, ty'), statements) = makeTerm loc (Declaration.Method [readonly, typeParameters', ty'] receiver propertyName' params statements modifier)
callSignatureParts :: Assignment (Term, [Term], Term)
callSignatureParts = contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> callSignature' <*> many comment)
where
callSignature' = symbol Grammar.CallSignature *> children ((,,) <$> (term typeParameters <|> emptyTerm) <*> formalParameters <*> (term typeAnnotation' <|> emptyTerm))
contextualize' (cs, (typeParams, formalParams, annotation)) = case nonEmpty cs of
Just cs -> (makeTerm1 (Syntax.Context cs typeParams), formalParams, annotation)
Nothing -> (typeParams, formalParams, annotation)
postContextualize' (typeParams, formalParams, annotation) cs = case nonEmpty cs of
Just cs -> (typeParams, formalParams, makeTerm1 (Syntax.Context cs annotation))
Nothing -> (typeParams, formalParams, annotation)
callSignature :: Assignment Term
callSignature = makeTerm <$> symbol Grammar.CallSignature <*> children (TSX.Syntax.CallSignature <$> (fromMaybe <$> emptyTerm <*> optional (term typeParameters)) <*> formalParameters <*> (fromMaybe <$> emptyTerm <*> optional (term typeAnnotation')))
constructSignature :: Assignment Term
constructSignature = makeTerm <$> symbol Grammar.ConstructSignature <*> children (TSX.Syntax.ConstructSignature <$> (fromMaybe <$> emptyTerm <*> optional (term typeParameters)) <*> formalParameters <*> (fromMaybe <$> emptyTerm <*> optional (term typeAnnotation')))
indexSignature :: Assignment Term
indexSignature = makeTerm <$> symbol Grammar.IndexSignature <*> children (TSX.Syntax.IndexSignature <$> term identifier <*> predefinedTy <*> term typeAnnotation')
methodSignature :: Assignment Term
methodSignature = makeMethodSignature <$> symbol Grammar.MethodSignature <*> children ((,,,) <$> accessibilityModifier' <*> (term readonly' <|> emptyTerm) <*> term propertyName <*> callSignatureParts)
where makeMethodSignature loc (accessControl, readonly, propertyName, (typeParams, params, annotation)) = makeTerm loc (Declaration.MethodSignature [readonly, typeParams, annotation] propertyName params accessControl)
formalParameters :: Assignment [Term]
formalParameters = symbol FormalParameters *> children (contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> (concat <$> many ((\as b -> as <> [b]) <$> manyTerm decorator <*> term parameter)) <*> many comment))
where
contextualize' (cs, formalParams) = case nonEmpty cs of
Just cs -> toList cs <> formalParams
Nothing -> formalParams
postContextualize' formalParams cs = case nonEmpty cs of
Just cs -> formalParams <> toList cs
Nothing -> formalParams
decorator :: Assignment Term
decorator = makeTerm <$> symbol Grammar.Decorator <*> children (TSX.Syntax.Decorator <$> term (identifier <|> memberExpression <|> callExpression))
typeParameters :: Assignment Term
typeParameters = makeTerm <$> symbol TypeParameters <*> children (Type.TypeParameters <$> manyTerm typeParameter')
typeAnnotation' :: Assignment Term
typeAnnotation' = makeTerm <$> symbol TypeAnnotation <*> children (TSX.Syntax.Annotation <$> term ty)
typeParameter' :: Assignment Term
typeParameter' = makeTerm <$> symbol Grammar.TypeParameter <*> children (TSX.Syntax.TypeParameter <$> term typeIdentifier <*> term (constraint <|> emptyTerm) <*> term (defaultType <|> emptyTerm))
defaultType :: Assignment Term
defaultType = makeTerm <$> symbol Grammar.DefaultType <*> children (TSX.Syntax.DefaultType <$> term ty)
constraint :: Assignment Term
constraint = makeTerm <$> symbol Grammar.Constraint <*> children (TSX.Syntax.Constraint <$> term ty)
function :: Assignment Term
function = makeFunction <$> (symbol Grammar.Function <|> symbol Grammar.GeneratorFunction) <*> children ((,,) <$> term (identifier <|> emptyTerm) <*> callSignatureParts <*> term statementBlock)
where makeFunction loc (id, (typeParams, params, annotation), statements) = makeTerm loc (Declaration.Function [typeParams, annotation] id params statements)
-- TODO: FunctionSignatures can, but don't have to be ambient functions.
ambientFunction :: Assignment Term
ambientFunction = makeAmbientFunction <$> symbol Grammar.FunctionSignature <*> children ((,) <$> term identifier <*> callSignatureParts)
where makeAmbientFunction loc (id, (typeParams, params, annotation)) = makeTerm loc (TSX.Syntax.AmbientFunction [typeParams, annotation] id params)
ty :: Assignment Term
ty = primaryType <|> unionType <|> intersectionType <|> functionTy <|> constructorTy
primaryType :: Assignment Term
primaryType = arrayTy
<|> existentialType
<|> flowMaybeTy
<|> genericType
<|> indexTypeQuery
<|> literalType
<|> lookupType
<|> nestedTypeIdentifier
<|> objectType
<|> parenthesizedTy
<|> predefinedTy
<|> thisType
<|> tupleType
<|> typeIdentifier
<|> typePredicate
<|> typeQuery
parenthesizedTy :: Assignment Term
parenthesizedTy = makeTerm <$> symbol Grammar.ParenthesizedType <*> children (TSX.Syntax.ParenthesizedType <$> term ty)
predefinedTy :: Assignment Term
predefinedTy = makeTerm <$> symbol Grammar.PredefinedType <*> (TSX.Syntax.PredefinedType <$> source)
typeIdentifier :: Assignment Term
typeIdentifier = makeTerm <$> symbol Grammar.TypeIdentifier <*> (TSX.Syntax.TypeIdentifier <$> source)
nestedIdentifier :: Assignment Term
nestedIdentifier = makeTerm <$> symbol Grammar.NestedIdentifier <*> children (TSX.Syntax.NestedIdentifier <$> term (identifier <|> nestedIdentifier) <*> term identifier)
nestedTypeIdentifier :: Assignment Term
nestedTypeIdentifier = makeTerm <$> symbol Grammar.NestedTypeIdentifier <*> children (TSX.Syntax.NestedTypeIdentifier <$> term (identifier <|> nestedIdentifier) <*> term typeIdentifier)
genericType :: Assignment Term
genericType = makeTerm <$> symbol Grammar.GenericType <*> children (TSX.Syntax.GenericType <$> term (typeIdentifier <|> nestedTypeIdentifier) <*> term typeArguments')
typeArguments' :: Assignment Term
typeArguments' = makeTerm <$> symbol Grammar.TypeArguments <*> children (TSX.Syntax.TypeArguments <$> some (term ty))
typePredicate :: Assignment Term
typePredicate = makeTerm <$> symbol Grammar.TypePredicate <*> children (TSX.Syntax.TypePredicate <$> term identifier <*> term ty)
objectType :: Assignment Term
objectType = makeTerm <$> symbol Grammar.ObjectType <*> children (TSX.Syntax.ObjectType <$> manyTerm (exportStatement <|> propertySignature <|> callSignature <|> constructSignature <|> indexSignature <|> methodSignature))
arrayTy :: Assignment Term
arrayTy = makeTerm <$> symbol Grammar.ArrayType <*> children (TSX.Syntax.ArrayType <$> term ty)
lookupType :: Assignment Term
lookupType = makeTerm <$> symbol Grammar.LookupType <*> children (TSX.Syntax.LookupType <$> term (typeIdentifier <|> nestedTypeIdentifier) <*> term ty)
flowMaybeTy :: Assignment Term
flowMaybeTy = makeTerm <$> symbol Grammar.FlowMaybeType <*> children (TSX.Syntax.FlowMaybeType <$> term primaryType)
typeQuery :: Assignment Term
typeQuery = makeTerm <$> symbol Grammar.TypeQuery <*> children (TSX.Syntax.TypeQuery <$> term (identifier <|> nestedIdentifier))
indexTypeQuery :: Assignment Term
indexTypeQuery = makeTerm <$> symbol Grammar.IndexTypeQuery <*> children (TSX.Syntax.IndexTypeQuery <$> term (typeIdentifier <|> nestedTypeIdentifier))
thisType :: Assignment Term
thisType = makeTerm <$> symbol Grammar.ThisType <*> (TSX.Syntax.ThisType <$> source)
existentialType :: Assignment Term
existentialType = makeTerm <$> symbol Grammar.ExistentialType <*> (TSX.Syntax.ExistentialType <$> source)
literalType :: Assignment Term
literalType = makeTerm <$> symbol Grammar.LiteralType <*> children (TSX.Syntax.LiteralType <$> term (number <|> string <|> true <|> false))
unionType :: Assignment Term
unionType = makeTerm <$> symbol UnionType <*> children (TSX.Syntax.Union <$> (term ty <|> emptyTerm) <*> term ty)
intersectionType :: Assignment Term
intersectionType = makeTerm <$> symbol IntersectionType <*> children (TSX.Syntax.Intersection <$> term ty <*> term ty)
functionTy :: Assignment Term
functionTy = makeTerm <$> symbol Grammar.FunctionType <*> children (TSX.Syntax.FunctionType <$> (fromMaybe <$> emptyTerm <*> optional (term typeParameters)) <*> formalParameters <*> term ty)
tupleType :: Assignment Term
tupleType = makeTerm <$> symbol TupleType <*> children (TSX.Syntax.Tuple <$> manyTerm ty)
constructorTy :: Assignment Term
constructorTy = makeTerm <$> symbol ConstructorType <*> children (TSX.Syntax.Constructor <$> (fromMaybe <$> emptyTerm <*> optional (term typeParameters)) <*> formalParameters <*> term ty)
statementTerm :: Assignment Term
statementTerm = makeTerm <$> symbol StatementBlock <*> children (Statement.Statements <$> manyTerm statement)
statementBlock :: Assignment Term
statementBlock = makeTerm <$> symbol StatementBlock <*> children (Statement.StatementBlock <$> manyTerm statement)
classBodyStatements :: Assignment Term
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))
where
contextualize' (cs, formalParams) = case nonEmpty cs of
Just cs -> toList cs <> formalParams
Nothing -> formalParams
postContextualize' formalParams cs = case nonEmpty cs of
Just cs -> formalParams <> toList cs
Nothing -> formalParams
publicFieldDefinition :: Assignment Term
publicFieldDefinition = makeField <$> symbol Grammar.PublicFieldDefinition <*> children ((,,,,) <$> accessibilityModifier' <*> (term readonly' <|> emptyTerm) <*> term propertyName <*> (term typeAnnotation' <|> emptyTerm) <*> (term expression <|> emptyTerm))
where makeField loc (accessControl, readonly, propertyName, annotation, expression) = makeTerm loc (Declaration.PublicFieldDefinition [readonly, annotation] propertyName expression accessControl)
statement :: Assignment Term
statement = handleError everything
where
everything = choice [
exportStatement
, importStatement
, debuggerStatement
, expressionStatement'
, declaration
, statementTerm
, ifStatement
, switchStatement
, forStatement
, forInStatement
, forOfStatement
, whileStatement
, doStatement
, tryStatement
, withStatement
, breakStatement
, continueStatement
, returnStatement
, throwStatement
, hashBang
, emptyStatement
, labeledStatement ]
forOfStatement :: Assignment Term
forOfStatement = makeTerm <$> symbol ForOfStatement <*> children (TSX.Syntax.ForOf <$> term expression <*> term expressions <*> term statement)
forInStatement :: Assignment Term
forInStatement = makeTerm <$> symbol ForInStatement <*> children (Statement.ForEach <$> term expression <*> term expression <*> term statement)
doStatement :: Assignment Term
doStatement = makeTerm <$> symbol DoStatement <*> children (flip Statement.DoWhile <$> term statement <*> term parenthesizedExpression)
continueStatement :: Assignment Term
continueStatement = makeTerm <$> symbol ContinueStatement <*> children (Statement.Continue <$> (statementIdentifier <|> term emptyTerm))
breakStatement :: Assignment Term
breakStatement = makeTerm <$> symbol BreakStatement <*> children (Statement.Break <$> (statementIdentifier <|> term emptyTerm))
withStatement :: Assignment Term
withStatement = makeTerm <$> symbol WithStatement <*> children (TSX.Syntax.With <$> term parenthesizedExpression <*> term statement)
returnStatement :: Assignment Term
returnStatement = makeTerm <$> symbol ReturnStatement <*> children (Statement.Return <$> (term expressions <|> term emptyTerm))
throwStatement :: Assignment Term
throwStatement = makeTerm <$> symbol Grammar.ThrowStatement <*> children (Statement.Throw <$> term expressions)
hashBang :: Assignment Term
hashBang = makeTerm <$> symbol HashBangLine <*> (Comment.HashBang <$> source)
labeledStatement :: Assignment Term
labeledStatement = makeTerm <$> symbol Grammar.LabeledStatement <*> children (TSX.Syntax.LabeledStatement <$> statementIdentifier <*> term statement)
statementIdentifier :: Assignment Term
statementIdentifier = makeTerm <$> symbol StatementIdentifier <*> (Syntax.Identifier . name <$> source)
importStatement :: Assignment Term
importStatement = makeImportTerm <$> symbol Grammar.ImportStatement <*> children ((,) <$> importClause <*> fromClause)
<|> makeTerm' <$> symbol Grammar.ImportStatement <*> children (requireImport <|> sideEffectImport)
where
-- `import foo = require "./foo"`
requireImport = inject <$> (symbol Grammar.ImportRequireClause *> children (TSX.Syntax.QualifiedAliasedImport <$> term identifier <*> fromClause))
-- `import "./foo"`
sideEffectImport = inject <$> (TSX.Syntax.SideEffectImport <$> fromClause)
-- `import { bar } from "./foo"`
namedImport = (,) Nothing <$> (symbol Grammar.NamedImports *> children (many importSymbol))
-- `import defaultMember from "./foo"`
defaultImport = (,) Nothing <$> (pure <$> (makeNameAliasPair <$> rawIdentifier <*> pure Nothing))
-- `import * as name from "./foo"`
namespaceImport = symbol Grammar.NamespaceImport *> children ((,) . Just <$> term identifier <*> pure [])
-- Combinations of the above.
importClause = symbol Grammar.ImportClause *>
children (
(pure <$> namedImport)
<|> (pure <$> namespaceImport)
<|> ((\a b -> [a, b]) <$> defaultImport <*> (namedImport <|> namespaceImport))
<|> (pure <$> defaultImport))
makeImportTerm1 loc from (Just alias, _) = makeTerm loc (TSX.Syntax.QualifiedAliasedImport alias from)
makeImportTerm1 loc from (Nothing, symbols) = makeTerm loc (TSX.Syntax.Import (uncurry TSX.Syntax.Alias <$> symbols) from)
makeImportTerm loc ([x], from) = makeImportTerm1 loc from x
makeImportTerm loc (xs, from) = makeTerm loc $ fmap (makeImportTerm1 loc from) xs
importSymbol = symbol Grammar.ImportSpecifier *> children (makeNameAliasPair <$> rawIdentifier <*> ((Just <$> rawIdentifier) <|> pure Nothing))
rawIdentifier = symbol Identifier *> (name <$> source)
makeNameAliasPair from (Just alias) = (from, alias)
makeNameAliasPair from Nothing = (from, from)
-- TODO: Need to validate that inline comments are still handled with this change in assigning to Path and not a Term.
fromClause = symbol Grammar.String *> (TypeScript.Resolution.importPath <$> source)
debuggerStatement :: Assignment Term
debuggerStatement = makeTerm <$> symbol Grammar.DebuggerStatement <*> (TSX.Syntax.Debugger <$ rawSource)
expressionStatement' :: Assignment Term
expressionStatement' = symbol ExpressionStatement *> children (term expressions)
declaration :: Assignment Term
declaration = everything
where
everything = choice [
exportStatement,
importAlias',
function,
internalModule,
ambientFunction,
abstractClass,
class',
module',
variableDeclaration,
typeAliasDeclaration,
enumDeclaration,
interfaceDeclaration,
ambientDeclaration
]
typeAliasDeclaration :: Assignment Term
typeAliasDeclaration = makeTypeAliasDecl <$> symbol Grammar.TypeAliasDeclaration <*> children ((,,) <$> term typeIdentifier <*> (term typeParameters <|> emptyTerm) <*> term ty)
where makeTypeAliasDecl loc (identifier, typeParams, body) = makeTerm loc (Declaration.TypeAlias [typeParams] identifier body)
enumDeclaration :: Assignment Term
enumDeclaration = makeTerm <$> symbol Grammar.EnumDeclaration <*> children (TSX.Syntax.EnumDeclaration <$> term identifier <*> (symbol EnumBody *> children (manyTerm (propertyName <|> enumAssignment))))
enumAssignment :: Assignment Term
enumAssignment = makeTerm <$> symbol Grammar.EnumAssignment <*> children (Statement.Assignment [] <$> term propertyName <*> term expression)
interfaceDeclaration :: Assignment Term
interfaceDeclaration = makeInterfaceDecl <$> symbol Grammar.InterfaceDeclaration <*> children ((,,,) <$> term typeIdentifier <*> (term typeParameters <|> emptyTerm) <*> optional (term extendsClause) <*> term objectType)
where makeInterfaceDecl loc (identifier, typeParams, clause, objectType) = makeTerm loc (Declaration.InterfaceDeclaration [typeParams] identifier (toList clause) objectType)
ambientDeclaration :: Assignment Term
ambientDeclaration = makeTerm <$> symbol Grammar.AmbientDeclaration <*> children (TSX.Syntax.AmbientDeclaration <$> term (choice [propertyIdentifier *> ty, declaration, statementBlock]))
exportStatement :: Assignment Term
exportStatement = makeTerm <$> symbol Grammar.ExportStatement <*> children (flip TSX.Syntax.QualifiedExportFrom <$> exportClause <*> fromClause)
<|> makeTerm <$> symbol Grammar.ExportStatement <*> children (TSX.Syntax.QualifiedExport <$> exportClause)
<|> makeTerm <$> symbol Grammar.ExportStatement <*> children (TSX.Syntax.DefaultExport <$> contextualize decorator (term (declaration <|> expression <|> identifier <|> importAlias')))
where
exportClause = symbol Grammar.ExportClause *> children (many exportSymbol)
exportSymbol = symbol Grammar.ExportSpecifier *> children (makeNameAliasPair <$> rawIdentifier <*> (Just <$> rawIdentifier))
<|> symbol Grammar.ExportSpecifier *> children (makeNameAliasPair <$> rawIdentifier <*> pure Nothing)
makeNameAliasPair from (Just alias) = TSX.Syntax.Alias from alias
makeNameAliasPair from Nothing = TSX.Syntax.Alias from from
rawIdentifier = symbol Identifier *> (name <$> source)
-- TODO: Need to validate that inline comments are still handled with this change in assigning to Path and not a Term.
fromClause = symbol Grammar.String *> (TypeScript.Resolution.importPath <$> source)
propertySignature :: Assignment Term
propertySignature = makePropertySignature <$> symbol Grammar.PropertySignature <*> children ((,,,) <$> accessibilityModifier' <*> (term readonly' <|> emptyTerm) <*> term propertyName <*> (term typeAnnotation' <|> emptyTerm))
where makePropertySignature loc (modifier, readonly, propertyName, annotation) = makeTerm loc (TSX.Syntax.PropertySignature [readonly, annotation] propertyName modifier)
propertyName :: Assignment Term
propertyName = term (propertyIdentifier <|> string <|> number <|> computedPropertyName)
computedPropertyName :: Assignment Term
computedPropertyName = makeTerm <$> symbol Grammar.ComputedPropertyName <*> children (TSX.Syntax.ComputedPropertyName <$> term expression)
assignmentPattern :: Assignment Term
assignmentPattern = makeTerm <$> symbol AssignmentPattern <*> children (Statement.Assignment [] <$> term shorthandPropertyIdentifier <*> term expression)
shorthandPropertyIdentifier :: Assignment Term
shorthandPropertyIdentifier = makeTerm <$> symbol Grammar.ShorthandPropertyIdentifier <*> (TSX.Syntax.ShorthandPropertyIdentifier <$> source)
requiredParameter :: Assignment Term
requiredParameter = makeRequiredParameter
<$> symbol Grammar.RequiredParameter
<*> children ( (,,,,)
<$> accessibilityModifier'
<*> (term readonly' <|> emptyTerm)
<*> term (identifier <|> destructuringPattern <|> this)
<*> (term typeAnnotation' <|> emptyTerm)
<*> (term expression <|> emptyTerm))
where
makeRequiredParameter loc (modifier, readonly, identifier, annotation, initializer) = makeTerm loc (TSX.Syntax.RequiredParameter [readonly, annotation] identifier initializer modifier)
restParameter :: Assignment Term
restParameter = makeRestParameter <$> symbol Grammar.RestParameter <*> children ((,) <$> term identifier <*> (term typeAnnotation' <|> emptyTerm))
where makeRestParameter loc (identifier, annotation) = makeTerm loc (TSX.Syntax.RestParameter [annotation] identifier)
optionalParameter :: Assignment Term
optionalParameter = makeOptionalParam <$> symbol Grammar.OptionalParameter <*> children ((,,,,) <$> accessibilityModifier' <*> (term readonly' <|> emptyTerm) <*> (term identifier <|> destructuringPattern) <*> (term typeAnnotation' <|> emptyTerm) <*> (term expression <|> emptyTerm))
where makeOptionalParam loc (modifier, readonly, subject, annotation, initializer) = makeTerm loc (TSX.Syntax.OptionalParameter [readonly, annotation] (makeTerm loc (Statement.Assignment [] subject initializer)) modifier)
internalModule :: Assignment Term
internalModule = makeTerm <$> symbol Grammar.InternalModule <*> children (TSX.Syntax.InternalModule <$> term (string <|> identifier <|> nestedIdentifier) <*> statements)
module' :: Assignment Term
module' = makeTerm <$> symbol Module <*> children (TSX.Syntax.Module <$> term (string <|> identifier <|> nestedIdentifier) <*> (statements <|> pure []))
statements :: Assignment [Term]
statements = symbol StatementBlock *> children (manyTerm statement)
arrowFunction :: Assignment Term
arrowFunction = makeArrowFun <$> symbol ArrowFunction <*> children ((,,) <$> emptyTerm <*> (((\a b c -> (a, [b], c)) <$> emptyTerm <*> term identifier <*> emptyTerm) <|> callSignatureParts) <*> term (expression <|> statementBlock))
where makeArrowFun loc (identifier, (typeParams, params, returnTy), body) = makeTerm loc (Declaration.Function [ typeParams, returnTy ] identifier params body)
comment :: Assignment Term
comment = makeTerm <$> symbol Comment <*> (Comment.Comment <$> source)
ifStatement :: Assignment Term
ifStatement = makeTerm <$> symbol IfStatement <*> children (Statement.If <$> term parenthesizedExpression <*> term statement <*> (term statement <|> emptyTerm))
whileStatement :: Assignment Term
whileStatement = makeTerm <$> symbol WhileStatement <*> children (Statement.While <$> term expression <*> term statement)
forStatement :: Assignment Term
forStatement = makeTerm <$> symbol ForStatement <*> children (Statement.For <$> term (variableDeclaration <|> expressionStatement' <|> emptyStatement) <*> term (expressionStatement' <|> emptyStatement) <*> term (expressions <|> emptyTerm) <*> term statement)
variableDeclaration :: Assignment Term
variableDeclaration = makeTerm <$> (symbol Grammar.VariableDeclaration <|> symbol Grammar.LexicalDeclaration) <*> children (Declaration.VariableDeclaration <$> manyTerm variableDeclarator)
variableDeclarator :: Assignment Term
variableDeclarator =
makeTerm <$> symbol VariableDeclarator <*> children (TSX.Syntax.JavaScriptRequire <$> identifier <*> requireCall)
<|> makeVarDecl <$> symbol VariableDeclarator <*> children ((,,) <$> term (identifier <|> destructuringPattern) <*> (term typeAnnotation' <|> emptyTerm) <*> (term expression <|> emptyTerm))
where
makeVarDecl loc (subject, annotations, value) = makeTerm loc (Statement.Assignment [annotations] subject value)
requireCall = symbol CallExpression *> children (symbol Identifier *> do
s <- source
guard (s == "require")
symbol Arguments *> children (symbol Grammar.String *> (TypeScript.Resolution.importPath <$> source))
)
parenthesizedExpression :: Assignment Term
parenthesizedExpression = symbol ParenthesizedExpression *> children (term expressions)
switchStatement :: Assignment Term
switchStatement = makeTerm <$> symbol SwitchStatement <*> children (Statement.Match <$> term parenthesizedExpression <*> term switchBody)
where
switchBody = symbol SwitchBody *> children (makeTerm <$> location <*> manyTerm switchCase)
switchCase = makeTerm <$> (symbol SwitchCase <|> symbol SwitchDefault) <*> children (Statement.Pattern <$> (term expressions <|> emptyTerm) <*> (makeTerm <$> location <*> manyTerm statement))
subscriptExpression :: Assignment Term
subscriptExpression = makeTerm <$> symbol SubscriptExpression <*> children (Expression.Subscript <$> term expression <*> (pure <$> term expressions))
pair :: Assignment Term
pair = makeTerm <$> symbol Pair <*> children (Literal.KeyValue <$> term propertyName <*> term expression)
callExpression :: Assignment Term
callExpression = makeCall <$> (symbol CallExpression <|> symbol CallExpression') <*> children ((,,,) <$> term (expression <|> super <|> function) <*> (typeArguments <|> pure []) <*> (arguments <|> (pure <$> term templateString)) <*> emptyTerm)
where makeCall loc (subject, typeArgs, args, body) = makeTerm loc (Expression.Call typeArgs subject args body)
typeArguments = symbol Grammar.TypeArguments *> children (some (term ty))
arguments :: Assignment [Term]
arguments = symbol Arguments *> children (manyTerm (expression <|> spreadElement))
tryStatement :: Assignment Term
tryStatement = makeTry <$> symbol TryStatement <*> children ((,,) <$> term statementTerm <*> optional (term catchClause) <*> optional (term finallyClause))
where
makeTry loc (statementBlock', catch, finally) = makeTerm loc (Statement.Try statementBlock' (catMaybes [catch, finally]))
catchClause = makeTerm <$> symbol CatchClause <*> children (Statement.Catch <$> (identifier <|> emptyTerm) <*> statementTerm)
finallyClause = makeTerm <$> symbol FinallyClause <*> children (Statement.Finally <$> statementTerm)
binaryExpression :: Assignment Term
binaryExpression = makeTerm' <$> symbol BinaryExpression <*> children (infixTerm expression (term expression)
[ (inject .) . Expression.Plus <$ symbol AnonPlus
, (inject .) . Expression.Minus <$ symbol AnonMinus
, (inject .) . Expression.Times <$ symbol AnonStar
, (inject .) . Expression.DividedBy <$ symbol AnonSlash
, (inject .) . Expression.Modulo <$ symbol AnonPercent
, (inject .) . Expression.Member <$ symbol AnonIn
, (inject .) . Expression.And <$ symbol AnonAmpersandAmpersand
, (inject .) . Expression.BAnd <$ symbol AnonAmpersand
, (inject .) . Expression.Or <$ symbol AnonPipePipe
, (inject .) . Expression.BOr <$ symbol AnonPipe
, (inject .) . Expression.BXOr <$ symbol AnonCaret
, (inject .) . Expression.InstanceOf <$ symbol AnonInstanceof
, (inject .) . Expression.Equal <$ symbol AnonEqualEqual
, (inject .) . Expression.StrictEqual <$ symbol AnonEqualEqualEqual
, (inject .) . invert Expression.Equal <$ symbol AnonBangEqual
, (inject .) . invert Expression.StrictEqual <$ symbol AnonBangEqualEqual
, (inject .) . Expression.LShift <$ symbol AnonLAngleLAngle
, (inject .) . Expression.RShift <$ symbol AnonRAngleRAngle
, (inject .) . Expression.UnsignedRShift <$ symbol AnonRAngleRAngleRAngle
, (inject .) . Expression.LessThan <$ symbol AnonLAngle
, (inject .) . Expression.GreaterThan <$ symbol AnonRAngle
, (inject .) . Expression.LessThanEqual <$ symbol AnonLAngleEqual
, (inject .) . Expression.GreaterThanEqual <$ symbol AnonRAngleEqual
])
where invert cons a b = Expression.Not (makeTerm1 (cons a b))
-- Helpers
-- | Match a term optionally preceded by comment(s), or a sequence of comments if the term is not present.
manyTerm :: Assignment Term -> Assignment [Term]
manyTerm term = many (contextualize comment term <|> makeTerm1 <$> (Syntax.Context <$> some1 comment <*> emptyTerm))
term :: Assignment Term -> Assignment Term
term term = contextualize comment (postContextualize comment term)
emptyStatement :: Assignment Term
emptyStatement = makeTerm <$> symbol EmptyStatement <*> (Syntax.Empty <$ rawSource <|> pure Syntax.Empty)
-- | Match infix terms separated by any of a list of operators, assigning any comments following each operand.
infixTerm :: Assignment Term
-> Assignment Term
-> [Assignment (Term -> Term -> Sum Syntax Term)]
-> Assignment (Sum Syntax Term)
infixTerm = infixContext comment

View File

@ -0,0 +1,7 @@
module Language.TSX.Syntax ( module X ) where
import Language.TypeScript.Syntax.Import as X
import Language.TypeScript.Syntax.JavaScript as X
import Language.TSX.Syntax.JSX as X
import Language.TypeScript.Syntax.TypeScript as X
import Language.TypeScript.Syntax.Types as X

View File

@ -1,17 +1,14 @@
{-# LANGUAGE DeriveAnyClass, DerivingVia, DuplicateRecordFields #-}
{-# OPTIONS_GHC -Wno-missing-export-lists #-}
module Language.TypeScript.Syntax.JSX where
module Language.TSX.Syntax.JSX where
import Prologue
import Control.Abstract as Abstract
import Data.Abstract.Evaluatable
import Data.Abstract.ScopeGraph (AccessControl(..))
import Data.JSON.Fields
import qualified Data.Text as T
import Diffing.Algorithm
import qualified Data.Map.Strict as Map
import qualified Data.Abstract.ScopeGraph as ScopeGraph
data JsxElement a = JsxElement { jsxOpeningElement :: !a, jsxElements :: ![a], jsxClosingElement :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
@ -55,53 +52,6 @@ data JsxAttribute a = JsxAttribute { jsxAttributeTarget :: !a, jsxAttributeValue
instance Evaluatable JsxAttribute
newtype ImplementsClause a = ImplementsClause { implementsClauseTypes :: [a] }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically ImplementsClause
instance Evaluatable ImplementsClause
data OptionalParameter a = OptionalParameter { optionalParameterContext :: ![a], optionalParameterSubject :: !a, optionalParameterAccessControl :: AccessControl }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically OptionalParameter
instance Evaluatable OptionalParameter
data RequiredParameter a = RequiredParameter { requiredParameterContext :: [a], requiredParameterSubject :: a, requiredParameterValue :: a, requiredParameterAccessControl :: AccessControl }
deriving (Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically RequiredParameter
instance Declarations1 RequiredParameter where
liftDeclaredName declaredName RequiredParameter{..} = declaredName requiredParameterSubject
instance Evaluatable RequiredParameter where
eval eval ref RequiredParameter{..} = do
span <- ask @Span
_ <- declareMaybeName (declaredName requiredParameterSubject) Default Public span ScopeGraph.RequiredParameter Nothing
lhs <- ref requiredParameterSubject
rhs <- eval requiredParameterValue
case declaredName requiredParameterValue of
Just rhsName -> do
assocScope <- associatedScope (Declaration rhsName)
case assocScope of
Just assocScope' -> do
objectScope <- newScope (Map.singleton Import [ assocScope' ])
putSlotDeclarationScope lhs (Just objectScope) -- TODO: not sure if this is right
Nothing ->
pure ()
Nothing ->
pure ()
assign lhs rhs
pure rhs
data RestParameter a = RestParameter { restParameterContext :: ![a], restParameterSubject :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically RestParameter
instance Evaluatable RestParameter
newtype JsxFragment a = JsxFragment { terms :: [a] }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically JsxFragment

View File

@ -0,0 +1,143 @@
{-# LANGUAGE DeriveAnyClass, DerivingVia, DuplicateRecordFields #-}
{-# OPTIONS_GHC -Wno-missing-export-lists #-}
module Language.TypeScript.Syntax.Types where
import Prologue
import Control.Abstract hiding (Import)
import Data.Abstract.Evaluatable as Evaluatable
import Data.JSON.Fields
import qualified Data.Text as T
import Diffing.Algorithm
import qualified Data.Abstract.ScopeGraph as ScopeGraph
-- | Lookup type for a type-level key in a typescript map.
data LookupType a = LookupType { lookupTypeIdentifier :: a, lookupTypeKey :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically LookupType
instance Evaluatable LookupType
data FunctionType a = FunctionType { functionTypeParameters :: !a, functionFormalParameters :: ![a], functionType :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically FunctionType
instance Evaluatable FunctionType
data TypeParameter a = TypeParameter { typeParameter :: !a, typeParameterConstraint :: !a, typeParameterDefaultType :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically TypeParameter
instance Evaluatable TypeParameter
data TypeAssertion a = TypeAssertion { typeAssertionParameters :: !a, typeAssertionExpression :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically TypeAssertion
instance Evaluatable TypeAssertion
newtype DefaultType a = DefaultType { defaultType :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically DefaultType
instance Evaluatable DefaultType
newtype ParenthesizedType a = ParenthesizedType { parenthesizedType :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically ParenthesizedType
instance Evaluatable ParenthesizedType
newtype PredefinedType a = PredefinedType { predefinedType :: T.Text }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically PredefinedType
-- TODO: Implement Eval instance for PredefinedType
instance Evaluatable PredefinedType
newtype TypeIdentifier a = TypeIdentifier { contents :: T.Text }
deriving (Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically TypeIdentifier
instance Declarations1 TypeIdentifier where
liftDeclaredName _ (TypeIdentifier identifier) = Just (Evaluatable.name identifier)
-- TODO: TypeIdentifier shouldn't evaluate to an address in the heap?
instance Evaluatable TypeIdentifier where
eval _ _ TypeIdentifier{..} = do
-- Add a reference to the type identifier in the current scope.
span <- ask @Span
reference (Reference (Evaluatable.name contents)) span ScopeGraph.TypeIdentifier (Declaration (Evaluatable.name contents))
unit
data NestedTypeIdentifier a = NestedTypeIdentifier { left :: !a, right :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically NestedTypeIdentifier
instance Evaluatable NestedTypeIdentifier
data GenericType a = GenericType { genericTypeIdentifier :: !a, genericTypeArguments :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically GenericType
instance Evaluatable GenericType
data TypePredicate a = TypePredicate { typePredicateIdentifier :: !a, typePredicateType :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically TypePredicate
instance Evaluatable TypePredicate
newtype ObjectType a = ObjectType { objectTypeElements :: [a] }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically ObjectType
instance Evaluatable ObjectType
newtype ArrayType a = ArrayType { arrayType :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically ArrayType
instance Evaluatable ArrayType
newtype FlowMaybeType a = FlowMaybeType { flowMaybeType :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically FlowMaybeType
instance Evaluatable FlowMaybeType
newtype TypeQuery a = TypeQuery { typeQuerySubject :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically TypeQuery
instance Evaluatable TypeQuery
newtype IndexTypeQuery a = IndexTypeQuery { indexTypeQuerySubject :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically IndexTypeQuery
instance Evaluatable IndexTypeQuery
newtype TypeArguments a = TypeArguments { typeArguments :: [a] }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically TypeArguments
instance Evaluatable TypeArguments
newtype ThisType a = ThisType { contents :: T.Text }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically ThisType
instance Evaluatable ThisType
newtype ExistentialType a = ExistentialType { contents :: T.Text }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically ExistentialType
instance Evaluatable ExistentialType
newtype LiteralType a = LiteralType { literalTypeSubject :: a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically LiteralType
instance Evaluatable LiteralType

View File

@ -169,15 +169,6 @@ type Syntax = '[
, TypeScript.Syntax.ClassHeritage
, TypeScript.Syntax.AbstractClass
, TypeScript.Syntax.ImplementsClause
, TypeScript.Syntax.JsxElement
, TypeScript.Syntax.JsxSelfClosingElement
, TypeScript.Syntax.JsxOpeningElement
, TypeScript.Syntax.JsxText
, TypeScript.Syntax.JsxClosingElement
, TypeScript.Syntax.JsxExpression
, TypeScript.Syntax.JsxAttribute
, TypeScript.Syntax.JsxFragment
, TypeScript.Syntax.JsxNamespaceName
, TypeScript.Syntax.OptionalParameter
, TypeScript.Syntax.RequiredParameter
, TypeScript.Syntax.RestParameter
@ -227,8 +218,6 @@ expression = handleError everything
super,
object,
array,
jsxElement',
jsxFragment,
class',
anonymousClass,
function,
@ -402,7 +391,7 @@ false :: Assignment Term
false = makeTerm <$> symbol Grammar.False <*> (Literal.false <$ rawSource)
identifier :: Assignment Term
identifier = makeTerm <$> (symbol Identifier <|> symbol Identifier' <|> symbol Identifier'') <*> (Syntax.Identifier . name <$> source)
identifier = makeTerm <$> symbol Identifier <*> (Syntax.Identifier . name <$> source)
class' :: Assignment Term
class' = makeClass <$> symbol Class <*> children ((,,,,) <$> manyTerm decorator <*> term typeIdentifier <*> (symbol TypeParameters *> children (manyTerm typeParameter') <|> pure []) <*> (classHeritage' <|> pure []) <*> classBodyStatements)
@ -414,46 +403,6 @@ object = makeTerm <$> (symbol Object <|> symbol ObjectPattern) <*> children (Lit
array :: Assignment Term
array = makeTerm <$> (symbol Array <|> symbol ArrayPattern) <*> children (Literal.Array <$> manyTerm (expression <|> spreadElement))
jsxElement' :: Assignment Term
jsxElement' = choice [ jsxElement, jsxSelfClosingElement ]
jsxElement :: Assignment Term
jsxElement = makeTerm <$> symbol Grammar.JsxElement <*> children (TypeScript.Syntax.JsxElement <$> term jsxOpeningElement' <*> manyTerm jsxChild <*> term jsxClosingElement')
jsxFragment :: Assignment Term
jsxFragment = makeTerm <$> symbol Grammar.JsxFragment <*> children (TypeScript.Syntax.JsxFragment <$> manyTerm jsxChild)
jsxChild :: Assignment Term
jsxChild = choice [ jsxElement', jsxExpression', jsxText ]
jsxSelfClosingElement :: Assignment Term
jsxSelfClosingElement = makeTerm <$> symbol Grammar.JsxSelfClosingElement <*> children (TypeScript.Syntax.JsxSelfClosingElement <$> term jsxElementName <*> manyTerm jsxAttribute')
jsxAttribute' :: Assignment Term
jsxAttribute' = jsxAttribute <|> jsxExpression'
jsxOpeningElement' :: Assignment Term
jsxOpeningElement' = makeTerm <$> symbol Grammar.JsxOpeningElement <*> children (TypeScript.Syntax.JsxOpeningElement <$> term jsxElementName <*> manyTerm jsxAttribute')
jsxElementName :: Assignment Term
jsxElementName = choice [ identifier, nestedIdentifier, jsxNamespaceName ]
jsxNamespaceName :: Assignment Term
jsxNamespaceName = makeTerm <$> symbol Grammar.JsxNamespaceName <*> children (TypeScript.Syntax.JsxNamespaceName <$> identifier <*> identifier)
jsxExpression' :: Assignment Term
jsxExpression' = makeTerm <$> symbol Grammar.JsxExpression <*> children (TypeScript.Syntax.JsxExpression <$> term (expressions <|> spreadElement <|> emptyTerm))
jsxText :: Assignment Term
jsxText = makeTerm <$> symbol Grammar.JsxText <*> (TypeScript.Syntax.JsxText <$> source)
jsxClosingElement' :: Assignment Term
jsxClosingElement' = makeTerm <$> symbol Grammar.JsxClosingElement <*> children (TypeScript.Syntax.JsxClosingElement <$> term jsxElementName)
jsxAttribute :: Assignment Term
jsxAttribute = makeTerm <$> symbol Grammar.JsxAttribute <*> children (TypeScript.Syntax.JsxAttribute <$> term (propertyIdentifier <|> jsxNamespaceName) <*> (term jsxAttributeValue <|> emptyTerm))
where jsxAttributeValue = choice [ string, jsxExpression', jsxElement', jsxFragment ]
propertyIdentifier :: Assignment Term
propertyIdentifier = makeTerm <$> symbol PropertyIdentifier <*> (Syntax.Identifier . name <$> source)
@ -754,7 +703,7 @@ importStatement = makeImportTerm <$> symbol Grammar.ImportStatement <*> childr
makeImportTerm loc ([x], from) = makeImportTerm1 loc from x
makeImportTerm loc (xs, from) = makeTerm loc $ fmap (makeImportTerm1 loc from) xs
importSymbol = symbol Grammar.ImportSpecifier *> children (makeNameAliasPair <$> rawIdentifier <*> ((Just <$> rawIdentifier) <|> pure Nothing))
rawIdentifier = (symbol Identifier <|> symbol Identifier' <|> symbol Identifier'') *> (name <$> source)
rawIdentifier = symbol Identifier *> (name <$> source)
makeNameAliasPair from (Just alias) = (from, alias)
makeNameAliasPair from Nothing = (from, from)
@ -813,7 +762,7 @@ exportStatement = makeTerm <$> symbol Grammar.ExportStatement <*> children (flip
<|> symbol Grammar.ExportSpecifier *> children (makeNameAliasPair <$> rawIdentifier <*> pure Nothing)
makeNameAliasPair from (Just alias) = TypeScript.Syntax.Alias from alias
makeNameAliasPair from Nothing = TypeScript.Syntax.Alias from from
rawIdentifier = (symbol Identifier <|> symbol Identifier' <|> symbol Identifier'') *> (name <$> source)
rawIdentifier = symbol Identifier *> (name <$> source)
-- TODO: Need to validate that inline comments are still handled with this change in assigning to Path and not a Term.
fromClause = symbol Grammar.String *> (TypeScript.Resolution.importPath <$> source)
@ -889,7 +838,7 @@ variableDeclarator =
where
makeVarDecl loc (subject, annotations, value) = makeTerm loc (Statement.Assignment [annotations] subject value)
requireCall = symbol CallExpression *> children ((symbol Identifier <|> symbol Identifier' <|> symbol Identifier'') *> do
requireCall = symbol CallExpression *> children (symbol Identifier *> do
s <- source
guard (s == "require")
symbol Arguments *> children (symbol Grammar.String *> (TypeScript.Resolution.importPath <$> source))

View File

@ -2,6 +2,5 @@ module Language.TypeScript.Syntax ( module X ) where
import Language.TypeScript.Syntax.Import as X
import Language.TypeScript.Syntax.JavaScript as X
import Language.TypeScript.Syntax.JSX as X
import Language.TypeScript.Syntax.TypeScript as X
import Language.TypeScript.Syntax.Types as X

View File

@ -13,6 +13,54 @@ import qualified Data.Map.Strict as Map
import Diffing.Algorithm
import Language.TypeScript.Resolution
newtype ImplementsClause a = ImplementsClause { implementsClauseTypes :: [a] }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically ImplementsClause
instance Evaluatable ImplementsClause
data OptionalParameter a = OptionalParameter { optionalParameterContext :: ![a], optionalParameterSubject :: !a, optionalParameterAccessControl :: AccessControl }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically OptionalParameter
instance Evaluatable OptionalParameter
data RequiredParameter a = RequiredParameter { requiredParameterContext :: [a], requiredParameterSubject :: a, requiredParameterValue :: a, requiredParameterAccessControl :: AccessControl }
deriving (Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically RequiredParameter
instance Declarations1 RequiredParameter where
liftDeclaredName declaredName RequiredParameter{..} = declaredName requiredParameterSubject
instance Evaluatable RequiredParameter where
eval eval ref RequiredParameter{..} = do
span <- ask @Span
_ <- declareMaybeName (declaredName requiredParameterSubject) Default Public span ScopeGraph.RequiredParameter Nothing
lhs <- ref requiredParameterSubject
rhs <- eval requiredParameterValue
case declaredName requiredParameterValue of
Just rhsName -> do
assocScope <- associatedScope (Declaration rhsName)
case assocScope of
Just assocScope' -> do
objectScope <- newScope (Map.singleton ScopeGraph.Import [ assocScope' ])
putSlotDeclarationScope lhs (Just objectScope) -- TODO: not sure if this is right
Nothing ->
pure ()
Nothing ->
pure ()
assign lhs rhs
pure rhs
data RestParameter a = RestParameter { restParameterContext :: ![a], restParameterSubject :: !a }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically RestParameter
instance Evaluatable RestParameter
data JavaScriptRequire a = JavaScriptRequire { javascriptRequireIden :: !a, javascriptRequireFrom :: ImportPath }
deriving (Declarations1, Diffable, Eq, Foldable, FreeVariables1, Functor, Generic1, Hashable1, NFData1, Ord, Show, ToJSONFields1, Traversable)
deriving (Eq1, Show1, Ord1) via Generically JavaScriptRequire

View File

@ -19,9 +19,8 @@ module Parsing.Parser
, markdownParser
, pythonParser
, pythonASTParser
, miniPythonParser
, rubyParser
, miniRubyParser
, tsxParser
, typescriptParser
, typescriptASTParser
, phpParser
@ -48,8 +47,7 @@ import qualified Language.Markdown.Assignment as Markdown
import qualified Language.PHP.Assignment as PHP
import qualified Language.Python.Assignment as Python
import qualified Language.Ruby.Assignment as Ruby
import qualified Language.MiniRuby.Assignment as MiniRuby
import qualified Language.MiniPython.Assignment as MiniPython
import qualified Language.TSX.Assignment as TSX
import qualified Language.TypeScript.Assignment as TypeScript
import Prologue
import TreeSitter.Go
@ -60,6 +58,7 @@ import qualified TreeSitter.Language as TS (Language, Symbol)
import TreeSitter.PHP
import TreeSitter.Python
import TreeSitter.Ruby
import TreeSitter.TSX
import TreeSitter.TypeScript
@ -98,6 +97,7 @@ someAnalysisParser _ PHP = SomeAnalysisParser phpParser (Proxy ::
someAnalysisParser _ Python = SomeAnalysisParser pythonParser (Proxy :: Proxy 'Python)
someAnalysisParser _ Ruby = SomeAnalysisParser rubyParser (Proxy :: Proxy 'Ruby)
someAnalysisParser _ TypeScript = SomeAnalysisParser typescriptParser (Proxy :: Proxy 'TypeScript)
someAnalysisParser _ TSX = SomeAnalysisParser typescriptParser (Proxy :: Proxy 'TSX)
someAnalysisParser _ l = error $ "Analysis not supported for: " <> show l
@ -134,9 +134,6 @@ goASTParser = ASTParser tree_sitter_go
rubyParser :: Parser Ruby.Term
rubyParser = AssignmentParser (ASTParser tree_sitter_ruby) Ruby.assignment
miniRubyParser :: Parser MiniRuby.Term
miniRubyParser = AssignmentParser (ASTParser tree_sitter_ruby) MiniRuby.assignment
phpParser :: Parser PHP.Term
phpParser = AssignmentParser (ASTParser tree_sitter_php) PHP.assignment
@ -146,9 +143,6 @@ pythonParser = AssignmentParser (ASTParser tree_sitter_python) Python.assignment
pythonASTParser :: Parser (AST [] Python.Grammar)
pythonASTParser = ASTParser tree_sitter_python
miniPythonParser :: Parser MiniPython.Term
miniPythonParser = AssignmentParser (ASTParser tree_sitter_python) MiniPython.assignment
javaParser :: Parser Java.Term
javaParser = AssignmentParser javaASTParser Java.assignment
@ -164,6 +158,9 @@ jsonASTParser = ASTParser tree_sitter_json
typescriptParser :: Parser TypeScript.Term
typescriptParser = AssignmentParser (ASTParser tree_sitter_typescript) TypeScript.assignment
tsxParser :: Parser TSX.Term
tsxParser = AssignmentParser (ASTParser tree_sitter_tsx) TSX.assignment
typescriptASTParser :: Parser (AST [] TypeScript.Grammar)
typescriptASTParser = ASTParser tree_sitter_typescript
@ -196,6 +193,7 @@ someASTParser JSX = Just (SomeASTParser (ASTParser tree_sitter_typescript
someASTParser Python = Just (SomeASTParser (ASTParser tree_sitter_python :: Parser (AST [] Python.Grammar)))
someASTParser Ruby = Just (SomeASTParser (ASTParser tree_sitter_ruby :: Parser (AST [] Ruby.Grammar)))
someASTParser TypeScript = Just (SomeASTParser (ASTParser tree_sitter_typescript :: Parser (AST [] TypeScript.Grammar)))
someASTParser TSX = Just (SomeASTParser (ASTParser tree_sitter_tsx :: Parser (AST [] TSX.Grammar)))
someASTParser PHP = Just (SomeASTParser (ASTParser tree_sitter_php :: Parser (AST [] PHP.Grammar)))
someASTParser Markdown = Nothing
someASTParser Unknown = Nothing

View File

@ -66,12 +66,15 @@ parseToAST :: ( Bounded grammar
-> Blob
-> m (Maybe (AST [] grammar))
parseToAST parseTimeout language b@Blob{..} = bracket (liftIO TS.ts_parser_new) (liftIO . TS.ts_parser_delete) $ \ parser -> do
result <- liftIO $ do
compatible <- liftIO $ do
let timeoutMicros = fromIntegral $ toMicroseconds parseTimeout
TS.ts_parser_set_timeout_micros parser timeoutMicros
TS.ts_parser_halt_on_error parser (CBool 1)
TS.ts_parser_set_language parser language
runParser parser blobSource
result <- if compatible then
liftIO $ runParser parser blobSource
else
Failed <$ trace "tree-sitter: incompatible versions"
case result of
Failed -> Nothing <$ trace ("tree-sitter: parsing failed " <> blobPath b)
(Succeeded ast) -> Just ast <$ trace ("tree-sitter: parsing succeeded " <> blobPath b)

View File

@ -78,6 +78,7 @@ instance APIBridge T.Text Data.Language where
Data.Python -> "Python"
Data.Ruby -> "Ruby"
Data.TypeScript -> "TypeScript"
Data.TSX -> "TSX"
Data.PHP -> "PHP"
apiLanguageToLanguage :: T.Text -> Data.Language
@ -92,6 +93,7 @@ instance APIBridge T.Text Data.Language where
"Python" -> Data.Python
"Ruby" -> Data.Ruby
"TypeScript" -> Data.TypeScript
"TSX" -> Data.TSX
"PHP" -> Data.PHP
_ -> Data.Unknown

View File

@ -131,13 +131,14 @@ doParse blobPair decorate = case languageForBlobPair blobPair of
Go -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse goParser blob >>= decorate blob)
Haskell -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse haskellParser blob >>= decorate blob)
Java -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse javaParser blob >>= decorate blob)
JavaScript -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse typescriptParser blob >>= decorate blob)
JavaScript -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse tsxParser blob >>= decorate blob)
JSON -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse jsonParser blob >>= decorate blob)
JSX -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse typescriptParser blob >>= decorate blob)
JSX -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse tsxParser blob >>= decorate blob)
Markdown -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse markdownParser blob >>= decorate blob)
Python -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse pythonParser blob >>= decorate blob)
Ruby -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse rubyParser blob >>= decorate blob)
TypeScript -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse typescriptParser blob >>= decorate blob)
TSX -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse tsxParser blob >>= decorate blob)
PHP -> SomeTermPair <$> distributeFor blobPair (\ blob -> parse phpParser blob >>= decorate blob)
_ -> noLanguageForBlob (pathForBlobPair blobPair)

View File

@ -117,12 +117,13 @@ doParse blob = case blobLanguage blob of
Go -> SomeTerm <$> parse goParser blob
Haskell -> SomeTerm <$> parse haskellParser blob
Java -> SomeTerm <$> parse javaParser blob
JavaScript -> SomeTerm <$> parse typescriptParser blob
JavaScript -> SomeTerm <$> parse tsxParser blob
JSON -> SomeTerm <$> parse jsonParser blob
JSX -> SomeTerm <$> parse typescriptParser blob
JSX -> SomeTerm <$> parse tsxParser blob
Markdown -> SomeTerm <$> parse markdownParser blob
Python -> SomeTerm <$> parse pythonParser blob
Ruby -> SomeTerm <$> parse rubyParser blob
TypeScript -> SomeTerm <$> parse typescriptParser blob
TSX -> SomeTerm <$> parse tsxParser blob
PHP -> SomeTerm <$> parse phpParser blob
_ -> noLanguageForBlob (blobPath blob)

View File

@ -52,10 +52,10 @@ import qualified Language.Markdown.Syntax as Markdown
import qualified Language.PHP.Syntax as PHP
import qualified Language.Python.Syntax as Python
import qualified Language.Ruby.Syntax as Ruby
import qualified Language.TSX.Syntax as TSX
import qualified Language.TypeScript.Syntax as TypeScript
-- TODO: Move to src/Data
data Token
= Enter { tokenName :: Text, tokenSnippetRange :: Maybe Range }
@ -603,24 +603,25 @@ instance Taggable Ruby.LowPrecedenceOr
instance Taggable Ruby.Assignment
instance Taggable Ruby.ZSuper
instance Taggable TSX.JsxElement
instance Taggable TSX.JsxOpeningElement
instance Taggable TSX.JsxSelfClosingElement
instance Taggable TSX.JsxAttribute
instance Taggable TSX.JsxText
instance Taggable TSX.JsxExpression
instance Taggable TSX.JsxClosingElement
instance Taggable TSX.JsxFragment
instance Taggable TSX.JsxNamespaceName
instance Taggable TypeScript.JavaScriptRequire
instance Taggable TypeScript.Debugger
instance Taggable TypeScript.Super
instance Taggable TypeScript.Undefined
instance Taggable TypeScript.With
instance Taggable TypeScript.JsxElement
instance Taggable TypeScript.JsxOpeningElement
instance Taggable TypeScript.JsxSelfClosingElement
instance Taggable TypeScript.JsxAttribute
instance Taggable TypeScript.OptionalParameter
instance Taggable TypeScript.RequiredParameter
instance Taggable TypeScript.RestParameter
instance Taggable TypeScript.JsxNamespaceName
instance Taggable TypeScript.JsxText
instance Taggable TypeScript.JsxExpression
instance Taggable TypeScript.JsxClosingElement
instance Taggable TypeScript.ImplementsClause
instance Taggable TypeScript.JsxFragment
instance Taggable TypeScript.Import
instance Taggable TypeScript.QualifiedAliasedImport
instance Taggable TypeScript.QualifiedExportFrom

View File

@ -83,7 +83,8 @@ languages :: [LanguageExample]
languages =
[ le "python" ".py" "examples" (Just "script/known_failures.txt")
, le "ruby" ".rb" "examples" (Just "script/known_failures.txt")
, le "typescript" ".ts" "examples" (Just "script/known_failures.txt")
, le "typescript" ".ts" "examples" (Just "typescript/script/known_failures.txt")
, le "typescript" ".tsx" "examples" (Just "typescript/script/known_failures.txt")
, le "typescript" ".js" "examples" Nothing -- parse JavaScript with TypeScript parser.
, le "go" ".go" "examples" (Just "script/known-failures.txt")

View File

@ -1,5 +1,6 @@
module Integration.Spec (spec) where
import Control.Exception (throw)
import Data.Foldable (find, traverse_, for_)
import Data.List (union, concat, transpose)
import qualified Data.ByteString as B
@ -9,7 +10,7 @@ import System.FilePath.Posix
import SpecHelpers
languages :: [FilePath]
languages = ["go", "javascript", "json", "python", "ruby", "typescript"]
languages = ["go", "javascript", "json", "python", "ruby", "typescript", "tsx"]
spec :: TaskSession -> Spec
spec config = parallel $ do
@ -83,9 +84,12 @@ normalizeName path = dropExtension $ dropExtension path
testParse :: TaskSession -> FilePath -> FilePath -> Expectation
testParse session path expectedOutput = do
actual <- verbatim <$> parseFilePath session path
expected <- verbatim <$> B.readFile expectedOutput
actual `shouldBe` expected
actual <- fmap verbatim <$> parseFilePath session path
case actual of
Left err -> throw err
Right actual -> do
expected <- verbatim <$> B.readFile expectedOutput
actual `shouldBe` expected
testDiff :: TaskSession -> Both FilePath -> FilePath -> Expectation
testDiff config paths expectedOutput = do

View File

@ -97,8 +97,11 @@ diffFilePaths :: TaskSession -> Both FilePath -> IO ByteString
diffFilePaths session paths = readFilePathPair paths >>= runTask session . parseDiffBuilder @[] DiffSExpression . pure >>= either (die . displayException) (pure . runBuilder)
-- | Returns an s-expression parse tree for the specified FilePath.
parseFilePath :: TaskSession -> FilePath -> IO ByteString
parseFilePath session path = (fromJust <$> readBlobFromFile (fileForPath path)) >>= runTask session . parseTermBuilder @[] TermSExpression . pure >>= either (die . displayException) (pure . runBuilder)
parseFilePath :: TaskSession -> FilePath -> IO (Either SomeException ByteString)
parseFilePath session path = do
blob <- readBlobFromFile (fileForPath path)
res <- runTask session $ parseTermBuilder TermSExpression (toList blob)
pure (runBuilder <$> res)
-- | Read two files to a BlobPair.
readFilePathPair :: Both FilePath -> IO BlobPair

View File

@ -44,21 +44,21 @@ spec = parallel $ do
it "produces tags for functions" $ do
(blob, tree) <- parseTestFile pythonParser "test/fixtures/python/tags/simple_functions.py"
runTagging blob symbolsToSummarize tree `shouldBe`
[ Tag "Foo" "Function" (Span (Pos 1 1) (Pos 5 17)) ["Statements"] (Just "def Foo(x)") Nothing
, Tag "Bar" "Function" (Span (Pos 7 1) (Pos 11 13)) ["Statements"] (Just "def Bar()") Nothing
, Tag "local" "Function" (Span (Pos 8 5) (Pos 9 17)) ["Statements", "Function", "Statements"] (Just "def local()") Nothing
[ Tag "Foo" "Function" (Span (Pos 1 1) (Pos 5 17)) ["Statements"] (Just "def Foo(x):") Nothing
, Tag "Bar" "Function" (Span (Pos 7 1) (Pos 11 13)) ["Statements"] (Just "def Bar():") Nothing
, Tag "local" "Function" (Span (Pos 8 5) (Pos 9 17)) ["Statements", "Function", "Statements"] (Just "def local():") Nothing
]
it "produces tags for functions with docs" $ do
(blob, tree) <- parseTestFile pythonParser "test/fixtures/python/tags/simple_function_with_docs.py"
runTagging blob symbolsToSummarize tree `shouldBe`
[ Tag "Foo" "Function" (Span (Pos 1 1) (Pos 3 13)) ["Statements"] (Just "def Foo(x)") (Just "\"\"\"This is the foo function\"\"\"") ]
[ Tag "Foo" "Function" (Span (Pos 1 1) (Pos 3 13)) ["Statements"] (Just "def Foo(x):") (Just "\"\"\"This is the foo function\"\"\"") ]
it "produces tags for classes" $ do
(blob, tree) <- parseTestFile pythonParser "test/fixtures/python/tags/class.py"
runTagging blob symbolsToSummarize tree `shouldBe`
[ Tag "Foo" "Class" (Span (Pos 1 1) (Pos 5 17)) ["Statements"] (Just "class Foo") (Just "\"\"\"The Foo class\"\"\"")
, Tag "f" "Function" (Span (Pos 3 5) (Pos 5 17)) ["Statements", "Class", "Statements"] (Just "def f(self)") (Just "\"\"\"The f method\"\"\"")
[ Tag "Foo" "Class" (Span (Pos 1 1) (Pos 5 17)) ["Statements"] (Just "class Foo:") (Just "\"\"\"The Foo class\"\"\"")
, Tag "f" "Function" (Span (Pos 3 5) (Pos 5 17)) ["Statements", "Class", "Statements"] (Just "def f(self):") (Just "\"\"\"The f method\"\"\"")
]
it "produces tags for multi-line functions" $ do

View File

@ -1,15 +1,17 @@
(Statements
(Try
{ (Identifier)
{ (Statements
{-(Identifier)-}
{-(Identifier)-})
->(Identifier) }
{+(Finally
{+(Identifier)+})+}
{-(Identifier)-}
{-(Catch
{-(Statements
{-(Identifier)-}
{-(Identifier)-}
{-(Identifier)-})-}
{-(Statements
{-(Identifier)-}
{-(Identifier)-})-})-}
{-(Statements)-})-}
{-(Catch
{-(Let
@ -23,8 +25,9 @@
{-(Statements
{-(Identifier)-}
{-(Identifier)-}
{-(Identifier)-}
{-(Identifier)-})-}
{-(Statements
{-(Identifier)-}
{-(Identifier)-})-})-}
{-(Statements)-})-}
{-(Catch
{-(Statements
@ -32,7 +35,9 @@
{-(Identifier)-})-}
{-(Statements)-})-})
(Try
{ (Identifier)
{ (Statements
{-(Identifier)-}
{-(Identifier)-})
->(Identifier) }
{+(Catch
{+(Statements
@ -54,7 +59,6 @@
{+(Catch
{+(Identifier)+}
{+(Statements)+})+}
{-(Identifier)-}
{-(Finally
{-(Statements
{-(Identifier)-}

View File

@ -1,13 +1,15 @@
(Statements
(Try
{ (Identifier)
->(Identifier) }
{+(Identifier)+}
->(Statements
{+(Identifier)+}
{+(Identifier)+}) }
{+(Catch
{+(Statements
{+(Identifier)+}
{+(Identifier)+}
{+(Identifier)+})+}
{+(Statements
{+(Identifier)+}
{+(Identifier)+})+})+}
{+(Statements)+})+}
{+(Catch
{+(Let
@ -21,8 +23,9 @@
{+(Statements
{+(Identifier)+}
{+(Identifier)+}
{+(Identifier)+}
{+(Identifier)+})+}
{+(Statements
{+(Identifier)+}
{+(Identifier)+})+})+}
{+(Statements)+})+}
{+(Catch
{+(Statements
@ -33,8 +36,9 @@
{-(Identifier)-})-})
(Try
{ (Identifier)
->(Identifier) }
{+(Identifier)+}
->(Statements
{+(Identifier)+}
{+(Identifier)+}) }
{+(Finally
{+(Statements
{+(Identifier)+}

View File

@ -1,12 +1,14 @@
(Statements
(Try
(Identifier)
(Identifier)
(Statements
(Identifier)
(Identifier))
(Catch
(Statements
(Identifier)
(Identifier)
(Identifier))
(Statements
(Identifier)
(Identifier)))
(Statements))
(Catch
(Let
@ -20,8 +22,9 @@
(Statements
(Identifier)
(Identifier)
(Identifier)
(Identifier))
(Statements
(Identifier)
(Identifier)))
(Statements))
(Catch
(Statements
@ -29,8 +32,9 @@
(Identifier))
(Statements)))
(Try
(Identifier)
(Identifier)
(Statements
(Identifier)
(Identifier))
(Finally
(Statements
(Identifier)

View File

@ -21,18 +21,16 @@
{-(Assignment
{-(Identifier)-}
{-(Boolean)-})-})-})-}))
{+(Statements
{+(Let
{+(Empty)+}
{+(Call
{+(MemberAccess
{+(Identifier)+}
{+(Identifier)+})+}
{+(Let
{+(Empty)+}
{+(Call
{+(MemberAccess
{+(Identifier)+}
{+(TextElement)+}
{+(Identifier)+}
{+(Empty)+})+}
{+(Statements)+})+}
{+(Identifier)+})+}
{+(Identifier)+}
{+(TextElement)+}
{+(Identifier)+}
{+(Empty)+})+}
{+(Let
{+(Empty)+}
{+(Call

View File

@ -21,18 +21,16 @@
{+(Assignment
{+(Identifier)+}
{+(Boolean)+})+})+})+}))
{-(Statements
{-(Let
{-(Empty)-}
{-(Call
{-(MemberAccess
{-(Identifier)-}
{-(Identifier)-})-}
{-(Let
{-(Empty)-}
{-(Call
{-(MemberAccess
{-(Identifier)-}
{-(TextElement)-}
{-(Identifier)-}
{-(Empty)-})-}
{-(Statements)-})-}
{-(Identifier)-})-}
{-(Identifier)-}
{-(TextElement)-}
{-(Identifier)-}
{-(Empty)-})-}
{-(Let
{-(Empty)-}
{-(Call

View File

@ -8,18 +8,16 @@
(Assignment
(Identifier)
(Boolean))))
(Statements
(Let
(Empty)
(Call
(MemberAccess
(Identifier)
(Identifier))
(Let
(Empty)
(Call
(MemberAccess
(Identifier)
(TextElement)
(Identifier)
(Empty))
(Statements))
(Identifier))
(Identifier)
(TextElement)
(Identifier)
(Empty))
(Let
(Empty)
(Call

View File

@ -1,7 +1,10 @@
(Statements
{+(Import)+}
{+(QualifiedAliasedImport
{+(Identifier)+})+}
{ (Import)
->(Import) }
{ (QualifiedAliasedImport
{-(Identifier)-})
->(QualifiedAliasedImport
{+(Identifier)+}) }
{+(Import)+}
{+(Import)+}
{+(Import)+}
@ -14,9 +17,6 @@
{+(Identifier)+})+})+}
{+(SideEffectImport)+}
{-(Import)-}
{-(QualifiedAliasedImport
{-(Identifier)-})-}
{-(Import)-}
{-(Import)-}
{-(Import)-}
{-(Statements

View File

@ -1,7 +1,10 @@
(Statements
{+(Import)+}
{+(QualifiedAliasedImport
{+(Identifier)+})+}
{ (Import)
->(Import) }
{ (QualifiedAliasedImport
{-(Identifier)-})
->(QualifiedAliasedImport
{+(Identifier)+}) }
{+(Import)+}
{+(Import)+}
{+(Import)+}
@ -16,9 +19,6 @@
{+(QualifiedAliasedImport
{+(Identifier)+})+}
{-(Import)-}
{-(QualifiedAliasedImport
{-(Identifier)-})-}
{-(Import)-}
{-(Import)-}
{-(Import)-}
{-(Statements

@ -1 +1 @@
Subproject commit cc1b4fd6673c4d749bbba7abe6232fa60f3921de
Subproject commit aa1b3c74410a71648a5301d6241566dfe79165a4

@ -1 +0,0 @@
Subproject commit 94af5871c24ba319f7f72fefa53c1a4d074c9a29

1
vendor/proto3-suite vendored

@ -1 +0,0 @@
Subproject commit 83f3352f0c7c94ea091e6087f60692eda9991fae

1
vendor/proto3-wire vendored

@ -1 +0,0 @@
Subproject commit 84664e22f01beb67870368f1f88ada5d0ad01f56