Skip to content

Commit b9d1cae

Browse files
committed
Implementing broken return expectation
1 parent 2eb86b2 commit b9d1cae

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

spec/JavaScriptSpec.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ spec = do
3838
it "differentiates procedures and functions" $ do
3939
(js "function f() { return 1 }" /= js "function f() { 1 }") `shouldBe` True
4040

41+
it "differentiates procedures and functions with returns in if" $ do
42+
(js "function f(){ if (x) { } else { return 4 } }") `shouldBe` (SimpleFunction "f" [] (If (Reference "x") None (Return (MuNumber 4.0))))
43+
4144
it "handles lambdas likes haskell does" $ do
4245
js "var m = function(x) { return 1 }" `shouldBe` hs "m = \\x -> 1"
4346

spec/SmellSpec.hs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,40 @@ spec = do
118118
it "is False when local variable is used as a cache" $ do
119119
hasRedundantLocalVariableReturn (js "function x(m) { var x = 5; var y = 1 + x; g(y); return x; }") `shouldBe` False
120120

121+
describe "hasBrokenReturn" $ do
122+
it "is False when there are no functions" $ do
123+
hasBrokenReturn (js "let y = 0; if (x) { y = 0 } ") `shouldBe` False
124+
125+
it "is False when there is a function that has only a return" $ do
126+
hasBrokenReturn (js "function f(){ return 4 } ") `shouldBe` False
127+
128+
it "is False when there is a function that has a single flow and return" $ do
129+
hasBrokenReturn (js "function f(){ console.log(2); return 4 } ") `shouldBe` False
130+
131+
it "is False when there is a function that has an if with no returns " $ do
132+
hasBrokenReturn (js "function f(){ if (x) { console.log(4) } else { console.log(5) } return 4 } ") `shouldBe` False
133+
134+
it "is False when there is a function that has an if with no returns and no else " $ do
135+
hasBrokenReturn (js "function f(){ if (x) { console.log(4) } return 4 } ") `shouldBe` False
136+
137+
it "is True when there is a function that has an if with a return and no else and not trailing return " $ do
138+
hasBrokenReturn (js "function f(){ if (x) { return 4 } } ") `shouldBe` True
139+
140+
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
141+
hasBrokenReturn (js "function f(){ if (x) { } else { return 4 } }") `shouldBe` True
142+
143+
it "is True when there is a function that nested ifs with incomplete return and no trailing return " $ do
144+
hasBrokenReturn (js "function f(){ if (x) { if (y) { return 5 } } else { return 4 } }") `shouldBe` True
145+
146+
it "is False when there is a function that has an if with a return and no else and trailing return " $ do
147+
hasBrokenReturn (js "function f(){ if (x) { return 4 } return 5; } ") `shouldBe` False
148+
149+
it "is False when there is a function that has an if with a return in else but not then and trailing return " $ do
150+
hasBrokenReturn (js "function f(){ if (x) { } else { return 4 } return 5; } ") `shouldBe` False
151+
152+
it "is False when there is a function that nested ifs with complete return and no trailing return " $ do
153+
hasBrokenReturn (js "function f(){ if (x) { if (y) { return 5 } else { return 6 } } else { return 4 } }") `shouldBe` False
154+
121155

122156
describe "hasAssignmentCondition" $ do
123157
it "is True when assigns within an if condition" $ do

src/Language/Mulang/Inspector/Generic/Smell.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module Language.Mulang.Inspector.Generic.Smell (
55
doesConsolePrint,
66
doesNilTest,
77
doesTypeTest,
8+
hasBrokenReturn,
89
hasAssignmentReturn,
910
hasAssignmentCondition,
1011
hasEmptyIfBranches,
@@ -131,6 +132,21 @@ hasRedundantLocalVariableReturn = containsExpression f
131132
Return (Reference returnedVariable)]) = returnedVariable == declaredVariable
132133
f _ = False
133134

135+
hasBrokenReturn :: Inspection
136+
hasBrokenReturn = containsDeclaration f
137+
where
138+
f (SimpleFunction _ _ body) = not . fullyReturns $ body
139+
f _ = False
140+
141+
fullyReturns :: Expression -> Bool
142+
fullyReturns (Sequence (Return _:_)) = True
143+
fullyReturns (Sequence (If _ b1 b2:es)) = fullyReturns b1 && fullyReturns b2 || fullyReturns (Sequence es)
144+
fullyReturns (Sequence (_:es)) = fullyReturns (Sequence es)
145+
fullyReturns (Return _) = True
146+
fullyReturns (If _ b1 b2) = fullyReturns b1 && fullyReturns b2
147+
fullyReturns _ = False
148+
149+
134150
hasAssignmentCondition :: Inspection
135151
hasAssignmentCondition = containsExpression f
136152
where f (If (Unification _ _) _ _) = True

src/Language/Mulang/Parsers/JavaScript.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ computationFor body | containsReturn body = Function
121121
| otherwise = Procedure
122122

123123
containsReturn :: Expression -> Bool
124+
containsReturn (Return None) = False
124125
containsReturn (Return _) = True
126+
containsReturn (If _ t e) = containsReturn t || containsReturn e
125127
containsReturn (Sequence xs) = any containsReturn xs
126128
containsReturn _ = False
127129

0 commit comments

Comments
 (0)