mirror of
https://github.com/github/semantic.git
synced 2024-12-23 23:11:50 +03:00
Data.Bifunctor.Join is actually Data.Functor.Both.
This commit is contained in:
parent
2b61360697
commit
0626228917
@ -18,7 +18,7 @@ library
|
||||
, Category
|
||||
, Control.Comonad.Cofree
|
||||
, Control.Monad.Free
|
||||
, Data.Bifunctor.Join
|
||||
, Data.Functor.Both
|
||||
, Data.Option
|
||||
, Data.OrderedMap
|
||||
, Diff
|
||||
|
@ -1,12 +0,0 @@
|
||||
module Data.Bifunctor.Join where
|
||||
|
||||
newtype Join a = Join { runJoin :: (a, a) }
|
||||
deriving (Eq, Show, Functor, Foldable, Traversable)
|
||||
|
||||
instance Applicative Join where
|
||||
pure a = Join (a, a)
|
||||
Join (f, g) <*> Join (a, b) = Join (f a, g b)
|
||||
|
||||
instance Monoid a => Monoid (Join a) where
|
||||
mempty = pure mempty
|
||||
mappend a b = pure mappend <*> a <*> b
|
12
src/Data/Functor/Both.hs
Normal file
12
src/Data/Functor/Both.hs
Normal file
@ -0,0 +1,12 @@
|
||||
module Data.Functor.Both where
|
||||
|
||||
newtype Both a = Both { runBoth :: (a, a) }
|
||||
deriving (Eq, Show, Functor, Foldable, Traversable)
|
||||
|
||||
instance Applicative Both where
|
||||
pure a = Both (a, a)
|
||||
Both (f, g) <*> Both (a, b) = Both (f a, g b)
|
||||
|
||||
instance Monoid a => Monoid (Both a) where
|
||||
mempty = pure mempty
|
||||
mappend a b = pure mappend <*> a <*> b
|
@ -1,6 +1,6 @@
|
||||
module DiffOutput where
|
||||
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import qualified Data.ByteString.Char8 as B1
|
||||
import Diffing
|
||||
import Parser
|
||||
@ -18,7 +18,7 @@ data Format = Split | Patch
|
||||
data DiffArguments = DiffArguments { format :: Format, output :: Maybe FilePath, outputPath :: FilePath }
|
||||
|
||||
-- | Return a renderer from the command-line arguments that will print the diff.
|
||||
printDiff :: Parser -> DiffArguments -> Join SourceBlob -> IO ()
|
||||
printDiff :: Parser -> DiffArguments -> Both SourceBlob -> IO ()
|
||||
printDiff parser arguments sources = case format arguments of
|
||||
Split -> put (output arguments) =<< diffFiles parser split sources
|
||||
where
|
||||
|
@ -13,7 +13,7 @@ import TreeSitter
|
||||
import Text.Parser.TreeSitter.Language
|
||||
|
||||
import Control.Comonad.Cofree
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import qualified Data.ByteString.Char8 as B1
|
||||
import Data.Foldable
|
||||
import qualified Data.Text as T
|
||||
@ -70,9 +70,9 @@ readAndTranscodeFile path = do
|
||||
|
||||
-- | Given a parser and renderer, diff two sources and return the rendered
|
||||
-- | result.
|
||||
diffFiles :: Parser -> Renderer T.Text b -> Join SourceBlob -> IO b
|
||||
diffFiles :: Parser -> Renderer T.Text b -> Both SourceBlob -> IO b
|
||||
diffFiles parser renderer sourceBlobs = do
|
||||
let sources = source <$> sourceBlobs
|
||||
terms <- sequence $ parser <$> sources
|
||||
let replaceLeaves = breakDownLeavesByWord <$> sources
|
||||
return $ renderer (uncurry diffTerms $ runJoin $ replaceLeaves <*> terms) sourceBlobs
|
||||
return $ renderer (uncurry diffTerms $ runBoth $ replaceLeaves <*> terms) sourceBlobs
|
||||
|
@ -1,8 +1,8 @@
|
||||
module Renderer where
|
||||
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import Diff
|
||||
import Source
|
||||
|
||||
-- | A function that will render a diff, given the two source files.
|
||||
type Renderer a b = Diff a Info -> Join SourceBlob -> b
|
||||
type Renderer a b = Diff a Info -> Both SourceBlob -> b
|
||||
|
@ -16,7 +16,7 @@ import Control.Monad.Free
|
||||
import Data.Maybe
|
||||
import Data.Monoid
|
||||
import Data.Bifunctor
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import Control.Monad
|
||||
|
||||
-- | Render a diff in the traditional patch format.
|
||||
@ -24,7 +24,7 @@ patch :: Renderer a String
|
||||
patch diff sources = mconcat $ showHunk sources <$> hunks diff sources
|
||||
|
||||
-- | A hunk in a patch, including the offset, changes, and context.
|
||||
data Hunk a = Hunk { offset :: Join (Sum Int), changes :: [Change a], trailingContext :: [Row a] }
|
||||
data Hunk a = Hunk { offset :: Both (Sum Int), changes :: [Change a], trailingContext :: [Row a] }
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | A change in a patch hunk, along with its preceding context.
|
||||
@ -32,16 +32,16 @@ data Change a = Change { context :: [Row a], contents :: [Row a] }
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | The number of lines in the hunk before and after.
|
||||
hunkLength :: Hunk a -> Join (Sum Int)
|
||||
hunkLength :: Hunk a -> Both (Sum Int)
|
||||
hunkLength hunk = mconcat $ (changeLength <$> changes hunk) <> (rowLength <$> trailingContext hunk)
|
||||
|
||||
-- | The number of lines in change before and after.
|
||||
changeLength :: Change a -> Join (Sum Int)
|
||||
changeLength :: Change a -> Both (Sum Int)
|
||||
changeLength change = mconcat $ (rowLength <$> context change) <> (rowLength <$> contents change)
|
||||
|
||||
-- | The number of lines in the row, each being either 0 or 1.
|
||||
rowLength :: Row a -> Join (Sum Int)
|
||||
rowLength (Row a b) = pure lineLength <*> Join (a, b)
|
||||
rowLength :: Row a -> Both (Sum Int)
|
||||
rowLength (Row a b) = pure lineLength <*> Both (a, b)
|
||||
|
||||
-- | The length of the line, being either 0 or 1.
|
||||
lineLength :: Line a -> Sum Int
|
||||
@ -49,14 +49,14 @@ lineLength EmptyLine = 0
|
||||
lineLength _ = 1
|
||||
|
||||
-- | Given the before and after sources, render a hunk to a string.
|
||||
showHunk :: Join SourceBlob -> Hunk (SplitDiff a Info) -> String
|
||||
showHunk blobs hunk = header blobs hunk ++ concat (showChange sources <$> changes hunk) ++ showLines (snd $ runJoin sources) ' ' (unRight <$> trailingContext hunk)
|
||||
showHunk :: Both SourceBlob -> Hunk (SplitDiff a Info) -> String
|
||||
showHunk blobs hunk = header blobs hunk ++ concat (showChange sources <$> changes hunk) ++ showLines (snd $ runBoth sources) ' ' (unRight <$> trailingContext hunk)
|
||||
where sources = source <$> blobs
|
||||
|
||||
-- | Given the before and after sources, render a change to a string.
|
||||
showChange :: Join (Source Char) -> Change (SplitDiff a Info) -> String
|
||||
showChange sources change = showLines (snd $ runJoin sources) ' ' (unRight <$> context change) ++ deleted ++ inserted
|
||||
where (deleted, inserted) = runJoin $ pure showLines <*> sources <*> Join ('-', '+') <*> (pure fmap <*> Join (unLeft, unRight) <*> pure (contents change))
|
||||
showChange :: Both (Source Char) -> Change (SplitDiff a Info) -> String
|
||||
showChange sources change = showLines (snd $ runBoth sources) ' ' (unRight <$> context change) ++ deleted ++ inserted
|
||||
where (deleted, inserted) = runBoth $ pure showLines <*> sources <*> Both ('-', '+') <*> (pure fmap <*> Both (unLeft, unRight) <*> pure (contents change))
|
||||
|
||||
-- | Given a source, render a set of lines to a string with a prefix.
|
||||
showLines :: Source Char -> Char -> [Line (SplitDiff leaf Info)] -> String
|
||||
@ -75,31 +75,31 @@ getRange (Free (Annotated (Info range _) _)) = range
|
||||
getRange (Pure patch) = let Info range _ :< _ = getSplitTerm patch in range
|
||||
|
||||
-- | Returns the header given two source blobs and a hunk.
|
||||
header :: Join SourceBlob -> Hunk a -> String
|
||||
header :: Both SourceBlob -> Hunk a -> String
|
||||
header blobs hunk = "diff --git a/" ++ pathA ++ " b/" ++ pathB ++ "\n" ++
|
||||
"index " ++ oidA ++ ".." ++ oidB ++ "\n" ++
|
||||
"@@ -" ++ show offsetA ++ "," ++ show lengthA ++ " +" ++ show offsetB ++ "," ++ show lengthB ++ " @@\n"
|
||||
where (lengthA, lengthB) = runJoin . fmap getSum $ hunkLength hunk
|
||||
(offsetA, offsetB) = runJoin . fmap getSum $ offset hunk
|
||||
(pathA, pathB) = runJoin $ path <$> blobs
|
||||
(oidA, oidB) = runJoin $ oid <$> blobs
|
||||
where (lengthA, lengthB) = runBoth . fmap getSum $ hunkLength hunk
|
||||
(offsetA, offsetB) = runBoth . fmap getSum $ offset hunk
|
||||
(pathA, pathB) = runBoth $ path <$> blobs
|
||||
(oidA, oidB) = runBoth $ oid <$> blobs
|
||||
|
||||
-- | Render a diff as a series of hunks.
|
||||
hunks :: Renderer a [Hunk (SplitDiff a Info)]
|
||||
hunks diff blobs = hunksInRows (Join (1, 1)) . fst $ splitDiffByLines diff (0, 0) (before, after)
|
||||
hunks diff blobs = hunksInRows (Both (1, 1)) . fst $ splitDiffByLines diff (0, 0) (before, after)
|
||||
where
|
||||
(before, after) = runJoin $ source <$> blobs
|
||||
(before, after) = runBoth $ source <$> blobs
|
||||
|
||||
-- | Given beginning line numbers, turn rows in a split diff into hunks in a
|
||||
-- | patch.
|
||||
hunksInRows :: Join (Sum Int) -> [Row (SplitDiff a Info)] -> [Hunk (SplitDiff a Info)]
|
||||
hunksInRows :: Both (Sum Int) -> [Row (SplitDiff a Info)] -> [Hunk (SplitDiff a Info)]
|
||||
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 :: Join (Sum Int) -> [Row (SplitDiff a Info)] -> Maybe (Hunk (SplitDiff a Info), [Row (SplitDiff a Info)])
|
||||
nextHunk :: Both (Sum Int) -> [Row (SplitDiff a Info)] -> Maybe (Hunk (SplitDiff a Info), [Row (SplitDiff a Info)])
|
||||
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')
|
||||
@ -111,7 +111,7 @@ nextHunk start rows = case nextChange start rows of
|
||||
|
||||
-- | Given beginning line numbers, return the number of lines to the next
|
||||
-- | the next change, and the remaining rows of the split diff.
|
||||
nextChange :: Join (Sum Int) -> [Row (SplitDiff a Info)] -> Maybe (Join (Sum Int), Change (SplitDiff a Info), [Row (SplitDiff a Info)])
|
||||
nextChange :: Both (Sum Int) -> [Row (SplitDiff a Info)] -> Maybe (Both (Sum Int), Change (SplitDiff a Info), [Row (SplitDiff a Info)])
|
||||
nextChange start rows = case changeIncludingContext leadingContext afterLeadingContext of
|
||||
Nothing -> Nothing
|
||||
Just (change, afterChanges) -> Just (start <> mconcat (rowLength <$> skippedContext), change, afterChanges)
|
||||
|
@ -21,7 +21,7 @@ import qualified Text.Blaze.Html5.Attributes as A
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Lazy as TL
|
||||
import Text.Blaze.Html.Renderer.Text
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import Data.Foldable
|
||||
import Data.Monoid
|
||||
import Source hiding ((++))
|
||||
@ -62,7 +62,7 @@ split diff blobs = renderHtml
|
||||
((colgroup $ (col ! A.width (stringValue . show $ columnWidth)) <> col <> (col ! A.width (stringValue . show $ columnWidth)) <> col) <>)
|
||||
. mconcat $ numberedLinesToMarkup <$> reverse numbered
|
||||
where
|
||||
(before, after) = runJoin $ Source.source <$> blobs
|
||||
(before, after) = runBoth $ Source.source <$> blobs
|
||||
rows = fst (splitDiffByLines diff (0, 0) (before, after))
|
||||
numbered = foldl' numberRows [] rows
|
||||
maxNumber = case numbered of
|
||||
|
@ -7,7 +7,7 @@ import qualified Renderer.Split as Split
|
||||
|
||||
import qualified Source as S
|
||||
import Control.DeepSeq
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import qualified Data.ByteString.Char8 as B1
|
||||
import Data.List as List
|
||||
import Data.Map as Map
|
||||
@ -72,10 +72,10 @@ normalizeName path = addExtension (dropExtension $ dropExtension path) (takeExte
|
||||
-- | is true, but the diff will still be calculated.
|
||||
testDiff :: Renderer T.Text String -> FilePath -> FilePath -> Maybe FilePath -> ((String, String) -> Expectation) -> Expectation
|
||||
testDiff renderer a b diff matcher = do
|
||||
let paths = Join (a, b)
|
||||
let paths = Both (a, b)
|
||||
let parser = parserForFilepath a
|
||||
sources <- sequence $ readAndTranscodeFile <$> paths
|
||||
let sourceBlobs = Join (S.SourceBlob, S.SourceBlob) <*> sources <*> Join (mempty, mempty) <*> paths
|
||||
let sourceBlobs = Both (S.SourceBlob, S.SourceBlob) <*> sources <*> Both (mempty, mempty) <*> paths
|
||||
actual <- diffFiles parser renderer sourceBlobs
|
||||
case diff of
|
||||
Nothing -> actual `deepseq` matcher (actual, actual)
|
||||
|
@ -1,6 +1,6 @@
|
||||
module PatchOutputSpec where
|
||||
|
||||
import Data.Bifunctor.Join
|
||||
import Data.Functor.Both
|
||||
import Diff
|
||||
import Renderer.Patch
|
||||
import Range
|
||||
@ -13,4 +13,4 @@ spec :: Spec
|
||||
spec = parallel $
|
||||
describe "hunks" $
|
||||
it "empty diffs have no hunks" $
|
||||
hunks (Free . Annotated (Info (Range 0 0) mempty, Info (Range 0 0) mempty) $ Leaf "") (Join (SourceBlob (fromList "") "abcde" "path2.txt", SourceBlob (fromList "") "xyz" "path2.txt")) `shouldBe` []
|
||||
hunks (Free . Annotated (Info (Range 0 0) mempty, Info (Range 0 0) mempty) $ Leaf "") (Both (SourceBlob (fromList "") "abcde" "path2.txt", SourceBlob (fromList "") "xyz" "path2.txt")) `shouldBe` []
|
||||
|
Loading…
Reference in New Issue
Block a user