This repository was archived by the owner on Apr 1, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 458
Factor source code-related facilities into a new package #269
Merged
Merged
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit
Hold shift + click to select a range
974e2ca
Define a semantic-source package.
robrix a66f459
Merge branch 'master' into semantic-source
robrix 5802d46
Move the ToJSONFields instance for Range into Data.JSON.Fields.
robrix 10e4bbb
Move the ToJSONFields instance for Span into Data.JSON.Fields.
robrix 57ab2f6
Link the doctests against the lib.
robrix 2c99f09
Link the doctests against QuickCheck.
robrix a126e39
Use the right dir for the doctests.
robrix 4e40108
Copy Range in.
robrix 325e1f1
Derive a Hashable instance for Range.
robrix ddef713
Copy Span in.
robrix 81f43c9
Move the ToJSONFields instance for Location into Data.JSON.Fields.
robrix 2748529
Copy Location in as Loc.
robrix cc82051
Depend on semantic-source.
robrix 1d5e150
Switch everything over to using Source.Range.
robrix 17c61c1
Switch everything over to using Source.Span.
robrix 0f8e69c
Switch everything over to using Source.Loc.
robrix f6e4864
Move the span/range stuff into CMark.
robrix b20dcf4
Copy Source in.
robrix 8aae312
Rename the Source symbols and recommend importing it qualified.
robrix ca6a785
Flip lineRangesWithin.
robrix d929a8c
Make Data.Source reexport Source.Source.
948deb4
Fixup remaining test cases.
7b599a6
Use Source.Source instead of Data.Source.
a422061
Delete Data.Source.
f17a2e8
Remove Data.Source from the .cabal file.
f0567fd
De-suffix dropSource and takeSource.
86682d8
De-suffix sourceBytes.
74693f4
Bring in the Source tests.
robrix 2ce8b51
:fire: Data.Source.Spec.
robrix c86186a
:fire: a redundant import.
robrix a00a78e
Merge branch 'master' into semantic-source
robrix bb20471
Define lenses for the starts/ends of Range.
robrix 64ef37e
Rename the line/column lenses to line_/column_.
robrix 1e6ebd2
Rename posLine/posColumn to line/column.
robrix 57c385d
Rename the HasSpan start/end lenses to start_/end_.
robrix d59a44b
Rename the HasSpan span lens to span_.
robrix 7d1567e
:fire: a bunch of redundant hidden imports.
robrix 0312300
Rename the spanStart/spanEnd fields to start/end.
robrix e08a495
Define a point fiunction for Range.
robrix 935acb4
:memo: point.
robrix 6356443
Define a point constructor for Span.
robrix e28e81b
:memo: point.
robrix 9551742
Use point to define emptyTerm.
robrix 52bc7e6
Rename locByteRange/locSpan to byteRange/span.
robrix 4bc5491
Extract lens to the top level.
robrix 909fa63
Define a byteRange_ lens for Loc.
robrix 8df1345
Run semantic-source’s tests in CI.
robrix 918bfb4
Apparently this should not exist.
robrix 77ff50b
Run the doctests from the right place.
robrix File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Make Data.Source reexport Source.Source.
- Loading branch information
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,127 +1,5 @@ | ||
{-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
module Data.Source | ||
( Source | ||
, sourceBytes | ||
, fromUTF8 | ||
-- Measurement | ||
, sourceLength | ||
, nullSource | ||
, totalRange | ||
, totalSpan | ||
-- En/decoding | ||
, fromText | ||
, toText | ||
-- Slicing | ||
, slice | ||
, dropSource | ||
-- Splitting | ||
, sourceLines | ||
, sourceLineRanges | ||
, sourceLineRangesWithin | ||
, newlineIndices | ||
( module Source.Source | ||
) where | ||
|
||
import Prologue | ||
|
||
import Data.Aeson (FromJSON (..), withText) | ||
import qualified Data.ByteString as B | ||
import Data.Char (ord) | ||
import Data.String (IsString (..)) | ||
import qualified Data.Text as T | ||
import qualified Data.Text.Encoding as T | ||
import Source.Range | ||
|
||
|
||
-- | The contents of a source file. This is represented as a UTF-8 | ||
-- 'ByteString' under the hood. Construct these with 'fromUTF8'; obviously, | ||
-- passing 'fromUTF8' non-UTF8 bytes will cause crashes. | ||
newtype Source = Source { sourceBytes :: B.ByteString } | ||
deriving (Eq, Semigroup, Monoid, IsString, Show, Generic) | ||
|
||
fromUTF8 :: B.ByteString -> Source | ||
fromUTF8 = Source | ||
|
||
instance FromJSON Source where | ||
parseJSON = withText "Source" (pure . fromText) | ||
|
||
-- Measurement | ||
|
||
sourceLength :: Source -> Int | ||
sourceLength = B.length . sourceBytes | ||
|
||
nullSource :: Source -> Bool | ||
nullSource = B.null . sourceBytes | ||
|
||
-- | Return a 'Range' that covers the entire text. | ||
totalRange :: Source -> Range | ||
totalRange = Range 0 . B.length . sourceBytes | ||
|
||
-- | Return a 'Span' that covers the entire text. | ||
totalSpan :: Source -> Span | ||
totalSpan source = Span (Pos 1 1) (Pos (length ranges) (succ (end lastRange - start lastRange))) | ||
where ranges = sourceLineRanges source | ||
lastRange = fromMaybe lowerBound (getLast (foldMap (Last . Just) ranges)) | ||
|
||
|
||
-- En/decoding | ||
|
||
-- | Return a 'Source' from a 'Text'. | ||
fromText :: T.Text -> Source | ||
fromText = Source . T.encodeUtf8 | ||
|
||
-- | Return the Text contained in the 'Sou B41A rce'. | ||
toText :: Source -> T.Text | ||
toText = T.decodeUtf8 . sourceBytes | ||
|
||
|
||
-- | Return a 'Source' that contains a slice of the given 'Source'. | ||
slice :: Range -> Source -> Source | ||
slice range = take . drop | ||
where drop = dropSource (start range) | ||
take = takeSource (rangeLength range) | ||
|
||
dropSource :: Int -> Source -> Source | ||
dropSource i = Source . drop . sourceBytes | ||
where drop = B.drop i | ||
|
||
takeSource :: Int -> Source -> Source | ||
takeSource i = Source . take . sourceBytes | ||
where take = B.take i | ||
|
||
|
||
-- Splitting | ||
|
||
-- | Split the contents of the source after newlines. | ||
sourceLines :: Source -> [Source] | ||
sourceLines source = (`slice` source) <$> sourceLineRanges source | ||
|
||
-- | Compute the 'Range's of each line in a 'Source'. | ||
sourceLineRanges :: Source -> [Range] | ||
sourceLineRanges source = sourceLineRangesWithin (totalRange source) source | ||
|
||
-- | Compute the 'Range's of each line in a 'Range' of a 'Source'. | ||
sourceLineRangesWithin :: Range -> Source -> [Range] | ||
sourceLineRangesWithin range = uncurry (zipWith Range) | ||
. ((start range:) &&& (<> [ end range ])) | ||
. fmap (+ succ (start range)) | ||
. newlineIndices | ||
. sourceBytes | ||
. slice range | ||
|
||
-- | Return all indices of newlines ('\n', '\r', and '\r\n') in the 'ByteString'. | ||
newlineIndices :: B.ByteString -> [Int] | ||
newlineIndices = go 0 | ||
where go n bs | B.null bs = [] | ||
| otherwise = case (searchCR bs, searchLF bs) of | ||
(Nothing, Nothing) -> [] | ||
(Just i, Nothing) -> recur n i bs | ||
(Nothing, Just i) -> recur n i bs | ||
(Just crI, Just lfI) | ||
| succ crI == lfI -> recur n lfI bs | ||
| otherwise -> recur n (min crI lfI) bs | ||
recur n i bs = let j = n + i in j : go (succ j) (B.drop (succ i) bs) | ||
searchLF = B.elemIndex (toEnum (ord '\n')) | ||
searchCR = B.elemIndex (toEnum (ord '\r')) | ||
|
||
{-# INLINE newlineIndices #-} | ||
import Source.Source |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were only ever being used in this module, and so moving them here prevented having to have
semantic-source
depend onarray
.