Improve warnings about unnecessary subshells (fixes #2169)
This commit is contained in:
parent
10817533d6
commit
f5fd9c2fed
|
@ -3742,21 +3742,27 @@ checkForLoopGlobVariables _ t =
|
|||
suggest t = info (getId t) 2231
|
||||
"Quote expansions in this for loop glob to prevent wordsplitting, e.g. \"$dir\"/*.txt ."
|
||||
|
||||
|
||||
prop_checkSubshelledTests1 = verify checkSubshelledTests "a && ( [ b ] || ! [ c ] )"
|
||||
prop_checkSubshelledTests2 = verify checkSubshelledTests "( [ a ] )"
|
||||
prop_checkSubshelledTests3 = verify checkSubshelledTests "( [ a ] && [ b ] || test c )"
|
||||
prop_checkSubshelledTests4 = verify checkSubshelledTests "( [ a ] && { [ b ] && [ c ]; } )"
|
||||
prop_checkSubshelledTests5 = verifyNot checkSubshelledTests "( [[ ${var:=x} = y ]] )"
|
||||
prop_checkSubshelledTests6 = verifyNot checkSubshelledTests "( [[ $((i++)) = 10 ]] )"
|
||||
prop_checkSubshelledTests7 = verifyNot checkSubshelledTests "( [[ $((i+=1)) = 10 ]] )"
|
||||
prop_checkSubshelledTests8 = verify checkSubshelledTests "# shellcheck disable=SC2234\nf() ( [[ x ]] )"
|
||||
|
||||
checkSubshelledTests params t =
|
||||
case t of
|
||||
T_Subshell id list | all isTestStructure list ->
|
||||
T_Subshell id list | all isTestStructure list && (not (hasAssignment t)) ->
|
||||
case () of
|
||||
-- Special case for if (test) and while (test)
|
||||
_ | isCompoundCondition (getPath (parentMap params) t) ->
|
||||
style id 2233 "Remove superfluous (..) around condition."
|
||||
style id 2233 "Remove superfluous (..) around condition to avoid subshell overhead."
|
||||
|
||||
-- Special case for ([ x ])
|
||||
_ | isSingleTest list ->
|
||||
style id 2234 "Remove superfluous (..) around test command."
|
||||
-- Special case for ([ x ]), except for func() ( [ x ] )
|
||||
_ | isSingleTest list && (not $ isFunctionBody (getPath (parentMap params) t)) ->
|
||||
style id 2234 "Remove superfluous (..) around test command to avoid subshell overhead."
|
||||
|
||||
-- General case for ([ x ] || [ y ] && etc)
|
||||
_ -> style id 2235 "Use { ..; } instead of (..) to avoid subshell overhead."
|
||||
|
@ -3768,6 +3774,11 @@ checkSubshelledTests params t =
|
|||
[c] | isTestCommand c -> True
|
||||
_ -> False
|
||||
|
||||
isFunctionBody path =
|
||||
case path of
|
||||
(_:f:_) -> isFunction f
|
||||
_ -> False
|
||||
|
||||
isTestStructure t =
|
||||
case t of
|
||||
T_Banged _ t -> isTestStructure t
|
||||
|
@ -3798,6 +3809,19 @@ checkSubshelledTests params t =
|
|||
T_UntilExpression {} : _ -> True
|
||||
_ -> False
|
||||
|
||||
hasAssignment t = isNothing $ doAnalysis guardNotAssignment t
|
||||
guardNotAssignment t =
|
||||
case t of
|
||||
TA_Assignment {} -> Nothing
|
||||
TA_Unary _ s _ -> guard . not $ "++" `isInfixOf` s || "--" `isInfixOf` s
|
||||
T_DollarBraced _ _ l ->
|
||||
let str = concat $ oversimplify l
|
||||
modifier = getBracedModifier str
|
||||
in
|
||||
guard . not $ "=" `isPrefixOf` modifier || ":=" `isPrefixOf` modifier
|
||||
T_DollarBraceCommandExpansion {} -> Nothing
|
||||
_ -> Just ()
|
||||
|
||||
-- Skip any parent of a T_Subshell until we reach something interesting
|
||||
skippable t =
|
||||
case t of
|
||||
|
|
Loading…
Reference in New Issue