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:
commit
aa02a62f76
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@ -0,0 +1 @@
|
||||
Dockerfile
|
9
.gitmodules
vendored
9
.gitmodules
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
36
Dockerfile
Normal 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"]
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
@ -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)
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
971
src/Language/TSX/Assignment.hs
Normal file
971
src/Language/TSX/Assignment.hs
Normal 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 TSX’s grammar onto a program in TSX’s 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
|
7
src/Language/TSX/Syntax.hs
Normal file
7
src/Language/TSX/Syntax.hs
Normal 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
|
@ -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
|
143
src/Language/TSX/Syntax/Types.hs
Normal file
143
src/Language/TSX/Syntax/Types.hs
Normal 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
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)-}
|
||||
|
@ -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)+}
|
||||
|
@ -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)
|
||||
|
20
test/fixtures/python/corpus/with.diffA-B.txt
vendored
20
test/fixtures/python/corpus/with.diffA-B.txt
vendored
@ -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
|
||||
|
20
test/fixtures/python/corpus/with.diffB-A.txt
vendored
20
test/fixtures/python/corpus/with.diffB-A.txt
vendored
@ -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
|
||||
|
20
test/fixtures/python/corpus/with.parseB.txt
vendored
20
test/fixtures/python/corpus/with.parseB.txt
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
2
vendor/haskell-tree-sitter
vendored
2
vendor/haskell-tree-sitter
vendored
@ -1 +1 @@
|
||||
Subproject commit cc1b4fd6673c4d749bbba7abe6232fa60f3921de
|
||||
Subproject commit aa1b3c74410a71648a5301d6241566dfe79165a4
|
1
vendor/hspec-expectations-pretty-diff
vendored
1
vendor/hspec-expectations-pretty-diff
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 94af5871c24ba319f7f72fefa53c1a4d074c9a29
|
1
vendor/proto3-suite
vendored
1
vendor/proto3-suite
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 83f3352f0c7c94ea091e6087f60692eda9991fae
|
1
vendor/proto3-wire
vendored
1
vendor/proto3-wire
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 84664e22f01beb67870368f1f88ada5d0ad01f56
|
Loading…
Reference in New Issue
Block a user