packages feed

mulang 3.5.2 → 3.6.0

raw patch · 10 files changed

+223/−138 lines, 10 files

Files

mulang.cabal view
@@ -1,5 +1,5 @@ name:                mulang-version:             3.5.2+version:             3.6.0 synopsis:            An intermediate language designed to perform advanced code analysis description:         Mulang is an intermediate language, a combinators library for static code analysis and a multilanguage comand line tool license:             GPL@@ -28,6 +28,7 @@    exposed-modules:     Control.Fallible+    Data.List.Extra     Text.Dictionary     Text.SimpleParser     Text.Inflections.Tokenizer
+ src/Data/List/Extra.hs view
@@ -0,0 +1,5 @@+module Data.List.Extra (headOrElse) where++headOrElse:: a -> [a] -> a+headOrElse x []     = x+headOrElse _ (x:_)  = x
src/Language/Mulang/Analyzer/SmellsAnalyzer.hs view
@@ -52,6 +52,7 @@ detectionFor "DoesTypeTest"                    = simple doesTypeTest detectionFor "HasAssignmentReturn"             = simple hasAssignmentReturn detectionFor "HasCodeDuplication"              = unsupported+detectionFor "HasEmptyIfBranches"              = simple hasEmptyIfBranches detectionFor "HasLongParameterList"            = simple hasLongParameterList detectionFor "HasMisspelledIdentifiers"        = withLanguage hasMisspelledIdentifiers detectionFor "HasMisspelledBindings"           = withLanguage hasMisspelledIdentifiers
src/Language/Mulang/Ast.hs view
@@ -120,7 +120,7 @@     | Repeat Expression Expression     -- ^ Imperative programming fixed repetition control structure, composed by a repetition count expression, and a body     | Match Expression [Equation]-    | Switch Expression [(Expression, Expression)]+    | Switch Expression [(Expression, Expression)] Expression     | Try Expression [(Pattern, Expression)] Expression     -- ^ Generic try expression, composed by a body, a list of exception-handling patterns and statments, and a finally expression     | Raise Expression@@ -135,7 +135,9 @@     | NotEqual     | Self     | MuNull-    -- ^ Generic nothing value literal - nil, null, undefined or unit+    -- ^ Generic value indicating an absent expression, such as when there is no finally in a try or default in a switch or js' undefined+    | MuNil+    -- ^ Generic nothing value literal - nil, null or unit     | MuObject Expression     -- ^ Object oriented unnamed object literal     | MuNumber Double
src/Language/Mulang/Generator.hs view
@@ -74,7 +74,7 @@     subExpressions (Return v)              = [v]     subExpressions (Sequence es)           = es     subExpressions (Subroutine _ es)       = equationExpressions es-    subExpressions (Switch e1 list)        = e1 : concatMap (\(x,y) -> [x,y]) list+    subExpressions (Switch e1 list _)      = e1 : concatMap (\(x,y) -> [x,y]) list     subExpressions (Try t cs f)            = t : map snd cs ++ [f]     subExpressions (Variable _ v)          = [v]     subExpressions (While e1 e2)           = [e1, e2]
src/Language/Mulang/Inspector/Generic/Duplication.hs view
@@ -16,6 +16,7 @@ isLightweight (Reference _)             = True isLightweight Self                      = True isLightweight MuNull                    = True+isLightweight MuNil                     = True isLightweight Equal                     = True isLightweight (Application _ es)        = not $ any isApplication es isLightweight (Return e)                = isLightweight e
src/Language/Mulang/Inspector/Generic/Smell.hs view
@@ -6,6 +6,7 @@   hasRedundantParameter,   hasRedundantLocalVariableReturn,   hasAssignmentReturn,+  hasEmptyIfBranches,   doesNullTest,   doesTypeTest,   isLongCode,@@ -26,8 +27,8 @@  doesNullTest :: Inspection doesNullTest = compares f-  where f MuNull = True-        f _      = False+  where f MuNil = True+        f _     = False  doesTypeTest :: Inspection doesTypeTest = compares f@@ -48,8 +49,8 @@  returnsNull :: Inspection returnsNull = containsExpression f-  where f (Return MuNull) = True-        f _               = False+  where f (Return MuNil) = True+        f _              = False  -- | Inspection that tells whether an identifier has an if expression where both branches return -- boolean literals@@ -140,3 +141,8 @@                  isHash (HashMethod _) = True         isHash _ = False++hasEmptyIfBranches :: Inspection+hasEmptyIfBranches = containsExpression f+  where f (If _ MuNull elseBranch) = elseBranch /= MuNull+        f _                        = False
src/Language/Mulang/Inspector/Procedural.hs view
@@ -24,7 +24,7 @@ -- in its definition usesSwitch :: Inspection usesSwitch = containsExpression f-  where f (Switch _ _) = True+  where f (Switch _ _ _) = True         f _ = False  -- | Inspection that tells whether an expression uses reoeat
src/Language/Mulang/Parsers/Java.hs view
@@ -3,8 +3,8 @@  module Language.Mulang.Parsers.Java (java, parseJava) where -import Language.Mulang.Ast hiding (While, Return, Equal, Lambda, Try)-import qualified Language.Mulang.Ast as M (Expression(While, Return, Equal, Lambda, Try))+import Language.Mulang.Ast hiding (While, Return, Equal, Lambda, Try, Switch)+import qualified Language.Mulang.Ast as M (Expression(While, Return, Equal, Lambda, Try, Switch)) import Language.Mulang.Parsers import Language.Mulang.Builder (compact, compactMap, compactConcatMap) @@ -14,7 +14,8 @@ import Control.Fallible  import Data.Maybe (fromMaybe)-import Data.List (intercalate)+import Data.List (intercalate, partition)+import Data.List.Extra (headOrElse) import Data.Char (toLower)  java :: Parser@@ -86,7 +87,7 @@ muStmt (Throw exp)                     = Raise $ muExp exp muStmt (Try block catches finally)     = M.Try (muBlock block) (map muCatch catches) (fmapOrNull muBlock finally) --muStmt (EnhancedFor _ _ name gen body) = Other---Switch Exp [SwitchBlock]+muStmt (Switch exp cases)              = muSwitch exp . partition isDefault $ cases  muStmt _                               = Other  muExp (Lit lit)                         = muLit lit@@ -122,7 +123,7 @@ muLit (Float d)   = MuNumber d muLit (Double d)  = MuNumber d muLit (Boolean b) = MuBool   b-muLit Null        = MuNull+muLit Null        = MuNil muLit _           = Other  muOp Mult   = Reference "*"@@ -160,6 +161,15 @@ muRefType (ArrayType t)        = (muType t) ++ "[]"  muPrimType = map toLower . dropLast 1 . show++muSwitch exp (def, cases) =  M.Switch (muExp exp) (map muCase cases) (headOrElse MuNull . map muDefault $ def)++muCase (SwitchBlock (SwitchCase exp) block) = (muExp exp, compactConcatMap muBlockStmt block)++muDefault (SwitchBlock Default block) = compactConcatMap muBlockStmt block++isDefault (SwitchBlock Default _) = True+isDefault _                       = False  -- Combinators 
src/Language/Mulang/Parsers/JavaScript.hs view
@@ -8,6 +8,8 @@ import Language.JavaScript.Parser.AST  import Data.Either ()+import Data.List (partition)+import Data.List.Extra (headOrElse)  import Control.Fallible @@ -18,147 +20,204 @@ parseJavaScript = orNothing . parseJavaScript'  parseJavaScript' :: String -> Either String Expression-parseJavaScript' = fmap (normalize . mu) . (`parse` "src")+parseJavaScript' = fmap (normalize . muJSAST) . (`parse` "src") -mu :: JSNode -> Expression-mu = compact . muNode . gc-  where-    muNode (JSSourceElementsTop statements)                  = [compactMapMu statements]-    muNode (JSIdentifier "undefined")                        = [MuNull]-    muNode (JSIdentifier n)                                  = [Reference n]-    muNode (JSDecimal val)                                   = [MuNumber (read val)]-    muNode (JSExpression xs)                                 = [compactMapMu xs]-    muNode (JSLiteral "null")                                = [MuNull]-    muNode (JSLiteral "true")                                = [MuTrue]-    muNode (JSLiteral "false")                               = [MuFalse]-    muNode (JSLiteral _)                                     = []-    muNode (JSElision _)                                     = []-    muNode (JSHexInteger v)                                  = muNode (JSStringLiteral '\'' v)-    muNode (JSOctal v)                                       = muNode (JSStringLiteral '"' v)-    muNode (JSExpressionPostfix "++" [var] _)                = [muVarAssignment var (muPlus var (MuNumber 1))]-    muNode (JSExpressionPostfix "--" [var] _)                = [muVarAssignment var (muMinus var (MuNumber 1))]-    muNode (JSStringLiteral _ v)                             = [MuString v]-    muNode (JSVariables _ decls _)                           = mapMu decls-    muNode (JSArrayLiteral _ es _)                           = [MuList (mapMu es)]-    muNode (JSVarDecl var initial)                           = [muVarDeclaration var initial]-    muNode (JSWith _ _ _ _ _)                                = [Other]-    muNode (JSExpressionTernary cond _ true _ false)         = [muIf cond   true false]-    muNode (JSIf _ _ cond _ true false)                      = [muIf [cond] true false]-    muNode (JSWhile _ _ cond _ action)                       = [muWhile cond action]-    muNode (JSBlock _ exps _)                                = [compactMapMu exps]-    muNode (JSFunctionExpression _ [] _ params _ body)       = [Lambda (muParams params) (mu body)]-    muNode (JSFunctionExpression _ [name] _ params _ body)   = [muFunction  name params body]-    muNode (JSReturn _ e _)                                  = [Return (compactMapMu e)]-    muNode (JSExpressionParen _ e _)                         = [mu e]-    muNode (JSObjectLiteral _ es _)                          = [MuObject (compactMapMu es)]-    muNode (JSLabelled _ _ e)                                = [mu e]-    muNode (JSPropertyNameandValue var _ initial)            = [muVarDeclaration var initial]-    muNode (JSFunction _ name _ params _ body)               = [muFunction name params body]-    muNode (JSExpressionBinary op l _ r)                     = [Application (muOp op) [compactMapMu l, compactMapMu r]]-    muNode (JSMemberDot receptor _ selector)                 = [Send (compactMapMu receptor) (mu selector) []]-    muNode (JSThrow _ e)                                     = [Raise (mu e)]-    muNode e                                                 = [Other]+muJSAST:: JSAST -> Expression+muJSAST (JSAstProgram statements _)     = compactMap muJSStatement statements+muJSAST (JSAstStatement statement _)    = muJSStatement statement+muJSAST (JSAstExpression expression _)  = muJSExpression expression+muJSAST (JSAstLiteral expression _)     = muJSExpression expression  +muJSStatement:: JSStatement -> Expression+muJSStatement (JSStatementBlock _ statements _ _)                           = compactMap muJSStatement statements+--muJSStatement (JSConstant _ (JSCommaList JSExpression) _) -- ^const, decl, autosemi+muJSStatement (JSDoWhile _ statement _ _ expression _ _)                    = While (muJSExpression expression) (muJSStatement statement)+--muJSStatement (JSFor _ _ (JSCommaList JSExpression) _ (JSCommaList JSExpression) _ (JSCommaList JSExpression) _ JSStatement) -- ^for,lb,expr,semi,expr,semi,expr,rb.stmt+--muJSStatement (JSForIn _ _ (JSIdentifier _ name) _ JSExpression _ JSStatement)       = For [muJSExpression ]+--muJSStatement (JSForVar _ _ _ (JSCommaList JSExpression) _ (JSCommaList JSExpression) _ (JSCommaList JSExpression) _ JSStatement) -- ^for,lb,var,vardecl,semi,expr,semi,expr,rb,stmt+--muJSStatement (JSForVarIn _ _ _ JSExpression _ JSExpression _ JSStatement) -- ^for,lb,var,vardecl,in,expr,rb,stmt+muJSStatement (JSFunction _ ident _ params _ body _)                        = muComputation ident params body+muJSStatement (JSIf _ _ expression _ statement)                             = If (muJSExpression expression) (muJSStatement statement) MuNull+muJSStatement (JSIfElse _ _ expression _ ifStatement _ elseStatement)       = If (muJSExpression expression) (muJSStatement ifStatement) (muJSStatement elseStatement)+muJSStatement (JSLabelled _ _ statement)                                    = muJSStatement statement+muJSStatement (JSEmptyStatement _)                                          = MuNull+muJSStatement (JSExpressionStatement (JSIdentifier _ val) _)                = Reference val+muJSStatement (JSExpressionStatement expression _)                          = muJSExpression expression+muJSStatement (JSAssignStatement (JSIdentifier _ name) op value _)          = Assignment name (muJSAssignOp op name (muJSExpression value))+muJSStatement (JSMethodCall (JSMemberDot receptor _ message) _ params _ _)  = Send (muJSExpression receptor) (muJSExpression message) (map muJSExpression (muJSCommaList params))+muJSStatement (JSMethodCall ident _ params _ _)                             = Application (muJSExpression ident) (map muJSExpression (muJSCommaList params))+muJSStatement (JSReturn _ maybeExpression _)                                = Return (maybe MuNull muJSExpression maybeExpression)+muJSStatement (JSSwitch _ _ expression _ _ cases _ _)                       = muSwitch expression . partition isDefault $ cases+muJSStatement (JSThrow _ expression _)                                      = Raise (muJSExpression expression)+muJSStatement (JSTry _ block catches finally)                               = Try (muJSBlock block) (map muJSTryCatch catches) (muJSTryFinally finally)+muJSStatement (JSVariable _ list _)                                         = compactMap muJSExpression.muJSCommaList $ list+muJSStatement (JSWhile _ _ expression _ statement)                          = While (muJSExpression expression) (muJSStatement statement)+muJSStatement _                                                             = Other -    mapMu :: [JSNode] -> [Expression]-    mapMu [] = []-    mapMu (x:y:xs)   | (JSArguments _ args _) <- gc y =  [Application (mu x) (mapMu args)] ++ mapMu xs-    mapMu (x:y:z:xs) | (JSOperator (NT (JSLiteral "=") _ _))  <- gc y =  [muVarAssignment x (mu z)] ++ mapMu xs-                     | (JSOperator (NT (JSLiteral "+=") _ _))  <- gc y =  [muVarAssignment x (muPlus x (mu z))] ++ mapMu xs-    mapMu (x:xs) = (muNode.gc) x ++ mapMu xs+muSwitch expression (def, cases) = Switch (muJSExpression expression) (map muCase cases) (headOrElse MuNull . map muDefault $ def) -    muParams :: [JSNode] -> [Pattern]-    muParams params = concatMap (muPattern.gc) params+muCase (JSCase _ expression _ statements) = (muJSExpression expression, compactMap muJSStatement statements) -    muOp :: String -> Expression-    muOp "=="  = Equal-    muOp "===" = Equal-    muOp "!="  = NotEqual-    muOp "!==" = NotEqual-    muOp v    = Reference v+muDefault (JSDefault _ _ statements) = compactMap muJSStatement statements -    muPattern (JSLiteral _)    = []-    muPattern (JSIdentifier i) = [VariablePattern i]-    muPattern e                = error (show e)+muComputation JSIdentNone params body = Lambda (map muPattern (muJSCommaList params)) (muJSBlock body)+muComputation (JSIdentName _ name) params body = (computationFor (muJSBlock body)) name (muEquation (map muPattern (muJSCommaList params)) (muJSBlock body)) -    gc (NN n) = n-    gc (NT n _ _) = n+isDefault:: JSSwitchParts -> Bool+isDefault (JSDefault _ _ _) = True+isDefault _                 = False -    muId = f.gc-           where f (JSIdentifier id) = id+muPattern:: JSIdent -> Pattern+muPattern (JSIdentName _ name) = VariablePattern name +muEquation params body = [SimpleEquation params body] -    muEquation params body = [SimpleEquation params body]+computationFor :: Expression -> Identifier -> [Equation] -> Expression+computationFor body | containsReturn body = Function+                    | otherwise           = Procedure -    compactMapMu :: [JSNode] -> Expression-    compactMapMu  = compact . mapMu+containsReturn :: Expression -> Bool+containsReturn (Return _)    = True+containsReturn (Sequence xs) = any containsReturn xs+containsReturn _             = False -    muIf :: [JSNode] -> [JSNode] -> [JSNode] -> Expression-    muIf cond true false = If (compactMapMu cond) (compactMapMu true) (compactMapMu false) -    muWhile cond action  = While (mu cond) (mu action)+muJSExpression:: JSExpression -> Expression+muJSExpression (JSIdentifier _ "undefined")                         = MuNull+muJSExpression (JSIdentifier _ name)                                = Reference name+muJSExpression (JSDecimal _ val)                                    = MuNumber (read val)+muJSExpression (JSLiteral _ "null")                                 = MuNil+muJSExpression (JSLiteral _ "true")                                 = MuTrue+muJSExpression (JSLiteral _ "false")                                = MuFalse+--muJSExpression (JSHexInteger _ String)+--muJSExpression (JSOctal _ String)+muJSExpression (JSStringLiteral _ val)                              = MuString (removeQuotes val)+--muJSExpression (JSRegEx _ String)+muJSExpression (JSArrayLiteral _ list _)                            = MuList (muJSArrayList list)+muJSExpression (JSAssignExpression (JSIdentifier _ name) op value)  = Assignment name (muJSAssignOp op name.muJSExpression $ value)+--muJSExpression (JSCallExpression expression _ params _) = Application (muJSExpression expression) (map muJSExpression.muJSCommaList $ expressionList)+--muJSExpression (JSCallExpressionDot JSExpression _ JSExpression)  -- ^expr, dot, expr+--muJSExpression (JSCallExpressionSquare JSExpression _ JSExpression _)  -- ^expr, [, expr, ]+--muJSExpression (JSCommaExpression JSExpression _ JSExpression)          -- ^expression components+muJSExpression (JSExpressionBinary firstVal op secondVal)           = Application (muJSBinOp op) [muJSExpression firstVal, muJSExpression secondVal]+muJSExpression (JSExpressionParen _ expression _)                   = muJSExpression expression+muJSExpression (JSExpressionPostfix (JSIdentifier _ name) op)       = Assignment name (muJSUnaryOp op name)+muJSExpression (JSExpressionTernary condition _ trueVal _ falseVal) = If (muJSExpression condition) (muJSExpression trueVal) (muJSExpression falseVal)+muJSExpression (JSFunctionExpression _ ident _ params _ body)       = muComputation ident params body+--muJSExpression (JSMemberDot JSExpression _ JSExpression) -- ^firstpart, dot, name+muJSExpression (JSMemberExpression id _ params _)                   = Application (muJSExpression id) (map muJSExpression.muJSCommaList $ params)+muJSExpression (JSMemberNew _ (JSIdentifier _ name) _ args _)       = New name (map muJSExpression.muJSCommaList $ args)+--muJSExpression (JSMemberSquare JSExpression _ JSExpression _) -- ^firstpart, lb, expr, rb+muJSExpression (JSNewExpression _ (JSIdentifier _ name))            = New name []+muJSExpression (JSObjectLiteral _ propertyList _)                   = MuObject (compactMap id.map muJSObjectProperty.muJSCommaTrailingList $ propertyList)+muJSExpression (JSUnaryExpression op (JSIdentifier _ name))         = Assignment name (muJSUnaryOp op name)+muJSExpression (JSVarInitExpression (JSIdentifier _ name) initial)  = Variable name (muJSVarInitializer initial)+muJSExpression _ = Other -    muVarDeclaration var initial = Variable (muId var) (compactMapMu initial)-    muVarAssignment  var value  = Assignment (muId var)  value+removeQuotes = filter (flip notElem quoteMarks)+  where quoteMarks = "\"'" -    muPlus var delta = (Application (Reference "+") [Reference (muId var), delta])-    muMinus var delta = (Application (Reference "-") [Reference (muId var), delta])+muJSBinOp:: JSBinOp -> Expression+muJSBinOp (JSBinOpAnd _)        = Reference "&&"+muJSBinOp (JSBinOpBitAnd _)     = Reference "&"+muJSBinOp (JSBinOpBitOr _)      = Reference "|"+muJSBinOp (JSBinOpBitXor _)     = Reference "^"+muJSBinOp (JSBinOpDivide _)     = Reference "/"+muJSBinOp (JSBinOpEq _)         = Equal+muJSBinOp (JSBinOpGe _)         = Reference ">="+muJSBinOp (JSBinOpGt _)         = Reference ">"+muJSBinOp (JSBinOpInstanceOf _) = Reference "instanceof"+muJSBinOp (JSBinOpLe _)         = Reference "<="+muJSBinOp (JSBinOpLsh _)        = Reference "<<"+muJSBinOp (JSBinOpLt _)         = Reference "<"+muJSBinOp (JSBinOpMinus _)      = Reference "-"+muJSBinOp (JSBinOpMod _)        = Reference "%"+muJSBinOp (JSBinOpNeq _)        = NotEqual+muJSBinOp (JSBinOpOr _)         = Reference "||"+muJSBinOp (JSBinOpPlus _)       = Reference "+"+muJSBinOp (JSBinOpRsh _)        = Reference ">>"+muJSBinOp (JSBinOpStrictEq _)   = Equal+muJSBinOp (JSBinOpStrictNeq _)  = NotEqual+muJSBinOp (JSBinOpTimes _)      = Reference "*" -    muFunction :: JSNode -> [JSNode] -> JSNode -> Expression-    muFunction name params body = muComputation (muId name) (muParams params) (mu body)-                            where-                                muComputation name params body = (computationFor body) name (muEquation params body) -                                computationFor :: Expression -> Identifier -> [Equation] -> Expression-                                computationFor body | containsReturn body = Function-                                                    | otherwise = Procedure+muJSUnaryOp:: JSUnaryOp -> Identifier -> Expression+muJSUnaryOp (JSUnaryOpDecr _) r = (Application (Reference "-") [Reference r, MuNumber 1])+--muJSUnaryOp (JSUnaryOpDelete _)+muJSUnaryOp (JSUnaryOpIncr _) r = (Application (Reference "+") [Reference r, MuNumber 1])+--muJSUnaryOp (JSUnaryOpMinus _)+--muJSUnaryOp (JSUnaryOpNot _)+--muJSUnaryOp (JSUnaryOpPlus _)+--muJSUnaryOp (JSUnaryOpTilde _)+--muJSUnaryOp (JSUnaryOpTypeof _)+--muJSUnaryOp (JSUnaryOpVoid _)+muJSUnaryOp _ _                 = Other -                                containsReturn :: Expression -> Bool-                                containsReturn (Return _)    = True-                                containsReturn (Sequence xs) = any containsReturn xs-                                containsReturn _             = False+muJSAssignOp:: JSAssignOp -> Identifier -> Expression -> Expression+muJSAssignOp (JSAssign _) _ v = v+muJSAssignOp op r v           = (Application (muJSAssignOp' op) [Reference r, v]) -{-JSRegEx String-optional lb,optional block statements,optional rb-JSBreak JSNode [JSNode] JSNode-break, optional identifier, autosemi-JSCallExpression String [JSNode] [JSNode] [JSNode]-type : ., (), []; opening [ or ., contents, closing-JSCase JSNode JSNode JSNode [JSNode]-case,expr,colon,stmtlist-JSCatch JSNode JSNode JSNode [JSNode] JSNode JSNode-catch,lb,ident,[if,expr],rb,block-JSContinue JSNode [JSNode] JSNode-continue,optional identifier,autosemi-JSDefault JSNode JSNode [JSNode]-default,colon,stmtlist-JSDoWhile JSNode JSNode JSNode JSNode JSNode JSNode JSNode-do,stmt,while,lb,expr,rb,autosemi-JSExpressionPostfix String [JSNode] JSNode-type, expression, operator-JSExpressionTernary [JSNode] JSNode [JSNode] JSNode [JSNode]-cond, ?, trueval, :, falseval-JSFinally JSNode JSNode-finally,block-JSFor JSNode JSNode [JSNode] JSNode [JSNode] JSNode [JSNode] JSNode JSNode-for,lb,expr,semi,expr,semi,expr,rb.stmt-JSForIn JSNode JSNode [JSNode] JSNode JSNode JSNode JSNode-for,lb,expr,in,expr,rb,stmt-JSForVar JSNode JSNode JSNode [JSNode] JSNode [JSNode] JSNode [JSNode] JSNode JSNode-for,lb,var,vardecl,semi,expr,semi,expr,rb,stmt-JSForVarIn JSNode JSNode JSNode JSNode JSNode JSNode JSNode JSNode-for,lb,var,vardecl,in,expr,rb,stmt-JSMemberSquare [JSNode] JSNode JSNode JSNode-firstpart, lb, expr, rb-JSPropertyAccessor JSNode JSNode JSNode [JSNode] JSNode JSNode-(get|set), name, lb, params, rb, block-JSSwitch JSNode JSNode JSNode JSNode JSNode-switch,lb,expr,rb,caseblock-JSThrow JSNode JSNode-throw val-JSTry JSNode JSNode [JSNode]-try,block,rest-JSUnary String JSNode-type, operator- -}+muJSAssignOp':: JSAssignOp -> Expression+muJSAssignOp' (JSTimesAssign _)   = Reference "*"+muJSAssignOp' (JSDivideAssign _)  = Reference "/"+--muJSAssignOp' (JSModAssign _)+muJSAssignOp' (JSPlusAssign _)    = Reference "+"+muJSAssignOp' (JSMinusAssign _)   = Reference "-"+--muJSAssignOp' (JSLshAssign _)+--muJSAssignOp' (JSRshAssign _)+--muJSAssignOp' (JSUrshAssign _)+muJSAssignOp' (JSBwAndAssign _)   = Reference "&"+muJSAssignOp' (JSBwXorAssign _)   = Reference "^"+muJSAssignOp' (JSBwOrAssign _)    = Reference "|"+muJSAssignOp' _                   = Other++muJSTryCatch:: JSTryCatch -> (Pattern, Expression)+--muJSTryCatch JSCatch _ _ JSExpression _ JSBlock -- ^catch,lb,ident,rb,block+--muJSTryCatch JSCatchIf _ _ JSExpression _ JSExpression _ JSBlock -- ^catch,lb,ident,if,expr,rb,block+muJSTryCatch _ = (WildcardPattern, Other)++muJSTryFinally:: JSTryFinally -> Expression+muJSTryFinally (JSFinally _ block)   = muJSBlock block+muJSTryFinally JSNoFinally           = MuNull++muJSBlock:: JSBlock -> Expression+muJSBlock (JSBlock _ statements _)   = compactMap muJSStatement statements++muJSVarInitializer:: JSVarInitializer -> Expression+muJSVarInitializer (JSVarInit _ expression) = muJSExpression expression+--muJSVarInitializer JSVarInitNone+muJSVarInitializer _                        = Other+++muJSObjectProperty:: JSObjectProperty -> Expression+--muJSObjectProperty JSPropertyAccessor JSAccessor JSPropertyName _ [JSExpression] _ JSBlock -- ^(get|set), name, lb, params, rb, block+muJSObjectProperty (JSPropertyNameandValue id _ [JSFunctionExpression _ _ _ params _ block])   = Method (muJSPropertyName id) (muEquation (map muPattern (muJSCommaList params)) (muJSBlock block))+muJSObjectProperty (JSPropertyNameandValue id _ [expression])                                  = Variable (muJSPropertyName id) (muJSExpression expression)+muJSObjectProperty _ = Other++muJSPropertyName:: JSPropertyName -> Identifier+muJSPropertyName = removeQuotes.muJSPropertyName'++muJSPropertyName':: JSPropertyName -> Identifier+muJSPropertyName' (JSPropertyIdent _ name)   = name+muJSPropertyName' (JSPropertyString _ name)  = name+muJSPropertyName' (JSPropertyNumber _ name)  = name++muJSAccessor:: JSAccessor -> Expression+--muJSAccessor JSAccessorGet _+--muJSAccessor JSAccessorSet _+muJSAccessor _ = Other++muJSArrayList:: [JSArrayElement] -> [Expression]+muJSArrayList list = [muJSExpression expression | (JSArrayElement expression) <- list]++muJSCommaList:: JSCommaList a -> [a]+muJSCommaList (JSLCons xs _ x)   = muJSCommaList xs ++ [x]+muJSCommaList (JSLOne x)         = [x]+muJSCommaList JSLNil             = []++muJSCommaTrailingList:: JSCommaTrailingList a -> [a]+muJSCommaTrailingList (JSCTLComma list _) = muJSCommaList list+muJSCommaTrailingList (JSCTLNone list)    = muJSCommaList list+