提交 86999ded 编写于 作者: V Vidar Holen

Improve 'let' parsing, trigger unused var for ((a=1))

上级 7551a241
...@@ -34,6 +34,7 @@ data CaseType = CaseBreak | CaseFallThrough | CaseContinue deriving (Show, Eq) ...@@ -34,6 +34,7 @@ data CaseType = CaseBreak | CaseFallThrough | CaseContinue deriving (Show, Eq)
data Token = data Token =
TA_Binary Id String Token Token TA_Binary Id String Token Token
| TA_Assignment Id String Token Token
| TA_Expansion Id [Token] | TA_Expansion Id [Token]
| TA_Index Id Token | TA_Index Id Token
| TA_Sequence Id [Token] | TA_Sequence Id [Token]
...@@ -250,6 +251,7 @@ analyze f g i = ...@@ -250,6 +251,7 @@ analyze f g i =
delve (TC_Noary id typ token) = d1 token $ TC_Noary id typ delve (TC_Noary id typ token) = d1 token $ TC_Noary id typ
delve (TA_Binary id op t1 t2) = d2 t1 t2 $ TA_Binary id op delve (TA_Binary id op t1 t2) = d2 t1 t2 $ TA_Binary id op
delve (TA_Assignment id op t1 t2) = d2 t1 t2 $ TA_Assignment id op
delve (TA_Unary id op t1) = d1 t1 $ TA_Unary id op delve (TA_Unary id op t1) = d1 t1 $ TA_Unary id op
delve (TA_Sequence id l) = dl l $ TA_Sequence id delve (TA_Sequence id l) = dl l $ TA_Sequence id
delve (TA_Trinary id t1 t2 t3) = do delve (TA_Trinary id t1 t2 t3) = do
...@@ -344,6 +346,7 @@ getId t = case t of ...@@ -344,6 +346,7 @@ getId t = case t of
TC_Unary id _ _ _ -> id TC_Unary id _ _ _ -> id
TC_Noary id _ _ -> id TC_Noary id _ _ -> id
TA_Binary id _ _ _ -> id TA_Binary id _ _ _ -> id
TA_Assignment id _ _ _ -> id
TA_Unary id _ _ -> id TA_Unary id _ _ -> id
TA_Sequence id _ -> id TA_Sequence id _ -> id
TA_Trinary id _ _ _ -> id TA_Trinary id _ _ _ -> id
......
...@@ -2054,6 +2054,9 @@ prop_checkUnused26= verifyNotTree checkUnusedAssignments "declare -F foo" ...@@ -2054,6 +2054,9 @@ prop_checkUnused26= verifyNotTree checkUnusedAssignments "declare -F foo"
prop_checkUnused27= verifyTree checkUnusedAssignments "var=3; [ var -eq 3 ]" prop_checkUnused27= verifyTree checkUnusedAssignments "var=3; [ var -eq 3 ]"
prop_checkUnused28= verifyNotTree checkUnusedAssignments "var=3; [[ var -eq 3 ]]" prop_checkUnused28= verifyNotTree checkUnusedAssignments "var=3; [[ var -eq 3 ]]"
prop_checkUnused29= verifyNotTree checkUnusedAssignments "var=(a b); declare -p var" prop_checkUnused29= verifyNotTree checkUnusedAssignments "var=(a b); declare -p var"
prop_checkUnused30= verifyTree checkUnusedAssignments "let a=1"
prop_checkUnused31= verifyTree checkUnusedAssignments "let 'a=1'"
prop_checkUnused32= verifyTree checkUnusedAssignments "let a=b=c; echo $a"
checkUnusedAssignments params t = execWriter (mapM_ warnFor unused) checkUnusedAssignments params t = execWriter (mapM_ warnFor unused)
where where
flow = variableFlow params flow = variableFlow params
...@@ -2742,7 +2745,7 @@ checkLoopVariableReassignment params token = ...@@ -2742,7 +2745,7 @@ checkLoopVariableReassignment params token =
T_ForIn _ s _ _ -> return s T_ForIn _ s _ _ -> return s
T_ForArithmetic _ T_ForArithmetic _
(TA_Sequence _ (TA_Sequence _
[TA_Binary _ "=" [TA_Assignment _ "="
(TA_Expansion _ [T_Literal _ var]) _]) (TA_Expansion _ [T_Literal _ var]) _])
_ _ _ -> return var _ _ _ -> return var
_ -> fail "not loop" _ -> fail "not loop"
......
...@@ -40,8 +40,6 @@ import qualified Data.Map as Map ...@@ -40,8 +40,6 @@ import qualified Data.Map as Map
import Test.QuickCheck.All (forAllProperties) import Test.QuickCheck.All (forAllProperties)
import Test.QuickCheck.Test (quickCheckWithResult, stdArgs, maxSuccess) import Test.QuickCheck.Test (quickCheckWithResult, stdArgs, maxSuccess)
import Debug.Trace
type Analysis = ReaderT Parameters (Writer [TokenComment]) () type Analysis = ReaderT Parameters (Writer [TokenComment]) ()
...@@ -272,7 +270,7 @@ getVariableFlow shell parents t = ...@@ -272,7 +270,7 @@ getVariableFlow shell parents t =
assignFirst _ = False assignFirst _ = False
setRead t = setRead t =
let read = getReferencedVariables t let read = getReferencedVariables parents t
in mapM_ (\v -> modify (Reference v:)) read in mapM_ (\v -> modify (Reference v:)) read
setWritten t = setWritten t =
...@@ -331,7 +329,7 @@ getModifiedVariables t = ...@@ -331,7 +329,7 @@ getModifiedVariables t =
TA_Unary _ "|++" var -> maybeToList $ do TA_Unary _ "|++" var -> maybeToList $ do
name <- getLiteralString var name <- getLiteralString var
return (t, t, name, DataString $ SourceFrom [t]) return (t, t, name, DataString $ SourceFrom [t])
TA_Binary _ op lhs rhs -> maybeToList $ do TA_Assignment _ op lhs rhs -> maybeToList $ do
guard $ op `elem` ["=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="] guard $ op `elem` ["=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="]
name <- getLiteralString lhs name <- getLiteralString lhs
return (t, t, name, DataString $ SourceFrom [rhs]) return (t, t, name, DataString $ SourceFrom [rhs])
...@@ -476,12 +474,15 @@ getIndexReferences s = fromMaybe [] $ do ...@@ -476,12 +474,15 @@ getIndexReferences s = fromMaybe [] $ do
where where
re = mkRegex "(\\[.*\\])" re = mkRegex "(\\[.*\\])"
getReferencedVariables t = getReferencedVariables parents t =
case t of case t of
T_DollarBraced id l -> let str = bracedString t in T_DollarBraced id l -> let str = bracedString t in
(t, t, getBracedReference str) : (t, t, getBracedReference str) :
map (\x -> (l, l, x)) (getIndexReferences str) map (\x -> (l, l, x)) (getIndexReferences str)
TA_Expansion id _ -> getIfReference t t TA_Expansion id _ ->
if isArithmeticAssignment t
then []
else getIfReference t t
T_Assignment id mode str _ word -> T_Assignment id mode str _ word ->
[(t, t, str) | mode == Append] ++ specialReferences str t word [(t, t, str) | mode == Append] ++ specialReferences str t word
...@@ -518,6 +519,10 @@ getReferencedVariables t = ...@@ -518,6 +519,10 @@ getReferencedVariables t =
isDereferencing = (`elem` ["-eq", "-ne", "-lt", "-le", "-gt", "-ge"]) isDereferencing = (`elem` ["-eq", "-ne", "-lt", "-le", "-gt", "-ge"])
isArithmeticAssignment t = case getPath parents t of
this: TA_Assignment _ "=" _ _ :_ -> True
_ -> False
dataTypeFrom defaultType v = (case v of T_Array {} -> DataArray; _ -> defaultType) $ SourceFrom [v] dataTypeFrom defaultType v = (case v of T_Array {} -> DataArray; _ -> defaultType) $ SourceFrom [v]
......
...@@ -708,7 +708,9 @@ readArithmeticContents = ...@@ -708,7 +708,9 @@ readArithmeticContents =
l <- readAssignment `sepBy` (char ',' >> spacing) l <- readAssignment `sepBy` (char ',' >> spacing)
return $ TA_Sequence id l return $ TA_Sequence id l
readAssignment = readTrinary `splitBy` ["=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="] readAssignment = chainr1 readTrinary readAssignmentOp
readAssignmentOp = readComboOp ["=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="] TA_Assignment
readTrinary = do readTrinary = do
x <- readLogicalOr x <- readLogicalOr
do do
...@@ -2214,13 +2216,29 @@ readTimeSuffix = do ...@@ -2214,13 +2216,29 @@ readTimeSuffix = do
lookAhead $ char '-' lookAhead $ char '-'
readCmdWord readCmdWord
-- Fixme: this is a hack that doesn't handle let '++c' or let a\>b -- Fixme: this is a hack that doesn't handle let c='4'"5" or let a\>b
readLetSuffix :: Monad m => SCParser m [Token]
readLetSuffix = many1 (readIoRedirect <|> try readLetExpression <|> readCmdWord) readLetSuffix = many1 (readIoRedirect <|> try readLetExpression <|> readCmdWord)
where where
readLetExpression :: Monad m => SCParser m Token
readLetExpression = do readLetExpression = do
startPos <- getPosition startPos <- getPosition
expression <- readStringForParser readCmdWord expression <- readStringForParser readCmdWord
subParse startPos readArithmeticContents expression let (unQuoted, newPos) = kludgeAwayQuotes expression startPos
subParse newPos readArithmeticContents unQuoted
kludgeAwayQuotes :: String -> SourcePos -> (String, SourcePos)
kludgeAwayQuotes s p =
case s of
first:rest@(_:_) ->
let (last:backwards) = reverse rest
middle = reverse backwards
in
if first `elem` "'\"" && first == last
then (middle, updatePosChar p first)
else (s, p)
x -> (s, p)
-- bash allows a=(b), ksh allows $a=(b). dash allows neither. Let's warn. -- bash allows a=(b), ksh allows $a=(b). dash allows neither. Let's warn.
readEvalSuffix = many1 (readIoRedirect <|> readCmdWord <|> evalFallback) readEvalSuffix = many1 (readIoRedirect <|> readCmdWord <|> evalFallback)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册