{-# LANGUAGE LambdaCase #-}
module GLuaFixer.BadSequenceFinder (sequenceWarnings, checkFromString) where


import GLua.AG.Token
import GLua.PSParser
import GLuaFixer.LintMessage
import GLuaFixer.LintSettings
import Text.Parsec
import qualified GLua.PSLexer as PSL

-- | Satisfy for normal tokens
pTSatisfy :: (Token -> Bool) -> AParser MToken
pTSatisfy :: (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
f = (MToken -> Bool) -> AParser MToken
pMSatisfy MToken -> Bool
f'
 where
    f' :: MToken -> Bool
    f' :: MToken -> Bool
f' (MToken Region
_ Token
t) = Token -> Bool
f Token
t

-- | Parse an identifier
ident :: String -> AParser MToken
ident :: String -> AParser MToken
ident String
s = (MToken -> Bool) -> AParser MToken
pMSatisfy MToken -> Bool
isIdent
 where
    isIdent :: MToken -> Bool
    isIdent :: MToken -> Bool
isIdent (MToken Region
_ (Identifier String
s')) = String
s forall a. Eq a => a -> a -> Bool
== String
s'
    isIdent MToken
_ = Bool
False

-- | Parse any kind of whitespace
whitespace :: AParser MToken
whitespace :: AParser MToken
whitespace = (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isWhitespace

-- | Whether a token is whitespace
isWhitespace :: Token -> Bool
isWhitespace :: Token -> Bool
isWhitespace (Whitespace String
_) = Bool
True
isWhitespace Token
_ = Bool
False

-- | Whether a token consists of spaces
isSpaces :: Token -> Bool
isSpaces :: Token -> Bool
isSpaces (Whitespace String
str) = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
== Char
' ') String
str
isSpaces Token
_ = Bool
False

-- | Parse anything that isn't whitespace
notWhitespace :: AParser MToken
notWhitespace :: AParser MToken
notWhitespace = (MToken -> Bool) -> AParser MToken
pMSatisfy MToken -> Bool
isNotWhitespace
 where
    isNotWhitespace :: MToken -> Bool
    isNotWhitespace :: MToken -> Bool
isNotWhitespace (MToken Region
_ (Whitespace String
_)) = Bool
False
    isNotWhitespace MToken
_ = Bool
True

-- | Warnings for deprecated library functions
libraryWarnings :: String -> AParser String -> AParser String
libraryWarnings :: String -> AParser String -> AParser String
libraryWarnings String
s AParser String
p = do
    String -> AParser MToken
ident String
s
    Token -> AParser MToken
pMTok Token
Dot

    AParser String
p

-- | Warnings for the ai library
aiWarnings :: AParser String
aiWarnings :: AParser String
aiWarnings = String -> AParser String -> AParser String
libraryWarnings String
"ai" forall a b. (a -> b) -> a -> b
$
    String
"The function is broken" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetScheduleID" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"The function is broken" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetTaskID"

-- | Warnings for the math library
mathWarnings :: AParser String
mathWarnings :: AParser String
mathWarnings = String -> AParser String -> AParser String
libraryWarnings String
"math" forall a b. (a -> b) -> a -> b
$
    String
"Use math.Distance instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"Dist" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use math.fmod instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"mod"


-- | Warnings for the spawnmenu library
spawnmenuWarnings :: AParser String
spawnmenuWarnings :: AParser String
spawnmenuWarnings = String -> AParser String -> AParser String
libraryWarnings String
"spawnmenu" forall a b. (a -> b) -> a -> b
$
    String
"Use spawnmenu.SaveToTextFiles instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"DoSaveToTextFiles" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use spawnmenu.PopulateFromTextFiles instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"PopulateFromEngineTextFiles" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"The function is broken" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SwitchToolTab"

-- | Warnings for the string library
stringWarnings :: AParser String
stringWarnings :: AParser String
stringWarnings = String -> AParser String -> AParser String
libraryWarnings String
"string" forall a b. (a -> b) -> a -> b
$
    String
"Use either string.sub(str, index, index) or str[index]" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetChar" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use string.gmatch instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"gfind"

-- | Warnings for the surface library
surfaceWarnings :: AParser String
surfaceWarnings :: AParser String
surfaceWarnings = String -> AParser String -> AParser String
libraryWarnings String
"surface" forall a b. (a -> b) -> a -> b
$
    String
"Use ScrH instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"ScreenHeight" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use ScrW instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"ScreenWidth"

-- | Warnings for the table library
tableWarnings :: AParser String
tableWarnings :: AParser String
tableWarnings = String -> AParser String -> AParser String
libraryWarnings String
"table" forall a b. (a -> b) -> a -> b
$
    String
"Use ipairs or something instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (
        String -> AParser MToken
ident String
"FindNext" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        String -> AParser MToken
ident String
"FindPrev" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        String -> AParser MToken
ident String
"foreach"  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        String -> AParser MToken
ident String
"ForEach"  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        String -> AParser MToken
ident String
"foreachi"
    ) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use next instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (
        String -> AParser MToken
ident String
"GetFirstKey" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        String -> AParser MToken
ident String
"GetFirstValue"
    ) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use #tbl instead"      forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetLastKey"   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use tbl[#tbl] instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetLastValue" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use #tbl instead"      forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"getn"


-- | Warnings for the timer library
timerWarnings :: AParser String
timerWarnings :: AParser String
timerWarnings = String -> AParser String -> AParser String
libraryWarnings String
"timer" forall a b. (a -> b) -> a -> b
$
    String
"The function is broken" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"Check" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"Use timer.Remove instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"Destroy"

-- | Warnings for the umsg library
umsgWarnings :: AParser String
umsgWarnings :: AParser String
umsgWarnings = String -> AParser String -> AParser String
libraryWarnings String
"umsg" forall a b. (a -> b) -> a -> b
$
    String
"Use net messages." forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"Start"

-- | Warnings for the util library
utilWarnings :: AParser String
utilWarnings :: AParser String
utilWarnings = String -> AParser String -> AParser String
libraryWarnings String
"util" forall a b. (a -> b) -> a -> b
$
    String
"Use tobool, without the util bit" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"tobool" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String
"The function is broken" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"TraceEntityHull"

-- | Warnings for things to do with self
selfWarnings :: AParser String
selfWarnings :: AParser String
selfWarnings = String -> AParser String -> AParser String
libraryWarnings String
"self" forall a b. (a -> b) -> a -> b
$
    String
"Use self:GetOwner() instead" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"Owner"

-- | Warnings for meta functions
metaFuncWarnings :: AParser String
metaFuncWarnings :: AParser String
metaFuncWarnings = do
    Token -> AParser MToken
pMTok Token
Colon

    -- CLuaLocomotion functions
    String
"Use :IsUsingLadder instead"                                     forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"IsAscendingOrDescendingLadder"       forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

      -- Panel functions
      String
"Use :GetPaintBackground instead"                                forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetDrawBackground"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetPaintBackground instead"                                forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetDrawBackground"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"The function is broken"                                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"AddText"                             forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Only used by deprecated Derma controls"                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"PostMessage"                         forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Only used in deprecated Derma controls"                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetActionFunction"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetKeyboardInputEnabled instead"                           forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetKeyBoardInputEnabled"             forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"The function is broken"                                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetPaintFunction"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetTooltip instead, notice the lowercase fucking t"        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetToolTip"                          forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"use :SetTooltipPanel instead, notice the lowercase fucking t"   forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetToolTipPanel"                     forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :IsValid instead"                                           forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"Valid"                               forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

      -- Entity functions
      String
"Use :GetHitBoxBone instead, note the capital fucking B"         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetHitboxBone"                       forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWAngle instead"                                        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedAngle"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWBool instead"                                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedBool"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWEntity instead"                                       forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedEntity"                  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWFloat instead"                                        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedFloat"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWInt instead"                                          forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedInt"                     forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWString instead"                                       forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedString"                  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWVarProxy instead"                                     forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedVarProxy"                forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWVarTable instead"                                     forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedVarTable"                forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :GetNWVector instead"                                       forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetNetworkedVector"                  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"The function is broken"                                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetWorkshopID"                       forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWAngle instead"                                        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedAngle"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWBool instead"                                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedBool"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWEntity instead"                                       forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedEntity"                  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWFloat instead"                                        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedFloat"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWInt instead"                                          forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedInt"                     forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWString instead"                                       forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedString"                  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWVarProxy instead"                                     forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedVarProxy"                forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      String
"Use :SetNWVector instead"                                       forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetNetworkedVector"                  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

      -- Player functions
      String
"Use :GetViewPunchAngles instead"                                forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetPunchAngle"                       forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

      -- Material functions
      String
"The function is broken"                                         forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SetShader"                           forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

      -- Vector functions
      String
"Use :Dot instead"                                               forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"DotProduct"


-- | Parser for all deprecated sequences of tokens
deprecatedSequence :: LintSettings -> AParser Issue
deprecatedSequence :: LintSettings -> AParser Issue
deprecatedSequence LintSettings
opts = if Bool -> Bool
not (LintSettings -> Bool
lint_deprecated LintSettings
opts) then forall s u (m :: * -> *) a. ParsecT s u m a
parserZero else String -> Issue
Deprecated forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (

    -- Deprecated meta functions
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
metaFuncWarnings

    -- Library functions
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
aiWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
mathWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
spawnmenuWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
stringWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
surfaceWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
tableWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
timerWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
umsgWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
utilWarnings
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try AParser String
selfWarnings

    -- Global functions
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use collectgarbage(\"count\") instead"
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"gcinfo"
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use ConVar objects instead"
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetConVarNumber"
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use ConVar objects instead"
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"GetConVarString"
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use AddCSLuaFile in the file itself instead"
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"IncludeCS"
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use ScreenScale instead"
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SScale"
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use IsUselessModel instead"
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"UTIL_IsUselessModel"
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use IsValid instead"
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"ValidPanel"
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
"Use net messages."
        forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> AParser MToken
ident String
"SendUserMessage"
    )

-- | Parser for all beginner mistakes
beginnerMistakeSequence :: LintSettings -> AParser Issue
beginnerMistakeSequence :: LintSettings -> AParser Issue
beginnerMistakeSequence LintSettings
opts = if Bool -> Bool
not (LintSettings -> Bool
lint_beginnerMistakes LintSettings
opts) then forall s u (m :: * -> *) a. ParsecT s u m a
parserZero else String -> Issue
BeginnerMistake forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"There's little fucking reason to use ';' in the first place, don't use it twice in a row" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Token -> AParser MToken
pMTok Token
Semicolon forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Token -> AParser MToken
pMTok Token
Semicolon) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"The server already knows who sent the net message, use the first parameter of net.Receive" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ do
        String -> AParser MToken
ident String
"net"
        Token -> AParser MToken
pMTok Token
Dot
        String -> AParser MToken
ident String
"WriteEntity"
        Token -> AParser MToken
pMTok Token
LRound
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional AParser MToken
whitespace
        String -> AParser MToken
ident String
"LocalPlayer"
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional AParser MToken
whitespace
        Token -> AParser MToken
pMTok Token
LRound
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional AParser MToken
whitespace
        Token -> AParser MToken
pMTok Token
RRound
        ) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Jesus christ fuck off already" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ do
        Token -> AParser MToken
pMTok Token
While
        AParser MToken
whitespace
        Token -> AParser MToken
pMTok Token
TTrue
        AParser MToken
whitespace
        Token -> AParser MToken
pMTok Token
Do
        AParser MToken
whitespace
        Token -> AParser MToken
pMTok Token
End
        )
    )

