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 -- Conversion
, spanToRange , spanToRange
, spanToRangeInLineRanges , spanToRangeInLineRanges
, sourceLineRangesByLineNumber
, rangeToSpan , rangeToSpan
-- Listable -- Listable
, ListableByteString(..) , ListableByteString(..)
) where ) where
import Data.Array
import qualified Data.ByteString as B import qualified Data.ByteString as B
import Data.Char (ord) import Data.Char (ord)
import Data.List (span) 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'. -- | Compute the byte 'Range' corresponding to a given 'Span' in a 'Source'.
spanToRange :: Source -> Span -> Range spanToRange :: Source -> Span -> Range
spanToRange source = spanToRangeInLineRanges (sourceLineRanges source) spanToRange source = spanToRangeInLineRanges (sourceLineRangesByLineNumber source)
spanToRangeInLineRanges :: [Range] -> Span -> Range spanToRangeInLineRanges :: Array Int Range -> Span -> Range
spanToRangeInLineRanges lineRanges Span{..} = Range start end spanToRangeInLineRanges lineRanges Span{..} = Range
where start = pred (sumLengths leadingRanges + posColumn spanStart) (start (lineRanges ! posLine spanStart) + pred (posColumn spanStart))
end = start + sumLengths (take (posLine spanEnd - posLine spanStart) remainingRanges) + (posColumn spanEnd - posColumn spanStart) (start (lineRanges ! posLine spanEnd) + pred (posColumn spanEnd))
(leadingRanges, remainingRanges) = splitAt (pred (posLine spanStart)) lineRanges
sumLengths = sum . fmap rangeLength 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'. -- | Compute the 'Span' corresponding to a given byte 'Range' in a 'Source'.
rangeToSpan :: Source -> Range -> Span 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)) toSpan PosInfo{..} = Span (Pos startLine startColumn) (Pos endLine (succ endColumn))
lineRanges = sourceLineRanges source lineRanges = sourceLineRangesByLineNumber source
toGrammar :: NodeType -> Grammar toGrammar :: NodeType -> Grammar
toGrammar DOCUMENT{} = Document toGrammar DOCUMENT{} = Document