1
1
mirror of https://github.com/github/semantic.git synced 2024-12-29 09:55:52 +03:00

Add a type parameter for the elements of Sources.

This commit is contained in:
Rob Rix 2015-12-23 21:38:23 -05:00
parent 6a879d4967
commit 002147ac3e

View File

@ -19,15 +19,15 @@ import Data.Monoid
import qualified Data.Set as Set
type ClassName = String
type Source = String
type Source a = [a]
subsource :: Range -> Source -> Source
subsource :: Range -> Source a -> Source a
subsource = substring
toString :: Source -> String
toString :: Source Char -> String
toString source = source
at :: Source -> Int -> Char
at :: Source a -> Int -> a
at = (!!)
classifyMarkup :: Foldable f => f String -> Markup -> Markup
@ -76,7 +76,7 @@ split diff before after = return . renderHtml
-- | A diff with only one sides annotations.
type SplitDiff leaf annotation = Free (Annotated leaf annotation) (Term leaf annotation)
newtype Renderable a = Renderable (Source, a)
newtype Renderable a = Renderable (Source Char, a)
instance ToMarkup f => ToMarkup (Renderable (Info, Syntax a (f, Range))) where
toMarkup (Renderable (source, (Info range categories, syntax))) = classifyMarkup categories $ case syntax of
@ -98,7 +98,7 @@ instance ToMarkup (Renderable (SplitDiff a Info)) where
where toMarkupAndRange :: Term a Info -> (Markup, Range)
toMarkupAndRange term@(Info range _ :< _) = ((div ! A.class_ (stringValue "patch")) . toMarkup $ Renderable (source, term), range)
splitDiffByLines :: Diff a Info -> (Int, Int) -> (Source, Source) -> ([Row (SplitDiff a Info)], (Range, Range))
splitDiffByLines :: Diff a Info -> (Int, Int) -> (Source Char, Source Char) -> ([Row (SplitDiff a Info)], (Range, Range))
splitDiffByLines diff (prevLeft, prevRight) sources = case diff of
Free (Annotated annotation syntax) -> (splitAnnotatedByLines sources (ranges annotation) (categories annotation) syntax, ranges annotation)
Pure (Insert term) -> let (lines, range) = splitTermByLines term (snd sources) in
@ -112,7 +112,7 @@ splitDiffByLines diff (prevLeft, prevRight) sources = case diff of
ranges (Info left _, Info right _) = (left, right)
-- | Takes a term and a source and returns a list of lines and their range within source.
splitTermByLines :: Term a Info -> Source -> ([Line (Term a Info)], Range)
splitTermByLines :: Term a Info -> Source Char -> ([Line (Term a Info)], Range)
splitTermByLines (Info range categories :< syntax) source = flip (,) range $ case syntax of
Leaf a -> contextLines (:< Leaf a) range categories source
Indexed children -> adjoinChildLines Indexed children
@ -125,7 +125,7 @@ splitTermByLines (Info range categories :< syntax) source = flip (,) range $ cas
childLines constructor (lines, previous) child = let (childLines, childRange) = splitTermByLines child source in
(adjoin $ lines ++ contextLines (:< constructor) (Range previous $ start childRange) categories source ++ childLines, end childRange)
splitAnnotatedByLines :: (Source, Source) -> (Range, Range) -> (Set.Set Category, Set.Set Category) -> Syntax a (Diff a Info) -> [Row (SplitDiff a Info)]
splitAnnotatedByLines :: (Source Char, Source Char) -> (Range, Range) -> (Set.Set Category, Set.Set Category) -> Syntax a (Diff a Info) -> [Row (SplitDiff a Info)]
splitAnnotatedByLines sources ranges categories syntax = case syntax of
Leaf a -> contextRows (Leaf a) ranges categories sources
Indexed children -> adjoinChildRows Indexed children
@ -144,25 +144,25 @@ splitAnnotatedByLines sources ranges categories syntax = case syntax of
ends (left, right) = (end left, end right)
makeRanges (leftStart, rightStart) (leftEnd, rightEnd) = (Range leftStart leftEnd, Range rightStart rightEnd)
contextLines :: (Info -> a) -> Range -> Set.Set Category -> Source -> [Line a]
contextLines :: (Info -> a) -> Range -> Set.Set Category -> Source Char -> [Line a]
contextLines constructor range categories source = Line . (:[]) . constructor . (`Info` categories) <$> actualLineRanges range source
openRange :: Source -> Range -> Maybe Range
openRange :: Source Char -> Range -> Maybe Range
openRange source range = case (source `at`) <$> maybeLastIndex range of
Just '\n' -> Nothing
_ -> Just range
openTerm :: Source -> Term a Info -> Maybe (Term a Info)
openTerm :: Source Char -> Term a Info -> Maybe (Term a Info)
openTerm source term@(Info range _ :< _) = const term <$> openRange source range
openDiff :: Source -> SplitDiff a Info -> Maybe (SplitDiff a Info)
openDiff :: Source Char -> SplitDiff a Info -> Maybe (SplitDiff a Info)
openDiff source diff@(Free (Annotated (Info range _) _)) = const diff <$> openRange source range
openDiff source diff@(Pure term) = const diff <$> openTerm source term
zipWithDefaults :: (a -> b -> c) -> a -> b -> [a] -> [b] -> [c]
zipWithDefaults f da db a b = take (max (length a) (length b)) $ zipWith f (a ++ repeat da) (b ++ repeat db)
actualLines :: Source -> [Source]
actualLines :: Source Char -> [Source Char]
actualLines "" = [""]
actualLines lines = case break (== '\n') lines of
(l, lines') -> case lines' of
@ -170,6 +170,6 @@ actualLines lines = case break (== '\n') lines of
_:lines' -> (l ++ "\n") : actualLines lines'
-- | Compute the line ranges within a given range of a string.
actualLineRanges :: Range -> Source -> [Range]
actualLineRanges :: Range -> Source Char -> [Range]
actualLineRanges range = drop 1 . scanl toRange (Range (start range) (start range)) . actualLines . subsource range
where toRange previous string = Range (end previous) $ end previous + length string