Warn when calling functions before defining them.
This commit is contained in:
parent
43bb6a20ad
commit
81388cefd2
|
@ -308,6 +308,7 @@ isBraceExpansion t = case t of T_BraceExpansion {} -> True; _ -> False
|
||||||
|
|
||||||
-- Get the lists of commands from tokens that contain them, such as
|
-- Get the lists of commands from tokens that contain them, such as
|
||||||
-- the body of while loops or branches of if statements.
|
-- the body of while loops or branches of if statements.
|
||||||
|
getCommandSequences :: Token -> [[Token]]
|
||||||
getCommandSequences t =
|
getCommandSequences t =
|
||||||
case t of
|
case t of
|
||||||
T_Script _ _ cmds -> [cmds]
|
T_Script _ _ cmds -> [cmds]
|
||||||
|
@ -318,6 +319,7 @@ getCommandSequences t =
|
||||||
T_ForIn _ _ _ cmds -> [cmds]
|
T_ForIn _ _ _ cmds -> [cmds]
|
||||||
T_ForArithmetic _ _ _ _ cmds -> [cmds]
|
T_ForArithmetic _ _ _ _ cmds -> [cmds]
|
||||||
T_IfExpression _ thens elses -> map snd thens ++ [elses]
|
T_IfExpression _ thens elses -> map snd thens ++ [elses]
|
||||||
|
T_Annotation _ _ t -> getCommandSequences t
|
||||||
_ -> []
|
_ -> []
|
||||||
|
|
||||||
-- Get a list of names of associative arrays
|
-- Get a list of names of associative arrays
|
||||||
|
|
|
@ -63,6 +63,7 @@ treeChecks = [
|
||||||
,checkUnassignedReferences
|
,checkUnassignedReferences
|
||||||
,checkUncheckedCdPushdPopd
|
,checkUncheckedCdPushdPopd
|
||||||
,checkArrayAssignmentIndices
|
,checkArrayAssignmentIndices
|
||||||
|
,checkUseBeforeDefinition
|
||||||
]
|
]
|
||||||
|
|
||||||
runAnalytics :: AnalysisSpec -> [TokenComment]
|
runAnalytics :: AnalysisSpec -> [TokenComment]
|
||||||
|
@ -1522,7 +1523,7 @@ prop_subshellAssignmentCheck19 = verifyNotTree subshellAssignmentCheck "#!/bin/b
|
||||||
subshellAssignmentCheck params t =
|
subshellAssignmentCheck params t =
|
||||||
let flow = variableFlow params
|
let flow = variableFlow params
|
||||||
check = findSubshelled flow [("oops",[])] Map.empty
|
check = findSubshelled flow [("oops",[])] Map.empty
|
||||||
in snd $ runWriter check
|
in execWriter check
|
||||||
|
|
||||||
|
|
||||||
findSubshelled [] _ _ = return ()
|
findSubshelled [] _ _ = return ()
|
||||||
|
@ -2832,5 +2833,36 @@ checkPipeToNowhere _ t =
|
||||||
T_FdRedirect _ _ T_HereString {} -> True
|
T_FdRedirect _ _ T_HereString {} -> True
|
||||||
_ -> False
|
_ -> False
|
||||||
|
|
||||||
|
prop_checkUseBeforeDefinition1 = verifyTree checkUseBeforeDefinition "f; f() { true; }"
|
||||||
|
prop_checkUseBeforeDefinition2 = verifyNotTree checkUseBeforeDefinition "f() { true; }; f"
|
||||||
|
prop_checkUseBeforeDefinition3 = verifyNotTree checkUseBeforeDefinition "if ! mycmd --version; then mycmd() { true; }; fi"
|
||||||
|
prop_checkUseBeforeDefinition4 = verifyNotTree checkUseBeforeDefinition "mycmd || mycmd() { f; }"
|
||||||
|
checkUseBeforeDefinition _ t =
|
||||||
|
execWriter $ evalStateT (mapM_ examine $ revCommands) Map.empty
|
||||||
|
where
|
||||||
|
examine t = case t of
|
||||||
|
T_Pipeline _ _ [T_Redirecting _ _ (T_Function _ _ _ name _)] ->
|
||||||
|
modify $ Map.insert name t
|
||||||
|
T_Annotation _ _ w -> examine w
|
||||||
|
T_Pipeline _ _ cmds -> do
|
||||||
|
m <- get
|
||||||
|
unless (Map.null m) $
|
||||||
|
mapM_ (checkUsage m) $ concatMap recursiveSequences cmds
|
||||||
|
_ -> return ()
|
||||||
|
|
||||||
|
checkUsage map cmd = potentially $ do
|
||||||
|
name <- getCommandName cmd
|
||||||
|
def <- Map.lookup name map
|
||||||
|
return $
|
||||||
|
err (getId cmd) 2218
|
||||||
|
"This function is only defined later. Move the definition up."
|
||||||
|
|
||||||
|
revCommands = reverse $ concat $ getCommandSequences t
|
||||||
|
recursiveSequences x =
|
||||||
|
let list = concat $ getCommandSequences x in
|
||||||
|
if null list
|
||||||
|
then [x]
|
||||||
|
else concatMap recursiveSequences list
|
||||||
|
|
||||||
return []
|
return []
|
||||||
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])
|
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])
|
||||||
|
|
Loading…
Reference in New Issue