Skip to content

Commit

Permalink
Implementing broken return expectation
Browse files Browse the repository at this point in the history
  • Loading branch information
flbulgarelli committed Jan 4, 2021
1 parent 29d292e commit 9b5e014
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
3 changes: 3 additions & 0 deletions spec/JavaScriptSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ spec = do
it "differentiates procedures and functions" $ do
(js "function f() { return 1 }" /= js "function f() { 1 }") `shouldBe` True

it "differentiates procedures and functions with returns in if" $ do
(js "function f(){ if (x) { } else { return 4 } }") `shouldBe` (SimpleFunction "f" [] (If (Reference "x") None (Return (MuNumber 4.0))))

it "handles lambdas likes haskell does" $ do
js "var m = function(x) { return 1 }" `shouldBe` hs "m = \\x -> 1"

Expand Down
34 changes: 34 additions & 0 deletions spec/SmellSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,40 @@ spec = do
it "is False when local variable is used as a cache" $ do
hasRedundantLocalVariableReturn (js "function x(m) { var x = 5; var y = 1 + x; g(y); return x; }") `shouldBe` False

describe "hasBrokenReturn" $ do
it "is False when there are no functions" $ do
hasBrokenReturn (js "let y = 0; if (x) { y = 0 } ") `shouldBe` False

it "is False when there is a function that has only a return" $ do
hasBrokenReturn (js "function f(){ return 4 } ") `shouldBe` False

it "is False when there is a function that has a single flow and return" $ do
hasBrokenReturn (js "function f(){ console.log(2); return 4 } ") `shouldBe` False

it "is False when there is a function that has an if with no returns " $ do
hasBrokenReturn (js "function f(){ if (x) { console.log(4) } else { console.log(5) } return 4 } ") `shouldBe` False

it "is False when there is a function that has an if with no returns and no else " $ do
hasBrokenReturn (js "function f(){ if (x) { console.log(4) } return 4 } ") `shouldBe` False

it "is True when there is a function that has an if with a return and no else and not trailing return " $ do
hasBrokenReturn (js "function f(){ if (x) { return 4 } } ") `shouldBe` True

it "is True when there is a function that has an if with a return in else but not then and not trailing return " $ do
hasBrokenReturn (js "function f(){ if (x) { } else { return 4 } }") `shouldBe` True

it "is True when there is a function that nested ifs with incomplete return and no trailing return " $ do
hasBrokenReturn (js "function f(){ if (x) { if (y) { return 5 } } else { return 4 } }") `shouldBe` True

it "is False when there is a function that has an if with a return and no else and trailing return " $ do
hasBrokenReturn (js "function f(){ if (x) { return 4 } return 5; } ") `shouldBe` False

it "is False when there is a function that has an if with a return in else but not then and trailing return " $ do
hasBrokenReturn (js "function f(){ if (x) { } else { return 4 } return 5; } ") `shouldBe` False

it "is False when there is a function that nested ifs with complete return and no trailing return " $ do
hasBrokenReturn (js "function f(){ if (x) { if (y) { return 5 } else { return 6 } } else { return 4 } }") `shouldBe` False


describe "hasAssignmentCondition" $ do
it "is True when assigns within an if condition" $ do
Expand Down
16 changes: 16 additions & 0 deletions src/Language/Mulang/Inspector/Generic/Smell.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Language.Mulang.Inspector.Generic.Smell (
doesConsolePrint,
doesNilTest,
doesTypeTest,
hasBrokenReturn,
hasAssignmentReturn,
hasAssignmentCondition,
hasEmptyIfBranches,
Expand Down Expand Up @@ -140,6 +141,21 @@ hasRedundantLocalVariableReturn = containsExpression f
Return (Reference returnedVariable)]) = returnedVariable == declaredVariable
f _ = False

hasBrokenReturn :: Inspection
hasBrokenReturn = containsDeclaration f
where
f (SimpleFunction _ _ body) = not . fullyReturns $ body
f _ = False

fullyReturns :: Expression -> Bool
fullyReturns (Sequence (Return _:_)) = True
fullyReturns (Sequence (If _ b1 b2:es)) = fullyReturns b1 && fullyReturns b2 || fullyReturns (Sequence es)
fullyReturns (Sequence (_:es)) = fullyReturns (Sequence es)
fullyReturns (Return _) = True
fullyReturns (If _ b1 b2) = fullyReturns b1 && fullyReturns b2
fullyReturns _ = False


hasAssignmentCondition :: Inspection
hasAssignmentCondition = containsExpression f
where f (If (Unification _ _) _ _) = True
Expand Down
2 changes: 2 additions & 0 deletions src/Language/Mulang/Parsers/JavaScript.hs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ computationFor body | containsReturn body = Function
| otherwise = Procedure

containsReturn :: Expression -> Bool
containsReturn (Return None) = False
containsReturn (Return _) = True
containsReturn (If _ t e) = containsReturn t || containsReturn e
containsReturn (Sequence xs) = any containsReturn xs
containsReturn _ = False

Expand Down

0 comments on commit 9b5e014

Please sign in to comment.