mirror of
https://github.com/github/semantic.git
synced 2024-12-03 00:16:52 +03:00
🔥 the comparability parameter to diffTerms.
This commit is contained in:
parent
c4f37454d6
commit
fe326bcf03
@ -46,7 +46,7 @@ diffFiles parse render sourceBlobs = do
|
|||||||
(True, False) -> pure $ Insert (snd terms)
|
(True, False) -> pure $ Insert (snd terms)
|
||||||
(False, True) -> pure $ Delete (fst terms)
|
(False, True) -> pure $ Delete (fst terms)
|
||||||
(_, _) ->
|
(_, _) ->
|
||||||
runBothWith (diffTerms compareCategoryEq) terms
|
runBothWith diffTerms terms
|
||||||
areNullOids a b = (hasNullOid a, hasNullOid b)
|
areNullOids a b = (hasNullOid a, hasNullOid b)
|
||||||
hasNullOid blob = oid blob == nullOid || Source.null (source blob)
|
hasNullOid blob = oid blob == nullOid || Source.null (source blob)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{-# LANGUAGE GADTs, RankNTypes #-}
|
{-# LANGUAGE GADTs, RankNTypes #-}
|
||||||
module Interpreter (Comparable, diffTerms) where
|
module Interpreter (diffTerms) where
|
||||||
|
|
||||||
import Algorithm
|
import Algorithm
|
||||||
import Data.Align.Generic
|
import Data.Align.Generic
|
||||||
@ -15,28 +15,24 @@ import Prologue hiding (lookup)
|
|||||||
import Syntax as S
|
import Syntax as S
|
||||||
import Term
|
import Term
|
||||||
|
|
||||||
-- | Returns whether two terms are comparable
|
|
||||||
type Comparable f annotation = Term f annotation -> Term f annotation -> Bool
|
|
||||||
|
|
||||||
-- | Diff two terms recursively, given functions characterizing the diffing.
|
-- | Diff two terms recursively, given functions characterizing the diffing.
|
||||||
diffTerms :: (Eq leaf, HasField fields Category, HasField fields (Maybe FeatureVector))
|
diffTerms :: (Eq leaf, HasField fields Category, HasField fields (Maybe FeatureVector))
|
||||||
=> Comparable (Syntax leaf) (Record fields) -- ^ A function to determine whether or not two terms should even be compared.
|
=> SyntaxTerm leaf fields -- ^ A term representing the old state.
|
||||||
-> SyntaxTerm leaf fields -- ^ A term representing the old state.
|
|
||||||
-> SyntaxTerm leaf fields -- ^ A term representing the new state.
|
-> SyntaxTerm leaf fields -- ^ A term representing the new state.
|
||||||
-> SyntaxDiff leaf fields
|
-> SyntaxDiff leaf fields
|
||||||
diffTerms comparable a b = fromMaybe (replacing a b) $ diffComparableTerms comparable a b
|
diffTerms a b = fromMaybe (replacing a b) $ diffComparableTerms a b
|
||||||
|
|
||||||
-- | Diff two terms recursively, given functions characterizing the diffing. If the terms are incomparable, returns 'Nothing'.
|
-- | Diff two terms recursively, given functions characterizing the diffing. If the terms are incomparable, returns 'Nothing'.
|
||||||
diffComparableTerms :: (Eq leaf, HasField fields Category, HasField fields (Maybe FeatureVector))
|
diffComparableTerms :: (Eq leaf, HasField fields Category, HasField fields (Maybe FeatureVector))
|
||||||
=> Comparable (Syntax leaf) (Record fields)
|
=> SyntaxTerm leaf fields
|
||||||
-> SyntaxTerm leaf fields
|
|
||||||
-> SyntaxTerm leaf fields
|
-> SyntaxTerm leaf fields
|
||||||
-> Maybe (SyntaxDiff leaf fields)
|
-> Maybe (SyntaxDiff leaf fields)
|
||||||
diffComparableTerms comparable = recur
|
diffComparableTerms = recur
|
||||||
where recur a b
|
where recur a b
|
||||||
| (category <$> a) == (category <$> b) = hylo wrap runCofree <$> zipTerms a b
|
| (category <$> a) == (category <$> b) = hylo wrap runCofree <$> zipTerms a b
|
||||||
| comparable a b = runAlgorithm recur (Just <$> algorithmWithTerms a b)
|
| comparable a b = runAlgorithm recur (Just <$> algorithmWithTerms a b)
|
||||||
| otherwise = Nothing
|
| otherwise = Nothing
|
||||||
|
comparable = (==) `on` category . extract
|
||||||
|
|
||||||
-- | Construct an algorithm to diff a pair of terms.
|
-- | Construct an algorithm to diff a pair of terms.
|
||||||
algorithmWithTerms :: MonadFree (TermF (Syntax leaf) (Both a)) diff
|
algorithmWithTerms :: MonadFree (TermF (Syntax leaf) (Both a)) diff
|
||||||
|
@ -24,16 +24,16 @@ spec = parallel $ do
|
|||||||
|
|
||||||
prop "equal terms produce identity diffs" $
|
prop "equal terms produce identity diffs" $
|
||||||
\ a -> let term = decorate (unListableF a :: SyntaxTerm String '[Category]) in
|
\ a -> let term = decorate (unListableF a :: SyntaxTerm String '[Category]) in
|
||||||
diffCost (diffTerms (==) term term) `shouldBe` 0
|
diffCost (diffTerms term term) `shouldBe` 0
|
||||||
|
|
||||||
describe "beforeTerm" $ do
|
describe "beforeTerm" $ do
|
||||||
prop "recovers the before term" $
|
prop "recovers the before term" $
|
||||||
\ a b -> let diff = stripDiff $ diffTerms (==) (decorate (unListableF a)) (decorate (unListableF b :: SyntaxTerm String '[Category])) in
|
\ a b -> let diff = stripDiff $ diffTerms (decorate (unListableF a)) (decorate (unListableF b :: SyntaxTerm String '[Category])) in
|
||||||
beforeTerm diff `shouldBe` Just (unListableF a)
|
beforeTerm diff `shouldBe` Just (unListableF a)
|
||||||
|
|
||||||
describe "afterTerm" $ do
|
describe "afterTerm" $ do
|
||||||
prop "recovers the after term" $
|
prop "recovers the after term" $
|
||||||
\ a b -> let diff = stripDiff $ diffTerms (==) (decorate (unListableF a)) (decorate (unListableF b :: SyntaxTerm String '[Category])) in
|
\ a b -> let diff = stripDiff $ diffTerms (decorate (unListableF a)) (decorate (unListableF b :: SyntaxTerm String '[Category])) in
|
||||||
afterTerm diff `shouldBe` Just (unListableF b)
|
afterTerm diff `shouldBe` Just (unListableF b)
|
||||||
|
|
||||||
unListableDiff :: Functor f => ListableF (Free (TermF f (ListableF (Join (,)) annotation))) (Patch (ListableF (Term f) annotation)) -> Diff f annotation
|
unListableDiff :: Functor f => ListableF (Free (TermF f (ListableF (Join (,)) annotation))) (Patch (ListableF (Term f) annotation)) -> Diff f annotation
|
||||||
|
@ -51,7 +51,7 @@ spec = parallel $ do
|
|||||||
|
|
||||||
prop "equal terms produce identity diffs" $
|
prop "equal terms produce identity diffs" $
|
||||||
\ a -> let term = defaultFeatureVectorDecorator (category . headF) (unListableF a :: SyntaxTerm String '[Category, Range, SourceSpan]) in
|
\ a -> let term = defaultFeatureVectorDecorator (category . headF) (unListableF a :: SyntaxTerm String '[Category, Range, SourceSpan]) in
|
||||||
diffSummaries blobs (diffTerms (==) term term) `shouldBe` []
|
diffSummaries blobs (diffTerms term term) `shouldBe` []
|
||||||
|
|
||||||
describe "DiffInfo" $ do
|
describe "DiffInfo" $ do
|
||||||
prop "patches in summaries match the patches in diffs" $
|
prop "patches in summaries match the patches in diffs" $
|
||||||
|
@ -23,22 +23,21 @@ spec :: Spec
|
|||||||
spec = parallel $ do
|
spec = parallel $ do
|
||||||
describe "interpret" $ do
|
describe "interpret" $ do
|
||||||
let decorate = defaultFeatureVectorDecorator (category . headF)
|
let decorate = defaultFeatureVectorDecorator (category . headF)
|
||||||
let compare = (==) `on` category . extract
|
|
||||||
it "returns a replacement when comparing two unicode equivalent terms" $
|
it "returns a replacement when comparing two unicode equivalent terms" $
|
||||||
let termA = cofree $ (StringLiteral :. Nil) :< Leaf ("t\776" :: String)
|
let termA = cofree $ (StringLiteral :. Nil) :< Leaf ("t\776" :: String)
|
||||||
termB = cofree $ (StringLiteral :. Nil) :< Leaf "\7831" in
|
termB = cofree $ (StringLiteral :. Nil) :< Leaf "\7831" in
|
||||||
stripDiff (diffTerms compare (decorate termA) (decorate termB)) `shouldBe` replacing termA termB
|
stripDiff (diffTerms (decorate termA) (decorate termB)) `shouldBe` replacing termA termB
|
||||||
|
|
||||||
prop "produces correct diffs" $
|
prop "produces correct diffs" $
|
||||||
\ a b -> let diff = stripDiff $ diffTerms compare (decorate (unListableF a)) (decorate (unListableF b :: SyntaxTerm String '[Category])) in
|
\ a b -> let diff = stripDiff $ diffTerms (decorate (unListableF a)) (decorate (unListableF b :: SyntaxTerm String '[Category])) in
|
||||||
(beforeTerm diff, afterTerm diff) `shouldBe` (Just (unListableF a), Just (unListableF b))
|
(beforeTerm diff, afterTerm diff) `shouldBe` (Just (unListableF a), Just (unListableF b))
|
||||||
|
|
||||||
prop "constructs zero-cost diffs of equal terms" $
|
prop "constructs zero-cost diffs of equal terms" $
|
||||||
\ a -> let term = decorate (unListableF a :: SyntaxTerm String '[Category])
|
\ a -> let term = decorate (unListableF a :: SyntaxTerm String '[Category])
|
||||||
diff = diffTerms compare term term in
|
diff = diffTerms term term in
|
||||||
diffCost diff `shouldBe` 0
|
diffCost diff `shouldBe` 0
|
||||||
|
|
||||||
it "produces unbiased insertions within branches" $
|
it "produces unbiased insertions within branches" $
|
||||||
let term s = decorate (cofree ((StringLiteral :. Nil) :< Indexed [ cofree ((StringLiteral :. Nil) :< Leaf s) ]))
|
let term s = decorate (cofree ((StringLiteral :. Nil) :< Indexed [ cofree ((StringLiteral :. Nil) :< Leaf s) ]))
|
||||||
root = cofree . ((Just (listArray (0, defaultD) (repeat 0)) :. Program :. Nil) :<) . Indexed in
|
root = cofree . ((Just (listArray (0, defaultD) (repeat 0)) :. Program :. Nil) :<) . Indexed in
|
||||||
stripDiff (diffTerms compare (root [ term "b" ]) (root [ term "a", term "b" ])) `shouldBe` wrap (pure (Program :. Nil) :< Indexed [ inserting (stripTerm (term "a")), cata wrap (fmap pure (stripTerm (term "b"))) ])
|
stripDiff (diffTerms (root [ term "b" ]) (root [ term "a", term "b" ])) `shouldBe` wrap (pure (Program :. Nil) :< Indexed [ inserting (stripTerm (term "a")), cata wrap (fmap pure (stripTerm (term "b"))) ])
|
||||||
|
@ -94,7 +94,7 @@ spec = parallel $ do
|
|||||||
|
|
||||||
prop "equal terms produce identity diffs" $
|
prop "equal terms produce identity diffs" $
|
||||||
\a -> let term = defaultFeatureVectorDecorator (Info.category . headF) (unListableF a :: Term') in
|
\a -> let term = defaultFeatureVectorDecorator (Info.category . headF) (unListableF a :: Term') in
|
||||||
diffTOC blankDiffBlobs (diffTerms (==) term term) `shouldBe` []
|
diffTOC blankDiffBlobs (diffTerms term term) `shouldBe` []
|
||||||
|
|
||||||
type Diff' = SyntaxDiff String '[Range, Category, SourceSpan]
|
type Diff' = SyntaxDiff String '[Range, Category, SourceSpan]
|
||||||
type Term' = SyntaxTerm String '[Range, Category, SourceSpan]
|
type Term' = SyntaxTerm String '[Range, Category, SourceSpan]
|
||||||
@ -165,7 +165,7 @@ testDiff sourceBlobs = do
|
|||||||
diffTerms' terms blobs = case runBothWith areNullOids blobs of
|
diffTerms' terms blobs = case runBothWith areNullOids blobs of
|
||||||
(True, False) -> pure $ Insert (snd terms)
|
(True, False) -> pure $ Insert (snd terms)
|
||||||
(False, True) -> pure $ Delete (fst terms)
|
(False, True) -> pure $ Delete (fst terms)
|
||||||
(_, _) -> runBothWith (diffTerms compareCategoryEq) terms
|
(_, _) -> runBothWith diffTerms terms
|
||||||
areNullOids a b = (hasNullOid a, hasNullOid b)
|
areNullOids a b = (hasNullOid a, hasNullOid b)
|
||||||
hasNullOid blob = oid blob == nullOid || Source.null (source blob)
|
hasNullOid blob = oid blob == nullOid || Source.null (source blob)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user