whiteSpaceStyleSequence :: LintSettings -> AParser Issue
whiteSpaceStyleSequence :: LintSettings -> AParser Issue
whiteSpaceStyleSequence LintSettings
opts = if Bool -> Bool
not (LintSettings -> Bool
lint_whitespaceStyle LintSettings
opts) then forall s u (m :: * -> *) a. ParsecT s u m a
parserZero else String -> Issue
WhitespaceStyle forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Please put some whitespace after 'if'" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Token -> AParser MToken
pMTok Token
If forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy AParser MToken
whitespace)            forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Please put some whitespace after 'elseif'" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Token -> AParser MToken
pMTok Token
Elseif forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy AParser MToken
whitespace)    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Please put some whitespace after 'while'" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Token -> AParser MToken
pMTok Token
While forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy AParser MToken
whitespace)      forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Please put some whitespace after 'until'" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Token -> AParser MToken
pMTok Token
Until forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy AParser MToken
whitespace)      forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Please put some whitespace after ')'" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ do
        Token -> AParser MToken
pMTok Token
RRound
        (Token -> Bool) -> AParser MToken
pTSatisfy (\Token
t -> Bool -> Bool
not (Token -> Bool
isWhitespace Token
t) Bool -> Bool -> Bool
&& Token
t forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Token
Colon, Token
RRound, Token
LRound, Token
LSquare, Token
RSquare, Token
LCurly, Token
RCurly, Token
Comma, Token
Dot, Token
Semicolon])
        ) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Please put some whitespace before the operator" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ do
        AParser MToken
