1
1
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:
Rob Rix 2016-02-28 21:29:59 -05:00
parent 2b61360697
commit 0626228917
10 changed files with 48 additions and 48 deletions

View File

@ -18,7 +18,7 @@ library
, Category
, Control.Comonad.Cofree
, Control.Monad.Free
, Data.Bifunctor.Join
, Data.Functor.Both
, Data.Option
, Data.OrderedMap
, Diff

View File

@ -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
View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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` []