mirror of
https://github.com/github/semantic.git
synced 2024-11-29 02:44:36 +03:00
Merge branch 'master' into better-error-reporting-for-repetitions
This commit is contained in:
commit
7fcd50b512
@ -58,11 +58,8 @@ deriving instance Show ParseArguments
|
||||
sExpressionParseTree :: ParseMode -> FilePath -> [FilePath] -> ParseArguments
|
||||
sExpressionParseTree = ParseArguments (SExpressionParseTreeRenderer TreeOnly)
|
||||
|
||||
jsonParseTree :: Bool -> ParseMode -> FilePath -> [FilePath] -> ParseArguments
|
||||
jsonParseTree = ParseArguments . JSONParseTreeRenderer
|
||||
|
||||
jsonIndexParseTree :: Bool -> ParseMode -> FilePath -> [FilePath] -> ParseArguments
|
||||
jsonIndexParseTree = ParseArguments . JSONIndexParseTreeRenderer
|
||||
jsonParseTree :: ParseMode -> FilePath -> [FilePath] -> ParseArguments
|
||||
jsonParseTree = ParseArguments JSONParseTreeRenderer
|
||||
|
||||
data ProgramMode = Parse ParseArguments | Diff DiffArguments
|
||||
deriving Show
|
||||
|
@ -1,8 +1,6 @@
|
||||
{-# LANGUAGE DataKinds, GADTs, KindSignatures, MultiParamTypeClasses, TypeOperators #-}
|
||||
module Data.Record where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Aeson.Types
|
||||
import Data.Functor.Listable
|
||||
import GHC.Show
|
||||
import Prologue
|
||||
@ -57,22 +55,6 @@ instance (Show h, Show (Record t)) => Show (Record (h ': t)) where
|
||||
instance Show (Record '[]) where
|
||||
showsPrec n Nil = showParen (n > 0) ("Nil" <>)
|
||||
|
||||
instance (ToJSON h, ToJSONList (Record t)) => ToJSON (Record (h ': t)) where
|
||||
toJSON r = toJSONList (toJSONValues r)
|
||||
|
||||
instance ToJSON (Record '[]) where
|
||||
toJSON _ = emptyArray
|
||||
|
||||
class ToJSONList t where
|
||||
toJSONValues :: t -> [Value]
|
||||
|
||||
instance (ToJSON h, ToJSONList (Record t)) => ToJSONList (Record (h ': t)) where
|
||||
toJSONValues (h :. t) = toJSON h : toJSONValues t
|
||||
|
||||
instance ToJSONList (Record '[]) where
|
||||
toJSONValues _ = []
|
||||
|
||||
|
||||
instance (Eq h, Eq (Record t)) => Eq (Record (h ': t)) where
|
||||
(h1 :. t1) == (h2 :. t2) = h1 == h2 && t1 == t2
|
||||
|
||||
|
@ -10,14 +10,15 @@ module Renderer
|
||||
, File(..)
|
||||
) where
|
||||
|
||||
import Data.Aeson (ToJSON, Value)
|
||||
import Data.Aeson (Value, (.=))
|
||||
import Data.Functor.Both
|
||||
import Data.Functor.Classes
|
||||
import Text.Show
|
||||
import Data.Map as Map hiding (null)
|
||||
import Data.Record
|
||||
import Diff
|
||||
import Info
|
||||
import Info hiding (Identifier)
|
||||
import Language.Ruby.Syntax (decoratorWithAlgebra, fToR)
|
||||
import Prologue
|
||||
import Renderer.JSON as R
|
||||
import Renderer.Patch as R
|
||||
@ -25,7 +26,7 @@ import Renderer.SExpression as R
|
||||
import Renderer.Split as R
|
||||
import Renderer.Summary as R
|
||||
import Renderer.TOC as R
|
||||
import Source (SourceBlob)
|
||||
import Source (SourceBlob(..))
|
||||
import Syntax
|
||||
import Term
|
||||
|
||||
@ -33,7 +34,7 @@ import Term
|
||||
data DiffRenderer fields output where
|
||||
SplitRenderer :: (HasField fields Category, HasField fields Range) => DiffRenderer fields File
|
||||
PatchRenderer :: HasField fields Range => DiffRenderer fields File
|
||||
JSONDiffRenderer :: (ToJSON (Record fields), HasField fields Category, HasField fields Range) => DiffRenderer fields (Map Text Value)
|
||||
JSONDiffRenderer :: (ToJSONFields (Record fields), HasField fields Range) => DiffRenderer fields (Map Text Value)
|
||||
SummaryRenderer :: HasDefaultFields fields => DiffRenderer fields Summaries
|
||||
SExpressionDiffRenderer :: (HasField fields Category, HasField fields SourceSpan) => SExpressionFormat -> DiffRenderer fields ByteString
|
||||
ToCRenderer :: HasDefaultFields fields => DiffRenderer fields Summaries
|
||||
@ -53,14 +54,21 @@ runDiffRenderer = foldMap . uncurry . resolveDiffRenderer
|
||||
|
||||
data ParseTreeRenderer fields output where
|
||||
SExpressionParseTreeRenderer :: (HasField fields Category, HasField fields SourceSpan) => SExpressionFormat -> ParseTreeRenderer fields ByteString
|
||||
JSONParseTreeRenderer :: HasDefaultFields fields => Bool -> ParseTreeRenderer fields Value
|
||||
JSONIndexParseTreeRenderer :: HasDefaultFields fields => Bool -> ParseTreeRenderer fields Value
|
||||
JSONParseTreeRenderer :: (ToJSONFields (Record fields), HasField fields Range) => ParseTreeRenderer fields Value
|
||||
|
||||
resolveParseTreeRenderer :: (Monoid output, StringConv output ByteString) => ParseTreeRenderer fields output -> SourceBlob -> Term (Syntax Text) (Record fields) -> output
|
||||
resolveParseTreeRenderer renderer blob = case renderer of
|
||||
SExpressionParseTreeRenderer format -> R.sExpressionParseTree format blob
|
||||
JSONParseTreeRenderer -> R.jsonFile blob . decoratorWithAlgebra (fToR identifierAlg)
|
||||
where identifierAlg = fmap Identifier . maybeIdentifier . fmap (fmap unIdentifier)
|
||||
|
||||
|
||||
newtype Identifier = Identifier { unIdentifier :: Text }
|
||||
deriving (Eq, Show)
|
||||
|
||||
instance ToJSONFields Identifier where
|
||||
toJSONFields (Identifier i) = ["identifier" .= i]
|
||||
|
||||
resolveParseTreeRenderer :: (Monoid output, StringConv output ByteString) => ParseTreeRenderer fields output -> (SourceBlob -> Term (Syntax Text) (Record fields) -> output)
|
||||
resolveParseTreeRenderer renderer = case renderer of
|
||||
SExpressionParseTreeRenderer format -> R.sExpressionParseTree format
|
||||
JSONParseTreeRenderer debug -> R.jsonParseTree debug
|
||||
JSONIndexParseTreeRenderer debug -> R.jsonIndexParseTree debug
|
||||
|
||||
runParseTreeRenderer :: (Monoid output, StringConv output ByteString) => ParseTreeRenderer fields output -> [(SourceBlob, Term (Syntax Text) (Record fields))] -> output
|
||||
runParseTreeRenderer = foldMap . uncurry . resolveParseTreeRenderer
|
||||
@ -82,8 +90,7 @@ instance Show (DiffRenderer fields output) where
|
||||
|
||||
instance Show (ParseTreeRenderer fields output) where
|
||||
showsPrec d (SExpressionParseTreeRenderer format) = showsUnaryWith showsPrec "SExpressionParseTreeRenderer" d format
|
||||
showsPrec d (JSONParseTreeRenderer debug) = showsUnaryWith showsPrec "JSONParseTreeRenderer" d debug
|
||||
showsPrec d (JSONIndexParseTreeRenderer debug) = showsUnaryWith showsPrec "JSONIndexParseTreeRenderer" d debug
|
||||
showsPrec _ JSONParseTreeRenderer = showString "JSONParseTreeRenderer"
|
||||
|
||||
instance Monoid File where
|
||||
mempty = File mempty
|
||||
|
@ -1,20 +1,18 @@
|
||||
{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE DataKinds, GADTs, GeneralizedNewtypeDeriving, ScopedTypeVariables, TypeFamilies, TypeOperators #-}
|
||||
{-# LANGUAGE DataKinds, GADTs, GeneralizedNewtypeDeriving, ScopedTypeVariables, TypeFamilies, TypeOperators, UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||
module Renderer.JSON
|
||||
( json
|
||||
, jsonParseTree
|
||||
, jsonIndexParseTree
|
||||
, ParseTreeFile(..)
|
||||
, jsonFile
|
||||
, ToJSONFields(..)
|
||||
) where
|
||||
|
||||
import Alignment
|
||||
import Data.Aeson (ToJSON, toJSON, encode, object, (.=))
|
||||
import Data.Aeson as A hiding (json)
|
||||
import Data.Aeson.Types (Pair, emptyArray)
|
||||
import Data.Aeson.Types (emptyArray)
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import Data.Functor.Foldable hiding (Nil)
|
||||
import Data.Record
|
||||
import Data.These
|
||||
import Data.Vector as Vector hiding (toList)
|
||||
@ -22,18 +20,16 @@ import Diff
|
||||
import Info
|
||||
import Prologue
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Text as T
|
||||
import Source
|
||||
import SplitDiff
|
||||
import Syntax as S
|
||||
import Term
|
||||
|
||||
--
|
||||
-- Diffs
|
||||
--
|
||||
|
||||
-- | Render a diff to a string representing its JSON.
|
||||
json :: (ToJSON (Record fields), HasField fields Category, HasField fields Range) => Both SourceBlob -> Diff (Syntax Text) (Record fields) -> Map Text Value
|
||||
json :: (ToJSONFields (Record fields), HasField fields Range) => Both SourceBlob -> Diff (Syntax Text) (Record fields) -> Map Text Value
|
||||
json blobs diff = Map.fromList [
|
||||
("rows", toJSON (annotateRows (alignDiff (source <$> blobs) diff))),
|
||||
("oids", toJSON (oid <$> blobs)),
|
||||
@ -47,17 +43,9 @@ newtype NumberedLine a = NumberedLine (Int, a)
|
||||
instance StringConv (Map Text Value) ByteString where
|
||||
strConv _ = toS . (<> "\n") . encode
|
||||
|
||||
instance (ToJSON leaf, ToJSON (Record fields), HasField fields Category, HasField fields Range) => ToJSON (NumberedLine (SplitSyntaxDiff leaf fields)) where
|
||||
toJSON (NumberedLine (n, a)) = object (lineFields n a (getRange a))
|
||||
toEncoding (NumberedLine (n, a)) = pairs $ mconcat (lineFields n a (getRange a))
|
||||
|
||||
instance ToJSON Category where
|
||||
toJSON (Other s) = String s
|
||||
toJSON s = String (toS s)
|
||||
|
||||
instance ToJSON Range where
|
||||
toJSON (Range start end) = A.Array . Vector.fromList $ toJSON <$> [ start, end ]
|
||||
toEncoding (Range start end) = foldable [ start, end ]
|
||||
instance ToJSONFields a => ToJSON (NumberedLine a) where
|
||||
toJSON (NumberedLine (n, a)) = object $ "number" .= n : toJSONFields a
|
||||
toEncoding (NumberedLine (n, a)) = pairs $ "number" .= n <> mconcat (toJSONFields a)
|
||||
|
||||
instance ToJSON a => ToJSON (Join These a) where
|
||||
toJSON (Join vs) = A.Array . Vector.fromList $ toJSON <$> these pure pure (\ a b -> [ a, b ]) vs
|
||||
@ -66,124 +54,130 @@ instance ToJSON a => ToJSON (Join These a) where
|
||||
instance ToJSON a => ToJSON (Join (,) a) where
|
||||
toJSON (Join (a, b)) = A.Array . Vector.fromList $ toJSON <$> [ a, b ]
|
||||
|
||||
instance (ToJSON leaf, ToJSON (Record fields), HasField fields Category, HasField fields Range) => ToJSON (SplitSyntaxDiff leaf fields) where
|
||||
instance (ToJSONFields a, ToJSONFields (f (Free f a))) => ToJSON (Free f a) where
|
||||
toJSON splitDiff = case runFree splitDiff of
|
||||
(Free (info :< syntax)) -> object (termFields info syntax)
|
||||
(Pure patch) -> object (patchFields patch)
|
||||
(Free f) -> object (toJSONFields f)
|
||||
(Pure p) -> object (toJSONFields p)
|
||||
toEncoding splitDiff = case runFree splitDiff of
|
||||
(Free (info :< syntax)) -> pairs $ mconcat (termFields info syntax)
|
||||
(Pure patch) -> pairs $ mconcat (patchFields patch)
|
||||
(Free f) -> pairs $ mconcat (toJSONFields f)
|
||||
(Pure p) -> pairs $ mconcat (toJSONFields p)
|
||||
|
||||
instance (ToJSON (Record fields), ToJSON leaf, HasField fields Category, HasField fields Range) => ToJSON (SyntaxTerm leaf fields) where
|
||||
toJSON term |
|
||||
(info :< syntax) <- runCofree term = object (termFields info syntax)
|
||||
toEncoding term |
|
||||
(info :< syntax) <- runCofree term = pairs $ mconcat (termFields info syntax)
|
||||
instance ToJSONFields (CofreeF f a (Cofree f a)) => ToJSON (Cofree f a) where
|
||||
toJSON = object . toJSONFields . runCofree
|
||||
toEncoding = pairs . mconcat . toJSONFields . runCofree
|
||||
|
||||
lineFields :: (ToJSON leaf, ToJSON (Record fields), HasField fields Category, HasField fields Range, KeyValue kv) =>
|
||||
Int ->
|
||||
SplitSyntaxDiff leaf fields ->
|
||||
Range ->
|
||||
[kv]
|
||||
lineFields n term range = [ "number" .= n
|
||||
, "terms" .= [ term ]
|
||||
, "range" .= range
|
||||
, "hasChanges" .= hasChanges term
|
||||
]
|
||||
class ToJSONFields a where
|
||||
toJSONFields :: KeyValue kv => a -> [kv]
|
||||
|
||||
termFields :: (ToJSON recur, KeyValue kv, HasField fields Category, HasField fields Range) =>
|
||||
Record fields ->
|
||||
Syntax leaf recur ->
|
||||
[kv]
|
||||
termFields info syntax = "range" .= byteRange info : "category" .= Info.category info : syntaxToTermField syntax
|
||||
instance (ToJSONFields h, ToJSONFields (Record t)) => ToJSONFields (Record (h ': t)) where
|
||||
toJSONFields (h :. t) = toJSONFields h <> toJSONFields t
|
||||
|
||||
patchFields :: (ToJSON (Record fields), ToJSON leaf, KeyValue kv, HasField fields Category, HasField fields Range) =>
|
||||
SplitPatch (SyntaxTerm leaf fields) ->
|
||||
[kv]
|
||||
patchFields patch = case patch of
|
||||
SplitInsert term -> fields "insert" term
|
||||
SplitDelete term -> fields "delete" term
|
||||
SplitReplace term -> fields "replace" term
|
||||
where
|
||||
fields kind term |
|
||||
(info :< syntax) <- runCofree term = "patch" .= T.pack kind : termFields info syntax
|
||||
instance ToJSONFields (Record '[]) where
|
||||
toJSONFields _ = []
|
||||
|
||||
syntaxToTermField :: (ToJSON recur, KeyValue kv) =>
|
||||
Syntax leaf recur ->
|
||||
[kv]
|
||||
syntaxToTermField syntax = case syntax of
|
||||
Leaf _ -> []
|
||||
Indexed c -> childrenFields c
|
||||
Fixed c -> childrenFields c
|
||||
S.FunctionCall identifier typeParameters parameters -> [ "identifier" .= identifier ] <> [ "typeArguments" .= typeParameters] <> [ "parameters" .= parameters ]
|
||||
S.Ternary expression cases -> [ "expression" .= expression ] <> [ "cases" .= cases ]
|
||||
S.AnonymousFunction callSignature c -> [ "callSignature" .= callSignature ] <> childrenFields c
|
||||
S.Function identifier callSignature c -> [ "identifier" .= identifier ] <> [ "callSignature" .= callSignature ] <> childrenFields c
|
||||
S.Assignment assignmentId value -> [ "identifier" .= assignmentId ] <> [ "value" .= value ]
|
||||
S.OperatorAssignment identifier value -> [ "identifier" .= identifier ] <> [ "value" .= value ]
|
||||
S.MemberAccess identifier value -> [ "identifier" .= identifier ] <> [ "value" .= value ]
|
||||
S.MethodCall identifier methodIdentifier typeParameters parameters -> [ "identifier" .= identifier ] <> [ "methodIdentifier" .= methodIdentifier ] <> [ "typeParameters" .= typeParameters ] <> [ "parameters" .= parameters ]
|
||||
S.Operator syntaxes -> [ "operatorSyntaxes" .= syntaxes ]
|
||||
S.VarDecl children -> childrenFields children
|
||||
S.VarAssignment identifier value -> [ "identifier" .= identifier ] <> [ "value" .= value ]
|
||||
S.SubscriptAccess identifier property -> [ "identifier" .= identifier ] <> [ "property" .= property ]
|
||||
S.Switch expression cases -> [ "expression" .= expression ] <> [ "cases" .= cases ]
|
||||
S.Case expression statements -> [ "expression" .= expression ] <> [ "statements" .= statements ]
|
||||
S.Object ty keyValuePairs -> [ "type" .= ty ] <> childrenFields keyValuePairs
|
||||
S.Pair a b -> childrenFields [a, b]
|
||||
S.Comment _ -> []
|
||||
S.Commented comments child -> childrenFields (comments <> maybeToList child)
|
||||
S.ParseError c -> childrenFields c
|
||||
S.For expressions body -> [ "expressions" .= expressions ] <> [ "body" .= body ]
|
||||
S.DoWhile expression body -> [ "expression" .= expression ] <> [ "body" .= body ]
|
||||
S.While expression body -> [ "expression" .= expression ] <> [ "body" .= body ]
|
||||
S.Return expression -> [ "expression" .= expression ]
|
||||
S.Throw c -> [ "expression" .= c ]
|
||||
S.Constructor expression -> [ "expression" .= expression ]
|
||||
S.Try body catchExpression elseExpression finallyExpression -> [ "body" .= body ] <> [ "catchExpression" .= catchExpression ] <> [ "elseExpression" .= elseExpression ] <> [ "finallyExpression" .= finallyExpression ]
|
||||
S.Array ty c -> [ "type" .= ty ] <> childrenFields c
|
||||
S.Class identifier superclass definitions -> [ "identifier" .= identifier ] <> [ "superclass" .= superclass ] <> [ "definitions" .= definitions ]
|
||||
S.Method clauses identifier receiver callSignature definitions -> [ "clauses" .= clauses ] <> [ "identifier" .= identifier ] <> [ "receiver" .= receiver ] <> [ "callSignature" .= callSignature ] <> [ "definitions" .= definitions ]
|
||||
S.If expression clauses -> [ "expression" .= expression ] <> childrenFields clauses
|
||||
S.Module identifier definitions -> [ "identifier" .= identifier ] <> [ "definitions" .= definitions ]
|
||||
S.Namespace identifier definitions -> [ "identifier" .= identifier ] <> [ "definitions" .= definitions ]
|
||||
S.Interface identifier clauses definitions -> [ "identifier" .= identifier ] <> [ "clauses" .= clauses ] <> [ "definitions" .= definitions ]
|
||||
S.Import identifier statements -> [ "identifier" .= identifier ] <> [ "statements" .= statements ]
|
||||
S.Export identifier statements -> [ "identifier" .= identifier ] <> [ "statements" .= statements ]
|
||||
S.Yield expr -> [ "yieldExpression" .= expr ]
|
||||
S.Negate expr -> [ "negate" .= expr ]
|
||||
S.Rescue args expressions -> [ "args" .= args ] <> childrenFields expressions
|
||||
S.Select cases -> childrenFields cases
|
||||
S.Go cases -> childrenFields cases
|
||||
S.Defer cases -> childrenFields cases
|
||||
S.TypeAssertion a b -> childrenFields [a, b]
|
||||
S.TypeConversion a b -> childrenFields [a, b]
|
||||
S.Struct ty fields -> [ "type" .= ty ] <> childrenFields fields
|
||||
S.Break expr -> [ "expression" .= expr ]
|
||||
S.Continue expr -> [ "expression" .= expr ]
|
||||
S.BlockStatement c -> childrenFields c
|
||||
S.ParameterDecl ty field -> [ "type" .= ty ] <> [ "identifier" .= field ]
|
||||
S.DefaultCase c -> childrenFields c
|
||||
S.TypeDecl id ty -> [ "type" .= ty ] <> [ "identifier" .= id ]
|
||||
S.FieldDecl children -> childrenFields children
|
||||
S.Ty ty -> [ "type" .= ty ]
|
||||
S.Send channel expr -> [ "channel" .= channel ] <> [ "expression" .= expr ]
|
||||
where childrenFields c = [ "children" .= c ]
|
||||
instance ToJSONFields Range where
|
||||
toJSONFields Range{..} = ["range" .= [ start, end ]]
|
||||
|
||||
instance ToJSONFields Category where
|
||||
toJSONFields c = ["category" .= case c of { Other s -> s ; _ -> toS c }]
|
||||
|
||||
instance ToJSONFields SourceSpan where
|
||||
toJSONFields sourceSpan = [ "sourceSpan" .= sourceSpan ]
|
||||
|
||||
instance ToJSONFields SourceText where
|
||||
toJSONFields (SourceText t) = [ "sourceText" .= t ]
|
||||
|
||||
instance ToJSONFields a => ToJSONFields (Maybe a) where
|
||||
toJSONFields = maybe [] toJSONFields
|
||||
|
||||
instance (ToJSONFields a, ToJSONFields (f (Cofree f a))) => ToJSONFields (Cofree f a) where
|
||||
toJSONFields = toJSONFields . runCofree
|
||||
|
||||
instance (ToJSONFields a, ToJSONFields (f b)) => ToJSONFields (CofreeF f a b) where
|
||||
toJSONFields (a :< f) = toJSONFields a <> toJSONFields f
|
||||
|
||||
instance (ToJSONFields a, ToJSONFields (f (Free f a))) => ToJSONFields (Free f a) where
|
||||
toJSONFields = toJSONFields . runFree
|
||||
|
||||
instance (ToJSONFields a, ToJSONFields (f b)) => ToJSONFields (FreeF f a b) where
|
||||
toJSONFields (Free f) = toJSONFields f
|
||||
toJSONFields (Pure a) = toJSONFields a
|
||||
|
||||
instance ToJSON a => ToJSONFields (SplitPatch a) where
|
||||
toJSONFields (SplitInsert a) = [ "insert" .= a ]
|
||||
toJSONFields (SplitDelete a) = [ "delete" .= a ]
|
||||
toJSONFields (SplitReplace a) = [ "replace" .= a ]
|
||||
|
||||
instance ToJSON recur => ToJSONFields (Syntax leaf recur) where
|
||||
toJSONFields syntax = case syntax of
|
||||
Leaf _ -> []
|
||||
Indexed c -> childrenFields c
|
||||
Fixed c -> childrenFields c
|
||||
S.FunctionCall identifier typeParameters parameters -> [ "identifier" .= identifier, "typeArguments" .= typeParameters, "parameters" .= parameters ]
|
||||
S.Ternary expression cases -> [ "expression" .= expression, "cases" .= cases ]
|
||||
S.AnonymousFunction callSignature c -> "callSignature" .= callSignature : childrenFields c
|
||||
S.Function identifier callSignature c -> "identifier" .= identifier : "callSignature" .= callSignature : childrenFields c
|
||||
S.Assignment assignmentId value -> [ "identifier" .= assignmentId, "value" .= value ]
|
||||
S.OperatorAssignment identifier value -> [ "identifier" .= identifier, "value" .= value ]
|
||||
S.MemberAccess identifier value -> [ "identifier" .= identifier, "value" .= value ]
|
||||
S.MethodCall identifier methodIdentifier typeParameters parameters -> [ "identifier" .= identifier, "methodIdentifier" .= methodIdentifier, "typeParameters" .= typeParameters, "parameters" .= parameters ]
|
||||
S.Operator syntaxes -> [ "operatorSyntaxes" .= syntaxes ]
|
||||
S.VarDecl children -> childrenFields children
|
||||
S.VarAssignment identifier value -> [ "identifier" .= identifier, "value" .= value ]
|
||||
S.SubscriptAccess identifier property -> [ "identifier" .= identifier, "property" .= property ]
|
||||
S.Switch expression cases -> [ "expression" .= expression, "cases" .= cases ]
|
||||
S.Case expression statements -> [ "expression" .= expression, "statements" .= statements ]
|
||||
S.Object ty keyValuePairs -> "type" .= ty : childrenFields keyValuePairs
|
||||
S.Pair a b -> childrenFields [a, b]
|
||||
S.Comment _ -> []
|
||||
S.Commented comments child -> childrenFields (comments <> maybeToList child)
|
||||
S.ParseError c -> childrenFields c
|
||||
S.For expressions body -> [ "expressions" .= expressions, "body" .= body ]
|
||||
S.DoWhile expression body -> [ "expression" .= expression, "body" .= body ]
|
||||
S.While expression body -> [ "expression" .= expression, "body" .= body ]
|
||||
S.Return expression -> [ "expression" .= expression ]
|
||||
S.Throw c -> [ "expression" .= c ]
|
||||
S.Constructor expression -> [ "expression" .= expression ]
|
||||
S.Try body catchExpression elseExpression finallyExpression -> [ "body" .= body, "catchExpression" .= catchExpression, "elseExpression" .= elseExpression, "finallyExpression" .= finallyExpression ]
|
||||
S.Array ty c -> "type" .= ty : childrenFields c
|
||||
S.Class identifier superclass definitions -> [ "identifier" .= identifier, "superclass" .= superclass, "definitions" .= definitions ]
|
||||
S.Method clauses identifier receiver callSignature definitions -> [ "clauses" .= clauses, "identifier" .= identifier, "receiver" .= receiver, "callSignature" .= callSignature, "definitions" .= definitions ]
|
||||
S.If expression clauses -> "expression" .= expression : childrenFields clauses
|
||||
S.Module identifier definitions -> [ "identifier" .= identifier, "definitions" .= definitions ]
|
||||
S.Namespace identifier definitions -> [ "identifier" .= identifier, "definitions" .= definitions ]
|
||||
S.Interface identifier clauses definitions -> [ "identifier" .= identifier, "clauses" .= clauses, "definitions" .= definitions ]
|
||||
S.Import identifier statements -> [ "identifier" .= identifier, "statements" .= statements ]
|
||||
S.Export identifier statements -> [ "identifier" .= identifier, "statements" .= statements ]
|
||||
S.Yield expr -> [ "yieldExpression" .= expr ]
|
||||
S.Negate expr -> [ "negate" .= expr ]
|
||||
S.Rescue args expressions -> "args" .= args : childrenFields expressions
|
||||
S.Select cases -> childrenFields cases
|
||||
S.Go cases -> childrenFields cases
|
||||
S.Defer cases -> childrenFields cases
|
||||
S.TypeAssertion a b -> childrenFields [a, b]
|
||||
S.TypeConversion a b -> childrenFields [a, b]
|
||||
S.Struct ty fields -> "type" .= ty : childrenFields fields
|
||||
S.Break expr -> [ "expression" .= expr ]
|
||||
S.Continue expr -> [ "expression" .= expr ]
|
||||
S.BlockStatement c -> childrenFields c
|
||||
S.ParameterDecl ty field -> [ "type" .= ty, "identifier" .= field ]
|
||||
S.DefaultCase c -> childrenFields c
|
||||
S.TypeDecl id ty -> [ "type" .= ty, "identifier" .= id ]
|
||||
S.FieldDecl children -> childrenFields children
|
||||
S.Ty ty -> [ "type" .= ty ]
|
||||
S.Send channel expr -> [ "channel" .= channel, "expression" .= expr ]
|
||||
where childrenFields c = [ "children" .= c ]
|
||||
|
||||
|
||||
--
|
||||
-- Parse Trees
|
||||
--
|
||||
|
||||
data ParseTreeFile = ParseTreeFile { parseTreeFilePath :: FilePath, node :: Rose ParseNode } deriving (Show)
|
||||
data File a = File { filePath :: FilePath, fileContent :: a }
|
||||
deriving (Generic, Show)
|
||||
|
||||
data Rose a = Rose a [Rose a]
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
instance ToJSON ParseTreeFile where
|
||||
toJSON ParseTreeFile{..} = object [ "filePath" .= parseTreeFilePath, "programNode" .= cata algebra node ]
|
||||
where algebra (RoseF a as) = object $ parseNodeToJSONFields a <> [ "children" .= as ]
|
||||
instance ToJSON a => ToJSON (File a) where
|
||||
toJSON File{..} = object [ "filePath" .= filePath, "programNode" .= fileContent ]
|
||||
|
||||
instance Monoid Value where
|
||||
mempty = emptyArray
|
||||
@ -192,74 +186,5 @@ instance Monoid Value where
|
||||
instance StringConv Value ByteString where
|
||||
strConv _ = toS . (<> "\n") . encode
|
||||
|
||||
data IndexFile = IndexFile { indexFilePath :: FilePath, nodes :: [ParseNode] } deriving (Show)
|
||||
|
||||
instance ToJSON IndexFile where
|
||||
toJSON IndexFile{..} = object [ "filePath" .= indexFilePath, "programNodes" .= foldMap (singleton . object . parseNodeToJSONFields) nodes ]
|
||||
where singleton a = [a]
|
||||
|
||||
data ParseNode = ParseNode
|
||||
{ category :: Category
|
||||
, sourceRange :: Range
|
||||
, sourceText :: Maybe SourceText
|
||||
, sourceSpan :: SourceSpan
|
||||
, identifier :: Maybe Text
|
||||
}
|
||||
deriving (Show)
|
||||
|
||||
-- | Produce a list of JSON 'Pair's for the fields in a given ParseNode.
|
||||
parseNodeToJSONFields :: ParseNode -> [Pair]
|
||||
parseNodeToJSONFields ParseNode{..} =
|
||||
[ "category" .= (toS category :: Text), "sourceRange" .= sourceRange, "sourceSpan" .= sourceSpan ]
|
||||
<> [ "sourceText" .= sourceText | isJust sourceText ]
|
||||
<> [ "identifier" .= identifier | isJust identifier ]
|
||||
|
||||
jsonParseTree :: HasDefaultFields fields => Bool -> SourceBlob -> Term (Syntax Text) (Record fields) -> Value
|
||||
jsonParseTree = jsonParseTree' ParseTreeFile Rose
|
||||
|
||||
jsonIndexParseTree :: HasDefaultFields fields => Bool -> SourceBlob -> Term (Syntax Text) (Record fields) -> Value
|
||||
jsonIndexParseTree = jsonParseTree' IndexFile combine
|
||||
where combine node siblings = node : Prologue.concat siblings
|
||||
|
||||
jsonParseTree' :: (ToJSON root, HasDefaultFields fields) => (FilePath -> a -> root) -> (ParseNode -> [a] -> a) -> Bool -> SourceBlob -> Term (Syntax Text) (Record fields) -> Value
|
||||
jsonParseTree' constructor combine debug SourceBlob{..} term = toJSON $ constructor path (para algebra term')
|
||||
where
|
||||
term' = decorateTerm (parseDecorator debug source) term
|
||||
algebra (annotation :< syntax) = combine (makeNode annotation (Prologue.fst <$> syntax)) (toList (Prologue.snd <$> syntax))
|
||||
|
||||
makeNode :: HasDefaultFields fields => Record (Maybe SourceText ': fields) -> Syntax Text (Term (Syntax Text) (Record (Maybe SourceText ': fields))) -> ParseNode
|
||||
makeNode (sourceText :. record) syntax = ParseNode (getField record) (getField record) sourceText (getField record) (identifierFor syntax)
|
||||
|
||||
-- | Determines the term decorator to use when parsing.
|
||||
parseDecorator :: (Functor f, HasField fields Range) => Bool -> (Source -> TermDecorator f fields (Maybe SourceText))
|
||||
parseDecorator True = termSourceTextDecorator
|
||||
parseDecorator False = const . const Nothing
|
||||
|
||||
-- | Returns a Just identifier text if the given Syntax term contains an identifier (leaf) syntax. Otherwise returns Nothing.
|
||||
identifierFor :: (HasField fields (Maybe SourceText), HasField fields Category, StringConv leaf Text) => Syntax leaf (Term (Syntax leaf) (Record fields)) -> Maybe Text
|
||||
identifierFor = fmap toS . extractLeafValue . unwrap <=< maybeIdentifier
|
||||
|
||||
-- | Decorate a 'Term' using a function to compute the annotation values at every node.
|
||||
decorateTerm :: (Functor f, HasDefaultFields fields) => TermDecorator f fields field -> Term f (Record fields) -> Term f (Record (field ': fields))
|
||||
decorateTerm decorator = cata $ \ term -> cofree ((decorator term :. headF term) :< tailF term)
|
||||
|
||||
-- | Term decorator extracting the source text for a term.
|
||||
termSourceTextDecorator :: (Functor f, HasField fields Range) => Source -> TermDecorator f fields (Maybe SourceText)
|
||||
termSourceTextDecorator source (ann :< _) = Just (SourceText (toText (Source.slice (byteRange ann) source)))
|
||||
|
||||
-- | A function computing a value to decorate terms with. This can be used to cache synthesized attributes on terms.
|
||||
type TermDecorator f fields field = TermF f (Record fields) (Term f (Record (field ': fields))) -> field
|
||||
|
||||
newtype Identifier = Identifier Text
|
||||
deriving (Eq, Show, ToJSON)
|
||||
|
||||
data RoseF a b = RoseF a [b]
|
||||
deriving (Eq, Functor, Show)
|
||||
|
||||
type instance Base (Rose a) = RoseF a
|
||||
|
||||
instance Recursive (Rose a) where
|
||||
project (Rose a tree) = RoseF a tree
|
||||
|
||||
instance Corecursive (Rose a) where
|
||||
embed (RoseF a tree) = Rose a tree
|
||||
jsonFile :: ToJSON a => SourceBlob -> a -> Value
|
||||
jsonFile SourceBlob{..} = toJSON . File path
|
||||
|
@ -92,8 +92,7 @@ arguments gitDir alternates = info (version <*> helper <*> argumentsParser) desc
|
||||
parseCommand = command "parse" (info parseArgumentsParser (progDesc "Print parse trees for a commit or paths"))
|
||||
parseArgumentsParser = Parse
|
||||
<$> ( ( flag sExpressionParseTree sExpressionParseTree (long "sexpression" <> help "Output s-expression parse trees (default)")
|
||||
<|> (flag' jsonParseTree (long "json" <> help "Output JSON parse trees") <*> switch (long "debug"))
|
||||
<|> (flag' jsonIndexParseTree (long "index" <> help "Output JSON parse trees in index format") <*> switch (long "debug")) )
|
||||
<|> flag' jsonParseTree (long "json" <> help "Output JSON parse trees") )
|
||||
<*> ( ParsePaths
|
||||
<$> some (argument str (metavar "FILES..."))
|
||||
<|> ParseCommit
|
||||
|
@ -1,8 +1,6 @@
|
||||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
module Syntax where
|
||||
|
||||
import Data.Record
|
||||
import qualified Info
|
||||
import Data.Aeson
|
||||
import Data.Functor.Classes
|
||||
import Data.Functor.Classes.Eq.Generic
|
||||
@ -119,21 +117,22 @@ extractLeafValue syntax = case syntax of
|
||||
Leaf a -> Just a
|
||||
_ -> Nothing
|
||||
|
||||
maybeIdentifier :: HasField fields Info.Category => Syntax leaf (Cofree (Syntax leaf) (Record fields)) -> Maybe (Cofree (Syntax leaf) (Record fields))
|
||||
maybeIdentifier syntax = case syntax of
|
||||
Assignment f _ -> Just f
|
||||
Class f _ _ -> Just f
|
||||
Export f _ -> f
|
||||
Function f _ _ -> Just f
|
||||
FunctionCall f _ _ -> Just f
|
||||
Import f _ -> Just f
|
||||
Method _ f _ _ _ -> Just f
|
||||
MethodCall _ f _ _ -> Just f
|
||||
Module f _ -> Just f
|
||||
OperatorAssignment f _ -> Just f
|
||||
SubscriptAccess f _ -> Just f
|
||||
TypeDecl f _ -> Just f
|
||||
VarAssignment f _ -> find ((== Info.Identifier) . Info.category . extract) f
|
||||
maybeIdentifier :: CofreeF (Syntax leaf) a (Maybe leaf) -> Maybe leaf
|
||||
maybeIdentifier (_ :< syntax) = case syntax of
|
||||
Leaf f -> Just f
|
||||
Assignment f _ -> f
|
||||
Class f _ _ -> f
|
||||
Export f _ -> join f
|
||||
Function f _ _ -> f
|
||||
FunctionCall f _ _ -> f
|
||||
Import f _ -> f
|
||||
Method _ f _ _ _ -> f
|
||||
MethodCall _ f _ _ -> f
|
||||
Module f _ -> f
|
||||
OperatorAssignment f _ -> f
|
||||
SubscriptAccess f _ -> f
|
||||
TypeDecl f _ -> f
|
||||
VarAssignment f _ -> asum f
|
||||
_ -> Nothing
|
||||
|
||||
-- Instances
|
||||
|
@ -32,19 +32,16 @@ data ParseFixture = ParseFixture
|
||||
|
||||
instance Listable ParseFixture where
|
||||
tiers = cons0 (ParseFixture (sExpressionParseTree pathMode "" []) sExpressionParseTreeOutput)
|
||||
\/ cons0 (ParseFixture (jsonParseTree False pathMode "" []) jsonParseTreeOutput)
|
||||
\/ cons0 (ParseFixture (jsonIndexParseTree False pathMode "" []) jsonIndexParseTreeOutput)
|
||||
\/ cons0 (ParseFixture (jsonParseTree pathMode "" []) jsonParseTreeOutput)
|
||||
\/ cons0 (ParseFixture (sExpressionParseTree commitMode repo []) "(Program\n (Method\n (Identifier)))")
|
||||
\/ cons0 (ParseFixture (jsonParseTree False commitMode repo []) "[{\"filePath\":\"methods.rb\",\"programNode\":{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"category\":\"Identifier\",\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}],\"identifier\":\"foo\",\"sourceRange\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}],\"sourceRange\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}}},[]]\n")
|
||||
\/ cons0 (ParseFixture (jsonIndexParseTree False commitMode repo []) "[{\"programNodes\":[{\"category\":\"Program\",\"sourceRange\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}},{\"category\":\"Method\",\"identifier\":\"foo\",\"sourceRange\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}},{\"category\":\"Identifier\",\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}],\"filePath\":\"methods.rb\"},[]]\n")
|
||||
\/ cons0 (ParseFixture (jsonParseTree commitMode repo []) "[{\"filePath\":\"methods.rb\",\"programNode\":{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"identifier\":{\"category\":\"Identifier\",\"identifier\":\"foo\",\"range\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}},\"clauses\":[],\"receiver\":null,\"range\":[0,11],\"callSignature\":[],\"definitions\":[],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}],\"range\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}}},[]]\n")
|
||||
|
||||
where
|
||||
pathMode = ParsePaths ["test/fixtures/ruby/and-or.A.rb"]
|
||||
commitMode = ParseCommit "2e4144eb8c44f007463ec34cb66353f0041161fe" ["methods.rb"]
|
||||
|
||||
sExpressionParseTreeOutput = "(Program\n (Binary\n (Identifier)\n (Other \"and\")\n (Identifier)))"
|
||||
jsonParseTreeOutput = "[{\"filePath\":\"test/fixtures/ruby/and-or.A.rb\",\"programNode\":{\"category\":\"Program\",\"children\":[{\"category\":\"Binary\",\"children\":[{\"category\":\"Identifier\",\"children\":[],\"sourceRange\":[0,3],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,4]}},{\"category\":\"Other \\\"and\\\"\",\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}},{\"category\":\"Identifier\",\"children\":[],\"sourceRange\":[8,11],\"sourceSpan\":{\"start\":[1,9],\"end\":[1,12]}}],\"sourceRange\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,12]}}],\"sourceRange\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,1]}}},[]]\n"
|
||||
jsonIndexParseTreeOutput = "[{\"programNodes\":[{\"category\":\"Program\",\"sourceRange\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,1]}},{\"category\":\"Binary\",\"sourceRange\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,12]}},{\"category\":\"Identifier\",\"sourceRange\":[0,3],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,4]}},{\"category\":\"Other \\\"and\\\"\",\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}},{\"category\":\"Identifier\",\"sourceRange\":[8,11],\"sourceSpan\":{\"start\":[1,9],\"end\":[1,12]}}],\"filePath\":\"test/fixtures/ruby/and-or.A.rb\"},[]]\n"
|
||||
jsonParseTreeOutput = "[{\"filePath\":\"test/fixtures/ruby/and-or.A.rb\",\"programNode\":{\"category\":\"Program\",\"children\":[{\"operatorSyntaxes\":[{\"category\":\"Identifier\",\"identifier\":\"foo\",\"range\":[0,3],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,4]}},{\"category\":\"and\",\"identifier\":\"and\",\"range\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}},{\"category\":\"Identifier\",\"identifier\":\"bar\",\"range\":[8,11],\"sourceSpan\":{\"start\":[1,9],\"end\":[1,12]}}],\"category\":\"Binary\",\"range\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,12]}}],\"range\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,1]}}},[]]\n"
|
||||
|
||||
|
||||
data DiffFixture = DiffFixture
|
||||
@ -76,8 +73,8 @@ instance Listable DiffFixture where
|
||||
splitOutput' = "<!DOCTYPE HTML>\n<html><head><link rel=\"stylesheet\" href=\"style.css\"></head><body><table class=\"diff\"><colgroup><col width=\"40\"><col><col width=\"40\"><col></colgroup><tr><td class=\"blob-num blob-num-empty empty-cell\"></td><td class=\"blob-code blob-code-empty empty-cell\"></td>\n<td class=\"blob-num blob-num-replacement\">1</td><td class=\"blob-code blob-code-replacement\"><div class=\"patch insert\"><ul class=\"category-program\"><li><ul class=\"category-method\">def <li><span class=\"category-identifier\">foo</span></li>\n</ul></li></ul></div></td>\n\n</tr><tr><td class=\"blob-num blob-num-empty empty-cell\"></td><td class=\"blob-code blob-code-empty empty-cell\"></td>\n<td class=\"blob-num blob-num-replacement\">2</td><td class=\"blob-code blob-code-replacement\"><div class=\"patch insert\"><ul class=\"category-program\"><li><ul class=\"category-method\">end</ul></li>\n</ul></div></td>\n\n</tr><tr><td class=\"blob-num blob-num-empty empty-cell\"></td><td class=\"blob-code blob-code-empty empty-cell\"></td>\n<td class=\"blob-num blob-num-replacement\">3</td><td class=\"blob-code blob-code-replacement\"><div class=\"patch insert\"><ul class=\"category-program\"></ul></div></td>\n\n</tr></table></body></html>\n"
|
||||
summaryOutput = "{\"changes\":{\"test/fixtures/ruby/method-declaration.A.rb -> test/fixtures/ruby/method-declaration.B.rb\":[{\"span\":{\"replace\":[{\"start\":[1,5],\"end\":[1,8]},{\"start\":[1,5],\"end\":[1,8]}]},\"summary\":\"Replaced the 'foo' identifier with the 'bar' identifier in the 'bar(\226\128\166)' method\"},{\"span\":{\"insert\":{\"start\":[1,9],\"end\":[1,10]}},\"summary\":\"Added the 'a' identifier in the 'bar(\226\128\166)' method\"},{\"span\":{\"insert\":{\"start\":[2,3],\"end\":[2,6]}},\"summary\":\"Added the 'baz' identifier in the 'bar(\226\128\166)' method\"}]},\"errors\":{}}\n"
|
||||
summaryOutput' = "{\"changes\":{\"methods.rb\":[{\"span\":{\"insert\":{\"start\":[1,1],\"end\":[2,4]}},\"summary\":\"Added the 'foo()' method\"}]},\"errors\":{}}\n"
|
||||
jsonOutput = "{\"oids\":[\"0000000000000000000000000000000000000000\",\"0000000000000000000000000000000000000000\"],\"paths\":[\"test/fixtures/ruby/method-declaration.A.rb\",\"test/fixtures/ruby/method-declaration.B.rb\"],\"rows\":[[{\"terms\":[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"category\":\"Identifier\",\"patch\":\"replace\",\"range\":[4,7]}],\"range\":[0,8]}],\"range\":[0,8]}],\"hasChanges\":true,\"range\":[0,8],\"number\":1},{\"terms\":[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"category\":\"Identifier\",\"patch\":\"replace\",\"range\":[4,7]},{\"category\":\"Params\",\"children\":[{\"category\":\"Identifier\",\"range\":[8,9]}],\"patch\":\"insert\",\"range\":[7,11]}],\"range\":[0,11]}],\"range\":[0,11]}],\"hasChanges\":true,\"range\":[0,11],\"number\":1}],[{\"terms\":[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"category\":\"Params\",\"children\":[],\"patch\":\"insert\",\"range\":[11,13]},{\"category\":\"Identifier\",\"patch\":\"insert\",\"range\":[13,16]}],\"range\":[11,17]}],\"range\":[11,17]}],\"hasChanges\":true,\"range\":[11,17],\"number\":2}],[{\"terms\":[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[],\"range\":[8,11]}],\"range\":[8,12]}],\"hasChanges\":false,\"range\":[8,12],\"number\":2},{\"terms\":[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[],\"range\":[17,20]}],\"range\":[17,21]}],\"hasChanges\":false,\"range\":[17,21],\"number\":3}],[{\"terms\":[{\"category\":\"Program\",\"children\":[],\"range\":[12,12]}],\"hasChanges\":false,\"range\":[12,12],\"number\":3},{\"terms\":[{\"category\":\"Program\",\"children\":[],\"range\":[21,21]}],\"hasChanges\":false,\"range\":[21,21],\"number\":4}]]}\n"
|
||||
jsonOutput' = "{\"oids\":[\"0000000000000000000000000000000000000000\",\"ff7bbbe9495f61d9e1e58c597502d152bab1761e\"],\"paths\":[\"methods.rb\",\"methods.rb\"],\"rows\":[[{\"terms\":[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"category\":\"Identifier\",\"range\":[4,7]}],\"range\":[0,8]}],\"patch\":\"insert\",\"range\":[0,8]}],\"hasChanges\":true,\"range\":[0,8],\"number\":1}],[{\"terms\":[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[],\"range\":[8,11]}],\"patch\":\"insert\",\"range\":[8,12]}],\"hasChanges\":true,\"range\":[8,12],\"number\":2}],[{\"terms\":[{\"category\":\"Program\",\"children\":[],\"patch\":\"insert\",\"range\":[12,12]}],\"hasChanges\":true,\"range\":[12,12],\"number\":3}]]}\n"
|
||||
jsonOutput = "{\"oids\":[\"0000000000000000000000000000000000000000\",\"0000000000000000000000000000000000000000\"],\"paths\":[\"test/fixtures/ruby/method-declaration.A.rb\",\"test/fixtures/ruby/method-declaration.B.rb\"],\"rows\":[[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"replace\":{\"category\":\"Identifier\",\"range\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}}],\"range\":[0,8],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}],\"range\":[0,8],\"number\":1,\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}},{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"replace\":{\"category\":\"Identifier\",\"range\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}},{\"insert\":{\"category\":\"Params\",\"children\":[{\"category\":\"Identifier\",\"range\":[8,9],\"sourceSpan\":{\"start\":[1,9],\"end\":[1,10]}}],\"range\":[7,11],\"sourceSpan\":{\"start\":[1,8],\"end\":[2,3]}}}],\"range\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,4]}}],\"range\":[0,11],\"number\":1,\"sourceSpan\":{\"start\":[1,1],\"end\":[4,1]}}],[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"insert\":{\"category\":\"Params\",\"children\":[],\"range\":[11,13],\"sourceSpan\":{\"start\":[1,8],\"end\":[2,3]}}},{\"insert\":{\"category\":\"Identifier\",\"range\":[13,16],\"sourceSpan\":{\"start\":[2,3],\"end\":[2,6]}}}],\"range\":[11,17],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,4]}}],\"range\":[11,17],\"number\":2,\"sourceSpan\":{\"start\":[1,1],\"end\":[4,1]}}],[{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[],\"range\":[8,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}],\"range\":[8,12],\"number\":2,\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}},{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[],\"range\":[17,20],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,4]}}],\"range\":[17,21],\"number\":3,\"sourceSpan\":{\"start\":[1,1],\"end\":[4,1]}}],[{\"category\":\"Program\",\"children\":[],\"range\":[12,12],\"number\":3,\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}},{\"category\":\"Program\",\"children\":[],\"range\":[21,21],\"number\":4,\"sourceSpan\":{\"start\":[1,1],\"end\":[4,1]}}]]}\n"
|
||||
jsonOutput' = "{\"oids\":[\"0000000000000000000000000000000000000000\",\"ff7bbbe9495f61d9e1e58c597502d152bab1761e\"],\"paths\":[\"methods.rb\",\"methods.rb\"],\"rows\":[[{\"insert\":{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[{\"category\":\"Identifier\",\"range\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}],\"range\":[0,8],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}],\"range\":[0,8],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}},\"number\":1}],[{\"insert\":{\"category\":\"Program\",\"children\":[{\"category\":\"Method\",\"children\":[],\"range\":[8,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}],\"range\":[8,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}},\"number\":2}],[{\"insert\":{\"category\":\"Program\",\"children\":[],\"range\":[12,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}},\"number\":3}]]}\n"
|
||||
sExpressionOutput = "(Program\n (Method\n { (Identifier)\n ->(Identifier) }\n {+(Params\n (Identifier))+}\n {+(Identifier)+}))"
|
||||
sExpressionOutput' = "{+(Program\n (Method\n (Identifier)))+}"
|
||||
tocOutput = "{\"changes\":{\"test/fixtures/ruby/method-declaration.A.rb -> test/fixtures/ruby/method-declaration.B.rb\":[{\"span\":{\"start\":[1,1],\"end\":[3,4]},\"category\":\"Method\",\"term\":\"bar\",\"changeType\":\"modified\"}]},\"errors\":{}}\n"
|
||||
|
Loading…
Reference in New Issue
Block a user