1
1
mirror of https://github.com/github/semantic.git synced 2024-11-23 08:27:56 +03:00

Merge pull request #565 from github/syntax-type

Produce syntax_type while tagging, define possible types as enum in proto
This commit is contained in:
Timothy Clem 2020-06-08 09:28:21 -07:00 committed by GitHub
commit 128473268e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 618 additions and 805 deletions

View File

@ -11,13 +11,14 @@ packages: .
semantic-json
semantic-parse
semantic-php
semantic-proto
semantic-python
semantic-ruby
semantic-rust
semantic-scope-graph
semantic-tags
semantic-tsx
semantic-typescript
semantic-tags
semantic-rust
-- Packages brought in from other repos instead of hackage
-- ATTENTION: remember to update cabal.project.ci when bumping SHAs here!

View File

@ -11,13 +11,14 @@ packages: .
semantic-json
semantic-parse
semantic-php
semantic-proto
semantic-python
semantic-ruby
semantic-rust
semantic-scope-graph
semantic-tags
semantic-tsx
semantic-typescript
semantic-tags
-- Packages brought in from other repos instead of hackage
-- ATTENTION: remember to update cabal.project when bumping SHAs here!

View File

@ -129,6 +129,7 @@ message Symbol {
Span span = 4;
Docstring docs = 5;
NodeType node_type = 6;
SyntaxType syntax_type = 7;
}
message Docstring {
@ -161,12 +162,23 @@ enum NodeType {
REFERENCE = 4;
}
enum SyntaxType {
FUNCTION = 0;
METHOD = 1;
CLASS = 2;
MODULE = 3;
CALL = 4;
TYPE = 5;
INTERFACE = 6;
IMPLEMENTATION = 7;
}
message StackGraphNode {
int64 id = 1;
string name = 2;
string line = 3;
string kind = 4;
Span span = 5;
Span span = 4;
SyntaxType syntax_type = 5;
NodeType node_type = 6;
}

View File

@ -16,6 +16,6 @@ export PROJECT="github.com/github/semantic"
# Dockerfile for where the protoc pluggins are configured.
docker run --rm --user $(id -u):$(id -g) -v $(pwd):/go/src/$PROJECT -w /go/src/$PROJECT \
semantic-protoc --proto_path=proto \
--haskell_out=./src \
--jsonpb_haskell_out=./src \
--haskell_out=./semantic-proto/src \
--jsonpb_haskell_out=./semantic-proto/src \
semantic.proto

View File

@ -26,6 +26,7 @@ common haskell
, parsers ^>= 0.12.10
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, template-haskell ^>= 2.15

View File

@ -18,6 +18,7 @@ import Control.Effect.Writer
import Data.Foldable (for_)
import Data.Text (Text)
import qualified Language.CodeQL.AST as CodeQL
import Proto.Semantic as P
import Source.Loc
import Source.Source as Source
import Tags.Tag
@ -54,59 +55,59 @@ gtags ::
m ()
gtags = traverse1_ @ToTags (const (pure ())) tags
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> m ()
yieldTag name kind loc srcLineRange = do
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> P.SyntaxType -> P.NodeType -> Loc -> Range -> m ()
yieldTag name kind ty loc srcLineRange = do
src <- ask @Source
Tags.yield (Tag name kind loc (Tags.firstLine src srcLineRange) Nothing)
Tags.yield (Tag name kind ty loc (Tags.firstLine src srcLineRange) Nothing)
instance ToTags CodeQL.Module where
tags
t@CodeQL.Module
{ ann = Loc {byteRange},
name = CodeQL.ModuleName {extraChildren = CodeQL.SimpleId {text, ann}}
} = yieldTag text Module ann byteRange >> gtags t
} = yieldTag text P.MODULE P.DEFINITION ann byteRange >> gtags t
instance ToTags CodeQL.ClasslessPredicate where
tags
t@CodeQL.ClasslessPredicate
{ ann = Loc {byteRange},
name = CodeQL.PredicateName {text, ann}
} = yieldTag text Function ann byteRange >> gtags t
} = yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
instance ToTags CodeQL.AritylessPredicateExpr where
tags
t@CodeQL.AritylessPredicateExpr
{ ann = Loc {byteRange},
name = CodeQL.LiteralId {text, ann}
} = yieldTag text Call ann byteRange >> gtags t
} = yieldTag text P.CALL P.REFERENCE ann byteRange >> gtags t
instance ToTags CodeQL.Dataclass where
tags
t@CodeQL.Dataclass
{ ann = Loc {byteRange},
name = CodeQL.ClassName {text, ann}
} = yieldTag text Class ann byteRange >> gtags t
} = yieldTag text P.CLASS P.DEFINITION ann byteRange >> gtags t
instance ToTags CodeQL.MemberPredicate where
tags
t@CodeQL.MemberPredicate
{ ann = Loc {byteRange},
name = CodeQL.PredicateName {text, ann}
} = yieldTag text Method ann byteRange >> gtags t
} = yieldTag text P.METHOD P.DEFINITION ann byteRange >> gtags t
instance ToTags CodeQL.Datatype where
tags
t@CodeQL.Datatype
{ ann = Loc {byteRange},
name = CodeQL.ClassName {text, ann}
} = yieldTag text Class ann byteRange >> gtags t
} = yieldTag text P.CLASS P.DEFINITION ann byteRange >> gtags t
instance ToTags CodeQL.DatatypeBranch where
tags
t@CodeQL.DatatypeBranch
{ ann = Loc {byteRange},
name = CodeQL.ClassName {text, ann}
} = yieldTag text Class ann byteRange >> gtags t
} = yieldTag text P.CLASS P.DEFINITION ann byteRange >> gtags t
instance ToTags CodeQL.ClasslessPredicateCall where
tags
@ -122,7 +123,7 @@ instance ToTags CodeQL.QualifiedRhs where
{ ann = Loc {byteRange},
name = expr
} = case expr of
Just (Prj CodeQL.PredicateName {text, ann}) -> yieldTag text Call ann byteRange >> gtags t
Just (Prj CodeQL.PredicateName {text, ann}) -> yieldTag text P.CALL P.REFERENCE ann byteRange >> gtags t
_ -> gtags t
instance ToTags CodeQL.TypeExpr where
@ -131,7 +132,7 @@ instance ToTags CodeQL.TypeExpr where
{ ann = Loc {byteRange},
name = expr
} = case expr of
Just (Prj CodeQL.ClassName {text, ann}) -> yieldTag text Type ann byteRange >> gtags t
Just (Prj CodeQL.ClassName {text, ann}) -> yieldTag text P.TYPE P.REFERENCE ann byteRange >> gtags t
_ -> gtags t
instance ToTags CodeQL.AddExpr

View File

@ -26,6 +26,7 @@ common haskell
, parsers ^>= 0.12.10
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, template-haskell ^>= 2.15

View File

@ -16,6 +16,7 @@ import Control.Effect.Reader
import Control.Effect.Writer
import Data.Text as Text
import qualified Language.Go.AST as Go
import Proto.Semantic as P
import Source.Loc
import Source.Source as Source
import Tags.Tag
@ -42,14 +43,14 @@ instance ToTags Go.FunctionDeclaration where
t@Go.FunctionDeclaration
{ ann = Loc {byteRange},
name = Go.Identifier {text, ann}
} = yieldTag text Function ann byteRange >> gtags t
} = yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
instance ToTags Go.MethodDeclaration where
tags
t@Go.MethodDeclaration
{ ann = Loc {byteRange},
name = Go.FieldIdentifier {text, ann}
} = yieldTag text Method ann byteRange >> gtags t
} = yieldTag text P.METHOD P.DEFINITION ann byteRange >> gtags t
instance ToTags Go.CallExpression where
tags
@ -64,7 +65,7 @@ instance ToTags Go.CallExpression where
Prj Go.CallExpression {function = Go.Expression e} -> match e
Prj Go.ParenthesizedExpression {extraChildren = Go.Expression e} -> match e
_ -> gtags t
yield name loc = yieldTag name Call loc byteRange >> gtags t
yield name loc = yieldTag name P.CALL P.REFERENCE loc byteRange >> gtags t
instance (ToTags l, ToTags r) => ToTags (l :+: r) where
tags (L1 l) = tags l
@ -81,10 +82,10 @@ gtags ::
m ()
gtags = traverse1_ @ToTags (const (pure ())) tags
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> m ()
yieldTag name kind loc srcLineRange = do
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> P.SyntaxType -> P.NodeType -> Loc -> Range -> m ()
yieldTag name kind ty loc srcLineRange = do
src <- ask @Source
Tags.yield (Tag name kind loc (Tags.firstLine src srcLineRange) Nothing)
Tags.yield (Tag name kind ty loc (Tags.firstLine src srcLineRange) Nothing)
instance ToTags Go.ArgumentList

View File

@ -26,6 +26,7 @@ common haskell
, parsers ^>= 0.12.10
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, template-haskell ^>= 2.15

View File

@ -17,6 +17,7 @@ import Control.Effect.Reader
import Control.Effect.Writer
import Data.Foldable
import qualified Language.Java.AST as Java
import Proto.Semantic as P
import Source.Loc
import Source.Range
import Source.Source as Source
@ -61,7 +62,7 @@ instance ToTags Java.MethodDeclaration where
Just Java.Block {ann = Loc Range {end} _} -> end
Nothing -> end range
}
Tags.yield (Tag text Method ann line Nothing)
Tags.yield (Tag text P.METHOD P.DEFINITION ann line Nothing)
gtags t
-- TODO: we can coalesce a lot of these instances given proper use of HasField
@ -75,7 +76,7 @@ instance ToTags Java.ClassDeclaration where
body = Java.ClassBody {ann = Loc Range {start = end} _}
} = do
src <- ask @Source
Tags.yield (Tag text Class ann (Tags.firstLine src (Range start end)) Nothing)
Tags.yield (Tag text P.CLASS P.DEFINITION ann (Tags.firstLine src (Range start end)) Nothing)
gtags t
instance ToTags Java.MethodInvocation where
@ -85,7 +86,7 @@ instance ToTags Java.MethodInvocation where
name = Java.Identifier {text, ann}
} = do
src <- ask @Source
Tags.yield (Tag text Call ann (Tags.firstLine src range) Nothing)
Tags.yield (Tag text P.CALL P.REFERENCE ann (Tags.firstLine src range) Nothing)
gtags t
instance ToTags Java.InterfaceDeclaration where
@ -95,7 +96,7 @@ instance ToTags Java.InterfaceDeclaration where
name = Java.Identifier {text, ann}
} = do
src <- ask @Source
Tags.yield (Tag text Interface ann (Tags.firstLine src byteRange) Nothing)
Tags.yield (Tag text P.INTERFACE P.DEFINITION ann (Tags.firstLine src byteRange) Nothing)
gtags t
instance ToTags Java.InterfaceTypeList where
@ -103,7 +104,7 @@ instance ToTags Java.InterfaceTypeList where
src <- ask @Source
for_ interfaces $ \x -> case x of
Java.Type (Prj (Java.UnannotatedType (Prj (Java.SimpleType (Prj Java.TypeIdentifier {ann = loc@Loc {byteRange = range}, text = name}))))) ->
Tags.yield (Tag name Implementation loc (Tags.firstLine src range) Nothing)
Tags.yield (Tag name P.IMPLEMENTATION P.REFERENCE loc (Tags.firstLine src range) Nothing)
_ -> pure ()
gtags t

View File

@ -25,6 +25,7 @@ common haskell
, fused-syntax
, parsers ^>= 0.12.10
, semantic-ast
, semantic-proto ^>= 0
, semantic-core ^>= 0.0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0

View File

@ -18,6 +18,7 @@ import Control.Effect.Reader
import Control.Effect.Writer
import Data.Text (Text)
import qualified Language.PHP.AST as PHP
import Proto.Semantic as P
import Source.Loc
import Source.Source as Source
import Tags.Tag
@ -54,24 +55,24 @@ gtags ::
m ()
gtags = traverse1_ @ToTags (const (pure ())) tags
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> m ()
yieldTag name kind loc srcLineRange = do
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> P.SyntaxType -> P.NodeType -> Loc -> Range -> m ()
yieldTag name kind ty loc srcLineRange = do
src <- ask @Source
Tags.yield (Tag name kind loc (Tags.firstLine src srcLineRange) Nothing)
Tags.yield (Tag name kind ty loc (Tags.firstLine src srcLineRange) Nothing)
instance ToTags PHP.FunctionDefinition where
tags
t@PHP.FunctionDefinition
{ PHP.ann = Loc {byteRange},
PHP.name = PHP.Name {text, ann}
} = yieldTag text Method ann byteRange >> gtags t
} = yieldTag text P.METHOD P.DEFINITION ann byteRange >> gtags t
instance ToTags PHP.MethodDeclaration where
tags
t@PHP.MethodDeclaration
{ PHP.ann = Loc {byteRange},
PHP.name = PHP.Name {text, ann}
} = yieldTag text Function ann byteRange >> gtags t
} = yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
instance ToTags PHP.FunctionCallExpression where
tags
@ -80,7 +81,7 @@ instance ToTags PHP.FunctionCallExpression where
PHP.function = func
} = match func
where
yield name loc = yieldTag name Call loc byteRange >> gtags t
yield name loc = yieldTag name P.CALL P.REFERENCE loc byteRange >> gtags t
match expr = case expr of
Prj PHP.VariableName {extraChildren = PHP.Name {text, ann}} -> yield text ann *> gtags t
Prj PHP.QualifiedName {extraChildren = [Prj PHP.Name {text, ann}]} -> yield text ann *> gtags t
@ -92,7 +93,7 @@ instance ToTags PHP.MemberCallExpression where
t@PHP.MemberCallExpression
{ PHP.ann = Loc {byteRange},
PHP.name = Prj PHP.Name {text, ann}
} = yieldTag text Call ann byteRange >> gtags t
} = yieldTag text P.CALL P.REFERENCE ann byteRange >> gtags t
tags t = gtags t

