"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/ShellCheck/Fixer.hs" between
shellcheck-0.8.0.tar.gz and shellcheck-0.9.0.tar.gz

About: ShellCheck is a static analysis and linting tool for sh/bash scripts (written in Haskell).

Fixer.hs  (shellcheck-0.8.0):Fixer.hs  (shellcheck-0.9.0)
skipping to change at line 25 skipping to change at line 25
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
-} -}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
module ShellCheck.Fixer (applyFix, removeTabStops, mapPositions, Ranged(..), run Tests) where module ShellCheck.Fixer (applyFix, removeTabStops, mapPositions, Ranged(..), run Tests) where
import ShellCheck.Interface import ShellCheck.Interface
import ShellCheck.Prelude
import Control.Monad
import Control.Monad.State import Control.Monad.State
import Data.Array import Data.Array
import Data.List import Data.List
import Data.Semigroup import Data.Semigroup
import GHC.Exts (sortWith) import GHC.Exts (sortWith)
import Test.QuickCheck import Test.QuickCheck
-- The Ranged class is used for types that has a start and end position. -- The Ranged class is used for types that has a start and end position.
class Ranged a where class Ranged a where
start :: a -> Position start :: a -> Position
end :: a -> Position end :: a -> Position
overlap :: a -> a -> Bool overlap :: a -> a -> Bool
overlap x y = overlap x y =
(yStart >= xStart && yStart < xEnd) || (yStart < xStart && yEnd > xStart ) xEnd > yStart && yEnd > xStart
where where
yStart = start y yStart = start y
yEnd = end y yEnd = end y
xStart = start x xStart = start x
xEnd = end x xEnd = end x
-- Set a new start and end position on a Ranged -- Set a new start and end position on a Ranged
setRange :: (Position, Position) -> a -> a setRange :: (Position, Position) -> a -> a
-- Tests auto-verify that overlap commutes -- Tests auto-verify that overlap commutes
assertOverlap x y = overlap x y && overlap y x assertOverlap x y = overlap x y && overlap y x
skipping to change at line 88 skipping to change at line 90
setRange (s, e) r = r { setRange (s, e) r = r {
repStartPos = s, repStartPos = s,
repEndPos = e repEndPos = e
} }
-- The Monoid instance for Fix merges fixes that do not conflict. -- The Monoid instance for Fix merges fixes that do not conflict.
-- TODO: Make an efficient 'mconcat' -- TODO: Make an efficient 'mconcat'
instance Monoid Fix where instance Monoid Fix where
mempty = newFix mempty = newFix
mappend = (<>) mappend = (<>)
mconcat = foldl mappend mempty -- fold left to right since <> discards right on overlap
instance Semigroup Fix where instance Semigroup Fix where
f1 <> f2 = f1 <> f2 =
-- FIXME: This might need to also discard adjacent zero-width ranges for -- FIXME: This might need to also discard adjacent zero-width ranges for
-- when two fixes change the same AST node, e.g. `foo` -> "$(foo) " -- when two fixes change the same AST node, e.g. `foo` -> "$(foo) "
if or [ r2 `overlap` r1 | r1 <- fixReplacements f1, r2 <- fixReplacement s f2 ] if or [ r2 `overlap` r1 | r1 <- fixReplacements f1, r2 <- fixReplacement s f2 ]
then f1 then f1
else newFix { else newFix {
fixReplacements = fixReplacements f1 ++ fixReplacements f2 fixReplacements = fixReplacements f1 ++ fixReplacements f2
} }
skipping to change at line 227 skipping to change at line 230
applyReplacement2 :: Replacement -> String -> Fixer String applyReplacement2 :: Replacement -> String -> Fixer String
applyReplacement2 rep string = do applyReplacement2 rep string = do
tree <- get tree <- get
let transform pos = pos + getPrefixSum pos tree let transform pos = pos + getPrefixSum pos tree
let originalPos = (repStartPos rep, repEndPos rep) let originalPos = (repStartPos rep, repEndPos rep)
(oldStart, oldEnd) = tmap (fromInteger . posColumn) originalPos (oldStart, oldEnd) = tmap (fromInteger . posColumn) originalPos
(newStart, newEnd) = tmap transform (oldStart, oldEnd) (newStart, newEnd) = tmap transform (oldStart, oldEnd)
let (l1, l2) = tmap posLine originalPos in let (l1, l2) = tmap posLine originalPos in
when (l1 /= 1 || l2 /= 1) $ when (l1 /= 1 || l2 /= 1) $
error "ShellCheck internal error, please report: bad cross-line fix" error $ pleaseReport "bad cross-line fix"
let replacer = repString rep let replacer = repString rep
let shift = (length replacer) - (oldEnd - oldStart) let shift = (length replacer) - (oldEnd - oldStart)
let insertionPoint = let insertionPoint =
case repInsertionPoint rep of case repInsertionPoint rep of
InsertBefore -> oldStart InsertBefore -> oldStart
InsertAfter -> oldEnd+1 InsertAfter -> oldEnd+1
put $ addPSValue insertionPoint shift tree put $ addPSValue insertionPoint shift tree
return $ doReplace newStart newEnd string replacer return $ doReplace newStart newEnd string replacer
 End of changes. 4 change blocks. 
2 lines changed or deleted 5 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)