mirror of
https://github.com/github/semantic.git
synced 2024-11-24 17:04:47 +03:00
Merge branch 'master' of https://github.com/github/semantic-diff into integrate-abstract-interpretation
This commit is contained in:
commit
026cc46dbc
@ -14,7 +14,6 @@ cabal-version: >=1.10
|
||||
library
|
||||
hs-source-dirs: src
|
||||
exposed-modules: Algorithm
|
||||
, Alignment
|
||||
, Abstract.Configuration
|
||||
, Abstract.Environment
|
||||
, Abstract.Eval
|
||||
@ -70,7 +69,6 @@ library
|
||||
, Language.JSON.Assignment
|
||||
, Language.Ruby.Grammar
|
||||
, Language.Ruby.Assignment
|
||||
, Language.TypeScript
|
||||
, Language.TypeScript.Assignment
|
||||
, Language.TypeScript.Grammar
|
||||
, Language.TypeScript.Syntax
|
||||
@ -82,8 +80,8 @@ library
|
||||
, Paths_semantic_diff
|
||||
, Renderer
|
||||
, Renderer.JSON
|
||||
, Renderer.Patch
|
||||
, Renderer.SExpression
|
||||
, Renderer.Tag
|
||||
, Renderer.TOC
|
||||
, RWS
|
||||
, RWS.FeatureVector
|
||||
@ -114,6 +112,7 @@ library
|
||||
, freer-cofreer
|
||||
, ghc-prim
|
||||
, gitrev
|
||||
, Glob
|
||||
, hashable
|
||||
, kdt
|
||||
, mersenne-random-pure64
|
||||
@ -159,8 +158,7 @@ test-suite test
|
||||
type: exitcode-stdio-1.0
|
||||
hs-source-dirs: test
|
||||
main-is: Spec.hs
|
||||
other-modules: AlignmentSpec
|
||||
, CommandSpec
|
||||
other-modules: CommandSpec
|
||||
, Data.Functor.Classes.Ord.Generic.Spec
|
||||
, Data.Functor.Listable
|
||||
, Data.Mergeable.Spec
|
||||
@ -171,7 +169,6 @@ test-suite test
|
||||
, SemanticCmdLineSpec
|
||||
, Semantic.StatSpec
|
||||
, InterpreterSpec
|
||||
, PatchOutputSpec
|
||||
, SES.Spec
|
||||
, SourceSpec
|
||||
, SpecHelpers
|
||||
|
160
src/Alignment.hs
160
src/Alignment.hs
@ -1,160 +0,0 @@
|
||||
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
|
||||
module Alignment
|
||||
( hasChanges
|
||||
, numberedRows
|
||||
, alignDiff
|
||||
, alignBranch
|
||||
, applyThese
|
||||
, modifyJoin
|
||||
) where
|
||||
|
||||
import Data.Bifunctor (bimap, first, second)
|
||||
import Control.Arrow ((***))
|
||||
import Control.Monad (join)
|
||||
import Control.Monad.Free (wrap)
|
||||
import Data.Align
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Diff
|
||||
import Data.Foldable (toList)
|
||||
import Data.Function (on)
|
||||
import Data.Functor.Both
|
||||
import Data.Functor.Foldable (cata)
|
||||
import Data.Functor.Identity
|
||||
import Data.List (partition, sortBy)
|
||||
import Data.Maybe (catMaybes, fromJust, listToMaybe)
|
||||
import Data.Patch
|
||||
import Data.Range
|
||||
import Data.Record
|
||||
import Data.Semigroup ((<>))
|
||||
import Data.Source
|
||||
import Data.SplitDiff
|
||||
import Data.Term
|
||||
import Data.These
|
||||
import Info (byteRange, setByteRange)
|
||||
import Prelude hiding (fst, snd)
|
||||
|
||||
-- | Assign line numbers to the lines on each side of a list of rows.
|
||||
numberedRows :: [Join These a] -> [Join These (Int, a)]
|
||||
numberedRows = countUp (both 1 1)
|
||||
where countUp _ [] = []
|
||||
countUp from (row : rows) = numberedLine from row : countUp (nextLineNumbers from row) rows
|
||||
numberedLine from row = fromJust ((,) <$> modifyJoin (uncurry These) from `applyThese` row)
|
||||
nextLineNumbers from row = modifyJoin (fromThese id id) (succ <$ row) <*> from
|
||||
|
||||
-- | Determine whether a line contains any patches.
|
||||
hasChanges :: (Foldable f, Functor f) => SplitDiff f annotation -> Bool
|
||||
hasChanges = or . (True <$)
|
||||
|
||||
-- | Align a Diff into a list of Join These SplitDiffs representing the (possibly blank) lines on either side.
|
||||
alignDiff :: (HasField fields Range, Traversable f) => Both Source -> Diff f (Record fields) (Record fields) -> [Join These (SplitDiff [] (Record fields))]
|
||||
alignDiff sources = cata $ \ diff -> case diff of
|
||||
Patch patch -> alignPatch sources patch
|
||||
Merge (In (ann1, ann2) syntax) -> alignSyntax (runBothWith ((Join .) . These)) wrap getRange sources (In (both ann1 ann2) syntax)
|
||||
|
||||
-- | Align the contents of a patch into a list of lines on the corresponding side(s) of the diff.
|
||||
alignPatch :: forall fields f. (Traversable f, HasField fields Range) => Both Source -> Patch (TermF f (Record fields) [Join These (SplitDiff [] (Record fields))]) (TermF f (Record fields) [Join These (SplitDiff [] (Record fields))]) -> [Join These (SplitDiff [] (Record fields))]
|
||||
alignPatch sources patch = case patch of
|
||||
Delete term -> fmap (pure . SplitDelete) <$> alignSyntax' this (fst sources) term
|
||||
Insert term -> fmap (pure . SplitInsert) <$> alignSyntax' that (snd sources) term
|
||||
Replace term1 term2 -> fmap (pure . SplitReplace) <$> alignWith (fmap (these id id const . runJoin) . Join)
|
||||
(alignSyntax' this (fst sources) term1)
|
||||
(alignSyntax' that (snd sources) term2)
|
||||
where getRange = byteRange . extract
|
||||
alignSyntax' :: (forall a. Identity a -> Join These a) -> Source -> TermF f (Record fields) [Join These (SplitDiff [] (Record fields))] -> [Join These (Term [] (Record fields))]
|
||||
alignSyntax' side source = alignSyntax side Term getRange (Identity source) . bimap Identity (fmap (fmap unSplit))
|
||||
this = Join . This . runIdentity
|
||||
that = Join . That . runIdentity
|
||||
|
||||
-- | The Applicative instance f is either Identity or Both. Identity is for Terms in Patches, Both is for Diffs in unchanged portions of the diff.
|
||||
alignSyntax :: (Applicative f, HasField fields Range, Foldable g) => (forall a. f a -> Join These a) -> (TermF [] (Record fields) term -> term) -> (term -> Range) -> f Source -> TermF g (f (Record fields)) [Join These term] -> [Join These term]
|
||||
alignSyntax toJoinThese toNode getRange sources (In infos syntax) =
|
||||
catMaybes $ wrapInBranch <$> alignBranch getRange (join (toList syntax)) bothRanges
|
||||
where bothRanges = modifyJoin (fromThese [] []) lineRanges
|
||||
lineRanges = toJoinThese $ sourceLineRangesWithin . byteRange <$> infos <*> sources
|
||||
wrapInBranch = applyThese $ toJoinThese (makeNode <$> infos)
|
||||
makeNode info (range, children) = toNode (In (setByteRange info range) children)
|
||||
|
||||
-- | Given a function to get the range, a list of already-aligned children, and the lists of ranges spanned by a branch, return the aligned lines.
|
||||
alignBranch :: (term -> Range) -> [Join These term] -> Both [Range] -> [Join These (Range, [term])]
|
||||
-- There are no more ranges, so we’re done.
|
||||
alignBranch _ _ (Join ([], [])) = []
|
||||
-- There are no more children, so we can just zip the remaining ranges together.
|
||||
alignBranch _ [] ranges = runBothWith (alignWith Join) (fmap (flip (,) []) <$> ranges)
|
||||
-- There are both children and ranges, so we need to proceed line by line
|
||||
alignBranch getRange children ranges = case intersectingChildren of
|
||||
-- No child intersects the current ranges on either side, so advance.
|
||||
[] -> (flip (,) [] <$> headRanges) : alignBranch getRange children (drop 1 <$> ranges)
|
||||
-- At least one child intersects on at least one side.
|
||||
_ -> case intersectionsWithHeadRanges <$> listToMaybe symmetricalChildren of
|
||||
-- At least one child intersects on both sides, so align symmetrically.
|
||||
Just (True, True) -> let (line, remaining) = lineAndRemaining intersectingChildren (Just headRanges) in
|
||||
line $ alignBranch getRange (remaining <> nonIntersectingChildren) (drop 1 <$> ranges)
|
||||
-- A symmetrical child intersects on the right, so align asymmetrically on the left.
|
||||
Just (False, True) -> alignAsymmetrically leftRange first
|
||||
-- A symmetrical child intersects on the left, so align asymmetrically on the right.
|
||||
Just (True, False) -> alignAsymmetrically rightRange second
|
||||
-- No symmetrical child intersects, so align asymmetrically, picking the left side first to match the deletion/insertion order convention in diffs.
|
||||
_ -> if any (isThis . runJoin) asymmetricalChildren
|
||||
then alignAsymmetrically leftRange first
|
||||
else alignAsymmetrically rightRange second
|
||||
where (intersectingChildren, nonIntersectingChildren) = partition (or . intersects getRange headRanges) children
|
||||
(symmetricalChildren, asymmetricalChildren) = partition (isThese . runJoin) intersectingChildren
|
||||
intersectionsWithHeadRanges = fromThese True True . runJoin . intersects getRange headRanges
|
||||
Just headRanges = Join <$> bisequenceL (runJoin (listToMaybe <$> Join (runBothWith These ranges)))
|
||||
(leftRange, rightRange) = splitThese headRanges
|
||||
alignAsymmetrically range advanceBy = let (line, remaining) = lineAndRemaining asymmetricalChildren range in
|
||||
line $ alignBranch getRange (remaining <> symmetricalChildren <> nonIntersectingChildren) (modifyJoin (advanceBy (drop 1)) ranges)
|
||||
lineAndRemaining _ Nothing = (id, [])
|
||||
lineAndRemaining children (Just ranges) = let (intersections, remaining) = alignChildren getRange children ranges in
|
||||
((:) $ (,) <$> ranges `applyToBoth` (sortBy (compare `on` getRange) <$> intersections), remaining)
|
||||
|
||||
-- | Given a list of aligned children, produce lists of their intersecting first lines, and a list of the remaining lines/nonintersecting first lines.
|
||||
alignChildren :: (term -> Range) -> [Join These term] -> Join These Range -> (Both [term], [Join These term])
|
||||
alignChildren _ [] _ = (both [] [], [])
|
||||
alignChildren getRange (first:rest) headRanges
|
||||
| ~(l, r) <- splitThese first
|
||||
= case intersectionsWithHeadRanges first of
|
||||
-- It intersects on both sides, so we can just take the first line whole.
|
||||
(True, True) -> ((<>) <$> toTerms first <*> firstRemaining, restRemaining)
|
||||
-- It only intersects on the left, so split it up.
|
||||
(True, False) -> ((<>) <$> toTerms (fromJust l) <*> firstRemaining, maybe id (:) r restRemaining)
|
||||
-- It only intersects on the right, so split it up.
|
||||
(False, True) -> ((<>) <$> toTerms (fromJust r) <*> firstRemaining, maybe id (:) l restRemaining)
|
||||
-- It doesn’t intersect at all, so skip it and move along.
|
||||
(False, False) -> (firstRemaining, first:restRemaining)
|
||||
| otherwise = alignChildren getRange rest headRanges
|
||||
where (firstRemaining, restRemaining) = alignChildren getRange rest headRanges
|
||||
toTerms line = modifyJoin (fromThese [] []) (pure <$> line)
|
||||
intersectionsWithHeadRanges = fromThese False False . runJoin . intersects getRange headRanges
|
||||
|
||||
-- | Test ranges and terms for intersection on either or both sides.
|
||||
intersects :: (term -> Range) -> Join These Range -> Join These term -> Join These Bool
|
||||
intersects getRange ranges line = intersectsRange <$> ranges `applyToBoth` modifyJoin (fromThese (Range (-1) (-1)) (Range (-1) (-1))) (getRange <$> line)
|
||||
|
||||
-- | Split a These value up into independent These values representing the left and right sides, if any.
|
||||
splitThese :: Join These a -> (Maybe (Join These a), Maybe (Join These a))
|
||||
splitThese these = fromThese Nothing Nothing $ bimap (Just . Join . This) (Just . Join . That) (runJoin these)
|
||||
|
||||
infixl 4 `applyThese`
|
||||
|
||||
-- | Like `<*>`, but it returns its result in `Maybe` since the result is the intersection of the shapes of the inputs.
|
||||
applyThese :: Join These (a -> b) -> Join These a -> Maybe (Join These b)
|
||||
applyThese (Join fg) (Join ab) = fmap Join . uncurry maybeThese $ uncurry (***) (bimap (<*>) (<*>) (unpack fg)) (unpack ab)
|
||||
where unpack = fromThese Nothing Nothing . bimap Just Just
|
||||
|
||||
infixl 4 `applyToBoth`
|
||||
|
||||
-- | Like `<*>`, but it takes a `Both` on the right to ensure that it can always return a value.
|
||||
applyToBoth :: Join These (a -> b) -> Both a -> Join These b
|
||||
applyToBoth (Join fg) (Join (a, b)) = Join $ these (This . ($ a)) (That . ($ b)) (\ f g -> These (f a) (g b)) fg
|
||||
|
||||
-- Map over the bifunctor inside a Join, producing another Join.
|
||||
modifyJoin :: (p a a -> q b b) -> Join p a -> Join q b
|
||||
modifyJoin f = Join . f . runJoin
|
||||
|
||||
-- | Given a pair of Maybes, produce a These containing Just their values, or Nothing if they haven’t any.
|
||||
maybeThese :: Maybe a -> Maybe b -> Maybe (These a b)
|
||||
maybeThese (Just a) (Just b) = Just (These a b)
|
||||
maybeThese (Just a) _ = Just (This a)
|
||||
maybeThese _ (Just b) = Just (That b)
|
||||
maybeThese _ _ = Nothing
|
@ -5,7 +5,8 @@ import Data.ByteString (ByteString)
|
||||
import Data.ByteString.Lazy (toStrict)
|
||||
import Data.Map (Map)
|
||||
import Data.Semigroup
|
||||
import Data.Text (Text)
|
||||
import Data.Text (Text, intercalate)
|
||||
import Data.Text.Encoding (encodeUtf8)
|
||||
|
||||
class Monoid o => Output o where
|
||||
toOutput :: o -> ByteString
|
||||
@ -13,6 +14,9 @@ class Monoid o => Output o where
|
||||
instance Output ByteString where
|
||||
toOutput s = s
|
||||
|
||||
instance Output [Text] where
|
||||
toOutput = encodeUtf8 . intercalate "\n"
|
||||
|
||||
instance Output (Map Text Value) where
|
||||
toOutput = toStrict . (<> "\n") . encode
|
||||
|
||||
|
@ -4,6 +4,7 @@ module Data.Range
|
||||
, rangeLength
|
||||
, offsetRange
|
||||
, intersectsRange
|
||||
, subtractRange
|
||||
) where
|
||||
|
||||
import Data.Aeson
|
||||
@ -27,6 +28,9 @@ offsetRange a b = Range (start a + b) (end a + b)
|
||||
intersectsRange :: Range -> Range -> Bool
|
||||
intersectsRange range1 range2 = start range1 < end range2 && start range2 < end range1
|
||||
|
||||
subtractRange :: Range -> Range -> Range
|
||||
subtractRange range1 range2 = Range (start range1) (end range1 - rangeLength (Range (start range2) (max (end range1) (end range2))))
|
||||
|
||||
|
||||
-- Instances
|
||||
|
||||
|
@ -23,6 +23,7 @@ module Data.Source
|
||||
, spanToRangeInLineRanges
|
||||
, sourceLineRangesByLineNumber
|
||||
, rangeToSpan
|
||||
, newlineIndices
|
||||
) where
|
||||
|
||||
import Control.Arrow ((&&&))
|
||||
@ -103,7 +104,29 @@ sourceLineRanges source = sourceLineRangesWithin (totalRange source) source
|
||||
|
||||
-- | Compute the 'Range's of each line in a 'Range' of a 'Source'.
|
||||
sourceLineRangesWithin :: Range -> Source -> [Range]
|
||||
sourceLineRangesWithin range = uncurry (zipWith Range) . ((start range:) &&& (<> [ end range ])) . fmap (+ succ (start range)) . B.elemIndices (toEnum (ord '\n')) . sourceBytes . slice range
|
||||
sourceLineRangesWithin range = uncurry (zipWith Range)
|
||||
. ((start range:) &&& (<> [ end range ]))
|
||||
. fmap (+ succ (start range))
|
||||
. newlineIndices
|
||||
. sourceBytes
|
||||
. slice range
|
||||
|
||||
-- | Return all indices of newlines ('\n', '\r', and '\r\n') in the 'ByteString'.
|
||||
newlineIndices :: B.ByteString -> [Int]
|
||||
newlineIndices = go 0
|
||||
where go n bs | B.null bs = []
|
||||
| otherwise = case (searchCR bs, searchLF bs) of
|
||||
(Nothing, Nothing) -> []
|
||||
(Just i, Nothing) -> recur n i bs
|
||||
(Nothing, Just i) -> recur n i bs
|
||||
(Just crI, Just lfI)
|
||||
| succ crI == lfI -> recur n lfI bs
|
||||
| otherwise -> recur n (min crI lfI) bs
|
||||
recur n i bs = let j = n + i in j : go (succ j) (B.drop (succ i) bs)
|
||||
searchLF = B.elemIndex (toEnum (ord '\n'))
|
||||
searchCR = B.elemIndex (toEnum (ord '\r'))
|
||||
|
||||
{-# INLINE newlineIndices #-}
|
||||
|
||||
|
||||
-- Conversion
|
||||
|
@ -1,4 +1,4 @@
|
||||
{-# LANGUAGE DataKinds, GeneralizedNewtypeDeriving, TypeOperators, UndecidableInstances #-}
|
||||
{-# LANGUAGE DataKinds, GeneralizedNewtypeDeriving, MultiParamTypeClasses, ScopedTypeVariables, TypeFamilies, TypeOperators, UndecidableInstances #-}
|
||||
module Data.Syntax.Algebra
|
||||
( FAlgebra
|
||||
, RAlgebra
|
||||
@ -108,8 +108,8 @@ constructorNameAndConstantFields :: Show1 f => TermF f a b -> ByteString
|
||||
constructorNameAndConstantFields (In _ f) = pack (liftShowsPrec (const (const id)) (const id) 0 f "")
|
||||
|
||||
-- | Compute a 'ConstructorLabel' label for a 'Union' of syntax 'Term's.
|
||||
constructorLabel :: Apply ConstructorName fs => TermF (Union fs) a b -> ConstructorLabel
|
||||
constructorLabel (In _ u) = ConstructorLabel $ pack (apply (Proxy :: Proxy ConstructorName) constructorName u)
|
||||
constructorLabel :: ConstructorName syntax => TermF syntax a b -> ConstructorLabel
|
||||
constructorLabel (In _ s) = ConstructorLabel $ pack (constructorName s)
|
||||
|
||||
|
||||
newtype ConstructorLabel = ConstructorLabel ByteString
|
||||
@ -121,11 +121,40 @@ instance ToJSONFields ConstructorLabel where
|
||||
toJSONFields (ConstructorLabel s) = [ "category" .= decodeUtf8 s ]
|
||||
|
||||
|
||||
class ConstructorName f where
|
||||
constructorName :: f a -> String
|
||||
-- | A typeclass to retrieve the name of the data constructor for a value.
|
||||
--
|
||||
-- This typeclass employs the Advanced Overlap techniques designed by Oleg Kiselyov & Simon Peyton Jones: https://wiki.haskell.org/GHC/AdvancedOverlap; see also src/Renderer/TOC.hs for discussion of the details of the mechanism.
|
||||
class ConstructorName syntax where
|
||||
constructorName :: syntax a -> String
|
||||
|
||||
instance (Generic1 f, GConstructorName (Rep1 f)) => ConstructorName f where
|
||||
constructorName = gconstructorName . from1
|
||||
instance (ConstructorNameStrategy syntax ~ strategy, ConstructorNameWithStrategy strategy syntax) => ConstructorName syntax where
|
||||
constructorName = constructorNameWithStrategy (Proxy :: Proxy strategy)
|
||||
|
||||
class CustomConstructorName syntax where
|
||||
customConstructorName :: syntax a -> String
|
||||
|
||||
instance Apply ConstructorName fs => CustomConstructorName (Union fs) where
|
||||
customConstructorName = apply (Proxy :: Proxy ConstructorName) constructorName
|
||||
|
||||
instance CustomConstructorName [] where
|
||||
customConstructorName [] = "[]"
|
||||
customConstructorName _ = ""
|
||||
|
||||
data Strategy = Default | Custom
|
||||
|
||||
type family ConstructorNameStrategy syntax where
|
||||
ConstructorNameStrategy (Union _) = 'Custom
|
||||
ConstructorNameStrategy [] = 'Custom
|
||||
ConstructorNameStrategy syntax = 'Default
|
||||
|
||||
class ConstructorNameWithStrategy (strategy :: Strategy) syntax where
|
||||
constructorNameWithStrategy :: proxy strategy -> syntax a -> String
|
||||
|
||||
instance (Generic1 syntax, GConstructorName (Rep1 syntax)) => ConstructorNameWithStrategy 'Default syntax where
|
||||
constructorNameWithStrategy _ = gconstructorName . from1
|
||||
|
||||
instance CustomConstructorName syntax => ConstructorNameWithStrategy 'Custom syntax where
|
||||
constructorNameWithStrategy _ = customConstructorName
|
||||
|
||||
|
||||
class GConstructorName f where
|
||||
@ -139,6 +168,4 @@ instance (GConstructorName f, GConstructorName g) => GConstructorName (f :+: g)
|
||||
gconstructorName (R1 r) = gconstructorName r
|
||||
|
||||
instance Constructor c => GConstructorName (M1 C c f) where
|
||||
gconstructorName x = case conName x of
|
||||
":" -> ""
|
||||
n -> n
|
||||
gconstructorName = conName
|
||||
|
@ -87,7 +87,7 @@ instance Ord1 Variable where liftCompare = genericLiftCompare
|
||||
instance Show1 Variable where liftShowsPrec = genericLiftShowsPrec
|
||||
|
||||
|
||||
data Class a = Class { classContext :: ![a], classIdentifier :: !a, classSuperclasses :: ![a], classBody :: ![a] }
|
||||
data Class a = Class { classContext :: ![a], classIdentifier :: !a, classSuperclasses :: ![a], classBody :: !a }
|
||||
deriving (Eq, Foldable, Functor, GAlign, Generic1, Mergeable, Ord, Show, Traversable)
|
||||
|
||||
instance Diffable Class where
|
||||
|
19
src/Files.hs
19
src/Files.hs
@ -1,8 +1,11 @@
|
||||
{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, DeriveAnyClass, DuplicateRecordFields, ScopedTypeVariables #-}
|
||||
{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, DeriveAnyClass, DuplicateRecordFields, ScopedTypeVariables, TupleSections #-}
|
||||
module Files
|
||||
( readFile
|
||||
, isDirectory
|
||||
, readBlobPairsFromHandle
|
||||
, readBlobsFromHandle
|
||||
, readBlobsFromPaths
|
||||
, readBlobsFromDir
|
||||
, languageForFilePath
|
||||
) where
|
||||
|
||||
@ -25,6 +28,8 @@ import Prelude hiding (readFile)
|
||||
import System.Exit
|
||||
import System.FilePath
|
||||
import System.IO (Handle)
|
||||
import System.FilePath.Glob
|
||||
import System.Directory (doesDirectoryExist)
|
||||
import Text.Read
|
||||
|
||||
-- | Read a utf8-encoded file to a 'Blob'.
|
||||
@ -34,6 +39,9 @@ readFile path language = do
|
||||
raw <- liftIO $ (Just <$> B.readFile path) `catch` (const (pure Nothing) :: IOException -> IO (Maybe B.ByteString))
|
||||
pure $ fromMaybe (Blob.emptyBlob path) (Blob.sourceBlob path language . fromBytes <$> raw)
|
||||
|
||||
isDirectory :: MonadIO m => FilePath -> m Bool
|
||||
isDirectory path = liftIO (doesDirectoryExist path) >>= pure
|
||||
|
||||
-- | Return a language based on a FilePath's extension, or Nothing if extension is not found or not supported.
|
||||
languageForFilePath :: FilePath -> Maybe Language
|
||||
languageForFilePath = languageForType . takeExtension
|
||||
@ -51,6 +59,15 @@ readBlobsFromHandle :: MonadIO m => Handle -> m [Blob.Blob]
|
||||
readBlobsFromHandle = fmap toBlobs . readFromHandle
|
||||
where toBlobs BlobParse{..} = fmap toBlob blobs
|
||||
|
||||
readBlobsFromPaths :: MonadIO m => [(FilePath, Maybe Language)] -> m [Blob.Blob]
|
||||
readBlobsFromPaths = traverse (uncurry Files.readFile)
|
||||
|
||||
readBlobsFromDir :: MonadIO m => FilePath -> m [Blob.Blob]
|
||||
readBlobsFromDir path = do
|
||||
paths <- liftIO (globDir1 (compile "[^vendor]**/*[.rb|.js|.tsx|.go|.py]") path)
|
||||
let paths' = catMaybes $ fmap (\p -> (p,) . Just <$> languageForFilePath p) paths
|
||||
traverse (uncurry readFile) paths'
|
||||
|
||||
readFromHandle :: (FromJSON a, MonadIO m) => Handle -> m a
|
||||
readFromHandle h = do
|
||||
input <- liftIO $ BL.hGetContents h
|
||||
|
@ -8,13 +8,13 @@ module Language.Markdown.Assignment
|
||||
|
||||
import qualified CMarkGFM
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.Function (on)
|
||||
import Data.Functor (void)
|
||||
import Data.Record
|
||||
import Data.Syntax (makeTerm)
|
||||
import qualified Data.Syntax as Syntax
|
||||
import Data.Syntax.Assignment hiding (Assignment, Error)
|
||||
import qualified Data.Syntax.Assignment as Assignment
|
||||
import Data.Term as Term (Term(..), TermF(..), termIn, unwrap)
|
||||
import Data.Term as Term (Term(..), TermF(..), termIn)
|
||||
import qualified Data.Text as Text
|
||||
import Data.Text.Encoding (encodeUtf8)
|
||||
import Data.Union
|
||||
@ -30,7 +30,6 @@ type Syntax =
|
||||
, Markup.HTMLBlock
|
||||
, Markup.OrderedList
|
||||
, Markup.Paragraph
|
||||
, Markup.Section
|
||||
, Markup.ThematicBreak
|
||||
, Markup.UnorderedList
|
||||
, Markup.Table
|
||||
@ -61,7 +60,16 @@ assignment = Syntax.handleError $ makeTerm <$> symbol Document <*> children (Mar
|
||||
-- Block elements
|
||||
|
||||
blockElement :: Assignment
|
||||
blockElement = paragraph <|> list <|> blockQuote <|> codeBlock <|> thematicBreak <|> htmlBlock <|> section <|> table
|
||||
blockElement = choice
|
||||
[ paragraph
|
||||
, list
|
||||
, blockQuote
|
||||
, codeBlock
|
||||
, thematicBreak
|
||||
, htmlBlock
|
||||
, heading
|
||||
, table
|
||||
]
|
||||
|
||||
paragraph :: Assignment
|
||||
paragraph = makeTerm <$> symbol Paragraph <*> children (Markup.Paragraph <$> many inlineElement)
|
||||
@ -74,13 +82,8 @@ list = termIn <$> symbol List <*> ((\ (CMarkGFM.LIST CMarkGFM.ListAttributes{..}
|
||||
item :: Assignment
|
||||
item = makeTerm <$> symbol Item <*> children (many blockElement)
|
||||
|
||||
section :: Assignment
|
||||
section = makeTerm <$> symbol Heading <*> (heading >>= \ headingTerm -> Markup.Section (level headingTerm) headingTerm <$> while (((<) `on` level) headingTerm) blockElement)
|
||||
where heading = makeTerm <$> symbol Heading <*> ((\ (CMarkGFM.HEADING level) -> Markup.Heading level) . termAnnotation . termOut <$> currentNode <*> children (many inlineElement))
|
||||
level term = case term of
|
||||
_ | Just section <- prj (unwrap term) -> level (Markup.sectionHeading section)
|
||||
_ | Just heading <- prj (unwrap term) -> Markup.headingLevel heading
|
||||
_ -> maxBound
|
||||
heading :: Assignment
|
||||
heading = makeTerm <$> symbol Heading <*> ((\ (CMarkGFM.HEADING level) -> Markup.Heading level) . termAnnotation . termOut <$> currentNode <*> children (many inlineElement) <*> manyTill blockElement (void (symbol Heading) <|> eof))
|
||||
|
||||
blockQuote :: Assignment
|
||||
blockQuote = makeTerm <$> symbol BlockQuote <*> children (Markup.BlockQuote <$> many blockElement)
|
||||
@ -106,7 +109,18 @@ tableCell = makeTerm <$> symbol TableCell <*> children (Markup.TableCell <$> man
|
||||
-- Inline elements
|
||||
|
||||
inlineElement :: Assignment
|
||||
inlineElement = strong <|> emphasis <|> strikethrough <|> text <|> link <|> htmlInline <|> image <|> code <|> lineBreak <|> softBreak
|
||||
inlineElement = choice
|
||||
[ strong
|
||||
, emphasis
|
||||
, strikethrough
|
||||
, text
|
||||
, link
|
||||
, htmlInline
|
||||
, image
|
||||
, code
|
||||
, lineBreak
|
||||
, softBreak
|
||||
]
|
||||
|
||||
strong :: Assignment
|
||||
strong = makeTerm <$> symbol Strong <*> children (Markup.Strong <$> many inlineElement)
|
||||
|
@ -28,14 +28,7 @@ instance Eq1 Paragraph where liftEq = genericLiftEq
|
||||
instance Ord1 Paragraph where liftCompare = genericLiftCompare
|
||||
instance Show1 Paragraph where liftShowsPrec = genericLiftShowsPrec
|
||||
|
||||
data Section a = Section { sectionLevel :: Int, sectionHeading :: a, sectionContent :: [a] }
|
||||
deriving (Diffable, Eq, Foldable, Functor, GAlign, Generic1, Mergeable, Ord, Show, Traversable)
|
||||
|
||||
instance Eq1 Section where liftEq = genericLiftEq
|
||||
instance Ord1 Section where liftCompare = genericLiftCompare
|
||||
instance Show1 Section where liftShowsPrec = genericLiftShowsPrec
|
||||
|
||||
data Heading a = Heading { headingLevel :: Int, headingContent :: [a] }
|
||||
data Heading a = Heading { headingLevel :: Int, headingContent :: [a], sectionContent :: [a] }
|
||||
deriving (Diffable, Eq, Foldable, Functor, GAlign, Generic1, Mergeable, Ord, Show, Traversable)
|
||||
|
||||
instance Eq1 Heading where liftEq = genericLiftEq
|
||||
|
@ -255,7 +255,7 @@ async' :: Assignment
|
||||
async' = makeTerm <$> symbol AnonAsync <*> (Syntax.Identifier <$> source)
|
||||
|
||||
classDefinition :: Assignment
|
||||
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class <$> pure [] <*> term expression <*> argumentList <*> manyTerm expression)
|
||||
classDefinition = makeTerm <$> symbol ClassDefinition <*> children (Declaration.Class <$> pure [] <*> term expression <*> argumentList <*> expressions)
|
||||
where argumentList = symbol ArgumentList *> children (manyTerm expression)
|
||||
<|> pure []
|
||||
|
||||
|
@ -202,11 +202,11 @@ endBlock :: Assignment
|
||||
endBlock = makeTerm <$> symbol EndBlock <*> children (Statement.ScopeExit <$> many expression)
|
||||
|
||||
class' :: Assignment
|
||||
class' = makeTerm <$> symbol Class <*> children (Declaration.Class <$> pure [] <*> expression <*> (superclass <|> pure []) <*> many expression)
|
||||
class' = makeTerm <$> symbol Class <*> children (Declaration.Class <$> pure [] <*> expression <*> (superclass <|> pure []) <*> expressions)
|
||||
where superclass = pure <$ symbol Superclass <*> children expression
|
||||
|
||||
singletonClass :: Assignment
|
||||
singletonClass = makeTerm <$> symbol SingletonClass <*> children (Declaration.Class <$> pure [] <*> expression <*> pure [] <*> many expression)
|
||||
singletonClass = makeTerm <$> symbol SingletonClass <*> children (Declaration.Class <$> pure [] <*> expression <*> pure [] <*> expressions)
|
||||
|
||||
module' :: Assignment
|
||||
module' = makeTerm <$> symbol Module <*> children (Declaration.Module <$> expression <*> many expression)
|
||||
|
@ -1,183 +0,0 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
module Language.TypeScript where
|
||||
|
||||
import Control.Comonad (extract)
|
||||
import Control.Comonad.Cofree (unwrap)
|
||||
import Data.Foldable (toList)
|
||||
import Data.Record
|
||||
import Data.Source
|
||||
import Data.Term
|
||||
import Data.Text (Text)
|
||||
import Info
|
||||
import Language
|
||||
import qualified Syntax as S
|
||||
|
||||
termAssignment
|
||||
:: Source -- ^ The source of the term.
|
||||
-> Category -- ^ The category for the term.
|
||||
-> [ Term S.Syntax (Record DefaultFields) ] -- ^ The child nodes of the term.
|
||||
-> Maybe (S.Syntax (Term S.Syntax (Record DefaultFields))) -- ^ The resulting term, in Maybe.
|
||||
termAssignment _ category children =
|
||||
case (category, children) of
|
||||
(Assignment, [ identifier, value ]) -> Just $ S.Assignment identifier value
|
||||
(MathAssignment, [ identifier, value ]) -> Just $ S.OperatorAssignment identifier value
|
||||
(MemberAccess, [ base, property ]) -> Just $ S.MemberAccess base property
|
||||
(SubscriptAccess, [ base, element ]) -> Just $ S.SubscriptAccess base element
|
||||
(CommaOperator, [ a, b ])
|
||||
| S.Indexed rest <- unwrap b
|
||||
-> Just $ S.Indexed $ a : rest
|
||||
(FunctionCall, id : rest) -> case break ((== Args) . Info.category . extract) rest of
|
||||
(typeArgs, [ args ]) -> let flatArgs = toList (unwrap args) in
|
||||
Just $ case unwrap id of
|
||||
S.MemberAccess target method -> S.MethodCall target method typeArgs flatArgs
|
||||
_ -> S.FunctionCall id typeArgs flatArgs
|
||||
_ -> Nothing
|
||||
(Ternary, condition : cases) -> Just $ S.Ternary condition cases
|
||||
(Other "variable_declaration", _) -> Just . S.Indexed $ toVarDeclOrAssignment <$> children
|
||||
(Other "trailing_variable_declaration", _) -> Just . S.Indexed $ toVarDeclOrAssignment <$> children
|
||||
(Other "lexical_declaration", _) -> Just . S.Indexed $ toVarDeclOrAssignment <$> children
|
||||
(VarAssignment, [id, assignment]) -> Just $ S.VarAssignment [id] assignment
|
||||
(FieldDecl, _) -> Just $ S.FieldDecl children
|
||||
(Object, _) -> Just . S.Object Nothing $ foldMap toTuple children
|
||||
(DoWhile, [ expr, body ]) -> Just $ S.DoWhile expr body
|
||||
(Constructor, [ expr ]) -> Just $ S.Constructor expr
|
||||
(Try, [ body ]) -> Just $ S.Try [body] [] Nothing Nothing
|
||||
(Try, [ body, catch ])
|
||||
| Catch <- Info.category (extract catch)
|
||||
-> Just $ S.Try [body] [catch] Nothing Nothing
|
||||
(Try, [ body, finally ])
|
||||
| Finally <- Info.category (extract finally)
|
||||
-> Just $ S.Try [body] [] Nothing (Just finally)
|
||||
(Try, [ body, catch, finally ])
|
||||
| Catch <- Info.category (extract catch)
|
||||
, Finally <- Info.category (extract finally)
|
||||
-> Just $ S.Try [body] [catch] Nothing (Just finally)
|
||||
(ArrayLiteral, _) -> Just $ S.Array Nothing children
|
||||
(Method, children) -> case break ((== ExpressionStatements) . Info.category . extract) children of
|
||||
(prev, [body]) -> case break ((== Identifier) . Info.category . extract) prev of
|
||||
(prev, [id, callSignature]) -> Just $ S.Method prev id Nothing (toList (unwrap callSignature)) (toList (unwrap body))
|
||||
_ -> Nothing -- No identifier found or callSignature found.
|
||||
_ -> Nothing -- No body found.``
|
||||
(Class, identifier : rest) -> case break ((== Other "class_body") . Info.category . extract) rest of
|
||||
(clauses, [ definitions ]) -> Just $ S.Class identifier clauses (toList (unwrap definitions))
|
||||
_ -> Nothing
|
||||
(Module, [ identifier, definitions ]) -> Just $ S.Module identifier (toList (unwrap definitions))
|
||||
(Namespace, [ identifier, definitions ]) -> Just $ S.Namespace identifier (toList (unwrap definitions))
|
||||
(Import, [ statements, identifier ] ) -> Just $ S.Import identifier (toList (unwrap statements))
|
||||
(Import, [ identifier ] ) -> Just $ S.Import identifier []
|
||||
(Export, [ statements, identifier] ) -> Just $ S.Export (Just identifier) (toList (unwrap statements))
|
||||
(Export, [ statements ] )
|
||||
| S.Indexed _ <- unwrap statements
|
||||
-> Just $ S.Export Nothing (toList (unwrap statements))
|
||||
| otherwise -> Just $ S.Export (Just statements) []
|
||||
(For, _:_) -> Just $ S.For (init children >>= flattenExpressionStatements) [last children]
|
||||
(Function, children) -> case break ((== ExpressionStatements) . Info.category . extract) children of
|
||||
(inits, [body]) -> case inits of
|
||||
[id, callSignature] -> Just $ S.Function id (toList (unwrap callSignature)) (toList (unwrap body))
|
||||
[callSignature] -> Just $ S.AnonymousFunction (toList (unwrap callSignature)) (toList (unwrap body))
|
||||
_ -> Nothing -- More than 1 identifier found or no call signature found
|
||||
_ -> Nothing -- No body found.
|
||||
(Ty, children) -> Just $ S.Ty children
|
||||
(Interface, children) -> toInterface children
|
||||
_ -> Nothing
|
||||
where flattenExpressionStatements term
|
||||
| Info.category (extract term) `elem` [ExpressionStatements, CommaOperator] = toList (unwrap term) >>= flattenExpressionStatements
|
||||
| otherwise = [term]
|
||||
|
||||
categoryForTypeScriptName :: Text -> Category
|
||||
categoryForTypeScriptName category = case category of
|
||||
"object" -> Object
|
||||
"expression_statement" -> ExpressionStatements
|
||||
"trailing_expression_statement" -> ExpressionStatements
|
||||
"this_expression" -> Identifier
|
||||
"null" -> Identifier
|
||||
"undefined" -> Identifier
|
||||
"type_identifier" -> Identifier
|
||||
"property_identifier" -> Identifier
|
||||
"shorthand_property_identifier" -> Identifier
|
||||
"nested_identifier" -> Identifier
|
||||
"arrow_function" -> Function
|
||||
"generator_function" -> Function
|
||||
"math_op" -> MathOperator -- math operator, e.g. +, -, *, /.
|
||||
"update_expression" -> MathOperator -- math operator, e.g. ++, --
|
||||
"bool_op" -> BooleanOperator -- boolean operator, e.g. ||, &&.
|
||||
"comma_op" -> CommaOperator -- comma operator, e.g. expr1, expr2.
|
||||
"sequence_expression" -> CommaOperator -- comma operator, e.g. expr1, expr2.
|
||||
"delete_op" -> Operator -- delete operator, e.g. delete x[2].
|
||||
"type_op" -> Operator -- type operator, e.g. typeof Object.
|
||||
"void_op" -> Operator -- void operator, e.g. void 2.
|
||||
"for_statement" -> For
|
||||
"trailing_for_statement" -> For
|
||||
"for_in_statement" -> For
|
||||
"trailing_for_in_statement" -> For
|
||||
"for_of_statement" -> For
|
||||
"trailing_for_of_statement" -> For
|
||||
"new_expression" -> Constructor
|
||||
"class" -> Class
|
||||
"catch" -> Catch
|
||||
"catch_clause" -> Catch
|
||||
"finally" -> Finally
|
||||
"finally_clause" -> Finally
|
||||
"if_statement" -> If
|
||||
"trailing_if_statement" -> If
|
||||
"empty_statement" -> Empty
|
||||
"program" -> Program
|
||||
"function_call" -> FunctionCall
|
||||
"call_expression" -> FunctionCall
|
||||
"pair" -> Pair
|
||||
"string" -> StringLiteral
|
||||
"integer" -> IntegerLiteral
|
||||
"number" -> NumberLiteral
|
||||
"float" -> FloatLiteral
|
||||
"symbol" -> SymbolLiteral
|
||||
"array" -> ArrayLiteral
|
||||
"function" -> Function
|
||||
"identifier" -> Identifier
|
||||
"formal_parameters" -> Params
|
||||
"arguments" -> Args
|
||||
"statement_block" -> ExpressionStatements
|
||||
"assignment" -> Assignment
|
||||
"assignment_expression" -> Assignment
|
||||
"member_access" -> MemberAccess
|
||||
"member_expression" -> MemberAccess
|
||||
"op" -> Operator
|
||||
"subscript_access" -> SubscriptAccess
|
||||
"subscript_expression" -> SubscriptAccess
|
||||
"regex" -> Regex
|
||||
"template_string" -> TemplateString
|
||||
"switch_statement" -> Switch
|
||||
"math_assignment" -> MathAssignment
|
||||
"augmented_assignment_expression" -> MathAssignment
|
||||
"case" -> Case
|
||||
"switch_case" -> Case
|
||||
"true" -> Boolean
|
||||
"false" -> Boolean
|
||||
"ternary" -> Ternary
|
||||
"ternary_expression" -> Ternary
|
||||
"while_statement" -> While
|
||||
"trailing_while_statement" -> While
|
||||
"do_statement" -> DoWhile
|
||||
"trailing_do_statement" -> DoWhile
|
||||
"return_statement" -> Return
|
||||
"trailing_return_statement" -> Return
|
||||
"throw_statement" -> Throw
|
||||
"trailing_throw_statement" -> Throw
|
||||
"try_statement" -> Try
|
||||
"method_definition" -> Method
|
||||
"comment" -> Comment
|
||||
"bitwise_op" -> BitwiseOperator
|
||||
"rel_op" -> RelationalOperator
|
||||
"import_statement" -> Import
|
||||
"export_statement" -> Export
|
||||
"break_statement" -> Break
|
||||
"continue_statement" -> Continue
|
||||
"yield_expression" -> Yield
|
||||
"public_field_definition" -> FieldDecl
|
||||
"variable_declarator" -> VarAssignment
|
||||
"type_annotation" -> Ty
|
||||
"template_chars" -> TemplateString
|
||||
"module" -> Module
|
||||
"internal_module" -> Namespace
|
||||
"interface_declaration" -> Interface
|
||||
"parenthesized_expression" -> ParenthesizedExpression
|
||||
name -> Other name
|
@ -542,9 +542,11 @@ constructorTy = makeTerm <$> symbol ConstructorType <*> children (TypeScript.Syn
|
||||
statementBlock :: Assignment
|
||||
statementBlock = makeTerm <$> symbol StatementBlock <*> children (manyTerm statement)
|
||||
|
||||
classBodyStatements :: Assignment.Assignment [] Grammar [Term]
|
||||
classBodyStatements = symbol ClassBody *> children (contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> (concat <$> many ((\as b -> as ++ [b]) <$> manyTerm decorator <*> term (methodDefinition <|> publicFieldDefinition <|> methodSignature <|> indexSignature <|> abstractMethodSignature))) <*> many comment))
|
||||
classBodyStatements :: Assignment
|
||||
classBodyStatements = mk <$> symbol ClassBody <*> children (contextualize' <$> Assignment.manyThrough comment (postContextualize' <$> (concat <$> many ((\as b -> as ++ [b]) <$> manyTerm decorator <*> term (methodDefinition <|> publicFieldDefinition <|> methodSignature <|> indexSignature <|> abstractMethodSignature))) <*> many comment))
|
||||
where
|
||||
mk _ [a] = a
|
||||
mk loc children = makeTerm loc children
|
||||
contextualize' (cs, formalParams) = case nonEmpty cs of
|
||||
Just cs -> toList cs ++ formalParams
|
||||
Nothing -> formalParams
|
||||
|
@ -419,7 +419,7 @@ instance Eq1 ClassHeritage where liftEq = genericLiftEq
|
||||
instance Ord1 ClassHeritage where liftCompare = genericLiftCompare
|
||||
instance Show1 ClassHeritage where liftShowsPrec = genericLiftShowsPrec
|
||||
|
||||
data AbstractClass a = AbstractClass { _abstractClassIdentifier :: !a, _abstractClassTypeParameters :: !a, _classHeritage :: ![a], _classBody :: ![a] }
|
||||
data AbstractClass a = AbstractClass { _abstractClassIdentifier :: !a, _abstractClassTypeParameters :: !a, _classHeritage :: ![a], _classBody :: !a }
|
||||
deriving (Diffable, Eq, Foldable, Functor, GAlign, Generic1, Mergeable, Ord, Show, Traversable)
|
||||
|
||||
instance Eq1 AbstractClass where liftEq = genericLiftEq
|
||||
|
@ -3,6 +3,7 @@ module Parser
|
||||
( Parser(..)
|
||||
, SomeParser(..)
|
||||
, someParser
|
||||
, ApplyAll
|
||||
-- Syntax parsers
|
||||
, syntaxParserForLanguage
|
||||
-- À la carte parsers
|
||||
@ -55,30 +56,30 @@ data Parser term where
|
||||
MarkdownParser :: Parser (Term (TermF [] CMarkGFM.NodeType) (Node Markdown.Grammar))
|
||||
|
||||
-- | Apply all of a list of typeclasses to all of a list of functors using 'Apply'. Used by 'someParser' to constrain all of the language-specific syntax types to the typeclasses in question.
|
||||
type family ApplyAll (typeclasses :: [(* -> *) -> Constraint]) (functors :: [* -> *]) :: Constraint where
|
||||
ApplyAll (typeclass ': typeclasses) functors = (Apply typeclass functors, ApplyAll typeclasses functors)
|
||||
ApplyAll '[] functors = ()
|
||||
type family ApplyAll (typeclasses :: [(* -> *) -> Constraint]) (syntax :: * -> *) :: Constraint where
|
||||
ApplyAll (typeclass ': typeclasses) syntax = (typeclass syntax, ApplyAll typeclasses syntax)
|
||||
ApplyAll '[] syntax = ()
|
||||
|
||||
-- | A parser for some specific language, producing 'Term's whose syntax satisfies a list of typeclass constraints.
|
||||
--
|
||||
-- This enables us to abstract over the details of the specific syntax types in cases where we can describe all the requirements on the syntax with a list of typeclasses.
|
||||
data SomeParser typeclasses where
|
||||
SomeParser :: ApplyAll typeclasses fs => { unSomeParser :: Parser (Term (Union fs) (Record Location)) } -> SomeParser typeclasses
|
||||
data SomeParser typeclasses ann where
|
||||
SomeParser :: ApplyAll typeclasses syntax => Parser (Term syntax ann) -> SomeParser typeclasses ann
|
||||
|
||||
-- | Construct a 'SomeParser' given a proxy for a list of typeclasses and the 'Language' to be parsed, all of which must be satisfied by all of the types in the syntaxes of our supported languages.
|
||||
--
|
||||
-- This can be used to perform operations uniformly over terms produced by blobs with different 'Language's, and which therefore have different types in general. For example, given some 'Blob', we can parse and 'show' the parsed & assigned 'Term' like so:
|
||||
--
|
||||
-- > case someParser (Proxy :: Proxy '[Show1]) (blobLanguage language) of { Just (SomeParser parser) -> runTask (parse parser blob) >>= putStrLn . show ; _ -> return () }
|
||||
someParser :: ( ApplyAll typeclasses JSON.Syntax
|
||||
, ApplyAll typeclasses Markdown.Syntax
|
||||
, ApplyAll typeclasses Python.Syntax
|
||||
, ApplyAll typeclasses Ruby.Syntax
|
||||
, ApplyAll typeclasses TypeScript.Syntax
|
||||
someParser :: ( ApplyAll typeclasses (Union JSON.Syntax)
|
||||
, ApplyAll typeclasses (Union Markdown.Syntax)
|
||||
, ApplyAll typeclasses (Union Python.Syntax)
|
||||
, ApplyAll typeclasses (Union Ruby.Syntax)
|
||||
, ApplyAll typeclasses (Union TypeScript.Syntax)
|
||||
)
|
||||
=> proxy typeclasses -- ^ A proxy for the list of typeclasses required, e.g. @(Proxy :: Proxy '[Show1])@.
|
||||
-> Language -- ^ The 'Language' to select.
|
||||
-> Maybe (SomeParser typeclasses) -- ^ 'Maybe' a 'SomeParser' abstracting the syntax type to be produced.
|
||||
=> proxy typeclasses -- ^ A proxy for the list of typeclasses required, e.g. @(Proxy :: Proxy '[Show1])@.
|
||||
-> Language -- ^ The 'Language' to select.
|
||||
-> Maybe (SomeParser typeclasses (Record Location)) -- ^ 'Maybe' a 'SomeParser' abstracting the syntax type to be produced.
|
||||
someParser _ Go = Nothing
|
||||
someParser _ JavaScript = Just (SomeParser typescriptParser)
|
||||
someParser _ JSON = Just (SomeParser jsonParser)
|
||||
|
@ -3,18 +3,17 @@ module Renderer
|
||||
( DiffRenderer(..)
|
||||
, TermRenderer(..)
|
||||
, SomeRenderer(..)
|
||||
, renderPatch
|
||||
, renderSExpressionDiff
|
||||
, renderSExpressionTerm
|
||||
, renderJSONDiff
|
||||
, renderJSONTerm
|
||||
, renderToCDiff
|
||||
, renderToCTerm
|
||||
, renderToTags
|
||||
, HasDeclaration
|
||||
, declarationAlgebra
|
||||
, syntaxDeclarationAlgebra
|
||||
, Summaries(..)
|
||||
, File(..)
|
||||
) where
|
||||
|
||||
import Data.Aeson (Value)
|
||||
@ -23,14 +22,12 @@ import qualified Data.Map as Map
|
||||
import Data.Output
|
||||
import Data.Text (Text)
|
||||
import Renderer.JSON as R
|
||||
import Renderer.Patch as R
|
||||
import Renderer.SExpression as R
|
||||
import Renderer.Tag as R
|
||||
import Renderer.TOC as R
|
||||
|
||||
-- | Specification of renderers for diffs, producing output in the parameter type.
|
||||
data DiffRenderer output where
|
||||
-- | Render to git-diff-compatible textual output.
|
||||
PatchDiffRenderer :: DiffRenderer File
|
||||
-- | Compute a table of contents for the diff & encode it as JSON.
|
||||
OldToCDiffRenderer :: DiffRenderer Summaries
|
||||
-- | Compute a table of contents for the diff & encode it as JSON (uses the new Assignment parse tree parser).
|
||||
@ -51,6 +48,8 @@ data TermRenderer output where
|
||||
JSONTermRenderer :: TermRenderer [Value]
|
||||
-- | Render to a 'ByteString' formatted as nested s-expressions.
|
||||
SExpressionTermRenderer :: TermRenderer ByteString
|
||||
-- | Render to a list of tags.
|
||||
TagsTermRenderer :: TermRenderer [Value]
|
||||
|
||||
deriving instance Eq (TermRenderer output)
|
||||
deriving instance Show (TermRenderer output)
|
||||
|
@ -1,185 +0,0 @@
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
module Renderer.Patch
|
||||
( renderPatch
|
||||
, File(..)
|
||||
, hunks
|
||||
, Hunk(..)
|
||||
, truncatePatch
|
||||
) where
|
||||
|
||||
import Alignment
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Blob
|
||||
import Data.ByteString.Char8 (ByteString, pack)
|
||||
import qualified Data.ByteString.Char8 as ByteString
|
||||
import Data.Diff
|
||||
import Data.Functor.Both as Both
|
||||
import Data.List (span, unzip)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Monoid (Sum(..))
|
||||
import Data.Output
|
||||
import Data.Range
|
||||
import Data.Record
|
||||
import Data.Semigroup ((<>))
|
||||
import Data.Source
|
||||
import Data.SplitDiff
|
||||
import Data.These
|
||||
import Prelude hiding (fst, snd)
|
||||
|
||||
-- | Render a timed out file as a truncated diff.
|
||||
truncatePatch :: Both Blob -> ByteString
|
||||
truncatePatch blobs = header blobs <> "#timed_out\nTruncating diff: timeout reached.\n"
|
||||
|
||||
-- | Render a diff in the traditional patch format.
|
||||
renderPatch :: (HasField fields Range, Traversable f) => Both Blob -> Diff f (Record fields) (Record fields) -> File
|
||||
renderPatch blobs diff = File $ if not (ByteString.null text) && ByteString.last text /= '\n'
|
||||
then text <> "\n\\ No newline at end of file\n"
|
||||
else text
|
||||
where text = header blobs <> mconcat (showHunk blobs <$> hunks diff blobs)
|
||||
|
||||
newtype File = File { unFile :: ByteString }
|
||||
deriving Show
|
||||
|
||||
instance Monoid File where
|
||||
mempty = File mempty
|
||||
mappend (File a) (File b) = File (a <> "\n" <> b)
|
||||
|
||||
instance Output File where
|
||||
toOutput = unFile
|
||||
|
||||
|
||||
-- | A hunk in a patch, including the offset, changes, and context.
|
||||
data Hunk a = Hunk { offset :: Both (Sum Int), changes :: [Change a], trailingContext :: [Join These a] }
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | A change in a patch hunk, along with its preceding context.
|
||||
data Change a = Change { context :: [Join These a], contents :: [Join These a] }
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | The number of lines in the hunk before and after.
|
||||
hunkLength :: Hunk a -> Both (Sum Int)
|
||||
hunkLength hunk = mconcat $ (changeLength <$> changes hunk) <> (rowIncrement <$> trailingContext hunk)
|
||||
|
||||
-- | The number of lines in change before and after.
|
||||
changeLength :: Change a -> Both (Sum Int)
|
||||
changeLength change = mconcat $ (rowIncrement <$> context change) <> (rowIncrement <$> contents change)
|
||||
|
||||
-- | The increment the given row implies for line numbering.
|
||||
rowIncrement :: Join These a -> Both (Sum Int)
|
||||
rowIncrement = Join . fromThese (Sum 0) (Sum 0) . runJoin . (Sum 1 <$)
|
||||
|
||||
-- | Given the before and after sources, render a hunk to a string.
|
||||
showHunk :: Functor f => HasField fields Range => Both Blob -> Hunk (SplitDiff f (Record fields)) -> ByteString
|
||||
showHunk blobs hunk = maybeOffsetHeader <>
|
||||
mconcat (showChange sources <$> changes hunk) <>
|
||||
showLines (snd sources) ' ' (maybeSnd . runJoin <$> trailingContext hunk)
|
||||
where sources = blobSource <$> blobs
|
||||
maybeOffsetHeader = if lengthA > 0 && lengthB > 0
|
||||
then offsetHeader
|
||||
else mempty
|
||||
offsetHeader = "@@ -" <> offsetA <> "," <> pack (show lengthA) <> " +" <> offsetB <> "," <> pack (show lengthB) <> " @@" <> "\n"
|
||||
(lengthA, lengthB) = runJoin . fmap getSum $ hunkLength hunk
|
||||
(offsetA, offsetB) = runJoin . fmap (pack . show . getSum) $ offset hunk
|
||||
|
||||
-- | Given the before and after sources, render a change to a string.
|
||||
showChange :: Functor f => HasField fields Range => Both Source -> Change (SplitDiff f (Record fields)) -> ByteString
|
||||
showChange sources change = showLines (snd sources) ' ' (maybeSnd . runJoin <$> context change) <> deleted <> inserted
|
||||
where (deleted, inserted) = runJoin $ pure showLines <*> sources <*> both '-' '+' <*> Join (unzip (fromThese Nothing Nothing . runJoin . fmap Just <$> contents change))
|
||||
|
||||
-- | Given a source, render a set of lines to a string with a prefix.
|
||||
showLines :: Functor f => HasField fields Range => Source -> Char -> [Maybe (SplitDiff f (Record fields))] -> ByteString
|
||||
showLines source prefix lines = fromMaybe "" . mconcat $ fmap prepend . showLine source <$> lines
|
||||
where prepend "" = ""
|
||||
prepend source = ByteString.singleton prefix <> source
|
||||
|
||||
-- | Given a source, render a line to a string.
|
||||
showLine :: Functor f => HasField fields Range => Source -> Maybe (SplitDiff f (Record fields)) -> Maybe ByteString
|
||||
showLine source line | Just line <- line = Just . sourceBytes . (`slice` source) $ getRange line
|
||||
| otherwise = Nothing
|
||||
|
||||
-- | Returns the header given two source blobs and a hunk.
|
||||
header :: Both Blob -> ByteString
|
||||
header blobs = ByteString.intercalate "\n" ([filepathHeader, fileModeHeader] <> maybeFilepaths) <> "\n"
|
||||
where filepathHeader = "diff --git a/" <> pathA <> " b/" <> pathB
|
||||
fileModeHeader = case (modeA, modeB) of
|
||||
(Nothing, Just mode) -> ByteString.intercalate "\n" [ "new file mode " <> modeToDigits mode, blobOidHeader ]
|
||||
(Just mode, Nothing) -> ByteString.intercalate "\n" [ "deleted file mode " <> modeToDigits mode, blobOidHeader ]
|
||||
(Just mode, Just other) | mode == other -> "index " <> oidA <> ".." <> oidB <> " " <> modeToDigits mode
|
||||
(Just mode1, Just mode2) -> ByteString.intercalate "\n" [
|
||||
"old mode " <> modeToDigits mode1,
|
||||
"new mode " <> modeToDigits mode2,
|
||||
blobOidHeader
|
||||
]
|
||||
(Nothing, Nothing) -> ""
|
||||
blobOidHeader = "index " <> oidA <> ".." <> oidB
|
||||
modeHeader :: ByteString -> Maybe BlobKind -> ByteString -> ByteString
|
||||
modeHeader ty maybeMode path = case maybeMode of
|
||||
Just _ -> ty <> "/" <> path
|
||||
Nothing -> "/dev/null"
|
||||
maybeFilepaths = if (nullOid == oidA && nullSource (snd sources)) || (nullOid == oidB && nullSource (fst sources)) then [] else [ beforeFilepath, afterFilepath ]
|
||||
beforeFilepath = "--- " <> modeHeader "a" modeA pathA
|
||||
afterFilepath = "+++ " <> modeHeader "b" modeB pathB
|
||||
sources = blobSource <$> blobs
|
||||
(pathA, pathB) = case runJoin $ pack . blobPath <$> blobs of
|
||||
("", path) -> (path, path)
|
||||
(path, "") -> (path, path)
|
||||
paths -> paths
|
||||
(oidA, oidB) = runJoin $ blobOid <$> blobs
|
||||
(modeA, modeB) = runJoin $ blobKind <$> blobs
|
||||
|
||||
-- | A hunk representing no changes.
|
||||
emptyHunk :: Hunk (SplitDiff a annotation)
|
||||
emptyHunk = Hunk { offset = mempty, changes = [], trailingContext = [] }
|
||||
|
||||
-- | Render a diff as a series of hunks.
|
||||
hunks :: (Traversable f, HasField fields Range) => Diff f (Record fields) (Record fields) -> Both Blob -> [Hunk (SplitDiff [] (Record fields))]
|
||||
hunks _ blobs | sources <- blobSource <$> blobs
|
||||
, sourcesEqual <- runBothWith (==) sources
|
||||
, sourcesNull <- runBothWith (&&) (nullSource <$> sources)
|
||||
, sourcesEqual || sourcesNull
|
||||
= [emptyHunk]
|
||||
hunks diff blobs = hunksInRows (pure 1) $ alignDiff (blobSource <$> blobs) diff
|
||||
|
||||
-- | Given beginning line numbers, turn rows in a split diff into hunks in a
|
||||
-- | patch.
|
||||
hunksInRows :: (Foldable f, Functor f) => Both (Sum Int) -> [Join These (SplitDiff f annotation)] -> [Hunk (SplitDiff f annotation)]
|
||||
hunksInRows start rows = case nextHunk start rows of
|
||||
Nothing -> []
|
||||
Just (hunk, rest) -> hunk : hunksInRows (offset hunk <> hunkLength hunk) rest
|
||||
|
||||
-- | Given beginning line numbers, return the next hunk and the remaining rows
|
||||
-- | of the split diff.
|
||||
nextHunk :: (Foldable f, Functor f) => Both (Sum Int) -> [Join These (SplitDiff f annotation)] -> Maybe (Hunk (SplitDiff f annotation), [Join These (SplitDiff f annotation)])
|
||||
nextHunk start rows = case nextChange start rows of
|
||||
Nothing -> Nothing
|
||||
Just (offset, change, rest) -> let (changes, rest') = contiguousChanges rest in Just (Hunk offset (change : changes) $ take 3 rest', drop 3 rest')
|
||||
where contiguousChanges rows = case break rowHasChanges (take 7 rows) of
|
||||
(_, []) -> ([], rows)
|
||||
(context, _) -> case changeIncludingContext context (drop (length context) rows) of
|
||||
Nothing -> ([], rows)
|
||||
Just (change, rest) -> let (changes, rest') = contiguousChanges rest in (change : changes, rest')
|
||||
|
||||
-- | Given beginning line numbers, return the number of lines to the next
|
||||
-- | the next change, and the remaining rows of the split diff.
|
||||
nextChange :: (Foldable f, Functor f) => Both (Sum Int) -> [Join These (SplitDiff f annotation)] -> Maybe (Both (Sum Int), Change (SplitDiff f annotation), [Join These (SplitDiff f annotation)])
|
||||
nextChange start rows = case changeIncludingContext leadingContext afterLeadingContext of
|
||||
Nothing -> Nothing
|
||||
Just (change, afterChanges) -> Just (start <> mconcat (rowIncrement <$> skippedContext), change, afterChanges)
|
||||
where (leadingRows, afterLeadingContext) = break rowHasChanges rows
|
||||
(skippedContext, leadingContext) = splitAt (max (length leadingRows - 3) 0) leadingRows
|
||||
|
||||
-- | Return a Change with the given context and the rows from the begginning of
|
||||
-- | the given rows that have changes, or Nothing if the first row has no
|
||||
-- | changes.
|
||||
changeIncludingContext :: (Foldable f, Functor f) => [Join These (SplitDiff f annotation)] -> [Join These (SplitDiff f annotation)] -> Maybe (Change (SplitDiff f annotation), [Join These (SplitDiff f annotation)])
|
||||
changeIncludingContext leadingContext rows = case changes of
|
||||
[] -> Nothing
|
||||
_ -> Just (Change leadingContext changes, afterChanges)
|
||||
where (changes, afterChanges) = span rowHasChanges rows
|
||||
|
||||
-- | Whether a row has changes on either side.
|
||||
rowHasChanges :: (Foldable f, Functor f) => Join These (SplitDiff f annotation) -> Bool
|
||||
rowHasChanges row = or (hasChanges <$> row)
|
||||
|
||||
maybeSnd :: These a b -> Maybe b
|
||||
maybeSnd = these (const Nothing) Just (\ _ a -> Just a)
|
@ -4,17 +4,20 @@ module Renderer.TOC
|
||||
, renderToCTerm
|
||||
, diffTOC
|
||||
, Summaries(..)
|
||||
, JSONSummary(..)
|
||||
, TOCSummary(..)
|
||||
, isValidSummary
|
||||
, Declaration(..)
|
||||
, getDeclaration
|
||||
, declaration
|
||||
, HasDeclaration
|
||||
, declarationAlgebra
|
||||
, syntaxDeclarationAlgebra
|
||||
, Entry(..)
|
||||
, tableOfContentsBy
|
||||
, termTableOfContentsBy
|
||||
, dedupe
|
||||
, entrySummary
|
||||
, toCategoryName
|
||||
) where
|
||||
|
||||
import Data.Aeson
|
||||
@ -40,7 +43,7 @@ import Data.Record
|
||||
import Data.Semigroup ((<>), sconcat)
|
||||
import Data.Source as Source
|
||||
import Data.Term
|
||||
import Data.Text (toLower)
|
||||
import Data.Text (toLower, stripEnd)
|
||||
import qualified Data.Text as T
|
||||
import Data.Union
|
||||
import GHC.Generics
|
||||
@ -67,8 +70,9 @@ instance Output Summaries where
|
||||
instance ToJSON Summaries where
|
||||
toJSON Summaries{..} = object [ "changes" .= changes, "errors" .= errors ]
|
||||
|
||||
data JSONSummary
|
||||
= JSONSummary
|
||||
|
||||
data TOCSummary
|
||||
= TOCSummary
|
||||
{ summaryCategoryName :: T.Text
|
||||
, summaryTermName :: T.Text
|
||||
, summarySpan :: Span
|
||||
@ -77,21 +81,21 @@ data JSONSummary
|
||||
| ErrorSummary { error :: T.Text, errorSpan :: Span, errorLanguage :: Maybe Language }
|
||||
deriving (Generic, Eq, Show)
|
||||
|
||||
instance ToJSON JSONSummary where
|
||||
toJSON JSONSummary{..} = object [ "changeType" .= summaryChangeType, "category" .= summaryCategoryName, "term" .= summaryTermName, "span" .= summarySpan ]
|
||||
instance ToJSON TOCSummary where
|
||||
toJSON TOCSummary{..} = object [ "changeType" .= summaryChangeType, "category" .= summaryCategoryName, "term" .= summaryTermName, "span" .= summarySpan ]
|
||||
toJSON ErrorSummary{..} = object [ "error" .= error, "span" .= errorSpan, "language" .= errorLanguage ]
|
||||
|
||||
isValidSummary :: JSONSummary -> Bool
|
||||
isValidSummary :: TOCSummary -> Bool
|
||||
isValidSummary ErrorSummary{} = False
|
||||
isValidSummary _ = True
|
||||
|
||||
-- | A declaration’s identifier and type.
|
||||
data Declaration
|
||||
= MethodDeclaration { declarationIdentifier :: T.Text }
|
||||
| ClassDeclaration { declarationIdentifier :: T.Text }
|
||||
| FunctionDeclaration { declarationIdentifier :: T.Text }
|
||||
| SectionDeclaration { declarationIdentifier :: T.Text, declarationLevel :: Int }
|
||||
| ErrorDeclaration { declarationIdentifier :: T.Text, declarationLanguage :: Maybe Language }
|
||||
= MethodDeclaration { declarationIdentifier :: T.Text, declarationText :: T.Text, declarationLanguage :: Maybe Language, declarationReceiver :: Maybe T.Text }
|
||||
| ClassDeclaration { declarationIdentifier :: T.Text, declarationText :: T.Text, declarationLanguage :: Maybe Language }
|
||||
| FunctionDeclaration { declarationIdentifier :: T.Text, declarationText :: T.Text, declarationLanguage :: Maybe Language }
|
||||
| HeadingDeclaration { declarationIdentifier :: T.Text, declarationText :: T.Text, declarationLanguage :: Maybe Language, declarationLevel :: Int }
|
||||
| ErrorDeclaration { declarationIdentifier :: T.Text, declarationText :: T.Text, declarationLanguage :: Maybe Language }
|
||||
deriving (Eq, Generic, Show)
|
||||
|
||||
|
||||
@ -131,43 +135,45 @@ class CustomHasDeclaration syntax where
|
||||
customToDeclaration :: (Foldable whole, HasField fields Range, HasField fields Span) => Blob -> Record fields -> RAlgebra syntax (Term whole (Record fields)) (Maybe Declaration)
|
||||
|
||||
|
||||
-- | Produce a 'SectionDeclaration' from the first line of the heading of a 'Markdown.Section' node.
|
||||
instance CustomHasDeclaration Markdown.Section where
|
||||
customToDeclaration Blob{..} _ (Markdown.Section level (Term (In headingAnn headingF), _) _)
|
||||
= Just $ SectionDeclaration (maybe (getSource (byteRange headingAnn)) (getSource . sconcat) (nonEmpty (byteRange . termAnnotation . unTerm <$> toList headingF))) level
|
||||
where getSource = firstLine . toText . flip Source.slice blobSource
|
||||
-- | Produce a 'HeadingDeclaration' from the first line of the heading of a 'Markdown.Heading' node.
|
||||
instance CustomHasDeclaration Markdown.Heading where
|
||||
customToDeclaration Blob{..} ann (Markdown.Heading level terms _)
|
||||
= Just $ HeadingDeclaration (headingText terms) mempty blobLanguage level
|
||||
where headingText terms = getSource $ maybe (byteRange ann) sconcat (nonEmpty (headingByteRange <$> toList terms))
|
||||
headingByteRange (Term (In ann _), _) = byteRange ann
|
||||
getSource = firstLine . toText . flip Source.slice blobSource
|
||||
firstLine = T.takeWhile (/= '\n')
|
||||
|
||||
-- | Produce an 'ErrorDeclaration' for 'Syntax.Error' nodes.
|
||||
instance CustomHasDeclaration Syntax.Error where
|
||||
customToDeclaration Blob{..} ann err@Syntax.Error{}
|
||||
= Just $ ErrorDeclaration (T.pack (formatTOCError (Syntax.unError (sourceSpan ann) err))) blobLanguage
|
||||
= Just $ ErrorDeclaration (T.pack (formatTOCError (Syntax.unError (sourceSpan ann) err))) mempty blobLanguage
|
||||
|
||||
-- | Produce a 'FunctionDeclaration' for 'Declaration.Function' nodes so long as their identifier is non-empty (defined as having a non-empty 'byteRange').
|
||||
instance CustomHasDeclaration Declaration.Function where
|
||||
customToDeclaration Blob{..} _ (Declaration.Function _ (Term (In identifierAnn _), _) _ _)
|
||||
customToDeclaration blob@Blob{..} ann decl@(Declaration.Function _ (Term (In identifierAnn _), _) _ _)
|
||||
-- Do not summarize anonymous functions
|
||||
| isEmpty identifierAnn = Nothing
|
||||
-- Named functions
|
||||
| otherwise = Just $ FunctionDeclaration (getSource identifierAnn)
|
||||
| otherwise = Just $ FunctionDeclaration (getSource identifierAnn) (getFunctionSource blob (In ann decl)) blobLanguage
|
||||
where getSource = toText . flip Source.slice blobSource . byteRange
|
||||
isEmpty = (== 0) . rangeLength . byteRange
|
||||
|
||||
-- | Produce a 'MethodDeclaration' for 'Declaration.Method' nodes. If the method’s receiver is non-empty (defined as having a non-empty 'byteRange'), the 'declarationIdentifier' will be formatted as 'receiver.method_name'; otherwise it will be simply 'method_name'.
|
||||
instance CustomHasDeclaration Declaration.Method where
|
||||
customToDeclaration Blob{..} _ (Declaration.Method _ (Term (In receiverAnn _), _) (Term (In identifierAnn _), _) _ _)
|
||||
customToDeclaration blob@Blob{..} ann decl@(Declaration.Method _ (Term (In receiverAnn _), _) (Term (In identifierAnn _), _) _ _)
|
||||
-- Methods without a receiver
|
||||
| isEmpty receiverAnn = Just $ MethodDeclaration (getSource identifierAnn)
|
||||
| isEmpty receiverAnn = Just $ MethodDeclaration (getSource identifierAnn) (getMethodSource blob (In ann decl)) blobLanguage Nothing
|
||||
-- Methods with a receiver (class methods) are formatted like `receiver.method_name`
|
||||
| otherwise = Just $ MethodDeclaration (getSource receiverAnn <> "." <> getSource identifierAnn)
|
||||
| otherwise = Just $ MethodDeclaration (getSource identifierAnn) (getMethodSource blob (In ann decl)) blobLanguage (Just (getSource receiverAnn))
|
||||
where getSource = toText . flip Source.slice blobSource . byteRange
|
||||
isEmpty = (== 0) . rangeLength . byteRange
|
||||
|
||||
-- | Produce a 'ClassDeclaration' for 'Declaration.Class' nodes.
|
||||
instance CustomHasDeclaration Declaration.Class where
|
||||
customToDeclaration Blob{..} _ (Declaration.Class _ (Term (In identifierAnn _), _) _ _)
|
||||
customToDeclaration blob@Blob{..} ann decl@(Declaration.Class _ (Term (In identifierAnn _), _) _ _)
|
||||
-- Classes
|
||||
= Just $ ClassDeclaration (getSource identifierAnn)
|
||||
= Just $ ClassDeclaration (getSource identifierAnn) (getClassSource blob (In ann decl)) blobLanguage
|
||||
where getSource = toText . flip Source.slice blobSource . byteRange
|
||||
|
||||
-- | Produce a 'Declaration' for 'Union's using the 'HasDeclaration' instance & therefore using a 'CustomHasDeclaration' instance when one exists & the type is listed in 'DeclarationStrategy'.
|
||||
@ -194,7 +200,7 @@ type family DeclarationStrategy syntax where
|
||||
DeclarationStrategy Declaration.Class = 'Custom
|
||||
DeclarationStrategy Declaration.Function = 'Custom
|
||||
DeclarationStrategy Declaration.Method = 'Custom
|
||||
DeclarationStrategy Markdown.Section = 'Custom
|
||||
DeclarationStrategy Markdown.Heading = 'Custom
|
||||
DeclarationStrategy Syntax.Error = 'Custom
|
||||
DeclarationStrategy (Union fs) = 'Custom
|
||||
DeclarationStrategy a = 'Default
|
||||
@ -219,17 +225,47 @@ declaration (In annotation _) = annotation <$ getDeclaration annotation
|
||||
|
||||
-- | Compute 'Declaration's for methods and functions in 'Syntax'.
|
||||
syntaxDeclarationAlgebra :: HasField fields Range => Blob -> RAlgebra (TermF S.Syntax (Record fields)) (Term S.Syntax (Record fields)) (Maybe Declaration)
|
||||
syntaxDeclarationAlgebra Blob{..} (In a r) = case r of
|
||||
S.Function (identifier, _) _ _ -> Just $ FunctionDeclaration (getSource identifier)
|
||||
S.Method _ (identifier, _) Nothing _ _ -> Just $ MethodDeclaration (getSource identifier)
|
||||
syntaxDeclarationAlgebra blob@Blob{..} decl@(In a r) = case r of
|
||||
S.Function (identifier, _) _ _ -> Just $ FunctionDeclaration (getSource identifier) (getSyntaxDeclarationSource blob decl) blobLanguage
|
||||
S.Method _ (identifier, _) Nothing _ _ -> Just $ MethodDeclaration (getSource identifier) (getSyntaxDeclarationSource blob decl) blobLanguage Nothing
|
||||
S.Method _ (identifier, _) (Just (receiver, _)) _ _
|
||||
| S.Indexed [receiverParams] <- unwrap receiver
|
||||
, S.ParameterDecl (Just ty) _ <- unwrap receiverParams -> Just $ MethodDeclaration ("(" <> getSource ty <> ") " <> getSource identifier)
|
||||
| otherwise -> Just $ MethodDeclaration (getSource receiver <> "." <> getSource identifier)
|
||||
S.ParseError{} -> Just $ ErrorDeclaration (toText (Source.slice (byteRange a) blobSource)) blobLanguage
|
||||
, S.ParameterDecl (Just ty) _ <- unwrap receiverParams -> Just $ MethodDeclaration (getSource identifier) (getSyntaxDeclarationSource blob decl) blobLanguage (Just (getSource ty))
|
||||
| otherwise -> Just $ MethodDeclaration (getSource identifier) (getSyntaxDeclarationSource blob decl) blobLanguage (Just (getSource receiver))
|
||||
S.ParseError{} -> Just $ ErrorDeclaration (toText (Source.slice (byteRange a) blobSource)) mempty blobLanguage
|
||||
_ -> Nothing
|
||||
where getSource = toText . flip Source.slice blobSource . byteRange . extract
|
||||
where
|
||||
getSource = toText . flip Source.slice blobSource . byteRange . extract
|
||||
|
||||
getMethodSource :: HasField fields Range => Blob -> TermF Declaration.Method (Record fields) (Term syntax (Record fields), a) -> T.Text
|
||||
getMethodSource Blob{..} (In a r)
|
||||
= let declRange = byteRange a
|
||||
bodyRange = byteRange <$> case r of
|
||||
Declaration.Method _ _ _ _ (Term (In a' _), _) -> Just a'
|
||||
in maybe mempty (stripEnd . toText . flip Source.slice blobSource . subtractRange declRange) bodyRange
|
||||
|
||||
getFunctionSource :: HasField fields Range => Blob -> TermF Declaration.Function (Record fields) (Term syntax (Record fields), a) -> T.Text
|
||||
getFunctionSource Blob{..} (In a r)
|
||||
= let declRange = byteRange a
|
||||
bodyRange = byteRange <$> case r of
|
||||
Declaration.Function _ _ _ (Term (In a' _), _) -> Just a'
|
||||
in maybe mempty (stripEnd . toText . flip Source.slice blobSource . subtractRange declRange) bodyRange
|
||||
|
||||
getClassSource :: (HasField fields Range) => Blob -> TermF Declaration.Class (Record fields) (Term syntax (Record fields), a) -> T.Text
|
||||
getClassSource Blob{..} (In a r)
|
||||
= let declRange = byteRange a
|
||||
bodyRange = byteRange <$> case r of
|
||||
Declaration.Class _ _ _ (Term (In a' _), _) -> Just a'
|
||||
in maybe mempty (stripEnd . toText . flip Source.slice blobSource . subtractRange declRange) bodyRange
|
||||
|
||||
getSyntaxDeclarationSource :: HasField fields Range => Blob -> TermF Syntax (Record fields) (Term syntax (Record fields), a) -> T.Text
|
||||
getSyntaxDeclarationSource Blob{..} (In a r)
|
||||
= let declRange = byteRange a
|
||||
bodyRange = byteRange <$> case r of
|
||||
S.Function _ _ ((Term (In a' _), _) : _) -> Just a'
|
||||
S.Method _ _ _ _ ((Term (In a' _), _) : _) -> Just a'
|
||||
_ -> Nothing
|
||||
in maybe mempty (stripEnd . toText . flip Source.slice blobSource . subtractRange declRange) bodyRange
|
||||
|
||||
formatTOCError :: Error.Error String -> String
|
||||
formatTOCError e = showExpectation False (errorExpected e) (errorActual e) ""
|
||||
@ -261,7 +297,7 @@ termTableOfContentsBy :: (Foldable f, Functor f)
|
||||
-> Term f annotation
|
||||
-> [a]
|
||||
termTableOfContentsBy selector = cata termAlgebra
|
||||
where termAlgebra r | Just a <- selector r = [a]
|
||||
where termAlgebra r | Just a <- selector r = a : fold r
|
||||
| otherwise = fold r
|
||||
|
||||
|
||||
@ -292,20 +328,24 @@ dedupe = let tuples = sortOn fst . Map.elems . snd . foldl' go (0, Map.empty) in
|
||||
dedupeKey entry = DedupeKey ((fmap toCategoryName . getDeclaration . entryPayload) entry, (fmap (toLower . declarationIdentifier) . getDeclaration . entryPayload) entry)
|
||||
exactMatch = (==) `on` (getDeclaration . entryPayload)
|
||||
|
||||
-- | Construct a 'JSONSummary' from an 'Entry'.
|
||||
entrySummary :: (HasField fields (Maybe Declaration), HasField fields Span) => Entry (Record fields) -> Maybe JSONSummary
|
||||
-- | Construct a 'TOCSummary' from an 'Entry'.
|
||||
entrySummary :: (HasField fields (Maybe Declaration), HasField fields Span) => Entry (Record fields) -> Maybe TOCSummary
|
||||
entrySummary entry = case entry of
|
||||
Changed a -> recordSummary a "modified"
|
||||
Deleted a -> recordSummary a "removed"
|
||||
Inserted a -> recordSummary a "added"
|
||||
Replaced a -> recordSummary a "modified"
|
||||
Changed a -> recordSummary "modified" a
|
||||
Deleted a -> recordSummary "removed" a
|
||||
Inserted a -> recordSummary "added" a
|
||||
Replaced a -> recordSummary "modified" a
|
||||
|
||||
-- | Construct a 'JSONSummary' from a node annotation and a change type label.
|
||||
recordSummary :: (HasField fields (Maybe Declaration), HasField fields Span) => Record fields -> T.Text -> Maybe JSONSummary
|
||||
recordSummary record = case getDeclaration record of
|
||||
Just (ErrorDeclaration text language) -> Just . const (ErrorSummary text (sourceSpan record) language)
|
||||
Just declaration -> Just . JSONSummary (toCategoryName declaration) (declarationIdentifier declaration) (sourceSpan record)
|
||||
Nothing -> const Nothing
|
||||
-- | Construct a 'TOCSummary' from a node annotation and a change type label.
|
||||
recordSummary :: (HasField fields (Maybe Declaration), HasField fields Span) => T.Text -> Record fields -> Maybe TOCSummary
|
||||
recordSummary changeText record = case getDeclaration record of
|
||||
Just (ErrorDeclaration text _ language) -> Just $ ErrorSummary text (sourceSpan record) language
|
||||
Just declaration -> Just $ TOCSummary (toCategoryName declaration) (formatIdentifier declaration) (sourceSpan record) changeText
|
||||
Nothing -> Nothing
|
||||
where
|
||||
formatIdentifier (MethodDeclaration identifier _ (Just Language.Go) (Just receiver)) = "(" <> receiver <> ") " <> identifier
|
||||
formatIdentifier (MethodDeclaration identifier _ _ (Just receiver)) = receiver <> "." <> identifier
|
||||
formatIdentifier declaration = declarationIdentifier declaration
|
||||
|
||||
renderToCDiff :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Both Blob -> Diff f (Record fields) (Record fields) -> Summaries
|
||||
renderToCDiff blobs = uncurry Summaries . bimap toMap toMap . List.partition isValidSummary . diffTOC
|
||||
@ -317,22 +357,23 @@ renderToCDiff blobs = uncurry Summaries . bimap toMap toMap . List.partition isV
|
||||
| before == after -> after
|
||||
| otherwise -> before <> " -> " <> after
|
||||
|
||||
renderToCTerm :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Blob -> Term f (Record fields) -> Summaries
|
||||
renderToCTerm Blob{..} = uncurry Summaries . bimap toMap toMap . List.partition isValidSummary . termToC
|
||||
where toMap [] = mempty
|
||||
toMap as = Map.singleton (T.pack blobPath) (toJSON <$> as)
|
||||
|
||||
diffTOC :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Diff f (Record fields) (Record fields) -> [JSONSummary]
|
||||
diffTOC :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Diff f (Record fields) (Record fields) -> [TOCSummary]
|
||||
diffTOC = mapMaybe entrySummary . dedupe . tableOfContentsBy declaration
|
||||
|
||||
termToC :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Term f (Record fields) -> [JSONSummary]
|
||||
termToC = mapMaybe (flip recordSummary "unchanged") . termTableOfContentsBy declaration
|
||||
renderToCTerm :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Blob -> Term f (Record fields) -> Summaries
|
||||
renderToCTerm Blob{..} = uncurry Summaries . bimap toMap toMap . List.partition isValidSummary . termToC
|
||||
where
|
||||
toMap [] = mempty
|
||||
toMap as = Map.singleton (T.pack blobPath) (toJSON <$> as)
|
||||
|
||||
termToC :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Term f (Record fields) -> [TOCSummary]
|
||||
termToC = mapMaybe (recordSummary "unchanged") . termTableOfContentsBy declaration
|
||||
|
||||
-- The user-facing category name
|
||||
toCategoryName :: Declaration -> T.Text
|
||||
toCategoryName declaration = case declaration of
|
||||
FunctionDeclaration _ -> "Function"
|
||||
ClassDeclaration _ -> "Class"
|
||||
MethodDeclaration _ -> "Method"
|
||||
SectionDeclaration _ l -> "Heading " <> T.pack (show l)
|
||||
ClassDeclaration{} -> "Class"
|
||||
FunctionDeclaration{} -> "Function"
|
||||
MethodDeclaration{} -> "Method"
|
||||
HeadingDeclaration _ _ _ l -> "Heading " <> T.pack (show l)
|
||||
ErrorDeclaration{} -> "ParseError"
|
||||
|
46
src/Renderer/Tag.hs
Normal file
46
src/Renderer/Tag.hs
Normal file
@ -0,0 +1,46 @@
|
||||
{-# LANGUAGE DataKinds, MultiParamTypeClasses, RankNTypes, ScopedTypeVariables, TypeFamilies, TypeOperators, UndecidableInstances #-}
|
||||
module Renderer.Tag
|
||||
( renderToTags
|
||||
) where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Blob
|
||||
import Data.Maybe (mapMaybe)
|
||||
import Data.Record
|
||||
import Data.Term
|
||||
import GHC.Generics
|
||||
import Info
|
||||
import qualified Data.Text as T
|
||||
import Renderer.TOC
|
||||
|
||||
-- | Render a 'Term' to a ctags like output (See 'Tag').
|
||||
renderToTags :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Blob -> Term f (Record fields) -> [Value]
|
||||
renderToTags Blob{..} = fmap toJSON . termToC blobPath
|
||||
where
|
||||
termToC :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => FilePath -> Term f (Record fields) -> [Tag]
|
||||
termToC path = mapMaybe (tagSummary path "unchanged") . termTableOfContentsBy declaration
|
||||
|
||||
-- | Construct a 'Tag' from a node annotation and a change type label.
|
||||
tagSummary :: (HasField fields (Maybe Declaration), HasField fields Span) => FilePath -> T.Text -> Record fields -> Maybe Tag
|
||||
tagSummary path _ record = case getDeclaration record of
|
||||
Just ErrorDeclaration{} -> Nothing
|
||||
Just declaration -> Just $ Tag (declarationIdentifier declaration) (T.pack path) (T.pack . show <$> declarationLanguage declaration) (toCategoryName declaration) (declarationText declaration) (sourceSpan record)
|
||||
_ -> Nothing
|
||||
|
||||
data Tag
|
||||
= Tag { tagSymbol :: T.Text
|
||||
, tagPath :: T.Text
|
||||
, tagLanguage :: Maybe T.Text
|
||||
, tagKind :: T.Text
|
||||
, tagLine :: T.Text
|
||||
, tagSpan :: Span
|
||||
}
|
||||
deriving (Generic, Eq, Show)
|
||||
|
||||
instance ToJSON Tag where
|
||||
toJSON Tag{..} = object [ "symbol" .= tagSymbol
|
||||
, "path" .= tagPath
|
||||
, "language" .= tagLanguage
|
||||
, "kind" .= tagKind
|
||||
, "line" .= tagLine
|
||||
, "span" .= tagSpan ]
|
104
src/Semantic.hs
104
src/Semantic.hs
@ -9,16 +9,17 @@ module Semantic
|
||||
|
||||
import Algorithm (Diffable)
|
||||
import Control.Exception
|
||||
import Control.Monad ((<=<))
|
||||
import Control.Monad ((>=>), guard)
|
||||
import Control.Monad.Error.Class
|
||||
import Data.Align.Generic
|
||||
import Data.Bifoldable
|
||||
import Data.Blob
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.Diff
|
||||
import Data.Functor.Both as Both
|
||||
import Data.Functor.Classes
|
||||
import Data.JSON.Fields
|
||||
import Data.Output
|
||||
import Data.Bifoldable
|
||||
import Data.Record
|
||||
import Data.Syntax.Algebra
|
||||
import Data.Term
|
||||
@ -45,26 +46,22 @@ parseBlobs renderer = fmap toOutput . distributeFoldMap (parseBlob renderer) . f
|
||||
|
||||
-- | A task to parse a 'Blob' and render the resulting 'Term'.
|
||||
parseBlob :: TermRenderer output -> Blob -> Task output
|
||||
parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of
|
||||
(ToCTermRenderer, lang)
|
||||
| Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) ->
|
||||
parse parser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob)
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob) >>= render (renderToCTerm blob)
|
||||
parseBlob renderer blob@Blob{..}
|
||||
| Just (SomeParser parser) <- blobLanguage >>= someParser (Proxy :: Proxy '[ConstructorName, HasDeclaration, Foldable, Functor, ToJSONFields1])
|
||||
= parse parser blob >>= case renderer of
|
||||
ToCTermRenderer -> decorate (declarationAlgebra blob) >=> render (renderToCTerm blob)
|
||||
JSONTermRenderer -> decorate constructorLabel >=> render (renderJSONTerm blob)
|
||||
SExpressionTermRenderer -> decorate constructorLabel . (Nil <$) >=> render renderSExpressionTerm
|
||||
TagsTermRenderer -> decorate (declarationAlgebra blob) >=> render (renderToTags blob)
|
||||
|
||||
(JSONTermRenderer, lang)
|
||||
| Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) ->
|
||||
parse parser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob)
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
parse syntaxParser blob >>= decorate syntaxIdentifierAlgebra >>= render (renderJSONTerm blob)
|
||||
| Just parser <- blobLanguage >>= syntaxParserForLanguage
|
||||
= parse parser blob >>= case renderer of
|
||||
ToCTermRenderer -> decorate (syntaxDeclarationAlgebra blob) >=> render (renderToCTerm blob)
|
||||
JSONTermRenderer -> decorate syntaxIdentifierAlgebra >=> render (renderJSONTerm blob)
|
||||
SExpressionTermRenderer -> render renderSExpressionTerm . fmap keepCategory
|
||||
TagsTermRenderer -> decorate (syntaxDeclarationAlgebra blob) >=> render (renderToTags blob)
|
||||
|
||||
(SExpressionTermRenderer, lang)
|
||||
| Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) ->
|
||||
parse parser blob >>= decorate constructorLabel . (Nil <$) >>= render renderSExpressionTerm
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
parse syntaxParser blob >>= render renderSExpressionTerm . fmap keepCategory
|
||||
|
||||
_ -> throwError (SomeException (NoParserForLanguage blobPath blobLanguage))
|
||||
| otherwise = throwError (SomeException (NoParserForLanguage blobPath blobLanguage))
|
||||
|
||||
data NoParserForLanguage = NoParserForLanguage FilePath (Maybe Language.Language)
|
||||
deriving (Eq, Exception, Ord, Show, Typeable)
|
||||
@ -75,58 +72,45 @@ diffBlobPairs renderer = fmap toOutput . distributeFoldMap (diffBlobPair rendere
|
||||
|
||||
-- | A task to parse a pair of 'Blob's, diff them, and render the 'Diff'.
|
||||
diffBlobPair :: DiffRenderer output -> Both Blob -> Task output
|
||||
diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of
|
||||
(OldToCDiffRenderer, lang)
|
||||
| elem lang $ fmap Just [
|
||||
Language.JSX,
|
||||
Language.JavaScript,
|
||||
Language.Markdown,
|
||||
Language.Python,
|
||||
Language.Ruby,
|
||||
Language.TypeScript
|
||||
]
|
||||
, Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, HasDeclaration, Show1, Traversable]) ->
|
||||
run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms (renderToCDiff blobs)
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
run (\ blob -> parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffSyntaxTerms (renderToCDiff blobs)
|
||||
diffBlobPair renderer blobs
|
||||
| Just (SomeParser parser) <- effectiveLanguage >>= qualify >>= someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, GAlign, HasDeclaration, Show1, ToJSONFields1, Traversable])
|
||||
= case renderer of
|
||||
OldToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms renderToCDiff
|
||||
ToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms renderToCDiff
|
||||
JSONDiffRenderer -> run ( parse parser) diffTerms renderJSONDiff
|
||||
SExpressionDiffRenderer -> run ( parse parser >=> decorate constructorLabel . (Nil <$)) diffTerms (const renderSExpressionDiff)
|
||||
|
||||
(ToCDiffRenderer, lang)
|
||||
| Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, HasDeclaration, Show1, Traversable]) ->
|
||||
run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms (renderToCDiff blobs)
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
run (\ blob -> parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffSyntaxTerms (renderToCDiff blobs)
|
||||
| Just parser <- effectiveLanguage >>= syntaxParserForLanguage
|
||||
= case renderer of
|
||||
OldToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffSyntaxTerms renderToCDiff
|
||||
ToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffSyntaxTerms renderToCDiff
|
||||
JSONDiffRenderer -> run ( parse parser >=> decorate syntaxIdentifierAlgebra) diffSyntaxTerms renderJSONDiff
|
||||
SExpressionDiffRenderer -> run ( parse parser >=> pure . fmap keepCategory) diffSyntaxTerms (const renderSExpressionDiff)
|
||||
|
||||
(JSONDiffRenderer, lang)
|
||||
| Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) ->
|
||||
run (parse parser) diffTerms (renderJSONDiff blobs)
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
run (decorate syntaxIdentifierAlgebra <=< parse syntaxParser) diffSyntaxTerms (renderJSONDiff blobs)
|
||||
|
||||
(PatchDiffRenderer, lang)
|
||||
| Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) ->
|
||||
run (parse parser) diffTerms (renderPatch blobs)
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
run (parse syntaxParser) diffSyntaxTerms (renderPatch blobs)
|
||||
|
||||
(SExpressionDiffRenderer, lang)
|
||||
| Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) ->
|
||||
run (decorate constructorLabel . (Nil <$) <=< parse parser) diffTerms renderSExpressionDiff
|
||||
| Just syntaxParser <- lang >>= syntaxParserForLanguage ->
|
||||
run (fmap (fmap keepCategory) . parse syntaxParser) diffSyntaxTerms renderSExpressionDiff
|
||||
|
||||
_ -> throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage))
|
||||
| otherwise = throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage))
|
||||
where (effectivePath, effectiveLanguage) = case runJoin blobs of
|
||||
(Blob { blobLanguage = Just lang, blobPath = path }, _) -> (path, Just lang)
|
||||
(_, Blob { blobLanguage = Just lang, blobPath = path }) -> (path, Just lang)
|
||||
(Blob { blobPath = path }, _) -> (path, Nothing)
|
||||
|
||||
run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Diff syntax ann ann -> output) -> Task output
|
||||
qualify language | OldToCDiffRenderer <- renderer = guard (language `elem` aLaCarteLanguages) *> Just language
|
||||
| otherwise = Just language
|
||||
aLaCarteLanguages
|
||||
= [ Language.JSX
|
||||
, Language.JavaScript
|
||||
, Language.Markdown
|
||||
, Language.Python
|
||||
, Language.Ruby
|
||||
, Language.TypeScript
|
||||
]
|
||||
|
||||
run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Both Blob -> Diff syntax ann ann -> output) -> Task output
|
||||
run parse diff renderer = do
|
||||
terms <- distributeFor blobs parse
|
||||
time "diff" languageTag $ do
|
||||
diff <- runBothWith (diffTermPair blobs diff) terms
|
||||
writeStat (Stat.count "diff.nodes" (bilength diff) languageTag)
|
||||
render renderer diff
|
||||
render (renderer blobs) diff
|
||||
where
|
||||
showLanguage = pure . (,) "language" . show
|
||||
languageTag = let (a, b) = runJoin blobs
|
||||
|
@ -32,6 +32,7 @@ import Control.Parallel.Strategies
|
||||
import qualified Control.Concurrent.Async as Async
|
||||
import Control.Monad.Free.Freer
|
||||
import Data.Blob
|
||||
import Data.Bool
|
||||
import qualified Data.ByteString as B
|
||||
import Data.Diff
|
||||
import qualified Data.Error as Error
|
||||
@ -175,7 +176,9 @@ runTaskWithOptions options task = do
|
||||
where
|
||||
go :: Task a -> IO (Either SomeException a)
|
||||
go = iterFreerA (\ task yield -> case task of
|
||||
ReadBlobs source -> (either Files.readBlobsFromHandle (traverse (uncurry Files.readFile)) source >>= yield) `catchError` (pure . Left . toException)
|
||||
ReadBlobs (Left handle) -> (Files.readBlobsFromHandle handle >>= yield) `catchError` (pure . Left . toException)
|
||||
ReadBlobs (Right paths@[(path, Nothing)]) -> (Files.isDirectory path >>= bool (Files.readBlobsFromPaths paths) (Files.readBlobsFromDir path) >>= yield) `catchError` (pure . Left . toException)
|
||||
ReadBlobs (Right paths) -> (Files.readBlobsFromPaths paths >>= yield) `catchError` (pure . Left . toException)
|
||||
ReadBlobPairs source -> (either Files.readBlobPairsFromHandle (traverse (traverse (uncurry Files.readFile))) source >>= yield) `catchError` (pure . Left . toException)
|
||||
WriteToOutput destination contents -> either B.hPutStr B.writeFile destination contents >>= yield
|
||||
WriteLog level message pairs -> queueLogMessage logger level message pairs >>= yield
|
||||
|
@ -62,11 +62,10 @@ arguments = info (version <*> helper <*> ((,) <$> optionsParser <*> argumentsPar
|
||||
|
||||
diffCommand = command "diff" (info diffArgumentsParser (progDesc "Show changes between commits or paths"))
|
||||
diffArgumentsParser = runDiff
|
||||
<$> ( flag (SomeRenderer PatchDiffRenderer) (SomeRenderer PatchDiffRenderer) (long "patch" <> help "Output a patch(1)-compatible diff (default)")
|
||||
<|> flag' (SomeRenderer JSONDiffRenderer) (long "json" <> help "Output a json diff")
|
||||
<|> flag' (SomeRenderer SExpressionDiffRenderer) (long "sexpression" <> help "Output an s-expression diff tree")
|
||||
<|> flag' (SomeRenderer OldToCDiffRenderer) (long "toc" <> help "Output a table of contents for a diff")
|
||||
<|> flag' (SomeRenderer ToCDiffRenderer) (long "toc-assignment" <> help "Output a table of contents for a diff using the assignment parser") )
|
||||
<$> ( flag (SomeRenderer SExpressionDiffRenderer) (SomeRenderer SExpressionDiffRenderer) (long "sexpression" <> help "Output s-expression diff tree")
|
||||
<|> flag' (SomeRenderer JSONDiffRenderer) (long "json" <> help "Output JSON diff trees")
|
||||
<|> flag' (SomeRenderer OldToCDiffRenderer) (long "toc" <> help "Output JSON table of contents diff summary")
|
||||
<|> flag' (SomeRenderer ToCDiffRenderer) (long "toc-assignment" <> help "Output JSON table of contents diff summary using the assignment parser") )
|
||||
<*> ( Right <$> some (both
|
||||
<$> argument filePathReader (metavar "FILE_A")
|
||||
<*> argument filePathReader (metavar "FILE_B"))
|
||||
@ -76,7 +75,8 @@ arguments = info (version <*> helper <*> ((,) <$> optionsParser <*> argumentsPar
|
||||
parseArgumentsParser = runParse
|
||||
<$> ( flag (SomeRenderer SExpressionTermRenderer) (SomeRenderer SExpressionTermRenderer) (long "sexpression" <> help "Output s-expression parse trees (default)")
|
||||
<|> flag' (SomeRenderer JSONTermRenderer) (long "json" <> help "Output JSON parse trees")
|
||||
<|> flag' (SomeRenderer ToCTermRenderer) (long "toc" <> help "Output a table of contents for a file"))
|
||||
<|> flag' (SomeRenderer ToCTermRenderer) (long "toc" <> help "Output JSON table of contents summary")
|
||||
<|> flag' (SomeRenderer TagsTermRenderer) (long "tags" <> help "Output JSON tags/symbols"))
|
||||
<*> ( Right <$> some (argument filePathReader (metavar "FILES..."))
|
||||
<|> pure (Left stdin) )
|
||||
|
||||
|
@ -20,7 +20,6 @@ import Data.Term
|
||||
import Data.Text (Text, pack)
|
||||
import Language
|
||||
import qualified Language.Go as Go
|
||||
import qualified Language.TypeScript as TypeScript
|
||||
import Foreign
|
||||
import Foreign.C.String (peekCString)
|
||||
import Foreign.Marshal.Array (allocaArray)
|
||||
@ -29,7 +28,6 @@ import qualified TreeSitter.Document as TS
|
||||
import qualified TreeSitter.Node as TS
|
||||
import qualified TreeSitter.Language as TS
|
||||
import qualified TreeSitter.Go as TS
|
||||
import qualified TreeSitter.TypeScript as TS
|
||||
import Info
|
||||
|
||||
-- | Returns a TreeSitter parser for the given language and TreeSitter grammar.
|
||||
@ -112,7 +110,6 @@ assignTerm language source annotation children allChildren =
|
||||
where assignTermByLanguage :: Source -> Category -> [ Term S.Syntax (Record DefaultFields) ] -> Maybe (S.Syntax (Term S.Syntax (Record DefaultFields)))
|
||||
assignTermByLanguage = case languageForTSLanguage language of
|
||||
Just Language.Go -> Go.termAssignment
|
||||
Just TypeScript -> TypeScript.termAssignment
|
||||
_ -> \ _ _ _ -> Nothing
|
||||
|
||||
defaultTermAssignment :: Source -> Record DefaultFields -> [ Term S.Syntax (Record DefaultFields) ] -> IO [ Term S.Syntax (Record DefaultFields) ] -> IO (Term S.Syntax (Record DefaultFields))
|
||||
@ -190,12 +187,10 @@ categoryForLanguageProductionName = withDefaults . byLanguage
|
||||
|
||||
byLanguage language = case languageForTSLanguage language of
|
||||
Just Language.Go -> Go.categoryForGoName
|
||||
Just Language.TypeScript -> TypeScript.categoryForTypeScriptName
|
||||
_ -> Other
|
||||
|
||||
|
||||
languageForTSLanguage :: Ptr TS.Language -> Maybe Language
|
||||
languageForTSLanguage = flip lookup
|
||||
[ (TS.tree_sitter_go, Language.Go)
|
||||
, (TS.tree_sitter_typescript, TypeScript)
|
||||
]
|
||||
|
@ -1,280 +0,0 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
module AlignmentSpec where
|
||||
|
||||
import Alignment
|
||||
import Control.Arrow ((&&&))
|
||||
import Control.Monad.Free (wrap)
|
||||
import Control.Monad.State
|
||||
import Data.Align hiding (align)
|
||||
import Data.Bifunctor
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Diff
|
||||
import Data.Functor.Both as Both hiding (fst, snd)
|
||||
import Data.Functor.Listable
|
||||
import Data.List (nub, sort)
|
||||
import Data.Maybe (catMaybes, fromMaybe)
|
||||
import Data.Monoid hiding ((<>))
|
||||
import Data.Range
|
||||
import Data.Record
|
||||
import Data.Semigroup ((<>))
|
||||
import qualified Data.Source as Source
|
||||
import Data.SplitDiff
|
||||
import Data.Term
|
||||
import qualified Data.Text as Text
|
||||
import Data.These
|
||||
import Syntax
|
||||
import Test.Hspec (Spec, describe, it, parallel)
|
||||
import Test.Hspec.Expectations.Pretty
|
||||
import Test.Hspec.LeanCheck
|
||||
import Test.LeanCheck
|
||||
import GHC.Show (Show(..))
|
||||
|
||||
spec :: Spec
|
||||
spec = parallel $ do
|
||||
describe "alignBranch" $ do
|
||||
it "produces symmetrical context" $
|
||||
alignBranch getRange ([] :: [Join These (SplitDiff Syntax (Record '[Range]))]) (both [Range 0 2, Range 2 4] [Range 0 2, Range 2 4]) `shouldBe`
|
||||
[ Join (These (Range 0 2, [])
|
||||
(Range 0 2, []))
|
||||
, Join (These (Range 2 4, [])
|
||||
(Range 2 4, []))
|
||||
]
|
||||
|
||||
it "produces asymmetrical context" $
|
||||
alignBranch getRange ([] :: [Join These (SplitDiff Syntax (Record '[Range]))]) (both [Range 0 2, Range 2 4] [Range 0 1]) `shouldBe`
|
||||
[ Join (These (Range 0 2, [])
|
||||
(Range 0 1, []))
|
||||
, Join (This (Range 2 4, []))
|
||||
]
|
||||
|
||||
prop "covers every input line" $
|
||||
\ elements -> let (_, children, ranges) = toAlignBranchInputs elements in
|
||||
join <$> traverse (modifyJoin (fromThese [] []) . fmap (pure . fst)) (alignBranch snd children ranges) `shouldBe` ranges
|
||||
|
||||
prop "covers every input child" $
|
||||
\ elements -> let (_, children, ranges) = toAlignBranchInputs elements in
|
||||
sort (nub (keysOfAlignedChildren (alignBranch snd children ranges))) `shouldBe` sort (nub (catMaybes (branchElementKey <$> elements)))
|
||||
|
||||
prop "covers every line of every input child" $
|
||||
\ elements -> let (_, children, ranges) = toAlignBranchInputs elements in
|
||||
sort (keysOfAlignedChildren (alignBranch snd children ranges)) `shouldBe` sort (do
|
||||
line <- children
|
||||
these (pure . fst) (pure . fst) (\ (k1, _) (k2, _) -> [ k1, k2 ]) . runJoin $ line)
|
||||
|
||||
describe "alignDiff" $ do
|
||||
it "aligns identical branches on a single line" $
|
||||
let sources = both (Source.fromText "[ foo ]") (Source.fromText "[ foo ]") in
|
||||
align sources ((info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])
|
||||
(wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])) ]
|
||||
|
||||
it "aligns identical branches spanning multiple lines" $
|
||||
let sources = both (Source.fromText "[\nfoo\n]") (Source.fromText "[\nfoo\n]") in
|
||||
align sources ((info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 2 `In` [])
|
||||
(wrap $ info 0 2 `In` []))
|
||||
, Join (These (wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ])
|
||||
(wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ]))
|
||||
, Join (These (wrap $ info 6 7 `In` [])
|
||||
(wrap $ info 6 7 `In` []))
|
||||
]
|
||||
|
||||
it "aligns reformatted branches" $
|
||||
let sources = both (Source.fromText "[ foo ]") (Source.fromText "[\nfoo\n]") in
|
||||
align sources ((info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (That (wrap $ info 0 2 `In` []))
|
||||
, Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])
|
||||
(wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ]))
|
||||
, Join (That (wrap $ info 6 7 `In` []))
|
||||
]
|
||||
|
||||
it "aligns nodes following reformatted branches" $
|
||||
let sources = both (Source.fromText "[ foo ]\nbar\n") (Source.fromText "[\nfoo\n]\nbar\n") in
|
||||
align sources ((info 0 12, info 0 12) `merge` Indexed [ (info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ], (info 8 11, info 8 11) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (That (wrap $ info 0 2 `In` [ wrap $ info 0 2 `In` [] ]))
|
||||
, Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ] ])
|
||||
(wrap $ info 2 6 `In` [ wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ] ]))
|
||||
, Join (That (wrap $ info 6 8 `In` [ wrap $ info 6 7 `In` [] ]))
|
||||
, Join (These (wrap $ info 8 12 `In` [ wrap $ info 8 11 `In` [] ])
|
||||
(wrap $ info 8 12 `In` [ wrap $ info 8 11 `In` [] ]))
|
||||
, Join (These (wrap $ info 12 12 `In` [])
|
||||
(wrap $ info 12 12 `In` []))
|
||||
]
|
||||
|
||||
it "aligns identical branches with multiple children on the same line" $
|
||||
let sources = pure (Source.fromText "[ foo, bar ]") in
|
||||
align sources ((info 0 12, info 0 12) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo", (info 7 10, info 7 10) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (runBothWith These (pure (wrap $ info 0 12 `In` [ wrap $ info 2 5 `In` [], wrap $ info 7 10 `In` [] ])) ) ]
|
||||
|
||||
it "aligns insertions" $
|
||||
let sources = both (Source.fromText "a") (Source.fromText "a\nb") in
|
||||
align sources ((info 0 1, info 0 3) `merge` Indexed [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 1 `In` [ wrap $ info 0 1 `In` [] ])
|
||||
(wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ]))
|
||||
, Join (That (wrap $ info 2 3 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ]))
|
||||
]
|
||||
|
||||
it "aligns total insertions" $
|
||||
let sources = both (Source.fromText "") (Source.fromText "a") in
|
||||
align sources (inserting (Term (info 0 1 `In` Leaf "a"))) `shouldBe` prettyDiff sources
|
||||
[ Join (That (pure (SplitInsert (Term (info 0 1 `In` []))))) ]
|
||||
|
||||
it "aligns insertions into empty branches" $
|
||||
let sources = both (Source.fromText "[ ]") (Source.fromText "[a]") in
|
||||
align sources ((info 0 3, info 0 3) `merge` Indexed [ inserting (Term (info 1 2 `In` Leaf "a")) ]) `shouldBe` prettyDiff sources
|
||||
[ Join (That (wrap $ info 0 3 `In` [ pure (SplitInsert (Term (info 1 2 `In` []))) ]))
|
||||
, Join (This (wrap $ info 0 3 `In` []))
|
||||
]
|
||||
|
||||
it "aligns symmetrically following insertions" $
|
||||
let sources = both (Source.fromText "a\nc") (Source.fromText "a\nb\nc") in
|
||||
align sources ((info 0 3, info 0 5) `merge` Indexed [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")), (info 2 3, info 4 5) `merge` Leaf "c" ])
|
||||
`shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ])
|
||||
(wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ]))
|
||||
, Join (That (wrap $ info 2 4 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ]))
|
||||
, Join (These (wrap $ info 2 3 `In` [ wrap $ info 2 3 `In` [] ])
|
||||
(wrap $ info 4 5 `In` [ wrap $ info 4 5 `In` [] ]))
|
||||
]
|
||||
|
||||
it "symmetrical nodes force the alignment of asymmetrical nodes on both sides" $
|
||||
let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ b, c ]") in
|
||||
align sources ((info 0 8, info 0 8) `merge` Indexed [ deleting (Term (info 2 3 `In` Leaf "a")), (info 5 6, info 2 3) `merge` Leaf "b", inserting (Term (info 5 6 `In` Leaf "c")) ]) `shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ])
|
||||
(wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], pure (SplitInsert (Term (info 5 6 `In` []))) ])) ]
|
||||
|
||||
it "when one of two symmetrical nodes must be split, splits the latter" $
|
||||
let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ a\n, b\n]") in
|
||||
align sources ((info 0 8, info 0 9) `merge` Indexed [ (info 2 3, info 2 3) `merge` Leaf "a", (info 5 6, info 6 7) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], wrap $ info 5 6 `In` [] ])
|
||||
(wrap $ info 0 4 `In` [ wrap $ info 2 3 `In` [] ]))
|
||||
, Join (That (wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ]))
|
||||
, Join (That (wrap $ info 8 9 `In` []))
|
||||
]
|
||||
|
||||
it "aligns deletions before insertions" $
|
||||
let sources = both (Source.fromText "[ a ]") (Source.fromText "[ b ]") in
|
||||
align sources ((info 0 5, info 0 5) `merge` Indexed [ deleting (Term (info 2 3 `In` Leaf "a")), inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources
|
||||
[ Join (This (wrap $ info 0 5 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))) ]))
|
||||
, Join (That (wrap $ info 0 5 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ]))
|
||||
]
|
||||
|
||||
it "aligns context-only lines symmetrically" $
|
||||
let sources = both (Source.fromText "[\n a\n,\n b\n]") (Source.fromText "[\n a, b\n\n\n]") in
|
||||
align sources ((info 0 13, info 0 12) `merge` Indexed [ (info 4 5, info 4 5) `merge` Leaf "a", (info 10 11, info 7 8) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 2 `In` [])
|
||||
(wrap $ info 0 2 `In` []))
|
||||
, Join (These (wrap $ info 2 6 `In` [ wrap $ info 4 5 `In` [] ])
|
||||
(wrap $ info 2 9 `In` [ wrap $ info 4 5 `In` [], wrap $ info 7 8 `In` [] ]))
|
||||
, Join (These (wrap $ info 6 8 `In` [])
|
||||
(wrap $ info 9 10 `In` []))
|
||||
, Join (This (wrap $ info 8 12 `In` [ wrap $ info 10 11 `In` [] ]))
|
||||
, Join (These (wrap $ info 12 13 `In` [])
|
||||
(wrap $ info 10 11 `In` []))
|
||||
, Join (That (wrap $ info 11 12 `In` []))
|
||||
]
|
||||
|
||||
it "aligns asymmetrical nodes preceding their symmetrical siblings conservatively" $
|
||||
let sources = both (Source.fromText "[ b, c ]") (Source.fromText "[ a\n, c\n]") in
|
||||
align sources ((info 0 8, info 0 9) `merge` Indexed [ inserting (Term (info 2 3 `In` Leaf "a")), deleting (Term (info 2 3 `In` Leaf "b")), (info 5 6, info 6 7) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (That (wrap $ info 0 4 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ]))
|
||||
, Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ])
|
||||
(wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ]))
|
||||
, Join (That (wrap $ info 8 9 `In` []))
|
||||
]
|
||||
|
||||
it "aligns symmetrical reformatted nodes" $
|
||||
let sources = both (Source.fromText "a [ b ]\nc") (Source.fromText "a [\nb\n]\nc") in
|
||||
align sources ((info 0 9, info 0 9) `merge` Indexed [ (info 0 1, info 0 1) `merge` Leaf "a", (info 2 7, info 2 7) `merge` Indexed [ (info 4 5, info 4 5) `merge` Leaf "b" ], (info 8 9, info 8 9) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources
|
||||
[ Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 7 `In` [ wrap $ info 4 5 `In` [] ] ])
|
||||
(wrap $ info 0 4 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 4 `In` [] ]))
|
||||
, Join (That (wrap $ info 4 6 `In` [ wrap $ info 4 6 `In` [ wrap $ info 4 5 `In` [] ] ]))
|
||||
, Join (That (wrap $ info 6 8 `In` [ wrap $ info 6 7 `In` [] ]))
|
||||
, Join (These (wrap $ info 8 9 `In` [ wrap $ info 8 9 `In` [] ])
|
||||
(wrap $ info 8 9 `In` [ wrap $ info 8 9 `In` [] ]))
|
||||
]
|
||||
|
||||
describe "numberedRows" $ do
|
||||
prop "counts only non-empty values" $
|
||||
\ xs -> counts (numberedRows (unListableF <$> xs :: [Join These Char])) `shouldBe` length . catMaybes <$> Join (unalign (runJoin . unListableF <$> xs))
|
||||
|
||||
data BranchElement
|
||||
= Child Text.Text (Join These Text.Text)
|
||||
| Margin (Join These Text.Text)
|
||||
deriving Show
|
||||
|
||||
branchElementKey :: BranchElement -> Maybe Text.Text
|
||||
branchElementKey (Child key _) = Just key
|
||||
branchElementKey _ = Nothing
|
||||
|
||||
toAlignBranchInputs :: [BranchElement] -> (Both Source.Source, [Join These (Text.Text, Range)], Both [Range])
|
||||
toAlignBranchInputs elements = (sources, join . (`evalState` both 0 0) . traverse go $ elements, ranges)
|
||||
where go :: BranchElement -> State (Both Int) [Join These (Text.Text, Range)]
|
||||
go child@(Child key _) = do
|
||||
lines <- traverse (\ (Child _ contents) -> do
|
||||
prev <- get
|
||||
let next = (+) <$> prev <*> modifyJoin (fromThese 0 0) (Text.length <$> contents)
|
||||
put next
|
||||
pure $! modifyJoin (runBothWith bimap (const <$> (Range <$> prev <*> next))) contents) (alignBranchElement child)
|
||||
pure $! fmap ((,) key) <$> lines
|
||||
go (Margin contents) = do
|
||||
prev <- get
|
||||
put $ (+) <$> prev <*> modifyJoin (fromThese 0 0) (Text.length <$> contents)
|
||||
pure []
|
||||
alignBranchElement element = case element of
|
||||
Child key contents -> Child key <$> joinCrosswalk lines contents
|
||||
Margin contents -> Margin <$> joinCrosswalk lines contents
|
||||
where lines = fmap Source.toText . Source.sourceLines . Source.fromText
|
||||
sources = foldMap Source.fromText <$> bothContents elements
|
||||
ranges = fmap (filter (\ (Range start end) -> start /= end)) $ Source.sourceLineRangesWithin <$> (Source.totalRange <$> sources) <*> sources
|
||||
bothContents = foldMap (modifyJoin (fromThese [] []) . fmap (:[]) . branchElementContents)
|
||||
branchElementContents (Child _ contents) = contents
|
||||
branchElementContents (Margin contents) = contents
|
||||
|
||||
keysOfAlignedChildren :: [Join These (Range, [(Text.Text, Range)])] -> [Text.Text]
|
||||
keysOfAlignedChildren lines = lines >>= these id id (<>) . runJoin . fmap (fmap fst . snd)
|
||||
|
||||
joinCrosswalk :: Bicrosswalk p => Align f => (a -> f b) -> Join p a -> f (Join p b)
|
||||
joinCrosswalk f = fmap Join . bicrosswalk f f . runJoin
|
||||
|
||||
instance Listable BranchElement where
|
||||
tiers = oneof [ (\ key -> Child key `mapT` joinTheseOf (contents key)) `concatMapT` key
|
||||
, Margin `mapT` joinTheseOf (Text.singleton `mapT` padding '-') ]
|
||||
where key = Text.singleton `mapT` [['a'..'z'] <> ['A'..'Z'] <> ['0'..'9']]
|
||||
contents key = (wrap key . Text.singleton) `mapT` padding '*'
|
||||
wrap key contents = "(" <> key <> contents <> ")" :: Text.Text
|
||||
padding :: Char -> [Tier Char]
|
||||
padding char = frequency [ (10, [[char]])
|
||||
, (1, [['\n']]) ]
|
||||
joinTheseOf g = oneof [ (Join . This) `mapT` g
|
||||
, (Join . That) `mapT` g
|
||||
, productWith ((Join .) . These) g g ]
|
||||
frequency :: [(Int, [Tier a])] -> [Tier a]
|
||||
frequency = concatT . foldr ((\/) . pure . uncurry replicate) []
|
||||
oneof :: [[[a]]] -> [[a]]
|
||||
oneof = frequency . fmap ((,) 1)
|
||||
|
||||
|
||||
counts :: [Join These (Int, a)] -> Both Int
|
||||
counts numbered = fromMaybe 0 . getLast . mconcat . fmap Last <$> Join (unalign (runJoin . fmap fst <$> numbered))
|
||||
|
||||
align :: Both Source.Source -> Diff Syntax (Record '[Range]) (Record '[Range]) -> PrettyDiff (SplitDiff [] (Record '[Range]))
|
||||
align sources = PrettyDiff sources . fmap (fmap (getRange &&& id)) . alignDiff sources
|
||||
|
||||
info :: Int -> Int -> Record '[Range]
|
||||
info start end = Range start end :. Nil
|
||||
|
||||
prettyDiff :: Both Source.Source -> [Join These (SplitDiff [] (Record '[Range]))] -> PrettyDiff (SplitDiff [] (Record '[Range]))
|
||||
prettyDiff sources = PrettyDiff sources . fmap (fmap ((getRange &&& id)))
|
||||
|
||||
data PrettyDiff a = PrettyDiff { unPrettySources :: Both Source.Source, unPrettyLines :: [Join These (Range, a)] }
|
||||
deriving Eq
|
||||
|
||||
instance Show (PrettyDiff a) where
|
||||
showsPrec _ (PrettyDiff sources lines) = (prettyPrinted ++) -- . (("\n" ++ show lines) ++)
|
||||
where prettyPrinted = showLine (maximum (0 : (maximum . fmap length <$> shownLines))) <$> shownLines >>= ('\n':)
|
||||
shownLines = catMaybes $ toBoth <$> lines
|
||||
showLine n line = uncurry ((<>) . (++ " | ")) (fromThese (replicate n ' ') (replicate n ' ') (runJoin (pad n <$> line)))
|
||||
showDiff (range, _) = filter (/= '\n') . Text.unpack . Source.toText . Source.slice range
|
||||
pad n string = (<>) (take n string) (replicate (max 0 (n - length string)) ' ')
|
||||
toBoth them = showDiff <$> them `applyThese` modifyJoin (uncurry These) sources
|
@ -54,6 +54,7 @@ import Renderer.TOC
|
||||
import RWS
|
||||
import Syntax as S
|
||||
import Test.LeanCheck
|
||||
import qualified Language
|
||||
|
||||
type Tier a = [a]
|
||||
|
||||
@ -351,10 +352,17 @@ instance Listable Text where
|
||||
|
||||
instance Listable Declaration where
|
||||
tiers
|
||||
= cons1 (MethodDeclaration)
|
||||
\/ cons1 (FunctionDeclaration)
|
||||
\/ cons1 (flip ErrorDeclaration Nothing)
|
||||
= cons4 MethodDeclaration
|
||||
\/ cons3 FunctionDeclaration
|
||||
\/ cons2 (\ a b -> ErrorDeclaration a b Nothing)
|
||||
|
||||
instance Listable Language.Language where
|
||||
tiers
|
||||
= cons0 Language.Go
|
||||
\/ cons0 Language.JavaScript
|
||||
\/ cons0 Language.Python
|
||||
\/ cons0 Language.Ruby
|
||||
\/ cons0 Language.TypeScript
|
||||
|
||||
instance Listable Range where
|
||||
tiers = cons2 Range
|
||||
|
@ -1,17 +0,0 @@
|
||||
module PatchOutputSpec where
|
||||
|
||||
import Data.Blob
|
||||
import Data.Diff
|
||||
import Data.Functor.Both
|
||||
import Data.Range
|
||||
import Data.Record
|
||||
import Renderer.Patch
|
||||
import Syntax
|
||||
import Test.Hspec (Spec, describe, it, parallel)
|
||||
import Test.Hspec.Expectations.Pretty
|
||||
|
||||
spec :: Spec
|
||||
spec = parallel $ do
|
||||
describe "hunks" $ do
|
||||
it "empty diffs have empty hunks" $
|
||||
hunks (merge (Range 0 0 :. Nil, Range 0 0 :. Nil) (Leaf "")) (both (Blob mempty "abcde" "path2.txt" (Just defaultPlainBlob) Nothing) (Blob mempty "xyz" "path2.txt" (Just defaultPlainBlob) Nothing)) `shouldBe` [Hunk {offset = pure 0, changes = [], trailingContext = []}]
|
@ -53,15 +53,12 @@ parseFixtures =
|
||||
|
||||
diffFixtures :: [(SomeRenderer DiffRenderer, Either Handle [Both (FilePath, Maybe Language)], ByteString)]
|
||||
diffFixtures =
|
||||
[ (SomeRenderer PatchDiffRenderer, pathMode, patchOutput)
|
||||
, (SomeRenderer JSONDiffRenderer, pathMode, jsonOutput)
|
||||
[ (SomeRenderer JSONDiffRenderer, pathMode, jsonOutput)
|
||||
, (SomeRenderer SExpressionDiffRenderer, pathMode, sExpressionOutput)
|
||||
, (SomeRenderer OldToCDiffRenderer, pathMode, tocOutput)
|
||||
]
|
||||
where pathMode = Right [both ("test/fixtures/ruby/method-declaration.A.rb", Just Ruby) ("test/fixtures/ruby/method-declaration.B.rb", Just Ruby)]
|
||||
|
||||
patchOutput = "diff --git a/test/fixtures/ruby/method-declaration.A.rb b/test/fixtures/ruby/method-declaration.B.rb\nindex 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644\n--- a/test/fixtures/ruby/method-declaration.A.rb\n+++ b/test/fixtures/ruby/method-declaration.B.rb\n@@ -1,3 +1,4 @@\n-def foo\n+def bar(a)\n+ baz\n end\n\n"
|
||||
|
||||
jsonOutput = "{\"diff\":{\"merge\":{\"after\":{\"sourceRange\":[0,21],\"sourceSpan\":{\"start\":[1,1],\"end\":[4,1]}},\"children\":[{\"merge\":{\"after\":{\"sourceRange\":[0,20],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,4]}},\"children\":[{\"merge\":{\"after\":{\"sourceRange\":[0,0],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,1]}},\"children\":[],\"before\":{\"sourceRange\":[0,0],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,1]}}}},{\"patch\":{\"replace\":[{\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}},{\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}]}},{\"patch\":{\"insert\":{\"children\":[],\"sourceRange\":[8,9],\"sourceSpan\":{\"start\":[1,9],\"end\":[1,10]}}}},{\"merge\":{\"after\":{\"sourceRange\":[13,16],\"sourceSpan\":{\"start\":[2,3],\"end\":[2,6]}},\"children\":[{\"patch\":{\"insert\":{\"children\":[],\"sourceRange\":[13,16],\"sourceSpan\":{\"start\":[2,3],\"end\":[2,6]}}}}],\"before\":{\"sourceRange\":[8,11],\"sourceSpan\":{\"start\":[2,1],\"end\":[2,4]}}}}],\"before\":{\"sourceRange\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}}}],\"before\":{\"sourceRange\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}}}},\"oids\":[\"0000000000000000000000000000000000000000\",\"0000000000000000000000000000000000000000\"],\"paths\":[\"test/fixtures/ruby/method-declaration.A.rb\",\"test/fixtures/ruby/method-declaration.B.rb\"]}\n"
|
||||
sExpressionOutput = "(Program\n (Method\n (Empty)\n { (Identifier)\n ->(Identifier) }\n {+(Identifier)+}\n (\n {+(Identifier)+})))\n"
|
||||
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"
|
||||
|
@ -49,6 +49,20 @@ spec = parallel $ do
|
||||
prop "covers multiple lines" $
|
||||
\ n -> totalSpan (fromText (Text.intersperse '\n' (Text.replicate n "*"))) `shouldBe` Span (Pos 1 1) (Pos (max 1 n) (if n > 0 then 2 else 1))
|
||||
|
||||
describe "newlineIndices" $ do
|
||||
it "finds \\n" $
|
||||
let source = "a\nb" in
|
||||
newlineIndices source `shouldBe` [1]
|
||||
it "finds \\r" $
|
||||
let source = "a\rb" in
|
||||
newlineIndices source `shouldBe` [1]
|
||||
it "finds \\r\\n" $
|
||||
let source = "a\r\nb" in
|
||||
newlineIndices source `shouldBe` [2]
|
||||
it "finds intermixed line endings" $
|
||||
let source = "hi\r}\r}\n xxx \r a" in
|
||||
newlineIndices source `shouldBe` [2, 4, 6, 12]
|
||||
|
||||
prop "preserves characters" . forAll (toTiers (list +| [chr 0xa0..chr 0x24f])) $
|
||||
\ c -> Text.unpack (toText (fromText (Text.singleton c))) `shouldBe` [c]
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
module Main where
|
||||
|
||||
import qualified AlignmentSpec
|
||||
import qualified CommandSpec
|
||||
import qualified Data.Functor.Classes.Ord.Generic.Spec
|
||||
import qualified Data.Mergeable.Spec
|
||||
@ -8,7 +7,6 @@ import qualified Data.RandomWalkSimilarity.Spec
|
||||
import qualified Data.Syntax.Assignment.Spec
|
||||
import qualified DiffSpec
|
||||
import qualified InterpreterSpec
|
||||
import qualified PatchOutputSpec
|
||||
import qualified SES.Spec
|
||||
import qualified SourceSpec
|
||||
import qualified TermSpec
|
||||
@ -23,7 +21,6 @@ main :: IO ()
|
||||
main = hspec $ do
|
||||
describe "Semantic.Stat" Semantic.StatSpec.spec
|
||||
parallel $ do
|
||||
describe "Alignment" AlignmentSpec.spec
|
||||
describe "Command" CommandSpec.spec
|
||||
describe "Data.Functor.Classes.Ord.Generic" Data.Functor.Classes.Ord.Generic.Spec.spec
|
||||
describe "Data.Mergeable" Data.Mergeable.Spec.spec
|
||||
@ -31,7 +28,6 @@ main = hspec $ do
|
||||
describe "Data.Syntax.Assignment" Data.Syntax.Assignment.Spec.spec
|
||||
describe "Diff" DiffSpec.spec
|
||||
describe "Interpreter" InterpreterSpec.spec
|
||||
describe "PatchOutput" PatchOutputSpec.spec
|
||||
describe "SES" SES.Spec.spec
|
||||
describe "Source" SourceSpec.spec
|
||||
describe "Term" TermSpec.spec
|
||||
|
@ -67,50 +67,50 @@ spec = parallel $ do
|
||||
sourceBlobs <- blobsForPaths (both "ruby/methods.A.rb" "ruby/methods.B.rb")
|
||||
diff <- runTask $ diffWithParser rubyParser sourceBlobs
|
||||
diffTOC diff `shouldBe`
|
||||
[ JSONSummary "Method" "self.foo" (sourceSpanBetween (1, 1) (2, 4)) "added"
|
||||
, JSONSummary "Method" "bar" (sourceSpanBetween (4, 1) (6, 4)) "modified"
|
||||
, JSONSummary "Method" "baz" (sourceSpanBetween (4, 1) (5, 4)) "removed"
|
||||
[ TOCSummary "Method" "self.foo" (sourceSpanBetween (1, 1) (2, 4)) "added"
|
||||
, TOCSummary "Method" "bar" (sourceSpanBetween (4, 1) (6, 4)) "modified"
|
||||
, TOCSummary "Method" "baz" (sourceSpanBetween (4, 1) (5, 4)) "removed"
|
||||
]
|
||||
|
||||
it "summarizes changed classes" $ do
|
||||
sourceBlobs <- blobsForPaths (both "ruby/classes.A.rb" "ruby/classes.B.rb")
|
||||
diff <- runTask $ diffWithParser rubyParser sourceBlobs
|
||||
diffTOC diff `shouldBe`
|
||||
[ JSONSummary "Class" "Baz" (sourceSpanBetween (1, 1) (2, 4)) "removed"
|
||||
, JSONSummary "Class" "Foo" (sourceSpanBetween (1, 1) (3, 4)) "modified"
|
||||
, JSONSummary "Class" "Bar" (sourceSpanBetween (5, 1) (6, 4)) "added"
|
||||
[ TOCSummary "Class" "Baz" (sourceSpanBetween (1, 1) (2, 4)) "removed"
|
||||
, TOCSummary "Class" "Foo" (sourceSpanBetween (1, 1) (3, 4)) "modified"
|
||||
, TOCSummary "Class" "Bar" (sourceSpanBetween (5, 1) (6, 4)) "added"
|
||||
]
|
||||
|
||||
it "dedupes changes in same parent method" $ do
|
||||
sourceBlobs <- blobsForPaths (both "javascript/duplicate-parent.A.js" "javascript/duplicate-parent.B.js")
|
||||
diff <- runTask $ diffWithParser typescriptParser sourceBlobs
|
||||
diffTOC diff `shouldBe`
|
||||
[ JSONSummary "Function" "myFunction" (sourceSpanBetween (1, 1) (6, 2)) "modified" ]
|
||||
[ TOCSummary "Function" "myFunction" (sourceSpanBetween (1, 1) (6, 2)) "modified" ]
|
||||
|
||||
it "dedupes similar methods" $ do
|
||||
sourceBlobs <- blobsForPaths (both "javascript/erroneous-duplicate-method.A.js" "javascript/erroneous-duplicate-method.B.js")
|
||||
diff <- runTask $ diffWithParser typescriptParser sourceBlobs
|
||||
diffTOC diff `shouldBe`
|
||||
[ JSONSummary "Function" "performHealthCheck" (sourceSpanBetween (8, 1) (29, 2)) "modified" ]
|
||||
[ TOCSummary "Function" "performHealthCheck" (sourceSpanBetween (8, 1) (29, 2)) "modified" ]
|
||||
|
||||
it "summarizes Go methods with receivers with special formatting" $ do
|
||||
sourceBlobs <- blobsForPaths (both "go/method-with-receiver.A.go" "go/method-with-receiver.B.go")
|
||||
let Just goParser = syntaxParserForLanguage Go
|
||||
diff <- runTask $ distributeFor sourceBlobs (\ blob -> parse goParser blob >>= decorate (syntaxDeclarationAlgebra blob)) >>= runBothWith (diffTermPair sourceBlobs diffSyntaxTerms)
|
||||
diffTOC diff `shouldBe`
|
||||
[ JSONSummary "Method" "(*apiClient) CheckAuth" (sourceSpanBetween (3,1) (3,101)) "added" ]
|
||||
[ TOCSummary "Method" "(*apiClient) CheckAuth" (sourceSpanBetween (3,1) (3,101)) "added" ]
|
||||
|
||||
it "summarizes Ruby methods that start with two identifiers" $ do
|
||||
sourceBlobs <- blobsForPaths (both "ruby/method-starts-with-two-identifiers.A.rb" "ruby/method-starts-with-two-identifiers.B.rb")
|
||||
diff <- runTask $ diffWithParser rubyParser sourceBlobs
|
||||
diffTOC diff `shouldBe`
|
||||
[ JSONSummary "Method" "foo" (sourceSpanBetween (1, 1) (4, 4)) "modified" ]
|
||||
[ TOCSummary "Method" "foo" (sourceSpanBetween (1, 1) (4, 4)) "modified" ]
|
||||
|
||||
it "handles unicode characters in file" $ do
|
||||
sourceBlobs <- blobsForPaths (both "ruby/unicode.A.rb" "ruby/unicode.B.rb")
|
||||
diff <- runTask $ diffWithParser rubyParser sourceBlobs
|
||||
diffTOC diff `shouldBe`
|
||||
[ JSONSummary "Method" "foo" (sourceSpanBetween (6, 1) (7, 4)) "added" ]
|
||||
[ TOCSummary "Method" "foo" (sourceSpanBetween (6, 1) (7, 4)) "added" ]
|
||||
|
||||
it "properly slices source blob that starts with a newline and has multi-byte chars" $ do
|
||||
sourceBlobs <- blobsForPaths (both "javascript/starts-with-newline.js" "javascript/starts-with-newline.js")
|
||||
@ -146,13 +146,13 @@ spec = parallel $ do
|
||||
\a -> let term = defaultFeatureVectorDecorator (Info.category . termAnnotation) (a :: Term') in
|
||||
diffTOC (diffSyntaxTerms term term) `shouldBe` []
|
||||
|
||||
describe "JSONSummary" $ do
|
||||
describe "TOCSummary" $ do
|
||||
it "encodes modified summaries to JSON" $ do
|
||||
let summary = JSONSummary "Method" "foo" (sourceSpanBetween (1, 1) (4, 4)) "modified"
|
||||
let summary = TOCSummary "Method" "foo" (sourceSpanBetween (1, 1) (4, 4)) "modified"
|
||||
encode summary `shouldBe` "{\"span\":{\"start\":[1,1],\"end\":[4,4]},\"category\":\"Method\",\"term\":\"foo\",\"changeType\":\"modified\"}"
|
||||
|
||||
it "encodes added summaries to JSON" $ do
|
||||
let summary = JSONSummary "Method" "self.foo" (sourceSpanBetween (1, 1) (2, 4)) "added"
|
||||
let summary = TOCSummary "Method" "self.foo" (sourceSpanBetween (1, 1) (2, 4)) "added"
|
||||
encode summary `shouldBe` "{\"span\":{\"start\":[1,1],\"end\":[2,4]},\"category\":\"Method\",\"term\":\"self.foo\",\"changeType\":\"added\"}"
|
||||
|
||||
describe "diff with ToCDiffRenderer'" $ do
|
||||
@ -174,7 +174,7 @@ spec = parallel $ do
|
||||
it "summarizes Markdown headings" $ do
|
||||
blobs <- blobsForPaths (both "markdown/headings.A.md" "markdown/headings.B.md")
|
||||
output <- runTask (diffBlobPair ToCDiffRenderer blobs)
|
||||
toOutput output `shouldBe` ("{\"changes\":{\"test/fixtures/toc/markdown/headings.A.md -> test/fixtures/toc/markdown/headings.B.md\":[{\"span\":{\"start\":[1,1],\"end\":[7,10]},\"category\":\"Heading 1\",\"term\":\"One\",\"changeType\":\"modified\"},{\"span\":{\"start\":[5,1],\"end\":[7,10]},\"category\":\"Heading 2\",\"term\":\"Two\",\"changeType\":\"added\"},{\"span\":{\"start\":[9,1],\"end\":[10,4]},\"category\":\"Heading 1\",\"term\":\"Final\",\"changeType\":\"added\"}]},\"errors\":{}}\n" :: ByteString)
|
||||
toOutput output `shouldBe` ("{\"changes\":{\"test/fixtures/toc/markdown/headings.A.md -> test/fixtures/toc/markdown/headings.B.md\":[{\"span\":{\"start\":[1,1],\"end\":[3,16]},\"category\":\"Heading 1\",\"term\":\"Introduction\",\"changeType\":\"removed\"},{\"span\":{\"start\":[5,1],\"end\":[7,4]},\"category\":\"Heading 2\",\"term\":\"Two\",\"changeType\":\"modified\"},{\"span\":{\"start\":[9,1],\"end\":[11,10]},\"category\":\"Heading 3\",\"term\":\"This heading is new\",\"changeType\":\"added\"},{\"span\":{\"start\":[13,1],\"end\":[14,4]},\"category\":\"Heading 1\",\"term\":\"Final\",\"changeType\":\"added\"}]},\"errors\":{}}\n" :: ByteString)
|
||||
|
||||
|
||||
type Diff' = Diff Syntax (Record (Maybe Declaration ': DefaultFields)) (Record (Maybe Declaration ': DefaultFields))
|
||||
@ -187,14 +187,14 @@ numTocSummaries diff = length $ filter isValidSummary (diffTOC diff)
|
||||
programWithChange :: Term' -> Diff'
|
||||
programWithChange body = merge (programInfo, programInfo) (Indexed [ function' ])
|
||||
where
|
||||
function' = merge ((Just (FunctionDeclaration "foo") :. functionInfo, Just (FunctionDeclaration "foo") :. functionInfo)) (S.Function name' [] [ inserting body ])
|
||||
function' = merge ((Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo)) (S.Function name' [] [ inserting body ])
|
||||
name' = let info = Nothing :. Range 0 0 :. C.Identifier :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo")
|
||||
|
||||
-- Return a diff where term is inserted in the program, below a function found on both sides of the diff.
|
||||
programWithChangeOutsideFunction :: Term' -> Diff'
|
||||
programWithChangeOutsideFunction term = merge (programInfo, programInfo) (Indexed [ function', term' ])
|
||||
where
|
||||
function' = merge (Just (FunctionDeclaration "foo") :. functionInfo, Just (FunctionDeclaration "foo") :. functionInfo) (S.Function name' [] [])
|
||||
function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo) (S.Function name' [] [])
|
||||
name' = let info = Nothing :. Range 0 0 :. C.Identifier :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo")
|
||||
term' = inserting term
|
||||
|
||||
@ -211,7 +211,7 @@ programOf :: Diff' -> Diff'
|
||||
programOf diff = merge (programInfo, programInfo) (Indexed [ diff ])
|
||||
|
||||
functionOf :: Text -> Term' -> Term'
|
||||
functionOf name body = Term $ (Just (FunctionDeclaration name) :. functionInfo) `In` S.Function name' [] [body]
|
||||
functionOf name body = Term $ (Just (FunctionDeclaration name mempty Nothing) :. functionInfo) `In` S.Function name' [] [body]
|
||||
where
|
||||
name' = Term $ (Nothing :. Range 0 0 :. C.Identifier :. sourceSpanBetween (0,0) (0,0) :. Nil) `In` Leaf name
|
||||
|
||||
|
181
test/fixtures/javascript/class.diffA-B.txt
vendored
181
test/fixtures/javascript/class.diffA-B.txt
vendored
@ -1,111 +1,112 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
(
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{-(PublicFieldDefinition
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(Float)-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{-(PublicFieldDefinition
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Identifier)-}
|
||||
{-(Float)-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}))
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-})))
|
||||
|
103
test/fixtures/javascript/class.diffB-A.txt
vendored
103
test/fixtures/javascript/class.diffB-A.txt
vendored
@ -1,63 +1,64 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
{+(PublicFieldDefinition
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(Float)+})+}
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(
|
||||
{+(PublicFieldDefinition
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(Float)+})+}
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))))
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier)))))))
|
||||
|
97
test/fixtures/javascript/class.parseA.txt
vendored
97
test/fixtures/javascript/class.parseA.txt
vendored
@ -1,60 +1,61 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Identifier)
|
||||
(Float))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))))
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier)))))))
|
||||
|
85
test/fixtures/javascript/class.parseB.txt
vendored
85
test/fixtures/javascript/class.parseB.txt
vendored
@ -1,54 +1,55 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))))
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier)))))))
|
||||
|
@ -3,30 +3,33 @@
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
{+(Identifier)+}
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Identifier)
|
||||
->(Empty) })))
|
||||
(Empty)))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Identifier)
|
||||
->(Empty) })))
|
||||
(Empty))))
|
||||
{-(Class
|
||||
{-(Identifier)-}
|
||||
{-(NoOp
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(NoOp
|
||||
{-(Empty)-})-})-})-}
|
||||
(Class
|
||||
(Identifier)
|
||||
{-(Identifier)-}
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Empty)
|
||||
->(Identifier) })))
|
||||
(Empty))))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Empty)
|
||||
->(Identifier) })))
|
||||
(Empty)))))
|
||||
|
@ -3,30 +3,33 @@
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
{-(Identifier)-}
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Empty)
|
||||
->(Identifier) })))
|
||||
(Empty)))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Empty)
|
||||
->(Identifier) })))
|
||||
(Empty))))
|
||||
{+(Class
|
||||
{+(Identifier)+}
|
||||
{+(NoOp
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(NoOp
|
||||
{+(Empty)+})+})+})+}
|
||||
(Class
|
||||
(Identifier)
|
||||
{+(Identifier)+}
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Identifier)
|
||||
->(Empty) })))
|
||||
(Empty))))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
{ (Identifier)
|
||||
->(Empty) })))
|
||||
(Empty)))))
|
||||
|
39
test/fixtures/python/class-definition.parseA.txt
vendored
39
test/fixtures/python/class-definition.parseA.txt
vendored
@ -1,26 +1,29 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Empty)))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Empty))))
|
||||
(Class
|
||||
(Identifier)
|
||||
(NoOp
|
||||
(Empty)))
|
||||
(
|
||||
(NoOp
|
||||
(Empty))))
|
||||
(Class
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Empty))))
|
||||
(Empty))))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Empty))))
|
||||
(Empty)))))
|
||||
|
34
test/fixtures/python/class-definition.parseB.txt
vendored
34
test/fixtures/python/class-definition.parseB.txt
vendored
@ -2,21 +2,23 @@
|
||||
(Class
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Empty))))
|
||||
(Empty)))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Empty))))
|
||||
(Empty))))
|
||||
(Class
|
||||
(Identifier)
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Empty))))
|
||||
(
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(Identifier)
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Empty)))))
|
||||
|
@ -6,42 +6,38 @@
|
||||
(Class
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
([])
|
||||
(
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
{ (Identifier)
|
||||
->(Identifier) })
|
||||
(
|
||||
{+(Identifier)+}
|
||||
{-(Integer)-})
|
||||
(Identifier))
|
||||
([])
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
{ (Identifier)
|
||||
->(Identifier) })
|
||||
(
|
||||
{+(Identifier)+}
|
||||
{-(Integer)-}
|
||||
{-(Integer)-})
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
{ (Identifier)
|
||||
->(Identifier) })
|
||||
(
|
||||
{+(Integer)+}
|
||||
(Assignment
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Boolean))
|
||||
{+(Identifier)+}
|
||||
{+(Identifier)+})
|
||||
{ (Decorator
|
||||
{-(ScopeResolution
|
||||
{-(Identifier)-})-}
|
||||
{-(
|
||||
{-(Identifier)-})-}
|
||||
{-(Decorator
|
||||
{-(Integer)-}
|
||||
{-(Integer)-})
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
{+(Integer)+}
|
||||
(Assignment
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Boolean))
|
||||
{+(Identifier)+}
|
||||
{+(Identifier)+})
|
||||
{ (Decorator
|
||||
{-(ScopeResolution
|
||||
{-(Identifier)-})-}
|
||||
{-(
|
||||
@ -50,21 +46,26 @@
|
||||
{-(ScopeResolution
|
||||
{-(Identifier)-})-}
|
||||
{-(
|
||||
{-(Integer)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Boolean)-})-}
|
||||
{-(Identifier)-}
|
||||
{-(Identifier)-})-}
|
||||
{-(Annotation
|
||||
{-(Function
|
||||
{-(Decorator
|
||||
{-(ScopeResolution
|
||||
{-(Identifier)-})-}
|
||||
{-(
|
||||
{-(Integer)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Boolean)-})-}
|
||||
{-(Identifier)-}
|
||||
{-(
|
||||
{-(Identifier)-})-})-}
|
||||
{-(Empty)-})-})-})-})
|
||||
->(Annotation
|
||||
{+(Function
|
||||
{+(Identifier)+}
|
||||
{+(
|
||||
{+(Identifier)+})+})+}
|
||||
{+(Empty)+}) })))))))
|
||||
{-(Identifier)-})-}
|
||||
{-(Annotation
|
||||
{-(Function
|
||||
{-(Identifier)-}
|
||||
{-(
|
||||
{-(Identifier)-})-})-}
|
||||
{-(Empty)-})-})-})-})
|
||||
->(Annotation
|
||||
{+(Function
|
||||
{+(Identifier)+}
|
||||
{+(
|
||||
{+(Identifier)+})+})+}
|
||||
{+(Empty)+}) }))))))))
|
||||
|
@ -6,50 +6,46 @@
|
||||
(Class
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
([])
|
||||
(
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
{ (Identifier)
|
||||
->(Identifier) })
|
||||
(
|
||||
{+(Integer)+}
|
||||
{-(Identifier)-})
|
||||
(Identifier))
|
||||
([])
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
{ (Identifier)
|
||||
->(Identifier) })
|
||||
(
|
||||
{+(Integer)+}
|
||||
{+(Integer)+}
|
||||
{-(Identifier)-})
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
{ (Identifier)
|
||||
->(Identifier) })
|
||||
(
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Boolean)+})+}
|
||||
{-(Integer)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Boolean)-})-}
|
||||
{-(Identifier)-}
|
||||
{+(Integer)+}
|
||||
{+(Integer)+}
|
||||
{-(Identifier)-})
|
||||
{ (Annotation
|
||||
{-(Function
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Boolean)+})+}
|
||||
{-(Integer)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Boolean)-})-}
|
||||
{-(Identifier)-}
|
||||
{-(
|
||||
{-(Identifier)-})-})-}
|
||||
{-(Empty)-})
|
||||
->(Decorator
|
||||
{+(ScopeResolution
|
||||
{+(Identifier)+})+}
|
||||
{+(
|
||||
{+(Identifier)+})+}
|
||||
{+(Decorator
|
||||
{-(Identifier)-})
|
||||
{ (Annotation
|
||||
{-(Function
|
||||
{-(Identifier)-}
|
||||
{-(
|
||||
{-(Identifier)-})-})-}
|
||||
{-(Empty)-})
|
||||
->(Decorator
|
||||
{+(ScopeResolution
|
||||
{+(Identifier)+})+}
|
||||
{+(
|
||||
@ -58,15 +54,20 @@
|
||||
{+(ScopeResolution
|
||||
{+(Identifier)+})+}
|
||||
{+(
|
||||
{+(Integer)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Boolean)+})+}
|
||||
{+(Identifier)+}
|
||||
{+(Identifier)+})+}
|
||||
{+(Annotation
|
||||
{+(Function
|
||||
{+(Decorator
|
||||
{+(ScopeResolution
|
||||
{+(Identifier)+})+}
|
||||
{+(
|
||||
{+(Integer)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Boolean)+})+}
|
||||
{+(Identifier)+}
|
||||
{+(
|
||||
{+(Identifier)+})+})+}
|
||||
{+(Empty)+})+})+})+}) })))))))
|
||||
{+(Identifier)+})+}
|
||||
{+(Annotation
|
||||
{+(Function
|
||||
{+(Identifier)+}
|
||||
{+(
|
||||
{+(Identifier)+})+})+}
|
||||
{+(Empty)+})+})+})+}) }))))))))
|
||||
|
@ -5,33 +5,29 @@
|
||||
(Identifier))
|
||||
(Class
|
||||
(Identifier)
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
([])
|
||||
(
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Integer))
|
||||
([])
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Integer)
|
||||
(Integer))
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Boolean)))
|
||||
(Integer)
|
||||
(Integer))
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Identifier))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Boolean)))
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
@ -41,15 +37,20 @@
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Integer)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Boolean))
|
||||
(Identifier)
|
||||
(Identifier))
|
||||
(Annotation
|
||||
(Function
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Integer)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Boolean))
|
||||
(Identifier)
|
||||
(
|
||||
(Identifier)))
|
||||
(Empty))))))))))))
|
||||
(Identifier))
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(
|
||||
(Identifier)))
|
||||
(Empty)))))))))))))
|
||||
|
@ -5,15 +5,11 @@
|
||||
(Identifier))
|
||||
(Class
|
||||
(Identifier)
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
([])
|
||||
(
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Identifier))
|
||||
([])
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
@ -23,15 +19,20 @@
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Integer)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Boolean))
|
||||
(Identifier)
|
||||
(Identifier))
|
||||
(Annotation
|
||||
(Function
|
||||
(Decorator
|
||||
(ScopeResolution
|
||||
(Identifier))
|
||||
(
|
||||
(Integer)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Boolean))
|
||||
(Identifier)
|
||||
(
|
||||
(Identifier)))
|
||||
(Empty)))))))))
|
||||
(Identifier))
|
||||
(Annotation
|
||||
(Function
|
||||
(Identifier)
|
||||
(
|
||||
(Identifier)))
|
||||
(Empty))))))))))
|
||||
|
3
test/fixtures/ruby/class.diffA-B.txt
vendored
3
test/fixtures/ruby/class.diffA-B.txt
vendored
@ -9,4 +9,5 @@
|
||||
{-(Class
|
||||
{-(ScopeResolution
|
||||
{-(Identifier)-}
|
||||
{-(Identifier)-})-})-})
|
||||
{-(Identifier)-})-}
|
||||
{-([])-})-})
|
||||
|
3
test/fixtures/ruby/class.diffB-A.txt
vendored
3
test/fixtures/ruby/class.diffB-A.txt
vendored
@ -9,4 +9,5 @@
|
||||
{+(Class
|
||||
{+(ScopeResolution
|
||||
{+(Identifier)+}
|
||||
{+(Identifier)+})+})+})
|
||||
{+(Identifier)+})+}
|
||||
{+([])+})+})
|
||||
|
3
test/fixtures/ruby/class.parseA.txt
vendored
3
test/fixtures/ruby/class.parseA.txt
vendored
@ -9,4 +9,5 @@
|
||||
(Class
|
||||
(ScopeResolution
|
||||
(Identifier)
|
||||
(Identifier))))
|
||||
(Identifier))
|
||||
([])))
|
||||
|
8
test/fixtures/toc/markdown/headings.A.md
vendored
8
test/fixtures/toc/markdown/headings.A.md
vendored
@ -1,3 +1,11 @@
|
||||
# Introduction
|
||||
|
||||
one, two, three
|
||||
|
||||
# One
|
||||
|
||||
Just some text
|
||||
|
||||
## Two
|
||||
|
||||
abc
|
||||
|
4
test/fixtures/toc/markdown/headings.B.md
vendored
4
test/fixtures/toc/markdown/headings.B.md
vendored
@ -4,6 +4,10 @@ Just some text
|
||||
|
||||
## Two
|
||||
|
||||
xyz
|
||||
|
||||
### This heading is new
|
||||
|
||||
more text
|
||||
|
||||
Final
|
||||
|
@ -1,16 +1,19 @@
|
||||
(Program
|
||||
{+(AmbientDeclaration
|
||||
{+(InternalModule
|
||||
{+(Identifier)+})+})+}
|
||||
(AmbientDeclaration
|
||||
{ (Class
|
||||
{-(Identifier)-}
|
||||
{-(PublicFieldDefinition
|
||||
(Class
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
{ (PublicFieldDefinition
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Annotation
|
||||
{-(TypeIdentifier)-})-}
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})
|
||||
->(InternalModule
|
||||
{+(Identifier)+}) })
|
||||
{-(Empty)-})
|
||||
->([]) }))
|
||||
(AmbientDeclaration
|
||||
{ (VariableDeclaration
|
||||
{-(Assignment
|
||||
@ -18,14 +21,11 @@
|
||||
{-(PredefinedType)-})-}
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})
|
||||
->(Class
|
||||
{+(Identifier)+}) })
|
||||
{+(AmbientDeclaration
|
||||
{+(InterfaceDeclaration
|
||||
->(InterfaceDeclaration
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(ObjectType)+})+})+}
|
||||
{+(ObjectType)+}) })
|
||||
{-(AmbientDeclaration
|
||||
{-(AmbientFunction
|
||||
{-(Empty)-}
|
||||
@ -99,34 +99,35 @@
|
||||
(AmbientDeclaration
|
||||
(Class
|
||||
(Identifier)
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier))))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)))))
|
||||
{+(AmbientDeclaration
|
||||
{+(AmbientFunction
|
||||
{+(Empty)+}
|
||||
|
@ -1,8 +1,6 @@
|
||||
(Program
|
||||
(AmbientDeclaration
|
||||
{ (InternalModule
|
||||
{-(Identifier)-})
|
||||
->(Class
|
||||
{+(AmbientDeclaration
|
||||
{+(Class
|
||||
{+(Identifier)+}
|
||||
{+(PublicFieldDefinition
|
||||
{+(Empty)+}
|
||||
@ -10,16 +8,14 @@
|
||||
{+(Annotation
|
||||
{+(TypeIdentifier)+})+}
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+}) })
|
||||
(AmbientDeclaration
|
||||
{ (Class
|
||||
{-(Identifier)-})
|
||||
->(VariableDeclaration
|
||||
{+(Empty)+})+})+})+}
|
||||
{+(AmbientDeclaration
|
||||
{+(VariableDeclaration
|
||||
{+(Assignment
|
||||
{+(Annotation
|
||||
{+(PredefinedType)+})+}
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+}) })
|
||||
{+(Empty)+})+})+})+}
|
||||
{+(AmbientDeclaration
|
||||
{+(AmbientFunction
|
||||
{+(Empty)+}
|
||||
@ -34,13 +30,8 @@
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+})+})+}
|
||||
(AmbientDeclaration
|
||||
{ (InterfaceDeclaration
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(ObjectType)-})
|
||||
->(InternalModule
|
||||
{+(AmbientDeclaration
|
||||
{+(InternalModule
|
||||
{+(Identifier)+}
|
||||
{+(AmbientFunction
|
||||
{+(Empty)+}
|
||||
@ -94,38 +85,52 @@
|
||||
{+(Empty)+}
|
||||
{+(Annotation
|
||||
{+(PredefinedType)+})+}
|
||||
{+(Identifier)+})+})+})+}) })
|
||||
{+(Identifier)+})+})+})+})+})+}
|
||||
{-(AmbientDeclaration
|
||||
{-(InternalModule
|
||||
{-(Identifier)-})-})-}
|
||||
{-(AmbientDeclaration
|
||||
{-(Class
|
||||
{-(Identifier)-}
|
||||
{-([])-})-})-}
|
||||
{-(AmbientDeclaration
|
||||
{-(InterfaceDeclaration
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(ObjectType)-})-})-}
|
||||
(AmbientDeclaration
|
||||
(Class
|
||||
(Identifier)
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier))))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)))))
|
||||
{-(AmbientDeclaration
|
||||
{-(AmbientFunction
|
||||
{-(Empty)-}
|
||||
|
@ -89,31 +89,32 @@
|
||||
(AmbientDeclaration
|
||||
(Class
|
||||
(Identifier)
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)))))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier))))))
|
||||
|
@ -4,7 +4,8 @@
|
||||
(Identifier)))
|
||||
(AmbientDeclaration
|
||||
(Class
|
||||
(Identifier)))
|
||||
(Identifier)
|
||||
([])))
|
||||
(AmbientDeclaration
|
||||
(InterfaceDeclaration
|
||||
(Empty)
|
||||
@ -14,34 +15,35 @@
|
||||
(AmbientDeclaration
|
||||
(Class
|
||||
(Identifier)
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty))))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier))))
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(MethodSignature
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(PredefinedType))
|
||||
(Identifier)))))
|
||||
(AmbientDeclaration
|
||||
(AmbientFunction
|
||||
(Empty)
|
||||
|
@ -26,4 +26,5 @@
|
||||
{+(ShorthandPropertyIdentifier)+}
|
||||
{+(ShorthandPropertyIdentifier)+})+})+})+})+}
|
||||
{-(Class
|
||||
{-(Identifier)-})-}))
|
||||
{-(Identifier)-}
|
||||
{-([])-})-}))
|
||||
|
@ -1,7 +1,8 @@
|
||||
(Program
|
||||
(Export
|
||||
{+(Class
|
||||
{+(Identifier)+})+}
|
||||
{+(Identifier)+}
|
||||
{+([])+})+}
|
||||
{-(Function
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
|
@ -1,4 +1,5 @@
|
||||
(Program
|
||||
(Export
|
||||
(Class
|
||||
(Identifier))))
|
||||
(Identifier)
|
||||
([]))))
|
||||
|
181
test/fixtures/typescript/class.diffA-B.txt
vendored
181
test/fixtures/typescript/class.diffA-B.txt
vendored
@ -10,111 +10,112 @@
|
||||
(ExtendsClause
|
||||
{ (TypeIdentifier)
|
||||
->(TypeIdentifier) })
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
(
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{+(Method
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{-(PublicFieldDefinition
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(Float)-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(RequiredParameter
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Assignment
|
||||
{+(Identifier)+}
|
||||
{+(Empty)+})+})+}
|
||||
{+(
|
||||
{+(Return
|
||||
{+(Identifier)+})+})+})+}
|
||||
{-(PublicFieldDefinition
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Identifier)-}
|
||||
{-(Float)-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}))
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-}
|
||||
{-(Method
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Identifier)-}
|
||||
{-(RequiredParameter
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Empty)-}
|
||||
{-(Assignment
|
||||
{-(Identifier)-}
|
||||
{-(Empty)-})-})-}
|
||||
{-(
|
||||
{-(Return
|
||||
{-(Identifier)-})-})-})-})))
|
||||
|
103
test/fixtures/typescript/class.diffB-A.txt
vendored
103
test/fixtures/typescript/class.diffB-A.txt
vendored
@ -10,63 +10,64 @@
|
||||
(ExtendsClause
|
||||
{ (TypeIdentifier)
|
||||
->(TypeIdentifier) })
|
||||
{+(PublicFieldDefinition
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(Float)+})+}
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(
|
||||
{+(PublicFieldDefinition
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Empty)+}
|
||||
{+(Identifier)+}
|
||||
{+(Float)+})+}
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))))
|
||||
(Empty)
|
||||
(Empty)
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier)))))))
|
||||
|
97
test/fixtures/typescript/class.parseA.txt
vendored
97
test/fixtures/typescript/class.parseA.txt
vendored
@ -7,60 +7,61 @@
|
||||
(Identifier)
|
||||
(ExtendsClause
|
||||
(TypeIdentifier))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Identifier)
|
||||
(Float))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))))
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier)))))))
|
||||
|
85
test/fixtures/typescript/class.parseB.txt
vendored
85
test/fixtures/typescript/class.parseB.txt
vendored
@ -7,54 +7,55 @@
|
||||
(Identifier)
|
||||
(ExtendsClause
|
||||
(TypeIdentifier))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))
|
||||
(Method
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier))))))
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(RequiredParameter
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Assignment
|
||||
(Identifier)
|
||||
(Empty)))
|
||||
(
|
||||
(Return
|
||||
(Identifier)))))))
|
||||
|
@ -1,85 +1,86 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
{+(Annotation
|
||||
{+(TypeIdentifier)+})+}
|
||||
{-(Empty)-}
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
{+(Empty)+}
|
||||
{-(Readonly)-}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{+(Identifier)+}
|
||||
(Empty)
|
||||
{-(Readonly)-}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{+(Identifier)+}
|
||||
{-(Empty)-}
|
||||
(Readonly)
|
||||
(Annotation
|
||||
{ (TypeIdentifier)
|
||||
->(TypeIdentifier) })
|
||||
(Identifier)
|
||||
{ (Float)
|
||||
->(TextElement) })
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
{ (Float)
|
||||
->(Float) })))
|
||||
(
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
{+(Annotation
|
||||
{+(TypeIdentifier)+})+}
|
||||
{-(Empty)-}
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
{+(Empty)+}
|
||||
{-(Readonly)-}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{+(Identifier)+}
|
||||
(Empty)
|
||||
{-(Readonly)-}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{+(Identifier)+}
|
||||
{-(Empty)-}
|
||||
(Readonly)
|
||||
(Annotation
|
||||
{ (TypeIdentifier)
|
||||
->(TypeIdentifier) })
|
||||
(Identifier)
|
||||
{ (Float)
|
||||
->(TextElement) })
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
{ (Float)
|
||||
->(Float) }))))
|
||||
|
@ -1,85 +1,86 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
{+(Empty)+}
|
||||
{-(Annotation
|
||||
{-(TypeIdentifier)-})-}
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
{+(Readonly)+}
|
||||
{-(Empty)-}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{-(Identifier)-}
|
||||
(Empty)
|
||||
{+(Readonly)+}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{+(Empty)+}
|
||||
{-(Identifier)-}
|
||||
(Readonly)
|
||||
(Annotation
|
||||
{ (TypeIdentifier)
|
||||
->(TypeIdentifier) })
|
||||
(Identifier)
|
||||
{ (TextElement)
|
||||
->(Float) })
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
{ (Float)
|
||||
->(Float) })))
|
||||
(
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
{+(Empty)+}
|
||||
{-(Annotation
|
||||
{-(TypeIdentifier)-})-}
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
{+(Readonly)+}
|
||||
{-(Empty)-}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{-(Identifier)-}
|
||||
(Empty)
|
||||
{+(Readonly)+}
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
{+(Empty)+}
|
||||
{-(Identifier)-}
|
||||
(Readonly)
|
||||
(Annotation
|
||||
{ (TypeIdentifier)
|
||||
->(TypeIdentifier) })
|
||||
(Identifier)
|
||||
{ (TextElement)
|
||||
->(Float) })
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
{ (Identifier)
|
||||
->(Identifier) }
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
{ (Float)
|
||||
->(Float) }))))
|
||||
|
@ -1,75 +1,76 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float))))
|
||||
(
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float)))))
|
||||
|
@ -1,76 +1,77 @@
|
||||
(Program
|
||||
(Class
|
||||
(Identifier)
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(TextElement))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float))))
|
||||
(
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Empty))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Identifier)
|
||||
(Readonly)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(TextElement))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Annotation
|
||||
(TypeIdentifier))
|
||||
(Identifier)
|
||||
(Float))
|
||||
(PublicFieldDefinition
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Empty)
|
||||
(Identifier)
|
||||
(Float)))))
|
||||
|
Loading…
Reference in New Issue
Block a user