mirror of
https://github.com/github/semantic.git
synced 2024-11-28 10:15:55 +03:00
Source is no longer parametric in the character type.
This commit is contained in:
parent
2c0b19dd6f
commit
bc2a29d84e
@ -38,11 +38,11 @@ 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 => Both (Source Char) -> SyntaxDiff leaf fields -> [Join These (SplitSyntaxDiff leaf fields)]
|
||||
alignDiff :: HasField fields Range => Both Source -> SyntaxDiff leaf fields -> [Join These (SplitSyntaxDiff leaf fields)]
|
||||
alignDiff sources diff = iter (alignSyntax (runBothWith ((Join .) . These)) wrap getRange sources) (alignPatch sources <$> diff)
|
||||
|
||||
-- | Align the contents of a patch into a list of lines on the corresponding side(s) of the diff.
|
||||
alignPatch :: forall fields leaf. HasField fields Range => Both (Source Char) -> Patch (SyntaxTerm leaf fields) -> [Join These (SplitSyntaxDiff leaf fields)]
|
||||
alignPatch :: forall fields leaf. HasField fields Range => Both Source -> Patch (SyntaxTerm leaf fields) -> [Join These (SplitSyntaxDiff leaf 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
|
||||
@ -50,13 +50,13 @@ alignPatch sources patch = case patch of
|
||||
(alignSyntax' this (fst sources) term1)
|
||||
(alignSyntax' that (snd sources) term2)
|
||||
where getRange = characterRange . extract
|
||||
alignSyntax' :: (forall a. Identity a -> Join These a) -> Source Char -> SyntaxTerm leaf fields -> [Join These (SyntaxTerm leaf fields)]
|
||||
alignSyntax' :: (forall a. Identity a -> Join These a) -> Source -> SyntaxTerm leaf fields -> [Join These (SyntaxTerm leaf fields)]
|
||||
alignSyntax' side source term = hylo (alignSyntax side cofree getRange (Identity source)) runCofree (Identity <$> term)
|
||||
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) => (forall a. f a -> Join These a) -> (SyntaxTermF leaf fields term -> term) -> (term -> Range) -> f (Source Char) -> TermF (Syntax leaf) (f (Record fields)) [Join These term] -> [Join These term]
|
||||
alignSyntax :: (Applicative f, HasField fields Range) => (forall a. f a -> Join These a) -> (SyntaxTermF leaf fields term -> term) -> (term -> Range) -> f Source -> TermF (Syntax leaf) (f (Record fields)) [Join These term] -> [Join These term]
|
||||
alignSyntax toJoinThese toNode getRange sources (infos :< syntax) = catMaybes $ case syntax of
|
||||
Leaf s -> wrapInBranch (const (Leaf s)) <$> alignBranch getRange [] bothRanges
|
||||
Syntax.Comment a -> wrapInBranch (const (Syntax.Comment a)) <$> alignBranch getRange [] bothRanges
|
||||
|
@ -106,7 +106,7 @@ summaryToTexts DiffSummary{..} = appendParentContexts <$> summaries patch
|
||||
jsonSummary { summary = show $ summary jsonSummary <+> parentContexts parentAnnotation }
|
||||
|
||||
-- Returns a list of 'DiffSummary' given two source blobs and a diff.
|
||||
diffToDiffSummaries :: (StringConv leaf Text, DefaultFields fields) => Both (Source Char) -> SyntaxDiff leaf fields -> [DiffSummary DiffInfo]
|
||||
diffToDiffSummaries :: (StringConv leaf Text, DefaultFields fields) => Both Source -> SyntaxDiff leaf fields -> [DiffSummary DiffInfo]
|
||||
diffToDiffSummaries sources = para $ \diff ->
|
||||
let
|
||||
diff' = free (Prologue.fst <$> diff)
|
||||
@ -186,7 +186,7 @@ toLeafInfos LeafInfo{..} = pure $ JSONSummary (summary leafCategory termName) so
|
||||
vowels = Text.singleton <$> ("aeiouAEIOU" :: [Char])
|
||||
|
||||
-- Returns a text representing a specific term given a source and a term.
|
||||
toTermName :: forall leaf fields. (StringConv leaf Text, DefaultFields fields) => Source Char -> SyntaxTerm leaf fields -> Text
|
||||
toTermName :: forall leaf fields. (StringConv leaf Text, DefaultFields fields) => Source -> SyntaxTerm leaf fields -> Text
|
||||
toTermName source term = case unwrap term of
|
||||
S.Send _ _ -> termNameFromSource term
|
||||
S.Ty _ -> termNameFromSource term
|
||||
@ -323,7 +323,7 @@ parentContexts contexts = hsep $ either identifiableDoc annotatableDoc <$> conte
|
||||
toDoc :: Text -> Doc
|
||||
toDoc = string . toS
|
||||
|
||||
termToDiffInfo :: (StringConv leaf Text, DefaultFields fields) => Source Char -> SyntaxTerm leaf fields -> DiffInfo
|
||||
termToDiffInfo :: (StringConv leaf Text, DefaultFields fields) => Source -> SyntaxTerm leaf fields -> DiffInfo
|
||||
termToDiffInfo blob term = case unwrap term of
|
||||
S.Indexed children -> BranchInfo (termToDiffInfo' <$> children) (category $ extract term) BIndexed
|
||||
S.Fixed children -> BranchInfo (termToDiffInfo' <$> children) (category $ extract term) BFixed
|
||||
@ -340,7 +340,7 @@ termToDiffInfo blob term = case unwrap term of
|
||||
-- | For a DiffSummary without a parentAnnotation, we append a parentAnnotation with the first identifiable term.
|
||||
-- | For a DiffSummary with a parentAnnotation, we append the next annotatable term to the extant parentAnnotation.
|
||||
-- | If a DiffSummary already has a parentAnnotation, and a (grand) parentAnnotation, then we return the summary without modification.
|
||||
appendSummary :: (StringConv leaf Text, DefaultFields fields) => Source Char -> SyntaxTerm leaf fields -> DiffSummary DiffInfo -> DiffSummary DiffInfo
|
||||
appendSummary :: (StringConv leaf Text, DefaultFields fields) => Source -> SyntaxTerm leaf fields -> DiffSummary DiffInfo -> DiffSummary DiffInfo
|
||||
appendSummary source term summary =
|
||||
case (parentAnnotation summary, identifiable term, annotatable term) of
|
||||
([], Identifiable _, _) -> appendParentAnnotation Left
|
||||
|
@ -8,7 +8,7 @@ import qualified Syntax as S
|
||||
import Term
|
||||
|
||||
termAssignment
|
||||
:: Source Char -- ^ The source of the term.
|
||||
:: Source -- ^ The source of the term.
|
||||
-> Category -- ^ The category for the term.
|
||||
-> [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -- ^ The child nodes of the term.
|
||||
-> Maybe (S.Syntax Text (SyntaxTerm Text '[Range, Category, SourceSpan])) -- ^ The resulting term, in Maybe.
|
||||
|
@ -8,7 +8,7 @@ import Term
|
||||
import qualified Syntax as S
|
||||
|
||||
termAssignment
|
||||
:: Source Char -- ^ The source of the term.
|
||||
:: Source -- ^ The source of the term.
|
||||
-> Category -- ^ The category for the term.
|
||||
-> [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -- ^ The child nodes of the term.
|
||||
-> Maybe (S.Syntax Text (SyntaxTerm Text '[Range, Category, SourceSpan])) -- ^ The resulting term, in Maybe.
|
||||
|
@ -9,7 +9,7 @@ import qualified Syntax as S
|
||||
import Term
|
||||
|
||||
termAssignment
|
||||
:: Source Char -- ^ The source of the term.
|
||||
:: Source -- ^ The source of the term.
|
||||
-> Category -- ^ The category for the term.
|
||||
-> [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -- ^ The child nodes of the term.
|
||||
-> Maybe (S.Syntax Text (SyntaxTerm Text '[Range, Category, SourceSpan])) -- ^ The resulting term, in Maybe.
|
||||
|
@ -10,7 +10,7 @@ import qualified Syntax as S
|
||||
import Term
|
||||
|
||||
termAssignment
|
||||
:: Source Char -- ^ The source of the term.
|
||||
:: Source -- ^ The source of the term.
|
||||
-> Category -- ^ The category for the term.
|
||||
-> [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -- ^ The child nodes of the term.
|
||||
-> Maybe (S.Syntax Text (SyntaxTerm Text '[Range, Category, SourceSpan])) -- ^ The resulting term, in Maybe.
|
||||
|
@ -94,7 +94,7 @@ termCostDecorator :: (Foldable f, Functor f) => TermDecorator f a Cost
|
||||
termCostDecorator c = 1 + sum (cost <$> tailF c)
|
||||
|
||||
-- | Term decorator extracting the source text for a term.
|
||||
termSourceDecorator :: (HasField fields Range) => Source Char -> TermDecorator f fields SourceText
|
||||
termSourceDecorator :: (HasField fields Range) => Source -> TermDecorator f fields SourceText
|
||||
termSourceDecorator source c = SourceText . toText $ Source.slice range' source
|
||||
where range' = characterRange $ headF c
|
||||
|
||||
@ -116,13 +116,13 @@ parserForFilepath :: FilePath -> Parser (Syntax Text) (Record '[Cost, Range, Cat
|
||||
parserForFilepath path blob = decorateTerm termCostDecorator <$> parserForType (toS (takeExtension path)) blob
|
||||
|
||||
-- | Read the file and convert it to Unicode.
|
||||
readAndTranscodeFile :: FilePath -> IO (Source Char)
|
||||
readAndTranscodeFile :: FilePath -> IO Source
|
||||
readAndTranscodeFile path = do
|
||||
text <- B1.readFile path
|
||||
transcode text
|
||||
|
||||
-- | Transcode a file to a unicode source.
|
||||
transcode :: B1.ByteString -> IO (Source Char)
|
||||
transcode :: B1.ByteString -> IO Source
|
||||
transcode text = fromText <$> do
|
||||
match <- Detect.detectCharset text
|
||||
converter <- Convert.open match Nothing
|
||||
|
@ -67,18 +67,18 @@ showHunk blobs hunk = maybeOffsetHeader <>
|
||||
(offsetA, offsetB) = runJoin . fmap (show . getSum) $ offset hunk
|
||||
|
||||
-- | Given the before and after sources, render a change to a string.
|
||||
showChange :: Functor f => HasField fields Range => Both (Source Char) -> Change (SplitDiff f (Record fields)) -> String
|
||||
showChange :: Functor f => HasField fields Range => Both Source -> Change (SplitDiff f (Record fields)) -> String
|
||||
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 -> Char -> [Maybe (SplitDiff f (Record fields))] -> String
|
||||
showLines :: Functor f => HasField fields Range => Source -> Char -> [Maybe (SplitDiff f (Record fields))] -> String
|
||||
showLines source prefix lines = fromMaybe "" . mconcat $ fmap prepend . showLine source <$> lines
|
||||
where prepend "" = ""
|
||||
prepend source = prefix : source
|
||||
|
||||
-- | Given a source, render a line to a string.
|
||||
showLine :: Functor f => HasField fields Range => Source Char -> Maybe (SplitDiff f (Record fields)) -> Maybe String
|
||||
showLine :: Functor f => HasField fields Range => Source -> Maybe (SplitDiff f (Record fields)) -> Maybe String
|
||||
showLine source line | Just line <- line = Just . toString . (`slice` source) $ getRange line
|
||||
| otherwise = Nothing
|
||||
|
||||
|
@ -192,13 +192,13 @@ split blobs diff = SplitOutput . TL.toStrict . renderHtml
|
||||
data Cell a = Cell !Bool !Int !a
|
||||
|
||||
-- | Something that can be rendered as markup with reference to some source.
|
||||
data Renderable a = Renderable !(Source Char) !a
|
||||
data Renderable a = Renderable !Source !a
|
||||
|
||||
contentElements :: (Foldable t, ToMarkup f) => Source Char -> Range -> t (f, Range) -> [Markup]
|
||||
contentElements :: (Foldable t, ToMarkup f) => Source -> Range -> t (f, Range) -> [Markup]
|
||||
contentElements source range children = let (elements, next) = foldr' (markupForContextAndChild source) ([], end range) children in
|
||||
text (toText (slice (Range (start range) (max next (start range))) source)) : elements
|
||||
|
||||
markupForContextAndChild :: ToMarkup f => Source Char -> (f, Range) -> ([Markup], Int) -> ([Markup], Int)
|
||||
markupForContextAndChild :: ToMarkup f => Source -> (f, Range) -> ([Markup], Int) -> ([Markup], Int)
|
||||
markupForContextAndChild source (child, range) (rows, next) = (toMarkup child : text (toText (slice (Range (end range) next) source)) : rows, start range)
|
||||
|
||||
wrapIn :: (Markup -> Markup) -> Markup -> Markup
|
||||
|
@ -72,7 +72,7 @@ diffTOC blobs diff = do
|
||||
removeDupes [] = []
|
||||
removeDupes xs = (fmap unsafeHead . List.groupBy (\a b -> parentInfo a == parentInfo b)) xs
|
||||
|
||||
diffToTOCSummaries :: (StringConv leaf Text, DefaultFields fields) => Both (Source Char) -> SyntaxDiff leaf fields -> [TOCSummary DiffInfo]
|
||||
diffToTOCSummaries :: (StringConv leaf Text, DefaultFields fields) => Both Source -> SyntaxDiff leaf fields -> [TOCSummary DiffInfo]
|
||||
diffToTOCSummaries sources = para $ \diff ->
|
||||
let
|
||||
diff' = free (Prologue.fst <$> diff)
|
||||
@ -106,13 +106,13 @@ toLeafInfos' :: DiffInfo -> [DiffInfo]
|
||||
toLeafInfos' BranchInfo{..} = branches >>= toLeafInfos'
|
||||
toLeafInfos' leaf = [leaf]
|
||||
|
||||
mapToInSummarizable :: forall leaf fields. DefaultFields fields => Both (Source Char) -> SyntaxDiff leaf fields -> [TOCSummary DiffInfo] -> [TOCSummary DiffInfo]
|
||||
mapToInSummarizable :: forall leaf fields. DefaultFields fields => Both Source -> SyntaxDiff leaf fields -> [TOCSummary DiffInfo] -> [TOCSummary DiffInfo]
|
||||
mapToInSummarizable sources diff children = case (beforeTerm diff, afterTerm diff) of
|
||||
(_, Just diff') -> mapToInSummarizable' (Both.snd sources) diff' <$> children
|
||||
(Just diff', _) -> mapToInSummarizable' (Both.fst sources) diff' <$> children
|
||||
(Nothing, Nothing) -> []
|
||||
where
|
||||
mapToInSummarizable' :: Source Char -> SyntaxTerm leaf fields -> TOCSummary DiffInfo -> TOCSummary DiffInfo
|
||||
mapToInSummarizable' :: Source -> SyntaxTerm leaf fields -> TOCSummary DiffInfo -> TOCSummary DiffInfo
|
||||
mapToInSummarizable' source term summary =
|
||||
case (parentInfo summary, summarizable term) of
|
||||
(NotSummarizable, SummarizableTerm _) ->
|
||||
@ -142,7 +142,7 @@ toJSONSummaries TOCSummary{..} = case afterOrBefore summaryPatch of
|
||||
NotSummarizable -> []
|
||||
_ -> pure $ JSONSummary parentInfo
|
||||
|
||||
termToDiffInfo :: forall leaf fields. (StringConv leaf Text, DefaultFields fields) => Source Char -> SyntaxTerm leaf fields -> DiffInfo
|
||||
termToDiffInfo :: forall leaf fields. (StringConv leaf Text, DefaultFields fields) => Source -> SyntaxTerm leaf fields -> DiffInfo
|
||||
termToDiffInfo blob term = case unwrap term of
|
||||
S.Indexed children -> BranchInfo (termToDiffInfo' <$> children) (category $ extract term)
|
||||
S.Fixed children -> BranchInfo (termToDiffInfo' <$> children) (category $ extract term)
|
||||
@ -157,7 +157,7 @@ termToDiffInfo blob term = case unwrap term of
|
||||
termToDiffInfo' = termToDiffInfo blob
|
||||
toLeafInfo term = LeafInfo (category $ extract term) (toTermName' term) (getField $ extract term)
|
||||
|
||||
toTermName :: forall leaf fields. DefaultFields fields => Source Char -> SyntaxTerm leaf fields -> Text
|
||||
toTermName :: forall leaf fields. DefaultFields fields => Source -> SyntaxTerm leaf fields -> Text
|
||||
toTermName source term = case unwrap term of
|
||||
S.Function identifier _ _ _ -> toTermName' identifier
|
||||
S.Method identifier Nothing _ _ _ -> toTermName' identifier
|
||||
|
@ -10,12 +10,12 @@ import Range
|
||||
import SourceSpan
|
||||
|
||||
-- | The source, oid, path, and Maybe SourceKind of a blob in a Git repo.
|
||||
data SourceBlob = SourceBlob { source :: Source Char, oid :: String, path :: FilePath, blobKind :: Maybe SourceKind }
|
||||
data SourceBlob = SourceBlob { source :: Source, oid :: String, path :: FilePath, blobKind :: Maybe SourceKind }
|
||||
deriving (Show, Eq)
|
||||
|
||||
-- | The contents of a source file, backed by a vector for efficient slicing.
|
||||
newtype Source a = Source { unSource :: Text }
|
||||
deriving (Eq, Show, Functor)
|
||||
newtype Source = Source { unSource :: Text }
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | The kind of a blob, along with it's file mode.
|
||||
data SourceKind = PlainBlob Word32 | ExecutableBlob Word32 | SymlinkBlob Word32
|
||||
@ -34,7 +34,7 @@ defaultPlainBlob = PlainBlob 0o100644
|
||||
emptySourceBlob :: FilePath -> SourceBlob
|
||||
emptySourceBlob filepath = SourceBlob (Source.fromList "") Source.nullOid filepath Nothing
|
||||
|
||||
sourceBlob :: Source Char -> FilePath -> SourceBlob
|
||||
sourceBlob :: Source -> FilePath -> SourceBlob
|
||||
sourceBlob source filepath = SourceBlob source Source.nullOid filepath (Just defaultPlainBlob)
|
||||
|
||||
-- | Map blobs with Nothing blobKind to empty blobs.
|
||||
@ -47,39 +47,39 @@ nullOid :: String
|
||||
nullOid = "0000000000000000000000000000000000000000"
|
||||
|
||||
-- | Return a Source from a list of items.
|
||||
fromList :: [Char] -> Source Char
|
||||
fromList :: [Char] -> Source
|
||||
fromList = Source . Text.pack
|
||||
|
||||
-- | Return a Source of Chars from a Text.
|
||||
fromText :: Text -> Source Char
|
||||
fromText :: Text -> Source
|
||||
fromText = Source
|
||||
|
||||
-- | Return a Source that contains a slice of the given Source.
|
||||
slice :: Range -> Source Char -> Source Char
|
||||
slice :: Range -> Source -> Source
|
||||
slice range = Source . Text.take (rangeLength range) . Text.drop (start range) . unSource
|
||||
|
||||
-- | Return a String with the contents of the Source.
|
||||
toString :: Source Char -> String
|
||||
toString :: Source -> String
|
||||
toString = Text.unpack . unSource
|
||||
|
||||
-- | Return a text with the contents of the Source.
|
||||
toText :: Source Char -> Text
|
||||
toText :: Source -> Text
|
||||
toText = unSource
|
||||
|
||||
-- | Return the item at the given index.
|
||||
at :: Source Char -> Int -> Char
|
||||
at :: Source -> Int -> Char
|
||||
at = Text.index . unSource
|
||||
|
||||
-- | Remove the first item and return it with the rest of the source.
|
||||
uncons :: Source Char -> Maybe (Char, Source Char)
|
||||
uncons :: Source -> Maybe (Char, Source)
|
||||
uncons (Source vector) = if Text.null vector then Nothing else Just (Text.head vector, Source $ Text.tail vector)
|
||||
|
||||
-- | Split the source into the longest prefix of elements that do not satisfy the predicate and the rest without copying.
|
||||
break :: (Char -> Bool) -> Source Char -> (Source Char, Source Char)
|
||||
break :: (Char -> Bool) -> Source -> (Source, Source)
|
||||
break predicate (Source vector) = let (start, remainder) = Text.break predicate vector in (Source start, Source remainder)
|
||||
|
||||
-- | Split the contents of the source after newlines.
|
||||
actualLines :: Source Char -> [Source Char]
|
||||
actualLines :: Source -> [Source]
|
||||
actualLines source | Text.null (unSource source) = [ source ]
|
||||
actualLines source = case Source.break (== '\n') source of
|
||||
(l, lines') -> case uncons lines' of
|
||||
@ -87,12 +87,12 @@ actualLines source = case Source.break (== '\n') source of
|
||||
Just (_, lines') -> (l <> fromList "\n") : actualLines lines'
|
||||
|
||||
-- | Compute the line ranges within a given range of a string.
|
||||
actualLineRanges :: Range -> Source Char -> [Range]
|
||||
actualLineRanges :: Range -> Source -> [Range]
|
||||
actualLineRanges range = drop 1 . scanl toRange (Range (start range) (start range)) . actualLines . slice range
|
||||
where toRange previous string = Range (end previous) $ end previous + Text.length (unSource string)
|
||||
|
||||
-- | Compute the character range given a Source and a SourceSpan.
|
||||
sourceSpanToRange :: Source Char -> SourceSpan -> Range
|
||||
sourceSpanToRange :: Source -> SourceSpan -> Range
|
||||
sourceSpanToRange source SourceSpan{..} = Range start end
|
||||
where start = sumLengths leadingRanges + column spanStart
|
||||
end = start + sumLengths (take (line spanEnd - line spanStart) remainingRanges) + (column spanEnd - column spanStart)
|
||||
@ -100,10 +100,10 @@ sourceSpanToRange source SourceSpan{..} = Range start end
|
||||
sumLengths = sum . fmap (\ Range{..} -> end - start)
|
||||
|
||||
-- | Return a range that covers the entire text.
|
||||
totalRange :: Source Char -> Range
|
||||
totalRange :: Source -> Range
|
||||
totalRange = Range 0 . Text.length . unSource
|
||||
|
||||
rangeToSourceSpan :: Source Char -> Range -> SourceSpan
|
||||
rangeToSourceSpan :: Source -> Range -> SourceSpan
|
||||
rangeToSourceSpan source range@Range{} = SourceSpan startPos endPos
|
||||
where startPos = maybe (SourcePos 1 1) (toStartPos 1) (head lineRanges)
|
||||
endPos = toEndPos (Prologue.length lineRanges) (fromMaybe (rangeAt 0) (snd <$> unsnoc lineRanges))
|
||||
@ -111,15 +111,15 @@ rangeToSourceSpan source range@Range{} = SourceSpan startPos endPos
|
||||
toStartPos line range = SourcePos line (start range)
|
||||
toEndPos line range = SourcePos line (end range)
|
||||
|
||||
length :: Source Char -> Int
|
||||
length :: Source -> Int
|
||||
length = Text.length . unSource
|
||||
|
||||
null :: Source Char -> Bool
|
||||
null :: Source -> Bool
|
||||
null = Text.null . unSource
|
||||
|
||||
instance Semigroup (Source Char) where
|
||||
instance Semigroup Source where
|
||||
Source a <> Source b = Source (a <> b)
|
||||
|
||||
instance Monoid (Source Char) where
|
||||
instance Monoid Source where
|
||||
mempty = fromList []
|
||||
mappend = (<>)
|
||||
|
@ -70,12 +70,12 @@ documentToTerm language document SourceBlob{..} = alloca $ \ root -> do
|
||||
{-# INLINE getUnnamedChild #-}
|
||||
isNonEmpty child = category (extract child) /= Empty
|
||||
|
||||
assignTerm :: Language -> Source Char -> Record '[Range, Category, SourceSpan] -> [ SyntaxTerm Text '[ Range, Category, SourceSpan ] ] -> IO [ SyntaxTerm Text '[ Range, Category, SourceSpan ] ] -> IO (SyntaxTerm Text '[ Range, Category, SourceSpan ])
|
||||
assignTerm :: Language -> Source -> Record '[Range, Category, SourceSpan] -> [ SyntaxTerm Text '[ Range, Category, SourceSpan ] ] -> IO [ SyntaxTerm Text '[ Range, Category, SourceSpan ] ] -> IO (SyntaxTerm Text '[ Range, Category, SourceSpan ])
|
||||
assignTerm language source annotation children allChildren =
|
||||
cofree . (annotation :<) <$> case assignTermByLanguage language source (category annotation) children of
|
||||
Just a -> pure a
|
||||
_ -> defaultTermAssignment source (category annotation) children allChildren
|
||||
where assignTermByLanguage :: Language -> Source Char -> Category -> [ SyntaxTerm Text '[ Range, Category, SourceSpan ] ] -> Maybe (S.Syntax Text (SyntaxTerm Text '[ Range, Category, SourceSpan ]))
|
||||
where assignTermByLanguage :: Language -> Source -> Category -> [ SyntaxTerm Text '[ Range, Category, SourceSpan ] ] -> Maybe (S.Syntax Text (SyntaxTerm Text '[ Range, Category, SourceSpan ]))
|
||||
assignTermByLanguage = \case
|
||||
JavaScript -> JS.termAssignment
|
||||
C -> C.termAssignment
|
||||
@ -83,7 +83,7 @@ assignTerm language source annotation children allChildren =
|
||||
Ruby -> Ruby.termAssignment
|
||||
_ -> \ _ _ _ -> Nothing
|
||||
|
||||
defaultTermAssignment :: Source Char -> Category -> [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -> IO [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -> IO (S.Syntax Text (SyntaxTerm Text '[Range, Category, SourceSpan]))
|
||||
defaultTermAssignment :: Source -> Category -> [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -> IO [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -> IO (S.Syntax Text (SyntaxTerm Text '[Range, Category, SourceSpan]))
|
||||
defaultTermAssignment source category children allChildren
|
||||
| category `elem` operatorCategories = S.Operator <$> allChildren
|
||||
| otherwise = pure $! case (category, children) of
|
||||
|
@ -206,7 +206,7 @@ branchElementKey :: BranchElement -> Maybe Text
|
||||
branchElementKey (Child key _) = Just key
|
||||
branchElementKey _ = Nothing
|
||||
|
||||
toAlignBranchInputs :: [BranchElement] -> (Both (Source.Source Char), [Join These (Text, Range)], Both [Range])
|
||||
toAlignBranchInputs :: [BranchElement] -> (Both (Source.Source), [Join These (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, Range)]
|
||||
go child@(Child key _) = do
|
||||
@ -257,16 +257,16 @@ instance Listable BranchElement where
|
||||
counts :: [Join These (Int, a)] -> Both Int
|
||||
counts numbered = fromMaybe 0 . getLast . mconcat . fmap Last <$> Join (unalign (runJoin . fmap Prologue.fst <$> numbered))
|
||||
|
||||
align :: Both (Source.Source Char) -> ConstructibleFree (Patch (Term (Syntax Text) (Record '[Range]))) (Both (Record '[Range])) -> PrettyDiff (SplitDiff (Syntax Text) (Record '[Range]))
|
||||
align :: Both (Source.Source) -> ConstructibleFree (Patch (Term (Syntax Text) (Record '[Range]))) (Both (Record '[Range])) -> PrettyDiff (SplitDiff (Syntax Text) (Record '[Range]))
|
||||
align sources = PrettyDiff sources . fmap (fmap (getRange . Text.unpack &&& identity)) . alignDiff sources . deconstruct
|
||||
|
||||
info :: Int -> Int -> Record '[Range]
|
||||
info start end = Range start end :. Nil
|
||||
|
||||
prettyDiff :: Both (Source.Source Char) -> [Join These (ConstructibleFree (SplitPatch (Term (Syntax Text) (Record '[Range]))) (Record '[Range]))] -> PrettyDiff (SplitDiff (Syntax Text) (Record '[Range]))
|
||||
prettyDiff :: Both (Source.Source) -> [Join These (ConstructibleFree (SplitPatch (Term (Syntax Text) (Record '[Range]))) (Record '[Range]))] -> PrettyDiff (SplitDiff (Syntax Text) (Record '[Range]))
|
||||
prettyDiff sources = PrettyDiff sources . fmap (fmap ((getRange . Text.unpack &&& identity) . deconstruct))
|
||||
|
||||
data PrettyDiff a = PrettyDiff { unPrettySources :: Both (Source.Source Char), unPrettyLines :: [Join These (Range, a)] }
|
||||
data PrettyDiff a = PrettyDiff { unPrettySources :: Both (Source.Source), unPrettyLines :: [Join These (Range, a)] }
|
||||
deriving Eq
|
||||
|
||||
instance Show (PrettyDiff a) where
|
||||
|
@ -86,7 +86,7 @@ testDiff renderer paths diff matcher = do
|
||||
matcher actual (Just expected)
|
||||
where diffFiles' sources parser = diffFiles parser renderer (sourceBlobs sources paths)
|
||||
parser = parserWithCost <$> runBothWith (<|>) paths
|
||||
sourceBlobs :: Both (Maybe (S.Source Char)) -> Both (Maybe FilePath) -> Both S.SourceBlob
|
||||
sourceBlobs :: Both (Maybe (S.Source)) -> Both (Maybe FilePath) -> Both S.SourceBlob
|
||||
sourceBlobs sources paths = case runJoin paths of
|
||||
(Nothing, Nothing) -> Join (S.emptySourceBlob "", S.emptySourceBlob "")
|
||||
(Nothing, Just filepath) -> Join (S.emptySourceBlob "", S.sourceBlob (unsafeFromJust $ snd sources) filepath)
|
||||
|
@ -41,7 +41,7 @@ spec = parallel $ do
|
||||
prop "covers multiple lines" $
|
||||
\ n -> totalSpan (fromList (intersperse '\n' (replicate n '*'))) `shouldBe` SourceSpan (SourcePos 0 0) (SourcePos (max 0 (pred n)) (if n > 0 then 1 else 0))
|
||||
|
||||
totalSpan :: Source Char -> SourceSpan
|
||||
totalSpan :: Source -> SourceSpan
|
||||
totalSpan source = SourceSpan (SourcePos 0 0) (SourcePos (pred (Prologue.length ranges)) (end lastRange - start lastRange))
|
||||
where ranges = actualLineRanges (totalRange source) source
|
||||
lastRange = Prelude.last ranges
|
||||
|
Loading…
Reference in New Issue
Block a user