1
1
mirror of https://github.com/github/semantic.git synced 2024-12-20 13:21:59 +03:00

Compute spanToRangeInLineRanges in constant time.

This commit is contained in:
Rob Rix 2017-06-24 12:32:43 -04:00
parent 8284540ba0
commit 6b3f35c046
2 changed files with 12 additions and 8 deletions

View File

@ -21,11 +21,13 @@ module Data.Source
-- Conversion
, spanToRange
, spanToRangeInLineRanges
, sourceLineRangesByLineNumber
, rangeToSpan
-- Listable
, ListableByteString(..)
) where
import Data.Array
import qualified Data.ByteString as B
import Data.Char (ord)
import Data.List (span)
@ -108,14 +110,16 @@ sourceLineRangesWithin range = uncurry (zipWith Range) . ((start range:) &&& (<>
-- | Compute the byte 'Range' corresponding to a given 'Span' in a 'Source'.
spanToRange :: Source -> Span -> Range
spanToRange source = spanToRangeInLineRanges (sourceLineRanges source)
spanToRange source = spanToRangeInLineRanges (sourceLineRangesByLineNumber source)
spanToRangeInLineRanges :: [Range] -> Span -> Range
spanToRangeInLineRanges lineRanges Span{..} = Range start end
where start = pred (sumLengths leadingRanges + posColumn spanStart)
end = start + sumLengths (take (posLine spanEnd - posLine spanStart) remainingRanges) + (posColumn spanEnd - posColumn spanStart)
(leadingRanges, remainingRanges) = splitAt (pred (posLine spanStart)) lineRanges
sumLengths = sum . fmap rangeLength
spanToRangeInLineRanges :: Array Int Range -> Span -> Range
spanToRangeInLineRanges lineRanges Span{..} = Range
(start (lineRanges ! posLine spanStart) + pred (posColumn spanStart))
(start (lineRanges ! posLine spanEnd) + pred (posColumn spanEnd))
sourceLineRangesByLineNumber :: Source -> Array Int Range
sourceLineRangesByLineNumber source = listArray (1, length lineRanges) lineRanges
where lineRanges = sourceLineRanges source
-- | Compute the 'Span' corresponding to a given byte 'Range' in a 'Source'.
rangeToSpan :: Source -> Range -> Span

View File

@ -46,7 +46,7 @@ cmarkParser source = toTerm (totalRange source) (totalSpan source) $ commonmarkT
toSpan PosInfo{..} = Span (Pos startLine startColumn) (Pos endLine (succ endColumn))
lineRanges = sourceLineRanges source
lineRanges = sourceLineRangesByLineNumber source
toGrammar :: NodeType -> Grammar
toGrammar DOCUMENT{} = Document