mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-24 07:33:38 +03:00
Perf: Do not split source into lines at every fix
This commit is contained in:
parent
9e6160f8a6
commit
c5d706f739
214
src/Lint/Fix.elm
214
src/Lint/Fix.elm
@ -77,7 +77,8 @@ fix : List Fix -> String -> String
|
||||
fix fixes sourceCode =
|
||||
fixes
|
||||
|> List.sortBy (rangePosition >> negate)
|
||||
|> List.foldl applyFix sourceCode
|
||||
|> List.foldl applyFix (String.lines sourceCode)
|
||||
|> String.join "\n"
|
||||
|
||||
|
||||
rangePosition : Fix -> Int
|
||||
@ -101,6 +102,86 @@ rangePosition fix_ =
|
||||
row * 1000000 + column
|
||||
|
||||
|
||||
comparePosition : { row : Int, column : Int } -> { row : Int, column : Int } -> Order
|
||||
comparePosition a b =
|
||||
let
|
||||
order : Order
|
||||
order =
|
||||
compare a.row b.row
|
||||
in
|
||||
case order of
|
||||
EQ ->
|
||||
compare a.column b.column
|
||||
|
||||
_ ->
|
||||
order
|
||||
|
||||
|
||||
applyFix : Fix -> List String -> List String
|
||||
applyFix fix_ lines =
|
||||
lines
|
||||
|> (case fix_ of
|
||||
Replacement range replacement ->
|
||||
applyReplace range replacement
|
||||
|
||||
Removal range ->
|
||||
applyReplace range ""
|
||||
|
||||
InsertAt position insertion ->
|
||||
applyReplace { start = position, end = position } insertion
|
||||
)
|
||||
|
||||
|
||||
applyReplace : Range -> String -> List String -> List String
|
||||
applyReplace range replacement lines =
|
||||
let
|
||||
linesBefore : List String
|
||||
linesBefore =
|
||||
lines
|
||||
|> List.take (range.start.row - 1)
|
||||
|
||||
linesAfter : List String
|
||||
linesAfter =
|
||||
lines
|
||||
|> List.drop range.end.row
|
||||
|
||||
startLine : String
|
||||
startLine =
|
||||
getRowAtLine lines (range.start.row - 1)
|
||||
|
||||
startLineBefore : String
|
||||
startLineBefore =
|
||||
String.slice 0 (range.start.column - 1) startLine
|
||||
|
||||
endLine : String
|
||||
endLine =
|
||||
getRowAtLine lines (range.end.row - 1)
|
||||
|
||||
endLineAfter : String
|
||||
endLineAfter =
|
||||
String.dropLeft (range.end.column - 1) endLine
|
||||
in
|
||||
List.concat
|
||||
[ linesBefore
|
||||
, startLineBefore ++ replacement ++ endLineAfter |> String.lines
|
||||
, linesAfter
|
||||
]
|
||||
|
||||
|
||||
getRowAtLine : List String -> Int -> String
|
||||
getRowAtLine lines rowIndex =
|
||||
case lines |> Array.fromList |> Array.get rowIndex of
|
||||
Just line ->
|
||||
if String.trim line /= "" then
|
||||
line
|
||||
|
||||
else
|
||||
""
|
||||
|
||||
Nothing ->
|
||||
""
|
||||
|
||||
|
||||
|
||||
-- UTILITARIES FOR WORKING WITH RANGES
|
||||
|
||||
@ -144,134 +225,3 @@ mergeRanges a b =
|
||||
a.end
|
||||
in
|
||||
{ start = start, end = end }
|
||||
|
||||
|
||||
comparePosition : { row : Int, column : Int } -> { row : Int, column : Int } -> Order
|
||||
comparePosition a b =
|
||||
let
|
||||
order : Order
|
||||
order =
|
||||
compare a.row b.row
|
||||
in
|
||||
case order of
|
||||
EQ ->
|
||||
compare a.column b.column
|
||||
|
||||
_ ->
|
||||
order
|
||||
|
||||
|
||||
applyFix : Fix -> String -> String
|
||||
applyFix fix_ source =
|
||||
source
|
||||
|> (case fix_ of
|
||||
Replacement range replacement ->
|
||||
applyReplace range replacement
|
||||
|
||||
Removal range ->
|
||||
applyReplace range ""
|
||||
|
||||
InsertAt position insertion ->
|
||||
applyReplace { start = position, end = position } insertion
|
||||
)
|
||||
|
||||
|
||||
applyReplace : Range -> String -> String -> String
|
||||
applyReplace range replacement source =
|
||||
if range.start.row == range.end.row then
|
||||
applySingleLineReplace
|
||||
range
|
||||
replacement
|
||||
source
|
||||
|
||||
else
|
||||
applyMultiLineReplace
|
||||
range
|
||||
replacement
|
||||
source
|
||||
|
||||
|
||||
applySingleLineReplace : Range -> String -> String -> String
|
||||
applySingleLineReplace range replacement source =
|
||||
let
|
||||
lines : List String
|
||||
lines =
|
||||
String.lines source
|
||||
|
||||
linesBefore : String
|
||||
linesBefore =
|
||||
lines
|
||||
|> List.take (range.start.row - 1)
|
||||
|> String.join "\n"
|
||||
|
||||
linesAfter : String
|
||||
linesAfter =
|
||||
lines
|
||||
|> List.drop range.end.row
|
||||
|> String.join "\n"
|
||||
|
||||
line : String
|
||||
line =
|
||||
getRowAtLine lines (range.start.row - 1)
|
||||
|
||||
lineBefore : String
|
||||
lineBefore =
|
||||
String.slice 0 (range.start.column - 1) line
|
||||
|
||||
lineAfter : String
|
||||
lineAfter =
|
||||
String.dropLeft (range.end.column - 1) line
|
||||
in
|
||||
linesBefore ++ "\n" ++ lineBefore ++ replacement ++ lineAfter ++ "\n" ++ linesAfter
|
||||
|
||||
|
||||
applyMultiLineReplace : Range -> String -> String -> String
|
||||
applyMultiLineReplace range replacement source =
|
||||
let
|
||||
lines : List String
|
||||
lines =
|
||||
String.lines source
|
||||
|
||||
linesBefore : String
|
||||
linesBefore =
|
||||
lines
|
||||
|> List.take (range.start.row - 1)
|
||||
|> String.join "\n"
|
||||
|
||||
linesAfter : String
|
||||
linesAfter =
|
||||
lines
|
||||
|> List.drop range.end.row
|
||||
|> String.join "\n"
|
||||
|
||||
startLine : String
|
||||
startLine =
|
||||
getRowAtLine lines (range.start.row - 1)
|
||||
|
||||
startLineBefore : String
|
||||
startLineBefore =
|
||||
String.slice 0 (range.start.column - 1) startLine
|
||||
|
||||
endLine : String
|
||||
endLine =
|
||||
getRowAtLine lines (range.end.row - 1)
|
||||
|
||||
endLineAfter : String
|
||||
endLineAfter =
|
||||
String.dropLeft (range.end.column - 1) endLine
|
||||
in
|
||||
linesBefore ++ "\n" ++ startLineBefore ++ replacement ++ endLineAfter ++ "\n" ++ linesAfter
|
||||
|
||||
|
||||
getRowAtLine : List String -> Int -> String
|
||||
getRowAtLine lines rowIndex =
|
||||
case lines |> Array.fromList |> Array.get rowIndex of
|
||||
Just line ->
|
||||
if String.trim line /= "" then
|
||||
line
|
||||
|
||||
else
|
||||
""
|
||||
|
||||
Nothing ->
|
||||
""
|
||||
|
Loading…
Reference in New Issue
Block a user