notWhitespace
        forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [Token -> AParser MToken
pMTok Token
Plus, Token -> AParser MToken
pMTok Token
Multiply, Token -> AParser MToken
pMTok Token
Divide, Token -> AParser MToken
pMTok Token
Modulus, Token -> AParser MToken
pMTok Token
TEq, Token -> AParser MToken
pMTok Token
TNEq, Token -> AParser MToken
pMTok Token
TCNEq, Token -> AParser MToken
pMTok Token
TLEQ, Token -> AParser MToken
pMTok Token
TGEQ, Token -> AParser MToken
pMTok Token
TLT, Token -> AParser MToken
pMTok Token
TGT, Token -> AParser MToken
pMTok Token
Equals, Token -> AParser MToken
pMTok Token
Concatenate, Token -> AParser MToken
pMTok Token
And, Token -> AParser MToken
pMTok Token
CAnd, Token -> AParser MToken
pMTok Token
Or, Token -> AParser MToken
pMTok Token
COr]
        ) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String
"Please put some whitespace after the operator" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ do
        forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [Token -> AParser MToken
pMTok Token
Plus, Token -> AParser MToken
pMTok Token
Multiply, Token -> AParser MToken
pMTok Token
Divide, Token -> AParser MToken
pMTok Token
Modulus, Token -> AParser MToken
pMTok Token
TEq, Token -> AParser MToken
pMTok Token
TNEq, Token -> AParser MToken
pMTok Token
TCNEq, Token -> AParser MToken
pMTok Token
TLEQ, Token -> AParser MToken
pMTok Token
TGEQ, Token -> AParser MToken
pMTok Token
TLT, Token -> AParser MToken
pMTok Token
TGT, Token -> AParser MToken
pMTok Token
Equals, Token -> AParser MToken
pMTok Token
Concatenate, Token -> AParser MToken
pMTok Token
And, Token -> AParser MToken
pMTok Token
CAnd, Token -> AParser MToken
pMTok Token
Or, Token -> AParser MToken
pMTok Token
COr]
        AParser MToken