21
semantic-proto/LICENSE Normal file
View File

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

18
semantic-proto/README.md Normal file
View File

@ -0,0 +1,18 @@
# semantic-proto
Datatypes generated from the protobuf schema
## Development
This project consists of a Haskell package named `semantic-proto`. The librarys sources are in [`src`][].
Development of `semantic-proto` is typically done using `cabal v2-build`:
```shell
cabal v2-build # build the library
cabal v2-repl # load the package into ghci
cabal v2-test # build and run the doctests
```
[`src`]: https://github.com/github/semantic/tree/master/semantic-proto/src

2
semantic-proto/Setup.hs Normal file
View File

@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain

View File

@ -0,0 +1,48 @@
cabal-version: 2.4
name: semantic-proto
version: 0.0.0.0
synopsis: Datatypes generated from protobuf schema
description: Datatypes generated from protobuf schema
homepage: https://github.com/github/semantic/tree/master/semantic-proto#readme
bug-reports: https://github.com/github/semantic/issues
license: MIT
license-file: LICENSE
author: The Semantic authors
maintainer: opensource+semantic@github.com
copyright: (c) 2019 GitHub, Inc.
category: Language
build-type: Simple
stability: alpha
extra-source-files: README.md
tested-with: GHC == 8.6.5
library
exposed-modules:
Proto.Semantic
, Proto.Semantic_Fields
, Proto.Semantic_JSON
build-depends:
base >= 4.13 && < 5
, aeson ^>= 1.4.2.0
, text ^>= 1.2.3.1
, proto-lens >= 0.5 && < 0.7
, proto-lens-jsonpb
, proto-lens-runtime >= 0.5 && <0.7
hs-source-dirs: src
default-language: Haskell2010
ghc-options:
-Weverything
-Wno-missing-local-signatures
-Wno-missing-import-lists
-Wno-implicit-prelude
-Wno-safe
-Wno-unsafe
-Wno-name-shadowing
-Wno-monomorphism-restriction
-Wno-missed-specialisations
-Wno-all-missed-specialisations
-Wno-star-is-type
if (impl(ghc >= 8.8))
ghc-options: -Wno-missing-deriving-strategies

View File

