Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.

Commit b2ef8e9

Browse files
committed
Add semantic-tsx
1 parent e4bf165 commit b2ef8e9

File tree

17 files changed

+325
-21
lines changed

17 files changed

+325
-21
lines changed

cabal.project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ packages: .
77
semantic-json
88
semantic-python
99
semantic-ruby
10+
semantic-tsx
1011
semantic-typescript
1112
semantic-tags
1213

script/ghci-flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function flags {
4545
echo "-isemantic-json/src"
4646
echo "-isemantic-python/src"
4747
echo "-isemantic-ruby/src"
48+
echo "-isemantic-tsx/src"
4849
echo "-isemantic-typescript/src"
4950
echo "-isemantic-tags/src"
5051
echo "-iapp"

script/ghci-flags-dependencies

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ echo "semantic-java/semantic-java.cabal"
1717
echo "semantic-json/semantic-json.cabal"
1818
echo "semantic-python/semantic-python.cabal"
1919
echo "semantic-ruby/semantic-ruby.cabal"
20+
echo "semantic-tsx/semantic-tsx.cabal"
2021
echo "semantic-typescript/semantic-typescript.cabal"

semantic-tsx/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 GitHub
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

semantic-tsx/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Semantic support for TSX
2+
3+
This package implements `semantic` support for TSX using the `semantic-core` intermediate language.

semantic-tsx/Setup.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

semantic-tsx/semantic-tsx.cabal

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
cabal-version: 2.4
2+
3+
name: semantic-tsx
4+
version: 0.0.0.0
5+
synopsis: Semantic support for TSX.
6+
description: Semantic support for TSX using the semantic-core intermediate language.
7+
homepage: https://github.com/github/semantic/tree/master/semantic-tsx#readme
8+
bug-reports: https://github.com/github/semantic/issues
9+
license: MIT
10+
license-file: LICENSE
11+
author: The Semantic authors
12+
maintainer: [email protected]
13+
copyright: (c) 2019 GitHub, Inc.
14+
category: Language
15+
build-type: Simple
16+
stability: alpha
17+
extra-source-files: README.md
18+
19+
tested-with: GHC == 8.6.5
20+
21+
common haskell
22+
default-language: Haskell2010
23+
build-depends: base ^>= 4.13
24+
, fused-effects ^>= 1.0
25+
, fused-syntax
26+
, parsers ^>= 0.12.10
27+
, semantic-core ^>= 0.0
28+
, semantic-source ^>= 0.0
29+
, semantic-tags ^>= 0.0
30+
, text ^>= 1.2.3
31+
, tree-sitter ^>= 0.7.2
32+
, tree-sitter-tsx ^>= 0.4
33+
34+
ghc-options:
35+
-Weverything
36+
-Wno-missing-local-signatures
37+
-Wno-missing-import-lists
38+
-Wno-implicit-prelude
39+
-Wno-safe
40+
-Wno-unsafe
41+
-Wno-name-shadowing
42+
-Wno-monomorphism-restriction
43+
-Wno-missed-specialisations
44+
-Wno-all-missed-specialisations
45+
-Wno-star-is-type
46+
if (impl(ghc >= 8.8))
47+
ghc-options: -Wno-missing-deriving-strategies
48+
49+
library
50+
import: haskell
51+
exposed-modules:
52+
Language.TSX
53+
Language.TSX.Tags
54+
hs-source-dirs: src

semantic-tsx/src/Language/TSX.hs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{-# OPTIONS_GHC -freduction-depth=0 #-}
2+
-- | Semantic functionality for TSX programs.
3+
module Language.TSX
4+
( Term(..)
5+
, TreeSitter.TSX.tree_sitter_tsx
6+
) where
7+
8+
9+
import qualified Language.TSX.Tags as TsxTags
10+
import qualified Tags.Tagging.Precise as Tags
11+
import qualified TreeSitter.TSX (tree_sitter_tsx)
12+
import qualified TreeSitter.TSX.AST as TSX
13+
import qualified TreeSitter.Unmarshal as TS
14+
15+
newtype Term a = Term { getTerm :: TSX.Program a }
16+
17+
instance TS.Unmarshal Term where
18+
unmarshalNode node = Term <$> TS.unmarshalNode node
19+
20+
instance Tags.ToTags Term where
21+
tags src = Tags.runTagging src . TsxTags.tags . getTerm

semantic-tsx/src/Language/TSX/Tags.hs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
{-# LANGUAGE AllowAmbiguousTypes, DataKinds, DisambiguateRecordFields, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, NamedFieldPuns, PartialTypeSignatures, ScopedTypeVariables, TypeApplications, TypeFamilies, TypeOperators, UndecidableInstances #-}
2+
{-# OPTIONS_GHC -freduction-depth=0 #-}
3+
module Language.TSX.Tags
4+
( ToTags(..)
5+
) where
6+
7+
import AST.Element
8+
import Control.Effect.Reader
9+
import Control.Effect.Writer
10+
import Data.Monoid (Ap (..))
11+
import Data.Text as Text
12+
import GHC.Generics
13+
import Source.Loc
14+
import Source.Source as Source
15+
import Tags.Tag
16+
import qualified Tags.Tagging.Precise as Tags
17+
import qualified TreeSitter.TSX.AST as Tsx
18+
19+
class ToTags t where
20+
tags
21+
:: ( Has (Reader Source) sig m
22+
, Has (Writer Tags.Tags) sig m
23+
)
24+
=> t Loc
25+
-> m ()
26+
27+
instance (ToTagsBy strategy t, strategy ~ ToTagsInstance t) => ToTags t where
28+
tags = tags' @strategy
29+
30+
31+
class ToTagsBy (strategy :: Strategy) t where
32+
tags'
33+
:: ( Has (Reader Source) sig m
34+
, Has (Writer Tags.Tags) sig m
35+
)
36+
=> t Loc
37+
-> m ()
38+
39+
40+
data Strategy = Generic | Custom
41+
42+
type family ToTagsInstance t :: Strategy where
43+
ToTagsInstance (_ :+: _) = 'Custom
44+
ToTagsInstance Tsx.Function = 'Custom
45+
ToTagsInstance Tsx.FunctionSignature = 'Custom
46+
ToTagsInstance Tsx.FunctionDeclaration = 'Custom
47+
ToTagsInstance Tsx.MethodDefinition = 'Custom
48+
ToTagsInstance Tsx.ClassDeclaration = 'Custom
49+
ToTagsInstance Tsx.CallExpression = 'Custom
50+
51+
ToTagsInstance Tsx.Class = 'Custom
52+
53+
ToTagsInstance _ = 'Generic
54+
55+
instance ToTagsBy 'Custom Tsx.Function where
56+
tags' t@Tsx.Function
57+
{ ann = loc@Loc { byteRange }
58+
, name = Just Tsx.Identifier { text }
59+
} = yieldTag text Function loc byteRange >> gtags t
60+
tags' t = gtags t
61+
62+
instance ToTagsBy 'Custom Tsx.FunctionSignature where
63+
tags' t@Tsx.FunctionSignature
64+
{ ann = loc@Loc { byteRange }
65+
, name = Tsx.Identifier { text }
66+
} = yieldTag text Function loc byteRange >> gtags t
67+
68+
instance ToTagsBy 'Custom Tsx.FunctionDeclaration where
69+
tags' t@Tsx.FunctionDeclaration
70+
{ ann = loc@Loc { byteRange }
71+
, name = Tsx.Identifier { text }
72+
} = yieldTag text Function loc byteRange >> gtags t
73+
74+
instance ToTagsBy 'Custom Tsx.MethodDefinition where
75+
tags' t@Tsx.MethodDefinition
76+
{ ann = loc@Loc { byteRange }
77+
, name
78+
} = case name of
79+
Prj Tsx.PropertyIdentifier { text } -> yield text
80+
-- TODO: There are more here
81+
_ -> gtags t
82+
where
83+
yield name = yieldTag name Call loc byteRange >> gtags t
84+
85+
instance ToTagsBy 'Custom Tsx.ClassDeclaration where
86+
tags' t@Tsx.ClassDeclaration
87+
{ ann = loc@Loc { byteRange }
88+
, name = Tsx.TypeIdentifier { text }
89+
} = yieldTag text Class loc byteRange >> gtags t
90+
91+
instance ToTagsBy 'Custom Tsx.CallExpression where
92+
tags' t@Tsx.CallExpression
93+
{ ann = loc@Loc { byteRange }
94+
, function = Tsx.Expression expr
95+
} = match expr
96+
where
97+
match expr = case expr of
98+
Prj Tsx.Identifier { text } -> yield text
99+
Prj Tsx.NewExpression { constructor = Prj Tsx.Identifier { text } } -> yield text
100+
-- Prj Tsx.MemberExpression { property = Tsx.PropertyIdentifier { text }, object = (Tsx.Expression expr) } -> yieldTag text Call loc byteRange >> match expr
101+
Prj Tsx.CallExpression { function = Tsx.Expression expr } -> match expr
102+
Prj Tsx.MemberExpression { property = Tsx.PropertyIdentifier { text } } -> yield text
103+
_ -> gtags t
104+
yield name = yieldTag name Call loc byteRange >> gtags t
105+
106+
instance ToTagsBy 'Custom Tsx.Class where
107+
tags' t@Tsx.Class
108+
{ ann = loc@Loc { byteRange }
109+
, name = Just Tsx.TypeIdentifier { text }
110+
} = yieldTag text Class loc byteRange >> gtags t
111+
tags' t = gtags t
112+
113+
instance (ToTags l, ToTags r) => ToTagsBy 'Custom (l :+: r) where
114+
tags' (L1 l) = tags l
115+
tags' (R1 r) = tags r
116+
117+
gtags
118+
:: ( Has (Reader Source) sig m
119+
, Has (Writer Tags.Tags) sig m
120+
, Generic1 t
121+
, Tags.GFoldable1 ToTags (Rep1 t)
122+
)
123+
=> t Loc
124+
-> m ()
125+
gtags = getAp . Tags.gfoldMap1 @ToTags (Ap . tags) . from1
126+
127+
instance (Generic1 t, Tags.GFoldable1 ToTags (Rep1 t)) => ToTagsBy 'Generic t where
128+
tags' = gtags
129+
130+
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> m ()
131+
yieldTag name kind loc range = do
132+
src <- ask @Source
133+
let sliced = slice src range
134+
Tags.yield (Tag name kind loc (Tags.firstLine sliced) Nothing)

semantic.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ library
290290
, semantic-json ^>= 0
291291
, semantic-python ^>= 0
292292
, semantic-ruby ^>= 0
293+
, semantic-tsx ^>= 0
293294
, semantic-typescript ^>= 0
294295
, semantic-tags ^>= 0
295296
, semigroupoids ^>= 5.3.2

src/Data/Language.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ data PerLanguageModes = PerLanguageModes
155155
, rubyMode :: LanguageMode
156156
, goMode :: LanguageMode
157157
, typescriptMode :: LanguageMode
158+
, tsxMode :: LanguageMode
159+
, javascriptMode :: LanguageMode
160+
, jsxMode :: LanguageMode
158161
}
159162
deriving (Eq, Ord, Show)
160163

@@ -164,6 +167,9 @@ defaultLanguageModes = PerLanguageModes
164167
, rubyMode = ALaCarte
165168
, goMode = ALaCarte
166169
, typescriptMode = ALaCarte
170+
, tsxMode = ALaCarte
171+
, javascriptMode = ALaCarte
172+
, jsxMode = ALaCarte
167173
}
168174

169175
data LanguageMode

src/Language/TSX/Assignment.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ augmentedAssignmentExpression = makeTerm' <$> symbol AugmentedAssignmentExpressi
104104
, assign Expression.LShift <$ symbol AnonLAngleLAngleEqual
105105
, assign Expression.BOr <$ symbol AnonPipeEqual ])
106106
where assign :: (f :< TSX.Syntax) => (Term Loc -> Term Loc -> f (Term Loc)) -> Term Loc -> Term Loc -> Sum TSX.Syntax (Term Loc)
107-
assign c l r = inject (Statement.Assignment [] l (makeTerm1 (c l r)))
107+
assign c l r = inject (Statement.AugmentedAssignment (makeTerm1 (c l r)))
108108

109109

110110
awaitExpression :: Assignment (Term Loc)

src/Language/TSX/Term.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ type Syntax =
9393
, Literal.TextElement
9494
, Literal.Regex
9595
, Statement.Assignment
96+
, Statement.AugmentedAssignment
9697
, Statement.Break
9798
, Statement.Catch
9899
, Statement.Continue

0 commit comments

Comments
 (0)