notWhitespace
        )
    )

-- | Matches any token but the given one
pNotTToken :: Token -> AParser MToken
pNotTToken :: Token -> AParser MToken
pNotTToken Token
t = (Token -> Bool) -> AParser MToken
pTSatisfy (Token
t forall a. Eq a => a -> a -> Bool
/=)

-- | Warn about adding or removing spaces after an opening parenthesis. What it actually checks for
-- and wants the user to do depends on the prettyprint_spaceBetweenParens and
-- prettyprint_spaceEmptyParens settings
spaceAfterParenthesis :: LintSettings -> AParser Issue
spaceAfterParenthesis :: LintSettings -> AParser Issue
spaceAfterParenthesis LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceBetweenParens LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | Bool
otherwise =
        case (LintSettings -> Bool
prettyprint_spaceBetweenParens LintSettings
settings, LintSettings -> Bool
prettyprint_spaceEmptyParens LintSettings
settings) of
          (Bool
True, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceAfterParenthesis RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LRound forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> AParser MToken
notWhitespace)
          (Bool
False, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceAfterParenthesis RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LRound forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces)
          (Bool
True, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceAfterParenthesis RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LRound forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> AParser MToken
notWhitespaceAndNotClose) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            RemoveOrAddSpace -> Issue
SpaceAfterParenthesis RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LRound forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RRound)
          (Bool
False, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceAfterParenthesis RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LRound forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pNotTToken Token
RRound) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            RemoveOrAddSpace -> Issue
SpaceAfterParenthesis RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LRound forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RRound)
  where
    notWhitespaceAndNotClose :: AParser MToken
    notWhitespaceAndNotClose :: AParser MToken