@ -14,8 +14,9 @@ module Proto.Semantic (
ParseTreeRequest(), ParseTreeSymbolResponse(), PingRequest(),
PingResponse(), Position(), ReplacedTerm(), Span(),
StackGraphFile(), StackGraphNode(), StackGraphPath(),
StackGraphRequest(), StackGraphResponse(), Symbol(), TermEdge(),
TermVertex()
StackGraphRequest(), StackGraphResponse(), Symbol(),
SyntaxType(..), SyntaxType(), SyntaxType'UnrecognizedValue,
TermEdge(), TermVertex()
) where
import qualified Data.ProtoLens.Runtime.Control.DeepSeq as Control.DeepSeq
import qualified Data.ProtoLens.Runtime.Data.ProtoLens.Prism as Data.ProtoLens.Prism
@ -4578,16 +4579,16 @@ instance Control.DeepSeq.NFData StackGraphFile where
* 'Proto.Semantic_Fields.id' @:: Lens' StackGraphNode Data.Int.Int64@
* 'Proto.Semantic_Fields.name' @:: Lens' StackGraphNode Data.Text.Text@
* 'Proto.Semantic_Fields.line' @:: Lens' StackGraphNode Data.Text.Text@
* 'Proto.Semantic_Fields.kind' @:: Lens' StackGraphNode Data.Text.Text@
* 'Proto.Semantic_Fields.span' @:: Lens' StackGraphNode Span@
* 'Proto.Semantic_Fields.maybe'span' @:: Lens' StackGraphNode (Prelude.Maybe Span)@
* 'Proto.Semantic_Fields.syntaxType' @:: Lens' StackGraphNode SyntaxType@
* 'Proto.Semantic_Fields.nodeType' @:: Lens' StackGraphNode NodeType@ -}
data StackGraphNode
= StackGraphNode'_constructor {_StackGraphNode'id :: !Data.Int.Int64,
_StackGraphNode'name :: !Data.Text.Text,
_StackGraphNode'line :: !Data.Text.Text,
_StackGraphNode'kind :: !Data.Text.Text,
_StackGraphNode'span :: !(Prelude.Maybe Span),
_StackGraphNode'syntaxType :: !SyntaxType,
_StackGraphNode'nodeType :: !NodeType,
_StackGraphNode'_unknownFields :: !Data.ProtoLens.FieldSet}
deriving (Prelude.Eq, Prelude.Ord)
@ -4617,13 +4618,6 @@ instance Data.ProtoLens.Field.HasField StackGraphNode "line" Data.Text.Text wher
_StackGraphNode'line
(\ x__ y__ -> x__ {_StackGraphNode'line = y__}))
Prelude.id
instance Data.ProtoLens.Field.HasField StackGraphNode "kind" Data.Text.Text where
fieldOf _
= (Prelude..)
(Lens.Family2.Unchecked.lens
_StackGraphNode'kind
(\ x__ y__ -> x__ {_StackGraphNode'kind = y__}))
Prelude.id
instance Data.ProtoLens.Field.HasField StackGraphNode "span" Span where
fieldOf _
= (Prelude..)
@ -4638,6 +4632,13 @@ instance Data.ProtoLens.Field.HasField StackGraphNode "maybe'span" (Prelude.Mayb
_StackGraphNode'span
(\ x__ y__ -> x__ {_StackGraphNode'span = y__}))
Prelude.id
instance Data.ProtoLens.Field.HasField StackGraphNode "syntaxType" SyntaxType where
fieldOf _
= (Prelude..)
(Lens.Family2.Unchecked.lens
_StackGraphNode'syntaxType
(\ x__ y__ -> x__ {_StackGraphNode'syntaxType = y__}))
Prelude.id
instance Data.ProtoLens.Field.HasField StackGraphNode "nodeType" NodeType where
fieldOf _
= (Prelude..)
@ -4673,14 +4674,6 @@ instance Data.ProtoLens.Message StackGraphNode where
(Data.ProtoLens.PlainField
Data.ProtoLens.Optional (Data.ProtoLens.Field.field @"line")) ::
Data.ProtoLens.FieldDescriptor StackGraphNode
kind__field_descriptor
= Data.ProtoLens.FieldDescriptor
"kind"
(Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
(Data.ProtoLens.PlainField
Data.ProtoLens.Optional (Data.ProtoLens.Field.field @"kind")) ::
Data.ProtoLens.FieldDescriptor StackGraphNode
span__field_descriptor
= Data.ProtoLens.FieldDescriptor
"span"
@ -4689,6 +4682,15 @@ instance Data.ProtoLens.Message StackGraphNode where
(Data.ProtoLens.OptionalField
(Data.ProtoLens.Field.field @"maybe'span")) ::
Data.ProtoLens.FieldDescriptor StackGraphNode
syntaxType__field_descriptor
= Data.ProtoLens.FieldDescriptor
"syntax_type"
(Data.ProtoLens.ScalarField Data.ProtoLens.EnumField ::
Data.ProtoLens.FieldTypeDescriptor SyntaxType)
(Data.ProtoLens.PlainField
Data.ProtoLens.Optional
(Data.ProtoLens.Field.field @"syntaxType")) ::
Data.ProtoLens.FieldDescriptor StackGraphNode
nodeType__field_descriptor
= Data.ProtoLens.FieldDescriptor
"node_type"
@ -4703,8 +4705,8 @@ instance Data.ProtoLens.Message StackGraphNode where
[(Data.ProtoLens.Tag 1, id__field_descriptor),
(Data.ProtoLens.Tag 2, name__field_descriptor),
(Data.ProtoLens.Tag 3, line__field_descriptor),
(Data.ProtoLens.Tag 4, kind__field_descriptor),
(Data.ProtoLens.Tag 5, span__field_descriptor),
(Data.ProtoLens.Tag 4, span__field_descriptor),
(Data.ProtoLens.Tag 5, syntaxType__field_descriptor),
(Data.ProtoLens.Tag 6, nodeType__field_descriptor)]
unknownFields
= Lens.Family2.Unchecked.lens
@ -4715,8 +4717,8 @@ instance Data.ProtoLens.Message StackGraphNode where
{_StackGraphNode'id = Data.ProtoLens.fieldDefault,
_StackGraphNode'name = Data.ProtoLens.fieldDefault,
_StackGraphNode'line = Data.ProtoLens.fieldDefault,
_StackGraphNode'kind = Data.ProtoLens.fieldDefault,
_StackGraphNode'span = Prelude.Nothing,
_StackGraphNode'syntaxType = Data.ProtoLens.fieldDefault,
_StackGraphNode'nodeType = Data.ProtoLens.fieldDefault,
_StackGraphNode'_unknownFields = []}
parseMessage
@ -4773,24 +4775,22 @@ instance Data.ProtoLens.Message StackGraphNode where
"line"
loop (Lens.Family2.set (Data.ProtoLens.Field.field @"line") y x)
34
-> do y <- (Data.ProtoLens.Encoding.Bytes.<?>)
(do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
Data.ProtoLens.Encoding.Bytes.getBytes
(Prelude.fromIntegral len)
Data.ProtoLens.Encoding.Bytes.runEither
(case Data.Text.Encoding.decodeUtf8' value of
(Prelude.Left err)
-> Prelude.Left (Prelude.show err)
(Prelude.Right r) -> Prelude.Right r))
"kind"
loop (Lens.Family2.set (Data.ProtoLens.Field.field @"kind") y x)
42
-> do y <- (Data.ProtoLens.Encoding.Bytes.<?>)
(do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
Data.ProtoLens.Encoding.Bytes.isolate
(Prelude.fromIntegral len) Data.ProtoLens.parseMessage)
"span"
loop (Lens.Family2.set (Data.ProtoLens.Field.field @"span") y x)
40
-> do y <- (Data.ProtoLens.Encoding.Bytes.<?>)
(Prelude.fmap
Prelude.toEnum
(Prelude.fmap
Prelude.fromIntegral
Data.ProtoLens.Encoding.Bytes.getVarInt))
"syntax_type"
loop
(Lens.Family2.set (Data.ProtoLens.Field.field @"syntaxType") y x)
48
-> do y <- (Data.ProtoLens.Encoding.Bytes.<?>)
(Prelude.fmap
@ -4855,37 +4855,37 @@ instance Data.ProtoLens.Message StackGraphNode where
Data.Text.Encoding.encodeUtf8
_v))
((Data.Monoid.<>)
(let _v = Lens.Family2.view (Data.ProtoLens.Field.field @"kind") _x
in
if (Prelude.==) _v Data.ProtoLens.fieldDefault then
Data.Monoid.mempty
else
(Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt 34)
((Prelude..)
(\ bs
-> (Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt
(Prelude.fromIntegral (Data.ByteString.length bs)))
(Data.ProtoLens.Encoding.Bytes.putBytes bs))
Data.Text.Encoding.encodeUtf8
_v))
(case
Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'span") _x
of
Prelude.Nothing -> Data.Monoid.mempty
(Prelude.Just _v)
-> (Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt 34)
((Prelude..)
(\ bs
-> (Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt
(Prelude.fromIntegral (Data.ByteString.length bs)))
(Data.ProtoLens.Encoding.Bytes.putBytes bs))
Data.ProtoLens.encodeMessage
_v))
((Data.Monoid.<>)
(case
Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'span") _x
of
Prelude.Nothing -> Data.Monoid.mempty
(Prelude.Just _v)
-> (Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt 42)
((Prelude..)
(\ bs
-> (Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt
(Prelude.fromIntegral (Data.ByteString.length bs)))
(Data.ProtoLens.Encoding.Bytes.putBytes bs))
Data.ProtoLens.encodeMessage
_v))
(let
_v
= Lens.Family2.view (Data.ProtoLens.Field.field @"syntaxType") _x
in
if (Prelude.==) _v Data.ProtoLens.fieldDefault then
Data.Monoid.mempty
else
(Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt 40)
((Prelude..)
((Prelude..)
Data.ProtoLens.Encoding.Bytes.putVarInt
Prelude.fromIntegral)
Prelude.fromEnum
_v))
((Data.Monoid.<>)
(let
_v = Lens.Family2.view (Data.ProtoLens.Field.field @"nodeType") _x
@ -4915,9 +4915,9 @@ instance Control.DeepSeq.NFData StackGraphNode where
(Control.DeepSeq.deepseq
(_StackGraphNode'line x__)
(Control.DeepSeq.deepseq
(_StackGraphNode'kind x__)
(_StackGraphNode'span x__)
(Control.DeepSeq.deepseq
(_StackGraphNode'span x__)
(_StackGraphNode'syntaxType x__)
(Control.DeepSeq.deepseq (_StackGraphNode'nodeType x__) ()))))))
{- | Fields :
@ -5686,7 +5686,8 @@ instance Control.DeepSeq.NFData StackGraphResponse where
* 'Proto.Semantic_Fields.maybe'span' @:: Lens' Symbol (Prelude.Maybe Span)@
* 'Proto.Semantic_Fields.docs' @:: Lens' Symbol Docstring@
* 'Proto.Semantic_Fields.maybe'docs' @:: Lens' Symbol (Prelude.Maybe Docstring)@
* 'Proto.Semantic_Fields.nodeType' @:: Lens' Symbol NodeType@ -}
* 'Proto.Semantic_Fields.nodeType' @:: Lens' Symbol NodeType@
* 'Proto.Semantic_Fields.syntaxType' @:: Lens' Symbol SyntaxType@ -}
data Symbol
= Symbol'_constructor {_Symbol'symbol :: !Data.Text.Text,
_Symbol'kind :: !Data.Text.Text,
@ -5694,6 +5695,7 @@ data Symbol
_Symbol'span :: !(Prelude.Maybe Span),
_Symbol'docs :: !(Prelude.Maybe Docstring),
_Symbol'nodeType :: !NodeType,
_Symbol'syntaxType :: !SyntaxType,
_Symbol'_unknownFields :: !Data.ProtoLens.FieldSet}
deriving (Prelude.Eq, Prelude.Ord)
instance Prelude.Show Symbol where
@ -5750,6 +5752,12 @@ instance Data.ProtoLens.Field.HasField Symbol "nodeType" NodeType where
(Lens.Family2.Unchecked.lens
_Symbol'nodeType (\ x__ y__ -> x__ {_Symbol'nodeType = y__}))
Prelude.id
instance Data.ProtoLens.Field.HasField Symbol "syntaxType" SyntaxType where
fieldOf _
= (Prelude..)
(Lens.Family2.Unchecked.lens
_Symbol'syntaxType (\ x__ y__ -> x__ {_Symbol'syntaxType = y__}))
Prelude.id
instance Data.ProtoLens.Message Symbol where
messageName _ = Data.Text.pack "github.semantic.Symbol"
fieldsByTag
@ -5803,6 +5811,15 @@ instance Data.ProtoLens.Message Symbol where
Data.ProtoLens.Optional
(Data.ProtoLens.Field.field @"nodeType")) ::
Data.ProtoLens.FieldDescriptor Symbol
syntaxType__field_descriptor
= Data.ProtoLens.FieldDescriptor
"syntax_type"
(Data.ProtoLens.ScalarField Data.ProtoLens.EnumField ::
Data.ProtoLens.FieldTypeDescriptor SyntaxType)
(Data.ProtoLens.PlainField
Data.ProtoLens.Optional
(Data.ProtoLens.Field.field @"syntaxType")) ::
Data.ProtoLens.FieldDescriptor Symbol
in
Data.Map.fromList
[(Data.ProtoLens.Tag 1, symbol__field_descriptor),
@ -5810,7 +5827,8 @@ instance Data.ProtoLens.Message Symbol where
(Data.ProtoLens.Tag 3, line__field_descriptor),
(Data.ProtoLens.Tag 4, span__field_descriptor),
(Data.ProtoLens.Tag 5, docs__field_descriptor),
(Data.ProtoLens.Tag 6, nodeType__field_descriptor)]
(Data.ProtoLens.Tag 6, nodeType__field_descriptor),
(Data.ProtoLens.Tag 7, syntaxType__field_descriptor)]
unknownFields
= Lens.Family2.Unchecked.lens
_Symbol'_unknownFields
@ -5822,6 +5840,7 @@ instance Data.ProtoLens.Message Symbol where
_Symbol'line = Data.ProtoLens.fieldDefault,
_Symbol'span = Prelude.Nothing, _Symbol'docs = Prelude.Nothing,
_Symbol'nodeType = Data.ProtoLens.fieldDefault,
_Symbol'syntaxType = Data.ProtoLens.fieldDefault,
_Symbol'_unknownFields = []}
parseMessage
= let
@ -5904,6 +5923,16 @@ instance Data.ProtoLens.Message Symbol where
"node_type"
loop
(Lens.Family2.set (Data.ProtoLens.Field.field @"nodeType") y x)
56
-> do y <- (Data.ProtoLens.Encoding.Bytes.<?>)
(Prelude.fmap
Prelude.toEnum
(Prelude.fmap
Prelude.fromIntegral
Data.ProtoLens.Encoding.Bytes.getVarInt))
"syntax_type"
loop
(Lens.Family2.set (Data.ProtoLens.Field.field @"syntaxType") y x)
wire
-> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
wire
@ -6011,8 +6040,25 @@ instance Data.ProtoLens.Message Symbol where
Prelude.fromIntegral)
Prelude.fromEnum
_v))
(Data.ProtoLens.Encoding.Wire.buildFieldSet
(Lens.Family2.view Data.ProtoLens.unknownFields _x)))))))
((Data.Monoid.<>)
(let
_v
= Lens.Family2.view
(Data.ProtoLens.Field.field @"syntaxType") _x
in
if (Prelude.==) _v Data.ProtoLens.fieldDefault then
Data.Monoid.mempty
else
(Data.Monoid.<>)
(Data.ProtoLens.Encoding.Bytes.putVarInt 56)
((Prelude..)
((Prelude..)
Data.ProtoLens.Encoding.Bytes.putVarInt
Prelude.fromIntegral)
Prelude.fromEnum
_v))
(Data.ProtoLens.Encoding.Wire.buildFieldSet
(Lens.Family2.view Data.ProtoLens.unknownFields _x))))))))
instance Control.DeepSeq.NFData Symbol where
rnf
= \ x__
@ -6028,7 +6074,110 @@ instance Control.DeepSeq.NFData Symbol where
(_Symbol'span x__)
(Control.DeepSeq.deepseq
(_Symbol'docs x__)
(Control.DeepSeq.deepseq (_Symbol'nodeType x__) ()))))))
(Control.DeepSeq.deepseq
(_Symbol'nodeType x__)
(Control.DeepSeq.deepseq (_Symbol'syntaxType x__) ())))))))
newtype SyntaxType'UnrecognizedValue
= SyntaxType'UnrecognizedValue Data.Int.Int32
deriving (Prelude.Eq, Prelude.Ord, Prelude.Show)
data SyntaxType
= FUNCTION |
METHOD |
CLASS |
MODULE |
CALL |
TYPE |
INTERFACE |
IMPLEMENTATION |
SyntaxType'Unrecognized !SyntaxType'UnrecognizedValue
deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)
instance Data.ProtoLens.MessageEnum SyntaxType where
maybeToEnum 0 = Prelude.Just FUNCTION
maybeToEnum 1 = Prelude.Just METHOD
maybeToEnum 2 = Prelude.Just CLASS
maybeToEnum 3 = Prelude.Just MODULE
maybeToEnum 4 = Prelude.Just CALL
maybeToEnum 5 = Prelude.Just TYPE
maybeToEnum 6 = Prelude.Just INTERFACE
maybeToEnum 7 = Prelude.Just IMPLEMENTATION
maybeToEnum k
= Prelude.Just
(SyntaxType'Unrecognized
(SyntaxType'UnrecognizedValue (Prelude.fromIntegral k)))
showEnum FUNCTION = "FUNCTION"
showEnum METHOD = "METHOD"
showEnum CLASS = "CLASS"
showEnum MODULE = "MODULE"
showEnum CALL = "CALL"
showEnum TYPE = "TYPE"
showEnum INTERFACE = "INTERFACE"
showEnum IMPLEMENTATION = "IMPLEMENTATION"
showEnum (SyntaxType'Unrecognized (SyntaxType'UnrecognizedValue k))
= Prelude.show k
readEnum k
| (Prelude.==) k "FUNCTION" = Prelude.Just FUNCTION
| (Prelude.==) k "METHOD" = Prelude.Just METHOD
| (Prelude.==) k "CLASS" = Prelude.Just CLASS
| (Prelude.==) k "MODULE" = Prelude.Just MODULE
| (Prelude.==) k "CALL" = Prelude.Just CALL
| (Prelude.==) k "TYPE" = Prelude.Just TYPE
| (Prelude.==) k "INTERFACE" = Prelude.Just INTERFACE
| (Prelude.==) k "IMPLEMENTATION" = Prelude.Just IMPLEMENTATION
| Prelude.otherwise
= (Prelude.>>=) (Text.Read.readMaybe k) Data.ProtoLens.maybeToEnum
instance Prelude.Bounded SyntaxType where
minBound = FUNCTION
maxBound = IMPLEMENTATION
instance Prelude.Enum SyntaxType where
toEnum k__
= Prelude.maybe
(Prelude.error
((Prelude.++)
"toEnum: unknown value for enum SyntaxType: " (Prelude.show k__)))
Prelude.id
(Data.ProtoLens.maybeToEnum k__)
fromEnum FUNCTION = 0
fromEnum METHOD = 1
fromEnum CLASS = 2
fromEnum MODULE = 3
fromEnum CALL = 4
fromEnum TYPE = 5
fromEnum INTERFACE = 6
fromEnum IMPLEMENTATION = 7
fromEnum (SyntaxType'Unrecognized (SyntaxType'UnrecognizedValue k))
= Prelude.fromIntegral k
succ IMPLEMENTATION
= Prelude.error
"SyntaxType.succ: bad argument IMPLEMENTATION. This value would be out of bounds."
succ FUNCTION = METHOD
succ METHOD = CLASS
succ CLASS = MODULE
succ MODULE = CALL
succ CALL = TYPE
succ TYPE = INTERFACE
succ INTERFACE = IMPLEMENTATION
succ (SyntaxType'Unrecognized _)
= Prelude.error "SyntaxType.succ: bad argument: unrecognized value"
pred FUNCTION
= Prelude.error
"SyntaxType.pred: bad argument FUNCTION. This value would be out of bounds."
pred METHOD = FUNCTION
pred CLASS = METHOD
pred MODULE = CLASS
pred CALL = MODULE
pred TYPE = CALL
pred INTERFACE = TYPE
pred IMPLEMENTATION = INTERFACE
pred (SyntaxType'Unrecognized _)
= Prelude.error "SyntaxType.pred: bad argument: unrecognized value"
enumFrom = Data.ProtoLens.Message.Enum.messageEnumFrom
enumFromTo = Data.ProtoLens.Message.Enum.messageEnumFromTo
enumFromThen = Data.ProtoLens.Message.Enum.messageEnumFromThen
enumFromThenTo = Data.ProtoLens.Message.Enum.messageEnumFromThenTo
instance Data.ProtoLens.FieldDefault SyntaxType where
fieldDefault = FUNCTION
instance Control.DeepSeq.NFData SyntaxType where
rnf x__ = Prelude.seq x__ ()
{- | Fields :
* 'Proto.Semantic_Fields.source' @:: Lens' TermEdge Data.Int.Int32@

View File

@ -326,6 +326,12 @@ symbols ::
(Prelude.Functor f, Data.ProtoLens.Field.HasField s "symbols" a) =>
Lens.Family2.LensLike' f s a
symbols = Data.ProtoLens.Field.field @"symbols"
syntaxType ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "syntaxType" a) =>
Lens.Family2.LensLike' f s a
syntaxType = Data.ProtoLens.Field.field @"syntaxType"
target ::
forall f s a.
(Prelude.Functor f, Data.ProtoLens.Field.HasField s "target" a) =>
@ -427,4 +433,4 @@ vertices ::
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "vertices" a) =>
Lens.Family2.LensLike' f s a
vertices = Data.ProtoLens.Field.field @"vertices"
vertices = Data.ProtoLens.Field.field @"vertices"

View File

@ -608,6 +608,7 @@ instance FromJSONPB Symbol where
span' <- obj A..:? "span"
docs' <- obj A..:? "docs"
nodeType' <- obj .: "nodeType"
syntaxType' <- obj .: "syntaxType"
pure $ defMessage
& P.symbol .~ symbol'
& P.kind .~ kind'
@ -615,6 +616,7 @@ instance FromJSONPB Symbol where
& P.maybe'span .~ span'
& P.maybe'docs .~ docs'
& P.nodeType .~ nodeType'
& P.syntaxType .~ syntaxType'
instance ToJSONPB Symbol where
toJSONPB x = object
@ -624,6 +626,7 @@ instance ToJSONPB Symbol where
, "span" .= (x^.maybe'span)
, "docs" .= (x^.maybe'docs)
, "nodeType" .= (x^.nodeType)
, "syntaxType" .= (x^.syntaxType)
]
toEncodingPB x = pairs
[ "symbol" .= (x^.symbol)
@ -632,6 +635,7 @@ instance ToJSONPB Symbol where
, "span" .= (x^.maybe'span)
, "docs" .= (x^.maybe'docs)
, "nodeType" .= (x^.nodeType)
, "syntaxType" .= (x^.syntaxType)
]
instance FromJSON Symbol where
@ -754,15 +758,15 @@ instance FromJSONPB StackGraphNode where
id' <- obj .: "id"
name' <- obj .: "name"
line' <- obj .: "line"
kind' <- obj .: "kind"
span' <- obj A..:? "span"
syntaxType' <- obj .: "syntaxType"
nodeType' <- obj .: "nodeType"
pure $ defMessage
& P.id .~ id'
& P.name .~ name'
& P.line .~ line'
& P.kind .~ kind'
& P.maybe'span .~ span'
& P.syntaxType .~ syntaxType'
& P.nodeType .~ nodeType'
instance ToJSONPB StackGraphNode where
@ -770,16 +774,16 @@ instance ToJSONPB StackGraphNode where
[ "id" .= (x^.id)
, "name" .= (x^.name)
, "line" .= (x^.line)
, "kind" .= (x^.kind)
, "span" .= (x^.maybe'span)
, "syntaxType" .= (x^.syntaxType)
, "nodeType" .= (x^.nodeType)
]
toEncodingPB x = pairs
[ "id" .= (x^.id)
, "name" .= (x^.name)
, "line" .= (x^.line)
, "kind" .= (x^.kind)
, "span" .= (x^.maybe'span)
, "syntaxType" .= (x^.syntaxType)
, "nodeType" .= (x^.nodeType)
]
@ -853,3 +857,25 @@ instance FromJSON NodeType where
instance ToJSON NodeType where
toJSON = toAesonValue
toEncoding = toAesonEncoding
instance FromJSONPB SyntaxType where
parseJSONPB (JSONPB.String "FUNCTION") = pure FUNCTION
parseJSONPB (JSONPB.String "METHOD") = pure METHOD
parseJSONPB (JSONPB.String "CLASS") = pure CLASS
parseJSONPB (JSONPB.String "MODULE") = pure MODULE
parseJSONPB (JSONPB.String "CALL") = pure CALL
parseJSONPB (JSONPB.String "TYPE") = pure TYPE
parseJSONPB (JSONPB.String "INTERFACE") = pure INTERFACE
parseJSONPB (JSONPB.String "IMPLEMENTATION") = pure IMPLEMENTATION
parseJSONPB x = typeMismatch "SyntaxType" x
instance ToJSONPB SyntaxType where
toJSONPB x _ = A.String . T.toUpper . T.pack $ show x
toEncodingPB x _ = E.text . T.toUpper . T.pack $ show x
instance FromJSON SyntaxType where
parseJSON = parseJSONPB
instance ToJSON SyntaxType where
toJSON = toAesonValue
toEncoding = toAesonEncoding

View File

@ -27,6 +27,7 @@ common haskell
, semantic-analysis ^>= 0
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, semantic-scope-graph ^>= 0.0

View File

@ -21,6 +21,7 @@ import Data.List.NonEmpty (NonEmpty (..))
import Data.Maybe (listToMaybe)
import Data.Text as Text
import qualified Language.Python.AST as Py
import Proto.Semantic as P
import Source.Loc
import Source.Range
import Source.Source as Source
@ -59,7 +60,7 @@ keywordFunctionCall ::
Range ->
Text ->
m ()
keywordFunctionCall t loc range name = yieldTag name Function loc range Nothing >> gtags t
keywordFunctionCall t loc range name = yieldTag name P.FUNCTION P.DEFINITION loc range Nothing >> gtags t
instance ToTags Py.String where
tags Py.String {extraChildren} = for_ extraChildren $ \x -> case x of
@ -101,7 +102,7 @@ instance ToTags Py.FunctionDefinition where
} = do
src <- ask @Source
let docs = listToMaybe extraChildren >>= docComment src
yieldTag text Function ann (Range start end) docs >> gtags t
yieldTag text P.FUNCTION P.DEFINITION ann (Range start end) docs >> gtags t
instance ToTags Py.ClassDefinition where
tags
@ -112,7 +113,7 @@ instance ToTags Py.ClassDefinition where
} = do
src <- ask @Source
let docs = listToMaybe extraChildren >>= docComment src
yieldTag text Class ann (Range start end) docs >> gtags t
yieldTag text P.CLASS P.DEFINITION ann (Range start end) docs >> gtags t
instance ToTags Py.Call where
tags
@ -127,12 +128,12 @@ instance ToTags Py.Call where
Prj Py.Call {function = Py.PrimaryExpression expr'} -> match expr' -- Nested call expression like this in Python represent creating an instance of a class and calling it: e.g. AClass()()
Prj (Py.ParenthesizedExpression _ (Prj (Py.Expression (Prj (Py.PrimaryExpression expr'))))) -> match expr' -- Parenthesized expressions
_ -> gtags t
yield name loc = yieldTag name Call loc byteRange Nothing >> gtags t
yield name loc = yieldTag name P.CALL P.REFERENCE loc byteRange Nothing >> gtags t
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> Maybe Text -> m ()
yieldTag name kind loc srcLineRange docs = do
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> P.SyntaxType -> P.NodeType -> Loc -> Range -> Maybe Text -> m ()
yieldTag name kind ty loc srcLineRange docs = do
src <- ask @Source
Tags.yield (Tag name kind loc (Tags.firstLine src srcLineRange) docs)
Tags.yield (Tag name kind ty loc (Tags.firstLine src srcLineRange) docs)
docComment :: Source -> (Py.CompoundStatement :+: Py.SimpleStatement) Loc -> Maybe Text
docComment src (R1 (Py.SimpleStatement (Prj Py.ExpressionStatement {extraChildren = L1 (Prj (Py.Expression (Prj (Py.PrimaryExpression (Prj Py.String {ann}))))) :| _}))) = Just (toText (slice src (byteRange ann)))

View File

@ -26,6 +26,7 @@ common haskell
, parsers ^>= 0.12.10
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, template-haskell ^>= 2.15

View File

@ -25,6 +25,7 @@ import Control.Monad
import Data.Foldable
import Data.Text as Text
import qualified Language.Ruby.AST as Rb
import Proto.Semantic as P
import Source.Loc
import Source.Range as Range
import Source.Source as Source
@ -72,11 +73,11 @@ nameBlacklist =
"lambda"
]
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> m ()
yieldTag name Call _ _ | name `elem` nameBlacklist = pure ()
yieldTag name kind loc srcLineRange = do
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> P.SyntaxType -> P.NodeType -> Loc -> Range -> m ()
yieldTag name P.CALL _ _ _ | name `elem` nameBlacklist = pure ()
yieldTag name kind ty loc srcLineRange = do
src <- ask @Source
Tags.yield (Tag name kind loc (Tags.firstLine src srcLineRange) Nothing)
Tags.yield (Tag name kind ty loc (Tags.firstLine src srcLineRange) Nothing)
instance ToTags Rb.Class where
tags
@ -94,7 +95,7 @@ instance ToTags Rb.Class where
Prj Rb.Superclass {ann = Loc {byteRange = Range {end}}} : _ -> Range start end
_ -> Range start (getEnd expr)
getEnd = Range.end . byteRange . TS.gann
yield name loc = yieldTag name Class loc range' >> gtags t
yield name loc = yieldTag name P.CLASS P.DEFINITION loc range' >> gtags t
instance ToTags Rb.SingletonClass where
tags
@ -112,7 +113,7 @@ instance ToTags Rb.SingletonClass where
x : _ -> Range start (getStart x)
_ -> range
getStart = Range.start . byteRange . TS.gann
yield name loc = yieldTag name Class loc range' >> gtags t
yield name loc = yieldTag name P.CLASS P.DEFINITION loc range' >> gtags t
instance ToTags Rb.Module where
tags
@ -131,7 +132,7 @@ instance ToTags Rb.Module where
_ -> Range start (getEnd expr)
getEnd = Range.end . byteRange . TS.gann
getStart = Range.start . byteRange . TS.gann
yield name loc = yieldTag name Module loc range' >> gtags t
yield name loc = yieldTag name P.MODULE P.DEFINITION loc range' >> gtags t
yieldMethodNameTag ::
( Has (State [Text]) sig m,
@ -155,7 +156,7 @@ yieldMethodNameTag t range (Rb.MethodName expr) = enterScope True $ case expr of
-- Prj Rb.Symbol { extraChildren = [Prj Rb.EscapeSequence { text = name }] } -> yield name
_ -> gtags t
where
yield name loc = yieldTag name Method loc range >> gtags t
yield name loc = yieldTag name P.METHOD P.DEFINITION loc range >> gtags t
enterScope :: (Has (State [Text]) sig m) => Bool -> m () -> m ()
enterScope createNew m = do
@ -241,16 +242,16 @@ instance ToTags Rb.Lhs where
Prj Rb.Operator {text, ann} -> yieldCall text ann byteRange
_ -> gtags t
-- These do check for locals before yielding a call tag
Prj (Rb.Variable (Prj Rb.Identifier {ann = loc@Loc {byteRange}, text})) -> yield text Call loc byteRange
Prj Rb.ScopeResolution {ann = loc@Loc {byteRange}, name = Prj Rb.Identifier {text}} -> yield text Call loc byteRange
Prj (Rb.Variable (Prj Rb.Constant { ann = loc@Loc { byteRange }, text })) -> yield text Call loc byteRange -- TODO: Should yield Constant
Prj Rb.ScopeResolution { ann = loc@Loc { byteRange }, name = Prj Rb.Constant { text } } -> yield text Call loc byteRange -- TODO: Should yield Constant
Prj (Rb.Variable (Prj Rb.Identifier {ann = loc@Loc {byteRange}, text})) -> yield text P.CALL loc byteRange
Prj Rb.ScopeResolution {ann = loc@Loc {byteRange}, name = Prj Rb.Identifier {text}} -> yield text P.CALL loc byteRange
Prj (Rb.Variable (Prj Rb.Constant { ann = loc@Loc { byteRange }, text })) -> yield text P.CALL loc byteRange -- TODO: Should yield Constant
Prj Rb.ScopeResolution { ann = loc@Loc { byteRange }, name = Prj Rb.Constant { text } } -> yield text P.CALL loc byteRange -- TODO: Should yield Constant
_ -> gtags t
where
yieldCall name loc range = yieldTag name Call loc range >> gtags t
yieldCall name loc range = yieldTag name P.CALL P.REFERENCE loc range >> gtags t
yield name kind loc range = do
locals <- get @[Text]
unless (name `elem` locals) $ yieldTag name kind loc range
unless (name `elem` locals) $ yieldTag name kind P.REFERENCE loc range
gtags t
-- TODO: Line of source produced here could be better.
@ -260,18 +261,18 @@ instance ToTags Rb.MethodCall where
{ ann = Loc {byteRange = byteRange@Range {}},
method = expr
} = case expr of
Prj (Rb.Variable (Prj Rb.Identifier {text, ann})) -> yield text Call ann
Prj (Rb.Variable (Prj Rb.Constant {text, ann})) -> yield text Call ann -- TODO: Should yield Constant
Prj Rb.ScopeResolution {name = Prj Rb.Identifier {text, ann}} -> yield text Call ann
Prj Rb.ScopeResolution {name = Prj Rb.Constant {text, ann}} -> yield text Call ann -- TODO: Should yield Constant
Prj (Rb.Variable (Prj Rb.Identifier {text, ann})) -> yield text P.CALL ann
Prj (Rb.Variable (Prj Rb.Constant {text, ann})) -> yield text P.CALL ann -- TODO: Should yield Constant
Prj Rb.ScopeResolution {name = Prj Rb.Identifier {text, ann}} -> yield text P.CALL ann
Prj Rb.ScopeResolution {name = Prj Rb.Constant {text, ann}} -> yield text P.CALL ann -- TODO: Should yield Constant
Prj Rb.Call {method} -> case method of
Prj Rb.Identifier {text, ann} -> yield text Call ann
Prj Rb.Constant {text, ann} -> yield text Call ann
Prj Rb.Operator {text, ann} -> yield text Call ann
Prj Rb.Identifier {text, ann} -> yield text P.CALL ann
Prj Rb.Constant {text, ann} -> yield text P.CALL ann
Prj Rb.Operator {text, ann} -> yield text P.CALL ann
_ -> gtags t
_ -> gtags t
where
yield name kind loc = yieldTag name kind loc byteRange >> gtags t
yield name kind loc = yieldTag name kind P.REFERENCE loc byteRange >> gtags t
instance ToTags Rb.Alias where
tags
@ -281,10 +282,10 @@ instance ToTags Rb.Alias where
ann = Loc {byteRange}
} = do
case aliasExpr of
Prj Rb.Identifier {ann, text} -> yieldTag text Function ann byteRange
Prj Rb.Identifier {ann, text} -> yieldTag text P.FUNCTION P.DEFINITION ann byteRange
_ -> tags aliasExpr
case nameExpr of
Prj Rb.Identifier {ann, text} -> yieldTag text Call ann byteRange
Prj Rb.Identifier {ann, text} -> yieldTag text P.CALL P.REFERENCE ann byteRange
_ -> tags nameExpr
gtags t
@ -295,7 +296,7 @@ instance ToTags Rb.Undef where
ann = Loc {byteRange}
} = for_ extraChildren $ \(Rb.MethodName expr) -> do
case expr of
Prj Rb.Identifier {ann, text} -> yieldTag text Call ann byteRange
Prj Rb.Identifier {ann, text} -> yieldTag text P.CALL P.REFERENCE ann byteRange
_ -> tags expr
gtags t

View File

@ -26,6 +26,7 @@ common haskell
, parsers ^>= 0.12.10
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, template-haskell ^>= 2.15
@ -84,4 +85,4 @@ test-suite test
-Wno-all-missed-specialisations
-Wno-star-is-type
if (impl(ghc >= 8.8))
ghc-options: -Wno-missing-deriving-strategies
ghc-options: -Wno-missing-deriving-strategies

View File

@ -205,4 +205,4 @@ instance ToTags Rust.VisibilityModifier
instance ToTags Rust.WhereClause
instance ToTags Rust.WherePredicate
instance ToTags Rust.WhileExpression
instance ToTags Rust.WhileLetExpression
instance ToTags Rust.WhileLetExpression

View File

@ -26,6 +26,7 @@ library
base >= 4.13 && < 5
, fused-effects ^>= 1.0
, semantic-source ^>= 0.1.0
, semantic-proto ^>= 0
, text ^>= 1.2.3.1
hs-source-dirs: src
default-language: Haskell2010

View File

@ -1,33 +1,16 @@
module Tags.Tag
( Tag(..)
, Kind(..)
) where
module Tags.Tag (Tag (..)) where
import Data.Text (Text)
import Proto.Semantic as P
import Source.Loc
data Tag = Tag
{ name :: Text
, kind :: Kind
, loc :: Loc
, line :: Text
, docs :: Maybe Text
}
data Tag
= Tag
{ tagName :: Text,
tagSyntaxType :: P.SyntaxType,
tagNodeType :: P.NodeType,
tagLoc :: Loc,
tagLine :: Text,
tagDocs :: Maybe Text
}
deriving (Eq, Show)
data Kind
-- Definitions
= Function
| Method
| Class
| Module
-- References
| Call
| Type
-- Just as Call is to Class and Function, Implementation is to Interface.
-- This suggests that perhaps we should have an Instantiation kind that
-- we use for Class.
| Interface
| Implementation
-- Constant -- TODO: New kind for constant references
deriving (Bounded, Enum, Eq, Show)

View File

@ -1,5 +1,6 @@
module Tags.Tagging.Precise
( Tags
, Tag(..)
, ToTags(..)
, yield
, runTagging
@ -26,7 +27,7 @@ class ToTags t where
yield :: Has (Writer Tags) sig m => Tag -> m ()
yield = tell . Endo . (:) . modSpan toOneIndexed where
modSpan f t@Tag{ loc = l } = t { loc = l { span = f (span l) } }
modSpan f t@Tag{ tagLoc = l } = t { tagLoc = l { span = f (span l) } }
toOneIndexed (Span (Pos l1 c1) (Pos l2 c2)) = Span (Pos (l1 + 1) (c1 + 1)) (Pos (l2 + 1) (c2 + 1))
runTagging :: Source -> ReaderC Source (WriterC Tags Identity) () -> [Tag]

View File

@ -26,6 +26,7 @@ common haskell
, parsers ^>= 0.12.10
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, template-haskell ^>= 2.15

View File

@ -19,6 +19,7 @@ import Control.Effect.Writer
import Data.Foldable
import Data.Text as Text
import qualified Language.TSX.AST as Tsx
import Proto.Semantic as P
import Source.Loc
import Source.Source as Source
import Tags.Tag
@ -42,20 +43,20 @@ class ToTags t where
instance ToTags Tsx.Function where
tags t@Tsx.Function {ann = Loc {byteRange}, name = Just Tsx.Identifier {text, ann}} =
yieldTag text Function ann byteRange >> gtags t
yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
tags t = gtags t
instance ToTags Tsx.FunctionSignature where
tags t@Tsx.FunctionSignature {ann = Loc {byteRange}, name = Tsx.Identifier {text, ann}} =
yieldTag text Function ann byteRange >> gtags t
yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
instance ToTags Tsx.FunctionDeclaration where
tags t@Tsx.FunctionDeclaration {ann = Loc {byteRange}, name = Tsx.Identifier {text, ann}} =
yieldTag text Function ann byteRange >> gtags t
yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
instance ToTags Tsx.MethodDefinition where
tags t@Tsx.MethodDefinition {ann = Loc {byteRange}, name} = case name of
Prj Tsx.PropertyIdentifier {text, ann} -> yieldTag text Method ann byteRange >> gtags t
Prj Tsx.PropertyIdentifier {text, ann} -> yieldTag text P.METHOD P.DEFINITION ann byteRange >> gtags t
_ -> gtags t
instance ToTags Tsx.Pair where
@ -64,11 +65,11 @@ instance ToTags Tsx.Pair where
(Prj Tsx.PropertyIdentifier {text, ann}, Prj Tsx.ArrowFunction {}) -> yield text ann
_ -> gtags t
where
yield text loc = yieldTag text Function loc byteRange >> gtags t
yield text loc = yieldTag text P.FUNCTION P.DEFINITION loc byteRange >> gtags t
instance ToTags Tsx.ClassDeclaration where
tags t@Tsx.ClassDeclaration {ann = Loc {byteRange}, name = Tsx.TypeIdentifier {text, ann}} =
yieldTag text Class ann byteRange >> gtags t
yieldTag text P.CLASS P.DEFINITION ann byteRange >> gtags t
instance ToTags Tsx.CallExpression where
tags t@Tsx.CallExpression {ann = Loc {byteRange}, function = Tsx.Expression expr} = match expr
@ -83,16 +84,16 @@ instance ToTags Tsx.CallExpression where
Prj (Tsx.Expression expr) -> match expr
_ -> tags x
_ -> gtags t
yield name loc = yieldTag name Call loc byteRange >> gtags t
yield name loc = yieldTag name P.CALL P.REFERENCE loc byteRange >> gtags t
instance ToTags Tsx.Class where
tags t@Tsx.Class {ann = Loc {byteRange}, name = Just Tsx.TypeIdentifier {text, ann}} =
yieldTag text Class ann byteRange >> gtags t
yieldTag text P.CLASS P.DEFINITION ann byteRange >> gtags t
tags t = gtags t
instance ToTags Tsx.Module where
tags t@Tsx.Module {ann = Loc {byteRange}, name} = case name of
Prj Tsx.Identifier {text, ann} -> yieldTag text Module ann byteRange >> gtags t
Prj Tsx.Identifier {text, ann} -> yieldTag text P.MODULE P.DEFINITION ann byteRange >> gtags t
_ -> gtags t
instance ToTags Tsx.VariableDeclarator where
@ -102,7 +103,7 @@ instance ToTags Tsx.VariableDeclarator where
(Prj Tsx.ArrowFunction {}, Prj Tsx.Identifier {text, ann}) -> yield text ann
_ -> gtags t
where
yield text loc = yieldTag text Function loc byteRange >> gtags t
yield text loc = yieldTag text P.FUNCTION P.DEFINITION loc byteRange >> gtags t
tags t = gtags t
instance ToTags Tsx.AssignmentExpression where
@ -114,7 +115,7 @@ instance ToTags Tsx.AssignmentExpression where
(Prj Tsx.MemberExpression {property = Tsx.PropertyIdentifier {text, ann}}, Prj Tsx.ArrowFunction {}) -> yield text ann
_ -> gtags t
where
yield text loc = yieldTag text Function loc byteRange >> gtags t
yield text loc = yieldTag text P.FUNCTION P.DEFINITION loc byteRange >> gtags t
instance (ToTags l, ToTags r) => ToTags (l :+: r) where
tags (L1 l) = tags l
@ -137,11 +138,11 @@ gtags = traverse1_ @ToTags (const (pure ())) tags
nameBlacklist :: [Text]
nameBlacklist = ["require"]
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> m ()
yieldTag name Call _ _ | name `elem` nameBlacklist = pure ()
yieldTag name kind loc srcLineRange = do
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> P.SyntaxType -> P.NodeType -> Loc -> Range -> m ()
yieldTag name P.CALL _ _ _ | name `elem` nameBlacklist = pure ()
yieldTag name kind ty loc srcLineRange = do
src <- ask @Source
Tags.yield (Tag name kind loc (Tags.firstLine src srcLineRange) Nothing)
Tags.yield (Tag name kind ty loc (Tags.firstLine src srcLineRange) Nothing)
{- ORMOLU_DISABLE -}
instance ToTags Tsx.AbstractClassDeclaration

View File

@ -26,6 +26,7 @@ common haskell
, parsers ^>= 0.12.10
, semantic-ast
, semantic-core ^>= 0.0
, semantic-proto ^>= 0
, semantic-source ^>= 0.1.0
, semantic-tags ^>= 0.0
, template-haskell ^>= 2.15

View File

@ -19,6 +19,7 @@ import Control.Effect.Writer
import Data.Foldable
import Data.Text as Text
import qualified Language.TypeScript.AST as Ts
import Proto.Semantic as P
import Source.Loc
import Source.Source as Source
import Tags.Tag
@ -42,20 +43,20 @@ class ToTags t where
instance ToTags Ts.Function where
tags t@Ts.Function {ann = Loc {byteRange}, name = Just Ts.Identifier {text, ann}} =
yieldTag text Function ann byteRange >> gtags t
yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
tags t = gtags t
instance ToTags Ts.FunctionSignature where
tags t@Ts.FunctionSignature {ann = Loc {byteRange}, name = Ts.Identifier {text, ann}} =
yieldTag text Function ann byteRange >> gtags t
yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
instance ToTags Ts.FunctionDeclaration where
tags t@Ts.FunctionDeclaration {ann = Loc {byteRange}, name = Ts.Identifier {text, ann}} =
yieldTag text Function ann byteRange >> gtags t
yieldTag text P.FUNCTION P.DEFINITION ann byteRange >> gtags t
instance ToTags Ts.MethodDefinition where
tags t@Ts.MethodDefinition {ann = Loc {byteRange}, name} = case name of
Prj Ts.PropertyIdentifier {text, ann} -> yieldTag text Method ann byteRange >> gtags t
Prj Ts.PropertyIdentifier {text, ann} -> yieldTag text P.METHOD P.DEFINITION ann byteRange >> gtags t
_ -> gtags t
instance ToTags Ts.Pair where
@ -64,11 +65,11 @@ instance ToTags Ts.Pair where
(Prj Ts.PropertyIdentifier {text, ann}, Prj Ts.ArrowFunction {}) -> yield text ann
_ -> gtags t
where
yield text loc = yieldTag text Function loc byteRange >> gtags t
yield text loc = yieldTag text P.FUNCTION P.DEFINITION loc byteRange >> gtags t
instance ToTags Ts.ClassDeclaration where
tags t@Ts.ClassDeclaration {ann = Loc {byteRange}, name = Ts.TypeIdentifier {text, ann}} =
yieldTag text Class ann byteRange >> gtags t
yieldTag text P.CLASS P.DEFINITION ann byteRange >> gtags t
instance ToTags Ts.CallExpression where
tags t@Ts.CallExpression {ann = Loc {byteRange}, function = Ts.Expression expr} = match expr
@ -83,16 +84,16 @@ instance ToTags Ts.CallExpression where
Prj (Ts.Expression expr) -> match expr
_ -> tags x
_ -> gtags t
yield name loc = yieldTag name Call loc byteRange >> gtags t
yield name loc = yieldTag name P.CALL P.REFERENCE loc byteRange >> gtags t
instance ToTags Ts.Class where
tags t@Ts.Class {ann = Loc {byteRange}, name = Just Ts.TypeIdentifier {text, ann}} =
yieldTag text Class ann byteRange >> gtags t
yieldTag text P.CLASS P.DEFINITION ann byteRange >> gtags t
tags t = gtags t
instance ToTags Ts.Module where
tags t@Ts.Module {ann = Loc {byteRange}, name} = case name of
Prj Ts.Identifier {text, ann} -> yieldTag text Module ann byteRange >> gtags t
Prj Ts.Identifier {text, ann} -> yieldTag text P.MODULE P.DEFINITION ann byteRange >> gtags t
_ -> gtags t
instance ToTags Ts.VariableDeclarator where
@ -102,7 +103,7 @@ instance ToTags Ts.VariableDeclarator where
(Prj Ts.ArrowFunction {}, Prj Ts.Identifier {text, ann}) -> yield text ann
_ -> gtags t
where
yield text loc = yieldTag text Function loc byteRange >> gtags t
yield text loc = yieldTag text P.FUNCTION P.DEFINITION loc byteRange >> gtags t
tags t = gtags t
instance ToTags Ts.AssignmentExpression where
@ -114,7 +115,7 @@ instance ToTags Ts.AssignmentExpression where
(Prj Ts.MemberExpression {property = Ts.PropertyIdentifier {text, ann}}, Prj Ts.ArrowFunction {}) -> yield text ann
_ -> gtags t
where
yield text loc = yieldTag text Function loc byteRange >> gtags t
yield text loc = yieldTag text P.FUNCTION P.DEFINITION loc byteRange >> gtags t
instance (ToTags l, ToTags r) => ToTags (l :+: r) where
tags (L1 l) = tags l
@ -137,11 +138,11 @@ gtags = traverse1_ @ToTags (const (pure ())) tags
nameBlacklist :: [Text]
nameBlacklist = ["require"]
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> Kind -> Loc -> Range -> m ()
yieldTag name Call _ _ | name `elem` nameBlacklist = pure ()
yieldTag name kind loc srcLineRange = do
yieldTag :: (Has (Reader Source) sig m, Has (Writer Tags.Tags) sig m) => Text -> P.SyntaxType -> P.NodeType -> Loc -> Range -> m ()
yieldTag name P.CALL _ _ _ | name `elem` nameBlacklist = pure ()
yieldTag name kind ty loc srcLineRange = do
src <- ask @Source
Tags.yield (Tag name kind loc (Tags.firstLine src srcLineRange) Nothing)
Tags.yield (Tag name kind ty loc (Tags.firstLine src srcLineRange) Nothing)
{- ORMOLU_DISABLE -}
instance ToTags Ts.AbstractClassDeclaration

View File

@ -214,13 +214,9 @@ library
-- High-level flow & operational functionality (logging, stats, etc.)
, Semantic.Analysis
-- API
, Proto.Semantic
, Proto.Semantic_Fields
, Proto.Semantic_JSON
, Semantic.Api
, Semantic.Api.Bridge
, Semantic.Api.Diffs
, Semantic.Api.LegacyTypes
, Semantic.Api.StackGraph
, Semantic.Api.Symbols
, Semantic.Api.Terms
@ -245,8 +241,6 @@ library
, Serializing.Format
, Serializing.SExpression
, Serializing.SExpression.Precise
, Tags.Taggable
, Tags.Tagging
-- Custom Prelude
autogen-modules: Paths_semantic
other-modules: Paths_semantic
@ -274,8 +268,6 @@ library
, pretty-show ^>= 1.9.5
, profunctors ^>= 5.3
, proto-lens >= 0.5 && < 0.7
, proto-lens-jsonpb
, proto-lens-runtime >= 0.5 && <0.7
, reducers ^>= 3.12.3
, semantic-go ^>= 0
, semantic-java ^>= 0
@ -284,6 +276,7 @@ library
, semantic-python ^>= 0
, semantic-codeql ^>= 0
, semantic-ruby ^>= 0
, semantic-proto ^>= 0
, semantic-scope-graph ^>= 0
, semantic-tags ^>= 0
, semantic-tsx ^>= 0
@ -356,6 +349,8 @@ test-suite test
, Properties
build-depends: semantic
, semantic-json
, semantic-tags ^>= 0
, semantic-proto ^>= 0
, tree-sitter-json ^>= 0.7
, Glob ^>= 0.10.0
, hedgehog ^>= 1
@ -381,6 +376,7 @@ test-suite parse-examples
, foldl ^>= 1.4.5
, lens >= 4.17 && < 4.19
, resourcet ^>= 1.2
, semantic-proto ^>= 0
, streaming
, streaming-bytestring ^>= 0.1.6
, tasty
@ -401,6 +397,7 @@ benchmark benchmarks
, lens >= 4.17 && < 4.19
, semantic
, semantic-ast
, semantic-proto
, semantic-source
source-repository head

View File

@ -18,7 +18,6 @@ import qualified Data.Text as T
import Data.Text.Lens
import qualified Proto.Semantic as API
import Proto.Semantic_Fields as P hiding (to)
import qualified Semantic.Api.LegacyTypes as Legacy
import qualified Source.Source as Source (fromText, toText, totalSpan)
import qualified Source.Span as Source
import qualified System.Path as Path
@ -52,11 +51,6 @@ class APIConvert api native | api -> native where
rev #? item = item ^? re rev
infixr 8 #?
instance APIBridge Legacy.Position Source.Pos where
bridging = iso fromAPI toAPI where
toAPI Source.Pos{..} = Legacy.Position line column
fromAPI Legacy.Position{..} = Source.Pos line column
instance APIBridge API.Position Source.Pos where
bridging = iso fromAPI toAPI where
toAPI Source.Pos{..} = defMessage & P.line .~ fromIntegral line & P.column .~ fromIntegral column
@ -67,11 +61,6 @@ instance APIConvert API.Span Source.Span where
toAPI Source.Span{..} = defMessage & P.maybe'start .~ (bridging #? start) & P.maybe'end .~ (bridging #? end)
fromAPI span = Source.Span <$> (span^.maybe'start >>= preview bridging) <*> (span^.maybe'end >>= preview bridging)
instance APIConvert Legacy.Span Source.Span where
converting = prism' toAPI fromAPI where
toAPI Source.Span{..} = Legacy.Span (bridging #? start) (bridging #? end)
fromAPI Legacy.Span {..} = Source.Span <$> (start >>= preview bridging) <*> (end >>= preview bridging)
instance APIBridge T.Text Data.Language where
bridging = iso Data.textToLanguage Data.languageToText

View File

@ -1,68 +0,0 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Semantic.Api.LegacyTypes
( ParseTreeRequest(..)
, ParseTreeSymbolResponse(..)
, File(..)
, Symbol(..)
, Span(..)
, Position(..)
) where
import Data.Aeson
import Data.Blob
import Data.Text (Text)
import GHC.Generics (Generic)
--
-- Legacy Symbols API
--
newtype ParseTreeRequest = ParseTreeRequest { blobs :: [Blob] }
deriving (Eq, Show, Generic, FromJSON)
newtype ParseTreeSymbolResponse = ParseTreeSymbolResponse { files :: [File] }
deriving (Eq, Show, Generic, ToJSON)
data File = File
{ filePath :: Text
, fileLanguage :: Text
, fileSymbols :: [Symbol]
}
deriving (Eq, Show, Generic)
instance ToJSON File where
toJSON File{..}
= object [ "path" .= filePath
, "language" .= fileLanguage
, "symbols" .= fileSymbols
]
data Symbol = Symbol
{ symbolName :: Text
, symbolKind :: Text
, symbolLine :: Text
, symbolSpan :: Maybe Span
}
deriving (Generic, Eq, Show)
instance ToJSON Symbol where
toJSON Symbol{..}
= object [ "symbol" .= symbolName
, "kind" .= symbolKind
, "line" .= symbolLine
, "span" .= symbolSpan
]
data Position = Position { line :: Int, column :: Int }
deriving (Eq, Ord, Show, Generic)
instance ToJSON Position
where toJSON Position{..} = toJSON [line, column]
data Span = Span { start :: Maybe Position, end :: Maybe Position }
deriving (Eq, Ord, Show, Generic, ToJSON)

View File

@ -70,9 +70,9 @@ parseStackGraph blobs = do
& P.id .~ nodeId node
& P.name .~ nodeName node
& P.line .~ nodeLine node
& P.kind .~ nodeKind node
& P.maybe'span ?~ converting # nodeSpan node
& P.nodeType .~ nodeTypeToNodeType (Semantic.Api.StackGraph.nodeType node)
& P.syntaxType .~ nodeSyntaxType node
& P.nodeType .~ nodeNodeType node
pathToPath :: SGPath -> StackGraphPath
pathToPath path
@ -85,14 +85,6 @@ parseStackGraph blobs = do
& P.endingScopeStack .~ pathEndingScopeStack path
& P.endingSymbolStack .~ pathEndingSymbolStack path
nodeTypeToNodeType :: SGNodeType -> NodeType
nodeTypeToNodeType = \case
RootScope -> P.ROOT_SCOPE
JumpToScope -> P.JUMP_TO_SCOPE
ExportedScope -> P.EXPORTED_SCOPE
Definition -> P.DEFINITION
Reference -> P.REFERENCE
-- TODO: These are temporary, will replace with proper datatypes from the scope graph work.
data TempStackGraph
= TempStackGraph
@ -114,16 +106,13 @@ data SGPath
data SGNode
= SGNode
{ nodeId :: Int64
, nodeName :: Text
, nodeLine :: Text
, nodeKind :: Text
, nodeSpan :: Loc.Span
, nodeType :: SGNodeType
}
deriving (Eq, Show)
data SGNodeType = RootScope | JumpToScope | ExportedScope | Definition | Reference
{ nodeId :: Int64,
nodeName :: Text,
nodeLine :: Text,
nodeSpan :: Loc.Span,
nodeSyntaxType :: P.SyntaxType,
nodeNodeType :: P.NodeType
}
deriving (Eq, Show)
graphForBlob :: (Has (Error SomeException) sig m, Has Parse sig m) => Blob -> m TempStackGraph

View File

@ -10,137 +10,79 @@
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Semantic.Api.Symbols
( legacyParseSymbols
, parseSymbols
, parseSymbolsBuilder
, tagsForBlob
) where
( parseSymbols,
parseSymbolsBuilder,
tagsForBlob,
)
where
import Control.Effect.Error
import Control.Effect.Parse
import Control.Effect.Reader
import Control.Exception
import Control.Lens
import Data.Abstract.Declarations
import Data.Blob
import Data.ByteString.Builder
import Data.Foldable
import Data.Functor.Foldable
import Data.Language
import Data.Map.Strict (Map)
import Data.ProtoLens (defMessage)
import Data.Term (IsTerm (..), TermF)
import Data.Text (Text)
import Data.Text (pack)
import Control.Effect.Error
import Control.Effect.Parse
import Control.Effect.Reader
import Control.Exception
import Control.Lens
import Data.Blob
import Data.ByteString.Builder
import Data.Foldable
import Data.Language
import Data.Map.Strict (Map)
import Data.ProtoLens (defMessage)
import Data.Text (pack, toTitle)
import qualified Parsing.Parser as Parser
import Proto.Semantic as P hiding (Blob)
import Proto.Semantic_Fields as P
import Proto.Semantic_JSON ()
import Semantic.Api.Bridge
import qualified Semantic.Api.LegacyTypes as Legacy
import Semantic.Config
import Semantic.Task
import Serializing.Format (Format)
import Source.Loc as Loc
import Tags.Tagging
import qualified Tags.Tagging.Precise as Precise
import Proto.Semantic as P hiding (Blob)
import Proto.Semantic_Fields as P
import Proto.Semantic_JSON ()
import Semantic.Api.Bridge
import Semantic.Config
import Semantic.Task
import Serializing.Format (Format)
import Source.Loc as Loc
import Tags.Tagging.Precise
legacyParseSymbols :: (Has Distribute sig m, Has (Error SomeException) sig m, Has (Reader PerLanguageModes) sig m, Has Parse sig m, Traversable t) => t Blob -> m Legacy.ParseTreeSymbolResponse
legacyParseSymbols blobs = Legacy.ParseTreeSymbolResponse <$> distributeFoldMap go blobs
where
go :: (Has (Error SomeException) sig m, Has (Reader PerLanguageModes) sig m, Has Parse sig m) => Blob -> m [Legacy.File]
go blob@Blob{..} = asks toTagsParsers >>= \ p -> parseWith p (pure . renderToSymbols) blob `catchError` (\(SomeException _) -> pure (pure emptyFile))
where
emptyFile = tagsToFile []
-- Legacy symbols output doesn't include Function Calls.
symbolsToSummarize :: [Text]
symbolsToSummarize = ["Function", "Method", "Class", "Module"]
renderToSymbols :: ToTags t => t Loc -> [Legacy.File]
renderToSymbols = pure . tagsToFile . tags symbolsToSummarize blob
tagsToFile :: [Tag] -> Legacy.File
tagsToFile tags = Legacy.File (pack (blobFilePath blob)) (pack (show (blobLanguage blob))) (fmap tagToSymbol tags)
tagToSymbol :: Tag -> Legacy.Symbol
tagToSymbol Tag{..}
= Legacy.Symbol
{ symbolName = name
, symbolKind = pack (show kind)
, symbolLine = line
, symbolSpan = converting #? Loc.span loc
}
parseSymbolsBuilder :: (Has Distribute sig m, Has (Error SomeException) sig m, Has Parse sig m, Has (Reader Config) sig m, Has (Reader PerLanguageModes) sig m, Traversable t) => Format ParseTreeSymbolResponse -> t Blob -> m Builder
parseSymbolsBuilder :: (Has Distribute sig m, Has (Error SomeException) sig m, Has Parse sig m, Has (Reader Config) sig m, Traversable t) => Format ParseTreeSymbolResponse -> t Blob -> m Builder
parseSymbolsBuilder format blobs = parseSymbols blobs >>= serialize format
parseSymbols :: (Has Distribute sig m, Has (Error SomeException) sig m, Has (Reader PerLanguageModes) sig m, Has Parse sig m, Traversable t) => t Blob -> m ParseTreeSymbolResponse
parseSymbols :: (Has Distribute sig m, Has (Error SomeException) sig m, Has Parse sig m, Traversable t) => t Blob -> m ParseTreeSymbolResponse
parseSymbols blobs = do
terms <- distributeFor blobs go
pure $ defMessage & P.files .~ toList terms
where
go :: (Has (Error SomeException) sig m, Has (Reader PerLanguageModes) sig m, Has Parse sig m) => Blob -> m File
go blob@Blob{..} = catching $ tagsToFile <$> tagsForBlob blob
go :: (Has (Error SomeException) sig m, Has Parse sig m) => Blob -> m File
go blob@Blob {..} = catching $ tagsToFile <$> tagsForBlob blob
where
catching m = m `catchError` (\(SomeException e) -> pure $ errorFile (show e))
blobLanguage' = blobLanguage blob
blobPath' = pack $ blobFilePath blob
errorFile e = defMessage
& P.path .~ blobPath'
& P.language .~ (bridging # blobLanguage')
& P.symbols .~ mempty
& P.errors .~ [defMessage & P.error .~ pack e]
errorFile e =
defMessage
& P.path .~ blobPath'
& P.language .~ (bridging # blobLanguage')
& P.symbols .~ mempty
& P.errors .~ [defMessage & P.error .~ pack e]
tagsToFile :: [Tag] -> File
tagsToFile tags = defMessage
& P.path .~ blobPath'
& P.language .~ (bridging # blobLanguage')
& P.symbols .~ fmap tagToSymbol tags
& P.errors .~ mempty
tagsToFile tags =
defMessage
& P.path .~ blobPath'
& P.language .~ (bridging # blobLanguage')
& P.symbols .~ fmap tagToSymbol tags
& P.errors .~ mempty
tagToSymbol :: Tag -> Symbol
tagToSymbol Tag{..} = defMessage
& P.symbol .~ name
& P.kind .~ pack (show kind)
& P.nodeType .~ nodeTypeForKind kind
& P.line .~ line
& P.maybe'span ?~ converting # Loc.span loc
& P.maybe'docs .~ fmap (flip (set P.docstring) defMessage) docs
tagToSymbol tag =
defMessage
& P.symbol .~ tagName tag
& P.kind .~ toKind tag
& P.nodeType .~ tagNodeType tag
& P.syntaxType .~ tagSyntaxType tag
& P.line .~ tagLine tag
& P.maybe'span ?~ converting # Loc.span (tagLoc tag)
& P.maybe'docs .~ fmap (flip (set P.docstring) defMessage) (tagDocs tag)
where
toKind = toTitle . pack . show . tagSyntaxType
nodeTypeForKind :: Kind -> NodeType
nodeTypeForKind = \case
Function -> DEFINITION
Method -> DEFINITION
Class -> DEFINITION
Module -> DEFINITION
Interface -> DEFINITION
Call -> REFERENCE
Type -> REFERENCE
Implementation -> REFERENCE
tagsForBlob :: (Has (Error SomeException) sig m, Has Parse sig m, Has (Reader PerLanguageModes) sig m) => Blob -> m [Tag]
tagsForBlob blob = asks toTagsParsers >>= \p -> parseWith p (pure . tags symbolsToSummarize blob) blob
symbolsToSummarize :: [Text]
symbolsToSummarize = ["Function", "AmbientFunction", "Method", "Class", "Module", "Call", "Send"]
class ToTags t where
tags :: [Text] -> Blob -> t Loc -> [Tag]
instance (Parser.TermMode term ~ strategy, ToTagsBy strategy term) => ToTags term where
tags = tagsBy @strategy
class ToTagsBy (strategy :: LanguageMode) term where
tagsBy :: [Text] -> Blob -> term Loc -> [Tag]
instance (IsTerm term, IsTaggable (Syntax term), Base (term Loc) ~ TermF (Syntax term) Loc, Recursive (term Loc), Declarations (term Loc)) => ToTagsBy 'ALaCarte term where
tagsBy symbols blob = runTagging (blobLanguage blob) symbols (blobSource blob)
instance Precise.ToTags term => ToTagsBy 'Precise term where
tagsBy _ = Precise.tags . blobSource
toTagsParsers :: PerLanguageModes -> Map Language (Parser.SomeParser ToTags Loc)
toTagsParsers = Parser.allParsers
tagsForBlob :: (Has (Error SomeException) sig m, Has Parse sig m) => Blob -> m [Tag]
tagsForBlob blob = parseWith toTagsParsers (pure . tags (blobSource blob)) blob
where
toTagsParsers :: Map Language (Parser.SomeParser ToTags Loc)
toTagsParsers = Parser.preciseParsers

View File

@ -1,235 +0,0 @@
{- |
Taggable allows projecting syntax terms to a list of named symbols. In order to
identify a new syntax as Taggable, you need to:
1. Give that syntax a non-derived @TaggableBy 'Custom@ instance and implement at least the
'symbolName'' method.
2. Add an equation to 'TaggableInstance' for the type with the value ''Custom'.
3. Make sure that 'symbolsToSummarize' in Tagging.hs includes the string
constructor name of this syntax.
-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Tags.Taggable
( Tagger
, Token(..)
, Taggable(..)
, IsTaggable
, HasTextElement
, tagging
)
where
import Analysis.ConstructorName
import Analysis.HasTextElement
import Analysis.Name
import Data.Abstract.Declarations
import Data.Algebra
import Data.Foldable
import Data.Functor.Foldable
import Data.Language
import Data.Sum
import Data.Term
import Data.Text hiding (empty)
import Source.Loc as Loc
import Source.Range
import Streaming hiding (Sum)
import Streaming.Prelude (yield)
import qualified Data.Syntax as Syntax
import qualified Data.Syntax.Declaration as Declaration
import qualified Data.Syntax.Expression as Expression
import qualified Language.Ruby.Syntax as Ruby
import qualified Language.TypeScript.Syntax as TypeScript
-- TODO: Move to src/Data
data Token
= Enter Text Range
| Exit Text Range
| Iden Text Loc (Maybe Range)
deriving (Eq, Show)
type Tagger = Stream (Of Token)
enter, exit :: Monad m => String -> Range -> Tagger m ()
enter c = yield . Enter (pack c)
exit c = yield . Exit (pack c)
emitIden :: Monad m => Loc -> Maybe Range -> Name -> Tagger m ()
emitIden loc docsLiteralRange name = yield (Iden (formatName name) loc docsLiteralRange)
class Taggable constr where
docsLiteral ::
( Foldable (Syntax term)
, IsTerm term
, HasTextElement (Syntax term)
)
=> Language -> constr (term Loc) -> Maybe Range
snippet :: (IsTerm term, Foldable (Syntax term)) => Loc -> constr (term Loc) -> Range
symbolName :: (IsTerm term, Declarations (term Loc)) => constr (term Loc) -> Maybe Name
data Strategy = Default | Custom
class TaggableBy (strategy :: Strategy) constr where
docsLiteral' ::
( Foldable (Syntax term)
, IsTerm term
, HasTextElement (Syntax term)
)
=> Language -> constr (term Loc) -> Maybe Range
docsLiteral' _ _ = Nothing
snippet' :: (IsTerm term, Foldable (Syntax term)) => Loc -> constr (term Loc) -> Range
snippet' ann _ = byteRange ann
symbolName' :: (IsTerm term, Declarations (term Loc)) => constr (term Loc) -> Maybe Name
symbolName' _ = Nothing
type IsTaggable syntax =
( Functor syntax
, Foldable syntax
, Taggable syntax
, ConstructorName syntax
, HasTextElement syntax
)
tagging :: (Monad m, IsTerm term, IsTaggable (Syntax term), Base (term Loc) ~ TermF (Syntax term) Loc, Recursive (term Loc), Declarations (term Loc))
=> Language
-> term Loc
-> Stream (Of Token) m ()
tagging = foldSubterms . descend
descend ::
( ConstructorName (TermF (Syntax term) Loc)
, Declarations (term Loc)
, IsTerm term
, IsTaggable (Syntax term)
, Monad m
)
=> Language -> SubtermAlgebra (TermF (Syntax term) Loc) (term Loc) (Tagger m ())
descend lang t@(In loc _) = do
let term = fmap subterm t
let snippetRange = snippet loc term
let litRange = docsLiteral lang term
enter (constructorName term) snippetRange
maybe (pure ()) (emitIden loc litRange) (symbolName term)
traverse_ subtermRef t
exit (constructorName term) snippetRange
subtractLoc :: Loc -> Loc -> Range
subtractLoc a b = subtractRange (byteRange a) (byteRange b)
-- Instances
instance (TaggableBy strategy t, strategy ~ TaggableInstance t) => Taggable t where
docsLiteral = docsLiteral' @strategy
snippet = snippet' @strategy
symbolName = symbolName' @strategy
type family TaggableInstance (t :: * -> *) :: Strategy where
TaggableInstance (Sum _) = 'Custom
TaggableInstance (TermF _ _) = 'Custom
TaggableInstance Syntax.Context = 'Custom
TaggableInstance Declaration.Function = 'Custom
TaggableInstance Declaration.Method = 'Custom
TaggableInstance Declaration.Class = 'Custom
TaggableInstance Ruby.Class = 'Custom
TaggableInstance Ruby.Module = 'Custom
TaggableInstance TypeScript.Module = 'Custom
TaggableInstance TypeScript.AmbientFunction = 'Custom
TaggableInstance Expression.Call = 'Custom
TaggableInstance Ruby.Send = 'Custom
TaggableInstance _ = 'Default
instance TaggableBy 'Default t
instance Apply Taggable fs => TaggableBy 'Custom (Sum fs) where
docsLiteral' a = apply @Taggable (docsLiteral a)
snippet' x = apply @Taggable (snippet x)
symbolName' = apply @Taggable symbolName
instance Taggable a => TaggableBy 'Custom (TermF a Loc) where
docsLiteral' l t = docsLiteral l (termFOut t)
snippet' ann t = snippet ann (termFOut t)
symbolName' t = symbolName (termFOut t)
instance TaggableBy 'Custom Syntax.Context where
snippet' ann (Syntax.Context _ subj) = subtractLoc ann (termAnnotation subj)
instance TaggableBy 'Custom Declaration.Function where
docsLiteral' Python (Declaration.Function _ _ _ body)
| bodyF <- termOut body
, expr:_ <- toList bodyF
, In exprAnn exprF <- toTermF expr
, isTextElement exprF = Just (byteRange exprAnn)
| otherwise = Nothing
docsLiteral' _ _ = Nothing
snippet' ann (Declaration.Function _ _ _ body) = subtractLoc ann (termAnnotation body)
symbolName' = declaredName . Declaration.functionName
instance TaggableBy 'Custom TypeScript.AmbientFunction where
snippet' ann _ = byteRange ann
symbolName' = declaredName . TypeScript.ambientFunctionIdentifier
instance TaggableBy 'Custom Declaration.Method where
docsLiteral' Python (Declaration.Method _ _ _ _ body _)
| bodyF <- termOut body
, expr:_ <- toList bodyF
, In exprAnn exprF <- toTermF expr
, isTextElement exprF = Just (byteRange exprAnn)
| otherwise = Nothing
docsLiteral' _ _ = Nothing
snippet' ann (Declaration.Method _ _ _ _ body _) = subtractLoc ann (termAnnotation body)
symbolName' = declaredName . Declaration.methodName
instance TaggableBy 'Custom Declaration.Class where
docsLiteral' Python (Declaration.Class _ _ _ body)
| bodyF <- termOut body
, expr:_ <- toList bodyF
, In exprAnn exprF <- toTermF expr
, isTextElement exprF = Just (byteRange exprAnn)
| otherwise = Nothing
docsLiteral' _ _ = Nothing
snippet' ann (Declaration.Class _ _ _ body) = subtractLoc ann (termAnnotation body)
symbolName' = declaredName . Declaration.classIdentifier
instance TaggableBy 'Custom Ruby.Class where
snippet' ann (Ruby.Class _ _ body) = subtractLoc ann (termAnnotation body)
symbolName' = declaredName . Ruby.classIdentifier
instance TaggableBy 'Custom Ruby.Module where
snippet' ann (Ruby.Module _ (body:_)) = subtractLoc ann (termAnnotation body)
snippet' ann (Ruby.Module _ _) = byteRange ann
symbolName' = declaredName . Ruby.moduleIdentifier
instance TaggableBy 'Custom TypeScript.Module where
snippet' ann (TypeScript.Module _ (body:_)) = subtractLoc ann (termAnnotation body)
snippet' ann (TypeScript.Module _ _ ) = byteRange ann
symbolName' = declaredName . TypeScript.moduleIdentifier
instance TaggableBy 'Custom Expression.Call where
snippet' ann (Expression.Call _ _ _ body) = subtractLoc ann (termAnnotation body)
symbolName' = declaredName . Expression.callFunction
instance TaggableBy 'Custom Ruby.Send where
snippet' ann (Ruby.Send _ _ _ (Just body)) = subtractLoc ann (termAnnotation body)
snippet' ann _ = byteRange ann
symbolName' Ruby.Send{..} = declaredName =<< sendSelector

View File

@ -1,88 +0,0 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Tags.Tagging
( runTagging
, Tag(..)
, Kind(..)
, IsTaggable
)
where
import Prelude hiding (fail, filter, log)
import Control.Carrier.State.Strict as Eff
import Control.Monad
import Data.Abstract.Declarations (Declarations)
import Data.Functor.Foldable
import Data.Text as T hiding (empty)
import Streaming
import qualified Streaming.Prelude as Streaming
import Data.Language
import Data.Term
import Source.Loc
import qualified Source.Source as Source
import Tags.Tag
import Tags.Taggable
runTagging :: (IsTerm term, IsTaggable (Syntax term), Base (term Loc) ~ TermF (Syntax term) Loc, Recursive (term Loc), Declarations (term Loc))
=> Language
-> [Text]
-> Source.Source
-> term Loc
-> [Tag]
runTagging lang symbolsToSummarize source
= Eff.run
. evalState @[ContextToken] []
. Streaming.toList_
. contextualizing source toKind
. tagging lang
where
toKind x = do
guard (x `elem` symbolsToSummarize)
case x of
"Function" -> Just Function
"Method" -> Just Method
"Class" -> Just Class
"Module" -> Just Module
"Call" -> Just Call
"Send" -> Just Call -- Rubys Send is considered to be a kind of 'Call'
"AmbientFunction" -> Just Function -- Classify TypeScript ambient functions as 'Function'
_ -> Nothing
type ContextToken = (Text, Range)
contextualizing :: Has (State [ContextToken]) sig m
=> Source.Source
-> (Text -> Maybe Kind)
-> Stream (Of Token) m a
-> Stream (Of Tag) m a
contextualizing source toKind = Streaming.mapMaybeM $ \case
Enter x r -> Nothing <$ enterScope (x, r)
Exit x r -> Nothing <$ exitScope (x, r)
Iden iden loc docsLiteralRange -> fmap go (get @[ContextToken]) where
go = \case
((x, r):("Context", cr):_) | Just kind <- toKind x -> Just $ Tag iden kind loc (firstLine r) (Just (sliceDocs cr))
((x, r):_) | Just kind <- toKind x -> Just $ Tag iden kind loc (firstLine r) (sliceDocs <$> docsLiteralRange)
_ -> Nothing
where
slice = Source.toText . Source.slice source
sliceDocs = T.stripEnd . slice
firstLine = T.stripEnd . T.take 180 . T.takeWhile (/= '\n') . slice
enterScope, exitScope :: Has (State [ContextToken]) sig m
=> ContextToken
-> m ()
enterScope c = modify @[ContextToken] (c :)
exitScope c = get @[ContextToken] >>= \case
x:xs -> when (x == c) (put xs)
-- If we run out of scopes to match, we've hit a tag balance issue;
-- just continue onwards.
[] -> pure ()

View File

@ -2,93 +2,94 @@
module Tags.Spec (spec) where
import qualified Analysis.File as File
import Control.Carrier.Reader
import Semantic.Api.Symbols
import Source.Loc
import SpecHelpers
import Proto.Semantic as P
import Semantic.Api.Symbols
import Source.Loc
import SpecHelpers
import qualified System.Path as Path
import Tags.Tagging as Tags
import Tags.Tagging.Precise
spec :: Spec
spec = do
describe "go" $ do
it "produces tags for functions with docs (TODO)" $
parseTestFile [Function] (Path.relFile "test/fixtures/go/tags/simple_functions.go") `shouldReturn`
[ Tag "TestFromBits" Function (Loc (Range 56 68) (Span (Pos 6 6) (Pos 6 18))) "func TestFromBits(t *testing.T) {" Nothing
, Tag "Hi" Function (Loc (Range 99 101) (Span (Pos 10 6) (Pos 10 8))) "func Hi() {" Nothing ]
parseTestFile [P.FUNCTION] (Path.relFile "test/fixtures/go/tags/simple_functions.go") `shouldReturn`
[ Tag "TestFromBits" P.FUNCTION P.DEFINITION (Loc (Range 56 68) (Span (Pos 6 6) (Pos 6 18))) "func TestFromBits(t *testing.T) {" Nothing
, Tag "Hi" P.FUNCTION P.DEFINITION (Loc (Range 99 101) (Span (Pos 10 6) (Pos 10 8))) "func Hi() {" Nothing ]
it "produces tags for methods" $
parseTestFile [Method] (Path.relFile "test/fixtures/go/tags/method.go") `shouldReturn`
[ Tag "CheckAuth" Method (Loc (Range 39 48) (Span (Pos 3 21) (Pos 3 30))) "func (c *apiClient) CheckAuth(req *http.Request, user, repo string) (*authenticatedActor, error) {}" Nothing]
parseTestFile [] (Path.relFile "test/fixtures/go/tags/method.go") `shouldReturn`
[ Tag "CheckAuth" P.METHOD P.DEFINITION (Loc (Range 39 48) (Span (Pos 3 21) (Pos 3 30))) "func (c *apiClient) CheckAuth(req *http.Request, user, repo string) (*authenticatedActor, error) {}" Nothing]
it "produces tags for calls" $
parseTestFile [Call] (Path.relFile "test/fixtures/go/tags/simple_functions.go") `shouldReturn`
[ Tag "Hi" Call (Loc (Range 86 88) (Span (Pos 7 2) (Pos 7 4))) "Hi()" Nothing]
parseTestFile [P.CALL] (Path.relFile "test/fixtures/go/tags/simple_functions.go") `shouldReturn`
[ Tag "Hi" P.CALL P.REFERENCE (Loc (Range 86 88) (Span (Pos 7 2) (Pos 7 4))) "Hi()" Nothing]
describe "javascript and typescript" $ do
it "produces tags for functions with docs (TODO)" $
parseTestFile [Function] (Path.relFile "test/fixtures/javascript/tags/simple_function_with_docs.js") `shouldReturn`
[ Tag "myFunction" Function (Loc (Range 31 41) (Span (Pos 2 10) (Pos 2 20))) "function myFunction() {" Nothing ]
parseTestFile [] (Path.relFile "test/fixtures/javascript/tags/simple_function_with_docs.js") `shouldReturn`
[ Tag "myFunction" P.FUNCTION P.DEFINITION (Loc (Range 31 41) (Span (Pos 2 10) (Pos 2 20))) "function myFunction() {" Nothing ]
it "produces tags for classes" $
parseTestFile [Class] (Path.relFile "test/fixtures/typescript/tags/class.ts") `shouldReturn`
[ Tag "FooBar" Class (Loc (Range 6 12) (Span (Pos 1 7) (Pos 1 13))) "class FooBar {}" Nothing ]
parseTestFile [] (Path.relFile "test/fixtures/typescript/tags/class.ts") `shouldReturn`
[ Tag "FooBar" P.CLASS P.DEFINITION (Loc (Range 6 12) (Span (Pos 1 7) (Pos 1 13))) "class FooBar {}" Nothing ]
it "produces tags for modules" $
parseTestFile [Tags.Module] (Path.relFile "test/fixtures/typescript/tags/module.ts") `shouldReturn`
[ Tag "APromise" Tags.Module (Loc (Range 7 15) (Span (Pos 1 8) (Pos 1 16))) "module APromise { }" Nothing ]
parseTestFile [] (Path.relFile "test/fixtures/typescript/tags/module.ts") `shouldReturn`
[ Tag "APromise" P.MODULE P.DEFINITION (Loc (Range 7 15) (Span (Pos 1 8) (Pos 1 16))) "module APromise { }" Nothing ]
describe "python" $ do
it "produces tags for functions" $
parseTestFile [Function] (Path.relFile "test/fixtures/python/tags/simple_functions.py") `shouldReturn`
[ Tag "Foo" Function (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def Foo(x):" Nothing
, Tag "Bar" Function (Loc (Range 74 77) (Span (Pos 7 5) (Pos 7 8))) "def Bar():" Nothing
, Tag "local" Function (Loc (Range 89 94) (Span (Pos 8 9) (Pos 8 14))) "def local():" Nothing
parseTestFile [] (Path.relFile "test/fixtures/python/tags/simple_functions.py") `shouldReturn`
[ Tag "Foo" P.FUNCTION P.DEFINITION (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def Foo(x):" Nothing
, Tag "Bar" P.FUNCTION P.DEFINITION (Loc (Range 74 77) (Span (Pos 7 5) (Pos 7 8))) "def Bar():" Nothing
, Tag "local" P.FUNCTION P.DEFINITION (Loc (Range 89 94) (Span (Pos 8 9) (Pos 8 14))) "def local():" Nothing
]
it "produces tags for functions with docs" $
parseTestFile [Function] (Path.relFile "test/fixtures/python/tags/simple_function_with_docs.py") `shouldReturn`
[ Tag "Foo" Function (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def Foo(x):" (Just "\"\"\"This is the foo function\"\"\"") ]
parseTestFile [] (Path.relFile "test/fixtures/python/tags/simple_function_with_docs.py") `shouldReturn`
[ Tag "Foo" P.FUNCTION P.DEFINITION (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def Foo(x):" (Just "\"\"\"This is the foo function\"\"\"") ]
it "produces tags for classes" $
parseTestFile [Class, Function] (Path.relFile "test/fixtures/python/tags/class.py") `shouldReturn`
[ Tag "Foo" Class (Loc (Range 6 9) (Span (Pos 1 7) (Pos 1 10))) "class Foo:" (Just "\"\"\"The Foo class\"\"\"")
, Tag "f" Function (Loc (Range 43 44) (Span (Pos 3 9) (Pos 3 10))) "def f(self):" (Just "\"\"\"The f method\"\"\"")
parseTestFile [] (Path.relFile "test/fixtures/python/tags/class.py") `shouldReturn`
[ Tag "Foo" P.CLASS P.DEFINITION (Loc (Range 6 9) (Span (Pos 1 7) (Pos 1 10))) "class Foo:" (Just "\"\"\"The Foo class\"\"\"")
, Tag "f" P.FUNCTION P.DEFINITION (Loc (Range 43 44) (Span (Pos 3 9) (Pos 3 10))) "def f(self):" (Just "\"\"\"The f method\"\"\"")
]
it "produces tags for multi-line functions" $
parseTestFile [Function] (Path.relFile "test/fixtures/python/tags/multiline.py") `shouldReturn`
[ Tag "Foo" Function (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def Foo(x," Nothing ]
parseTestFile [P.FUNCTION] (Path.relFile "test/fixtures/python/tags/multiline.py") `shouldReturn`
[ Tag "Foo" P.FUNCTION P.DEFINITION (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def Foo(x," Nothing ]
describe "ruby" $ do
it "produces tags for methods" $
parseTestFile [Method] (Path.relFile "test/fixtures/ruby/tags/simple_method.rb") `shouldReturn`
[ Tag "foo" Method (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def foo" Nothing ]
parseTestFile [P.METHOD] (Path.relFile "test/fixtures/ruby/tags/simple_method.rb") `shouldReturn`
[ Tag "foo" P.METHOD P.DEFINITION (Loc (Range 4 7) (Span (Pos 1 5) (Pos 1 8))) "def foo" Nothing ]
it "produces tags for sends" $
parseTestFile [Call] (Path.relFile "test/fixtures/ruby/tags/simple_method.rb") `shouldReturn`
[ Tag "puts" Call (Loc (Range 10 14) (Span (Pos 2 3) (Pos 2 7))) "puts \"hi\"" Nothing
, Tag "bar" Call (Loc (Range 24 27) (Span (Pos 3 5) (Pos 3 8))) "a.bar" Nothing
, Tag "a" Call (Loc (Range 22 23) (Span (Pos 3 3) (Pos 3 4))) "a" Nothing
parseTestFile [P.CALL] (Path.relFile "test/fixtures/ruby/tags/simple_method.rb") `shouldReturn`
[ Tag "puts" P.CALL P.REFERENCE (Loc (Range 10 14) (Span (Pos 2 3) (Pos 2 7))) "puts \"hi\"" Nothing
, Tag "bar" P.CALL P.REFERENCE (Loc (Range 24 27) (Span (Pos 3 5) (Pos 3 8))) "a.bar" Nothing
, Tag "a" P.CALL P.REFERENCE (Loc (Range 22 23) (Span (Pos 3 3) (Pos 3 4))) "a" Nothing
]
it "produces tags for methods with docs (TODO)" $
parseTestFile [Method] (Path.relFile "test/fixtures/ruby/tags/simple_method_with_docs.rb") `shouldReturn`
[ Tag "foo" Method (Loc (Range 18 21) (Span (Pos 2 5) (Pos 2 8))) "def foo" Nothing ]
parseTestFile [] (Path.relFile "test/fixtures/ruby/tags/simple_method_with_docs.rb") `shouldReturn`
[ Tag "foo" P.METHOD P.DEFINITION (Loc (Range 18 21) (Span (Pos 2 5) (Pos 2 8))) "def foo" Nothing ]
it "correctly tags files containing multibyte UTF-8 characters (TODO)" $
parseTestFile [Method] (Path.relFile "test/fixtures/ruby/tags/unicode_identifiers.rb") `shouldReturn`
[ Tag "日本語" Method (Loc (Range 20 29) (Span (Pos 2 5) (Pos 2 14))) "def 日本語" Nothing]
parseTestFile [] (Path.relFile "test/fixtures/ruby/tags/unicode_identifiers.rb") `shouldReturn`
[ Tag "日本語" P.METHOD P.DEFINITION (Loc (Range 20 29) (Span (Pos 2 5) (Pos 2 14))) "def 日本語" Nothing]
it "produces tags for methods and classes with docs (TODO)" $
parseTestFile [Class, Method, Tags.Module] (Path.relFile "test/fixtures/ruby/tags/class_module.rb") `shouldReturn`
[ Tag "Foo" Tags.Module (Loc (Range 21 24) (Span (Pos 2 8) (Pos 2 11))) "module Foo" Nothing
, Tag "Bar" Class (Loc (Range 50 53) (Span (Pos 5 9) (Pos 5 12))) "class Bar" Nothing
, Tag "baz" Method (Loc (Range 81 84) (Span (Pos 8 9) (Pos 8 12))) "def baz(a)" Nothing
, Tag "C" Class (Loc (Range 132 133) (Span (Pos 14 13) (Pos 14 14))) "class A::B::C" Nothing
, Tag "foo" Method (Loc (Range 140 143) (Span (Pos 15 7) (Pos 15 10))) "def foo" Nothing
, Tag "foo" Method (Loc (Range 175 178) (Span (Pos 18 12) (Pos 18 15))) "def self.foo" Nothing
parseTestFile [P.MODULE, P.CLASS, P.METHOD] (Path.relFile "test/fixtures/ruby/tags/class_module.rb") `shouldReturn`
[ Tag "Foo" P.MODULE P.DEFINITION (Loc (Range 21 24) (Span (Pos 2 8) (Pos 2 11))) "module Foo" Nothing
, Tag "Bar" P.CLASS P.DEFINITION (Loc (Range 50 53) (Span (Pos 5 9) (Pos 5 12))) "class Bar" Nothing
, Tag "baz" P.METHOD P.DEFINITION (Loc (Range 81 84) (Span (Pos 8 9) (Pos 8 12))) "def baz(a)" Nothing
, Tag "C" P.CLASS P.DEFINITION (Loc (Range 132 133) (Span (Pos 14 13) (Pos 14 14))) "class A::B::C" Nothing
, Tag "foo" P.METHOD P.DEFINITION (Loc (Range 140 143) (Span (Pos 15 7) (Pos 15 10))) "def foo" Nothing
, Tag "foo" P.METHOD P.DEFINITION (Loc (Range 175 178) (Span (Pos 18 12) (Pos 18 15))) "def self.foo" Nothing
]
parseTestFile :: Foldable t => t Tags.Kind -> Path.RelFile -> IO [Tag]
parseTestFile include path = runTaskOrDie $ readBlob (File.fromPath path) >>= runReader defaultLanguageModes . fmap (filter ((`elem` include) . kind)) . tagsForBlob
parseTestFile :: Foldable t => t P.SyntaxType -> Path.RelFile -> IO [Tag]
parseTestFile include path = runTaskOrDie $ readBlob (File.fromPath path) >>= fmap (filter only) . tagsForBlob
where only t = null include || (`elem` include) (tagSyntaxType t)

View File

@ -1 +1 @@
{"files":[{"path":"test/fixtures/ruby/corpus/method-declaration.A.rb","language":"Ruby","symbols":[{"symbol":"foo","kind":"Method","line":"def foo","span":{"start":{"line":1,"column":5},"end":{"line":1,"column":8}},"nodeType":"DEFINITION"}]}]}
{"files":[{"path":"test/fixtures/ruby/corpus/method-declaration.A.rb","language":"Ruby","symbols":[{"symbol":"foo","kind":"Method","line":"def foo","span":{"start":{"line":1,"column":5},"end":{"line":1,"column":8}},"nodeType":"DEFINITION","syntaxType":"METHOD"}]}]}

View File

@ -1,5 +1,5 @@
a
1test/fixtures/ruby/corpus/method-declaration.A.rbRuby&
c
1test/fixtures/ruby/corpus/method-declaration.A.rbRuby(
fooMethoddef foo"
0
08