notWhitespaceAndNotClose = (Token -> Bool) -> AParser MToken
pTSatisfy forall a b. (a -> b) -> a -> b
$ \case
      Token
RRound -> Bool
False
      Whitespace String
_ -> Bool
False
      Token
_ -> Bool
True

-- | Warn about adding or removing spaces before a closing parenthesis
spaceBeforeParenthesis :: LintSettings -> AParser Issue
spaceBeforeParenthesis :: LintSettings -> AParser Issue
spaceBeforeParenthesis LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceBetweenParens LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | Bool
otherwise =
        case (LintSettings -> Bool
prettyprint_spaceBetweenParens LintSettings
settings, LintSettings -> Bool
prettyprint_spaceEmptyParens LintSettings
settings) of
          (Bool
True, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeParenthesis RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (AParser MToken
notWhitespace forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RRound)
          (Bool
False, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeParenthesis RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ((Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RRound)
          (Bool
True, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeParenthesis RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (AParser MToken
notWhitespaceAndNotOpen forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RRound)
          (Bool
False, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeParenthesis RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pNotTToken Token
LRound forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RRound)
  where
    notWhitespaceAndNotOpen :: AParser MToken
    notWhitespaceAndNotOpen :: AParser MToken
notWhitespaceAndNotOpen = (Token -> Bool) -> AParser MToken
pTSatisfy forall a b. (a -> b) -> a -> b
$ \case
      Token
LRound -> Bool
False
      Whitespace String
_ -> Bool
False
      Token
_ -> Bool
True

-- | Warn about adding or removing spaces after an opening brace (`}`). What it actually checks for
-- and wants the user to do depends on the prettyprint_spaceBetweenBraces and
-- prettyprint_spaceEmptyBraces settings
spaceAfterBraces :: LintSettings -> AParser Issue
spaceAfterBraces :: LintSettings -> AParser Issue
spaceAfterBraces LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceBetweenBraces LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | Bool
otherwise =
        case (LintSettings -> Bool
prettyprint_spaceBetweenBraces LintSettings
settings, LintSettings -> Bool
prettyprint_spaceEmptyBraces LintSettings
settings) of
          (Bool
True, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceAfterBrace RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LCurly forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> AParser MToken
notWhitespace)
          (Bool
False, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceAfterBrace RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LCurly forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces)
          (Bool
True, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceAfterBrace RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LCurly forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> AParser MToken
notWhitespaceAndNotClose) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            RemoveOrAddSpace -> Issue
SpaceAfterBrace RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LCurly forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RCurly)
          (Bool
False, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceAfterBrace RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LCurly forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pNotTToken Token
RCurly) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            RemoveOrAddSpace -> Issue
SpaceAfterBrace RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LCurly forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RCurly)
  where
    notWhitespaceAndNotClose :: AParser MToken
    notWhitespaceAndNotClose :: AParser MToken
notWhitespaceAndNotClose = (Token -> Bool) -> AParser MToken
pTSatisfy forall a b. (a -> b) -> a -> b
$ \case
      Token
RCurly -> Bool
False
      Whitespace String
_ -> Bool
False
      Token
_ -> Bool
True

-- | Warn about adding or removing spaces before a closing brace (`}`)
spaceBeforeBraces :: LintSettings -> AParser Issue
spaceBeforeBraces :: LintSettings -> AParser Issue
spaceBeforeBraces LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceBetweenBraces LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | Bool
otherwise =
        case (LintSettings -> Bool
prettyprint_spaceBetweenBraces  LintSettings
settings, LintSettings -> Bool
prettyprint_spaceEmptyBraces LintSettings
settings) of
          (Bool
True, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeBrace RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (AParser MToken
notWhitespace forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RCurly)
          (Bool
False, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeBrace RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ((Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RCurly)
          (Bool
True, Bool
False) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeBrace RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (AParser MToken
notWhitespaceAndNotOpen forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RCurly)
          (Bool
False, Bool
True) ->
            RemoveOrAddSpace -> Issue
SpaceBeforeBrace RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pNotTToken Token
LCurly forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RCurly)
  where
    notWhitespaceAndNotOpen :: AParser MToken
    notWhitespaceAndNotOpen :: AParser MToken
notWhitespaceAndNotOpen = (Token -> Bool) -> AParser MToken
pTSatisfy forall a b. (a -> b) -> a -> b
$ \case
      Token
LCurly -> Bool
False
      Whitespace String
_ -> Bool
False
      Token
_ -> Bool
True

-- | Warn about adding or removing spaces after an opening bracket (`[`). What it actually checks
-- for and wants the user to do depends on the prettyprint_spaceBetweenBracket
spaceAfterBrackets :: LintSettings -> AParser Issue
spaceAfterBrackets :: LintSettings -> AParser Issue
spaceAfterBrackets LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceBetweenBrackets LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | LintSettings -> Bool
prettyprint_spaceBetweenBrackets LintSettings
settings =
      RemoveOrAddSpace -> Issue
SpaceAfterBracket RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LSquare forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> AParser MToken
notWhitespace)
    | Bool
otherwise =
      RemoveOrAddSpace -> Issue
SpaceAfterBracket RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
LSquare forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces)

-- | Warn about adding or removing spaces before a closing bracket (`]`)
spaceBeforeBrackets :: LintSettings -> AParser Issue
spaceBeforeBrackets :: LintSettings -> AParser Issue
spaceBeforeBrackets LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceBetweenBrackets LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | LintSettings -> Bool
prettyprint_spaceBetweenBrackets LintSettings
settings =
      RemoveOrAddSpace -> Issue
SpaceBeforeBracket RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (AParser MToken
notWhitespace forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RSquare)
    | Bool
otherwise =
      RemoveOrAddSpace -> Issue
SpaceBeforeBracket RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ((Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
RSquare)

-- | Warn about adding or removing spaces after a comma
spaceAfterComma :: LintSettings -> AParser Issue
spaceAfterComma :: LintSettings -> AParser Issue
spaceAfterComma LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceAfterComma LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | LintSettings -> Bool
prettyprint_spaceAfterComma LintSettings
settings =
      RemoveOrAddSpace -> Issue
SpaceAfterComma RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
Comma forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> AParser MToken
notWhitespace)
    | Bool
otherwise =
      RemoveOrAddSpace -> Issue
SpaceAfterComma RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Token -> AParser MToken
pMTok Token
Comma forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces)

-- | Warn about adding or removing spaces before a comma
spaceBeforeComma :: LintSettings -> AParser Issue
spaceBeforeComma :: LintSettings -> AParser Issue
spaceBeforeComma LintSettings
settings
    | Bool -> Bool
not (LintSettings -> Bool
lint_spaceBeforeComma LintSettings
settings) = forall s u (m :: * -> *) a. ParsecT s u m a
parserZero
    | LintSettings -> Bool
prettyprint_spaceBeforeComma LintSettings
settings =
      RemoveOrAddSpace -> Issue
SpaceBeforeComma RemoveOrAddSpace
AddSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (AParser MToken
notWhitespace forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
Comma)
    | Bool
otherwise =
      RemoveOrAddSpace -> Issue
SpaceBeforeComma RemoveOrAddSpace
RemoveSpace forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ((Token -> Bool) -> AParser MToken
pTSatisfy Token -> Bool
isSpaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token -> AParser MToken
pMTok Token
Comma)

-- | Parser for all profanity
profanitySequence :: LintSettings -> AParser Issue
profanitySequence :: LintSettings -> AParser Issue
profanitySequence LintSettings
opts = if Bool -> Bool
not (LintSettings -> Bool
lint_profanity LintSettings
opts) then forall s u (m :: * -> *) a. ParsecT s u m a
parserZero else Issue
Profanity forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (
    String -> AParser MToken
ident String
"anus"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"bitch"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"cock"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"cocks"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"cunt"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"dick"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"dicks"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"fuck"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"fucking"                 forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"goddamnit"               forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"knob"                    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"knobs"                   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"motherfucker"            forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"nipple"                  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    String -> AParser MToken
ident String
"shit"
    )

-- | Parses for any bad sequence
badSequence :: LintSettings -> AParser Issue
badSequence :: LintSettings -> AParser Issue
badSequence LintSettings
opts =
    LintSettings -> AParser Issue
deprecatedSequence LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    LintSettings -> AParser Issue
profanitySequence LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    LintSettings -> AParser Issue
beginnerMistakeSequence LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    LintSettings -> AParser Issue
whiteSpaceStyleSequence LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

    LintSettings -> AParser Issue
spaceAfterParenthesis LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    LintSettings -> AParser Issue
spaceBeforeParenthesis LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

    LintSettings -> AParser Issue
spaceAfterBraces LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    LintSettings -> AParser Issue
spaceBeforeBraces LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

    LintSettings -> AParser Issue
spaceAfterBrackets LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    LintSettings -> AParser Issue
spaceBeforeBrackets LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>

    LintSettings -> AParser Issue
spaceAfterComma LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    LintSettings -> AParser Issue
spaceBeforeComma LintSettings
opts

-- | Creates a warning for a certain sequence at any position
badSequenceWarning :: Region -> Issue -> [FilePath -> LintMessage] -> [FilePath -> LintMessage]
badSequenceWarning :: Region
-> Issue -> [String -> LintMessage] -> [String -> LintMessage]
badSequenceWarning Region
pos Issue
message = (:) (Severity -> Region -> Issue -> String -> LintMessage
LintMessage Severity
LintWarning Region
pos Issue
message)

-- | Searches for all the bad sequences
badSequenceParser :: LintSettings -> AParser [String -> LintMessage]
badSequenceParser :: LintSettings -> AParser [String -> LintMessage]
badSequenceParser LintSettings
opts =
    -- A bad sequence
    forall a b. (Region -> a -> b) -> AParser a -> AParser b
annotated Region
-> Issue -> [String -> LintMessage] -> [String -> LintMessage]
badSequenceWarning (LintSettings -> AParser Issue
badSequence LintSettings
opts) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> LintSettings -> AParser [String -> LintMessage]
badSequenceParser LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    -- Continue searching
    forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m t
anyToken forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> LintSettings -> AParser [String -> LintMessage]
badSequenceParser LintSettings
opts forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    -- end of input
    forall (m :: * -> *) a. Monad m => a -> m a
return []

-- | Returns all the warnings for a lexicon
sequenceWarnings :: LintSettings -> [MToken] -> [String -> LintMessage]
sequenceWarnings :: LintSettings -> [MToken] -> [String -> LintMessage]
sequenceWarnings LintSettings
opts [MToken]
mts = case forall a. String -> AParser a -> [MToken] -> Either ParseError a
execAParser String
"source.lua" (LintSettings -> AParser [String -> LintMessage]
badSequenceParser LintSettings
opts) [MToken]
mts of
    Left ParseError
_ -> forall a. HasCallStack => String -> a
error String
"[Error] line 1, column 1: Sequence finding error! Report an issue!"
    Right [String -> LintMessage]
warnings -> [String -> LintMessage]
warnings

-- | Helper function: check from string
checkFromString :: AParser a -> String -> Either ParseError a
checkFromString :: forall a. AParser a -> String -> Either ParseError a
checkFromString AParser a
p String
inp = do
    [MToken]
lexed <- String -> Either ParseError [MToken]
PSL.execParseTokens String
inp
    forall a. String -> AParser a -> [MToken] -> Either ParseError a
execAParser String
"source.lua" AParser a
p [MToken]
lexed