{-# LANGUAGE CPP, FlexibleInstances #-}
module Language.JavaScript.Process.Minify
(
minifyJS
) where
import Control.Applicative ((<$>))
import Language.JavaScript.Parser.AST
import Language.JavaScript.Parser.SrcLocation
import Language.JavaScript.Parser.Token
minifyJS :: JSAST -> JSAST
minifyJS (JSAstProgram xs _) = JSAstProgram (fixStatementList noSemi xs) emptyAnnot
minifyJS (JSAstModule xs _) = JSAstModule (map (fix emptyAnnot) xs) emptyAnnot
minifyJS (JSAstStatement (JSStatementBlock _ [s] _ _) _) = JSAstStatement (fixStmtE noSemi s) emptyAnnot
minifyJS (JSAstStatement s _) = JSAstStatement (fixStmtE noSemi s) emptyAnnot
minifyJS (JSAstExpression e _) = JSAstExpression (fixEmpty e) emptyAnnot
minifyJS (JSAstLiteral s _) = JSAstLiteral (fixEmpty s) emptyAnnot
class MinifyJS a where
fix :: JSAnnot -> a -> a
fixEmpty :: MinifyJS a => a -> a
fixEmpty = fix emptyAnnot
fixSpace :: MinifyJS a => a -> a
fixSpace = fix spaceAnnot
fixStmt :: JSAnnot -> JSSemi -> JSStatement -> JSStatement
fixStmt a s (JSStatementBlock _lb ss _rb _) = fixStatementBlock a s ss
fixStmt a s (JSBreak _ i _) = JSBreak a (fixSpace i) s
fixStmt a s (JSConstant _ ss _) = JSConstant a (fixVarList ss) s
fixStmt a s (JSContinue _ i _) = JSContinue a (fixSpace i) s
fixStmt a s (JSDoWhile _ st _ _ e _ _) = JSDoWhile a (mkStatementBlock noSemi st) emptyAnnot emptyAnnot (fixEmpty e) emptyAnnot s
fixStmt a s (JSFor _ _ el1 _ el2 _ el3 _ st) = JSFor a emptyAnnot (fixEmpty el1) emptyAnnot (fixEmpty el2) emptyAnnot (fixEmpty el3) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForIn _ _ e1 op e2 _ st) = JSForIn a emptyAnnot (fixEmpty e1) (fixSpace op) (fixSpace e2) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForVar _ _ _ el1 _ el2 _ el3 _ st) = JSForVar a emptyAnnot spaceAnnot (fixEmpty el1) emptyAnnot (fixEmpty el2) emptyAnnot (fixEmpty el3) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForVarIn _ _ _ e1 op e2 _ st) = JSForVarIn a emptyAnnot spaceAnnot (fixEmpty e1) (fixSpace op) (fixSpace e2) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForLet _ _ _ el1 _ el2 _ el3 _ st) = JSForLet a emptyAnnot spaceAnnot (fixEmpty el1) emptyAnnot (fixEmpty el2) emptyAnnot (fixEmpty el3) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForLetIn _ _ _ e1 op e2 _ st) = JSForLetIn a emptyAnnot spaceAnnot (fixEmpty e1) (fixSpace op) (fixSpace e2) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForLetOf _ _ _ e1 op e2 _ st) = JSForLetOf a emptyAnnot spaceAnnot (fixEmpty e1) (fixSpace op) (fixSpace e2) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForOf _ _ e1 op e2 _ st) = JSForOf a emptyAnnot (fixEmpty e1) (fixSpace op) (fixSpace e2) emptyAnnot (fixStmtE s st)
fixStmt a s (JSForVarOf _ _ _ e1 op e2 _ st) = JSForVarOf a emptyAnnot spaceAnnot (fixEmpty e1) (fixSpace op) (fixSpace e2) emptyAnnot (fixStmtE s st)
fixStmt a s (JSFunction _ n _ ps _ blk _) = JSFunction a (fixSpace n) emptyAnnot (fixEmpty ps) emptyAnnot (fixEmpty blk) s
fixStmt a s (JSIf _ _ e _ st) = JSIf a emptyAnnot (fixEmpty e) emptyAnnot (fixIfElseBlock emptyAnnot s st)
fixStmt a s (JSIfElse _ _ e _ (JSEmptyStatement _) _ sf) = JSIfElse a emptyAnnot (fixEmpty e) emptyAnnot (JSEmptyStatement emptyAnnot) emptyAnnot (fixStmt spaceAnnot s sf)
fixStmt a s (JSIfElse _ _ e _ st _ sf) = JSIfElse a emptyAnnot (fixEmpty e) emptyAnnot (mkStatementBlock noSemi st) emptyAnnot (fixIfElseBlock spaceAnnot s sf)
fixStmt a s (JSLabelled e _ st) = JSLabelled (fix a e) emptyAnnot (fixStmtE s st)
fixStmt a s (JSLet _ xs _) = JSLet a (fixVarList xs) s
fixStmt _ _ (JSEmptyStatement _) = JSEmptyStatement emptyAnnot
fixStmt a s (JSExpressionStatement e _) = JSExpressionStatement (fix a e) s
fixStmt a s (JSAssignStatement lhs op rhs _) = JSAssignStatement (fix a lhs) (fixEmpty op) (fixEmpty rhs) s
fixStmt a s (JSMethodCall e _ args _ _) = JSMethodCall (fix a e) emptyAnnot (fixEmpty args) emptyAnnot s
fixStmt a s (JSReturn _ me _) = JSReturn a (fixSpace me) s
fixStmt a s (JSSwitch _ _ e _ _ sps _ _) = JSSwitch a emptyAnnot (fixEmpty e) emptyAnnot emptyAnnot (fixSwitchParts sps) emptyAnnot s
fixStmt a s (JSThrow _ e _) = JSThrow a (fixSpace e) s
fixStmt a _ (JSTry _ b tc tf) = JSTry a (fixEmpty b) (map fixEmpty tc) (fixEmpty tf)
fixStmt a s (JSVariable _ ss _) = JSVariable a (fixVarList ss) s
fixStmt a s (JSWhile _ _ e _ st) = JSWhile a emptyAnnot (fixEmpty e) emptyAnnot (fixStmt a s st)
fixStmt a s (JSWith _ _ e _ st _) = JSWith a emptyAnnot (fixEmpty e) emptyAnnot (fixStmtE noSemi st) s
fixIfElseBlock :: JSAnnot -> JSSemi -> JSStatement -> JSStatement
fixIfElseBlock _ _ (JSStatementBlock _ [] _ _) = JSEmptyStatement emptyAnnot
fixIfElseBlock a s st = fixStmt a s st
fixStmtE :: JSSemi -> JSStatement -> JSStatement
fixStmtE = fixStmt emptyAnnot
mkStatementBlock :: JSSemi -> JSStatement -> JSStatement
mkStatementBlock s (JSStatementBlock _ blk _ _) = JSStatementBlock emptyAnnot (fixStatementList noSemi blk) emptyAnnot s
mkStatementBlock s x = JSStatementBlock emptyAnnot [fixStmtE noSemi x] emptyAnnot s
fixStatementBlock :: JSAnnot -> JSSemi -> [JSStatement] -> JSStatement
fixStatementBlock a s ss =
case filter (not . isEmpty) ss of
[] -> JSStatementBlock emptyAnnot [] emptyAnnot s
[sx] -> fixStmt a s sx
sss -> JSStatementBlock emptyAnnot (fixStatementList noSemi sss) emptyAnnot s
where
isEmpty (JSEmptyStatement _) = True
isEmpty (JSStatementBlock _ [] _ _) = True
isEmpty _ = False
fixStatementList :: JSSemi -> [JSStatement] -> [JSStatement]
fixStatementList trailingSemi =
fixList emptyAnnot trailingSemi . filter (not . isRedundant)
where
isRedundant (JSStatementBlock _ [] _ _) = True
isRedundant (JSEmptyStatement _) = True
isRedundant _ = False
fixList _ _ [] = []
fixList a s [JSStatementBlock _ blk _ _] = fixList a s blk
fixList a s [x] = [fixStmt a s x]
fixList _ s (JSStatementBlock _ blk _ _:xs) = fixList emptyAnnot semi (filter (not . isRedundant) blk) ++ fixList emptyAnnot s xs
fixList a s (JSConstant _ vs1 _:JSConstant _ vs2 _: xs) = fixList a s (JSConstant spaceAnnot (concatCommaList vs1 vs2) s : xs)
fixList a s (JSVariable _ vs1 _:JSVariable _ vs2 _: xs) = fixList a s (JSVariable spaceAnnot (concatCommaList vs1 vs2) s : xs)
fixList a s (x1@JSFunction{}:x2@JSFunction{}:xs) = fixStmt a noSemi x1 : fixList newlineAnnot s (x2:xs)
fixList a s (x:xs) = fixStmt a semi x : fixList emptyAnnot s xs
concatCommaList :: JSCommaList a -> JSCommaList a -> JSCommaList a
concatCommaList xs JSLNil = xs
concatCommaList JSLNil ys = ys
concatCommaList xs (JSLOne y) = JSLCons xs emptyAnnot y
concatCommaList xs ys =
let recurse (z, zs) = concatCommaList (JSLCons xs emptyAnnot z) zs
in maybe xs recurse $ headCommaList ys
headCommaList :: JSCommaList a -> Maybe (a, JSCommaList a)
headCommaList JSLNil = Nothing
headCommaList (JSLOne x) = Just (x, JSLNil)
headCommaList (JSLCons (JSLOne x) _ y) = Just (x, JSLOne y)
headCommaList (JSLCons xs _ y) =
let rebuild (x, ys) = (x, JSLCons ys emptyAnnot y)
in rebuild <$> headCommaList xs
instance MinifyJS JSExpression where
fix a (JSIdentifier _ s) = JSIdentifier a s
fix a (JSDecimal _ s) = JSDecimal a s
fix a (JSLiteral _ s) = JSLiteral a s
fix a (JSHexInteger _ s) = JSHexInteger a s
fix a (JSOctal _ s) = JSOctal a s
fix _ (JSStringLiteral _ s) = JSStringLiteral emptyAnnot s
fix _ (JSRegEx _ s) = JSRegEx emptyAnnot s
fix _ (JSArrayLiteral _ xs _) = JSArrayLiteral emptyAnnot (map fixEmpty xs) emptyAnnot
fix _ (JSArrowExpression _ ps _ _ ss) = JSArrowExpression emptyAnnot (fixEmpty ps) emptyAnnot emptyAnnot (fixStmt emptyAnnot noSemi ss)
fix a (JSAssignExpression lhs op rhs) = JSAssignExpression (fix a lhs) (fixEmpty op) (fixEmpty rhs)
fix a (JSCallExpression ex _ xs _) = JSCallExpression (fix a ex) emptyAnnot (fixEmpty xs) emptyAnnot
fix a (JSCallExpressionDot ex _ xs) = JSCallExpressionDot (fix a ex) emptyAnnot (fixEmpty xs)
fix a (JSCallExpressionSquare ex _ xs _) = JSCallExpressionSquare (fix a ex) emptyAnnot (fixEmpty xs) emptyAnnot
fix a (JSCommaExpression le _ re) = JSCommaExpression (fix a le) emptyAnnot (fixEmpty re)
fix a (JSExpressionBinary lhs op rhs) = fixBinOpExpression a op lhs rhs
fix _ (JSExpressionParen _ e _) = JSExpressionParen emptyAnnot (fixEmpty e) emptyAnnot
fix a (JSExpressionPostfix e op) = JSExpressionPostfix (fix a e) (fixEmpty op)
fix a (JSExpressionTernary cond _ v1 _ v2) = JSExpressionTernary (fix a cond) emptyAnnot (fixEmpty v1) emptyAnnot (fixEmpty v2)
fix a (JSFunctionExpression _ n _ x2s _ x3) = JSFunctionExpression a (fixSpace n) emptyAnnot (fixEmpty x2s) emptyAnnot (fixEmpty x3)
fix a (JSMemberDot xs _ n) = JSMemberDot (fix a xs) emptyAnnot (fixEmpty n)
fix a (JSMemberExpression e _ args _) = JSMemberExpression (fix a e) emptyAnnot (fixEmpty args) emptyAnnot
fix a (JSMemberNew _ n _ s _) = JSMemberNew a (fix spaceAnnot n) emptyAnnot (fixEmpty s) emptyAnnot
fix a (JSMemberSquare xs _ e _) = JSMemberSquare (fix a xs) emptyAnnot (fixEmpty e) emptyAnnot
fix a (JSNewExpression _ e) = JSNewExpression a (fixSpace e)
fix _ (JSObjectLiteral _ xs _) = JSObjectLiteral emptyAnnot (fixEmpty xs) emptyAnnot
fix a (JSUnaryExpression op x) = let (ta, fop) = fixUnaryOp a op in JSUnaryExpression fop (fix ta x)
fix a (JSVarInitExpression x1 x2) = JSVarInitExpression (fix a x1) (fixEmpty x2)
fix a (JSSpreadExpression _ e) = JSSpreadExpression a (fixEmpty e)
fixVarList :: JSCommaList JSExpression -> JSCommaList JSExpression
fixVarList (JSLCons h _ v) = JSLCons (fixVarList h) emptyAnnot (fixEmpty v)
fixVarList (JSLOne a) = JSLOne (fixSpace a)
fixVarList JSLNil = JSLNil
fixBinOpExpression :: JSAnnot -> JSBinOp -> JSExpression -> JSExpression -> JSExpression
fixBinOpExpression a (JSBinOpPlus _) lhs rhs = fixBinOpPlus a lhs rhs
fixBinOpExpression a (JSBinOpIn _) lhs rhs = JSExpressionBinary (fix a lhs) (JSBinOpIn spaceAnnot) (fix spaceAnnot rhs)
fixBinOpExpression a (JSBinOpInstanceOf _) lhs rhs = JSExpressionBinary (fix a lhs) (JSBinOpInstanceOf spaceAnnot) (fix spaceAnnot rhs)
fixBinOpExpression a op lhs rhs = JSExpressionBinary (fix a lhs) (fixEmpty op) (fixEmpty rhs)
fixBinOpPlus :: JSAnnot -> JSExpression -> JSExpression -> JSExpression
fixBinOpPlus a lhs rhs =
case (fix a lhs, fixEmpty rhs) of
(JSStringLiteral _ s1, JSStringLiteral _ s2) -> stringLitConcat (normalizeToSQ s1) (normalizeToSQ s2)
(nlhs, nrhs) -> JSExpressionBinary nlhs (JSBinOpPlus emptyAnnot) nrhs
stringLitConcat :: String -> String -> JSExpression
stringLitConcat xs [] = JSStringLiteral emptyAnnot xs
stringLitConcat [] ys = JSStringLiteral emptyAnnot ys
stringLitConcat xall (_:yss) =
JSStringLiteral emptyAnnot (init xall ++ init yss ++ "'")
normalizeToSQ :: String -> String
normalizeToSQ str =
case str of
[] -> []
('\'' : _) -> str
('"' : xs) -> '\'' : convertSQ xs
other -> other
where
convertSQ [] = []
convertSQ [_] = "'"
convertSQ ('\'':xs) = '\\' : '\'' : convertSQ xs
convertSQ ('\\':'\"':xs) = '"' : convertSQ xs
convertSQ (x:xs) = x : convertSQ xs
instance MinifyJS JSBinOp where
fix _ (JSBinOpAnd _) = JSBinOpAnd emptyAnnot
fix a (JSBinOpAs _) = JSBinOpAs a
fix _ (JSBinOpBitAnd _) = JSBinOpBitAnd emptyAnnot
fix _ (JSBinOpBitOr _) = JSBinOpBitOr emptyAnnot
fix _ (JSBinOpBitXor _) = JSBinOpBitXor emptyAnnot
fix _ (JSBinOpDivide _) = JSBinOpDivide emptyAnnot
fix _ (JSBinOpEq _) = JSBinOpEq emptyAnnot
fix _ (JSBinOpGe _) = JSBinOpGe emptyAnnot
fix _ (JSBinOpGt _) = JSBinOpGt emptyAnnot
fix a (JSBinOpIn _) = JSBinOpIn a
fix a (JSBinOpInstanceOf _) = JSBinOpInstanceOf a
fix _ (JSBinOpLe _) = JSBinOpLe emptyAnnot
fix _ (JSBinOpLsh _) = JSBinOpLsh emptyAnnot
fix _ (JSBinOpLt _) = JSBinOpLt emptyAnnot
fix _ (JSBinOpMinus _) = JSBinOpMinus emptyAnnot
fix _ (JSBinOpMod _) = JSBinOpMod emptyAnnot
fix _ (JSBinOpNeq _) = JSBinOpNeq emptyAnnot
fix a (JSBinOpOf _) = JSBinOpOf a
fix _ (JSBinOpOr _) = JSBinOpOr emptyAnnot
fix _ (JSBinOpPlus _) = JSBinOpPlus emptyAnnot
fix _ (JSBinOpRsh _) = JSBinOpRsh emptyAnnot
fix _ (JSBinOpStrictEq _) = JSBinOpStrictEq emptyAnnot
fix _ (JSBinOpStrictNeq _) = JSBinOpStrictNeq emptyAnnot
fix _ (JSBinOpTimes _) = JSBinOpTimes emptyAnnot
fix _ (JSBinOpUrsh _) = JSBinOpUrsh emptyAnnot
instance MinifyJS JSUnaryOp where
fix _ (JSUnaryOpDecr _) = JSUnaryOpDecr emptyAnnot
fix _ (JSUnaryOpDelete _) = JSUnaryOpDelete emptyAnnot
fix _ (JSUnaryOpIncr _) = JSUnaryOpIncr emptyAnnot
fix _ (JSUnaryOpMinus _) = JSUnaryOpMinus emptyAnnot
fix _ (JSUnaryOpNot _) = JSUnaryOpNot emptyAnnot
fix _ (JSUnaryOpPlus _) = JSUnaryOpPlus emptyAnnot
fix _ (JSUnaryOpTilde _) = JSUnaryOpTilde emptyAnnot
fix _ (JSUnaryOpTypeof _) = JSUnaryOpTypeof emptyAnnot
fix _ (JSUnaryOpVoid _) = JSUnaryOpVoid emptyAnnot
fixUnaryOp :: JSAnnot -> JSUnaryOp -> (JSAnnot, JSUnaryOp)
fixUnaryOp a (JSUnaryOpDelete _) = (spaceAnnot, JSUnaryOpDelete a)
fixUnaryOp a (JSUnaryOpTypeof _) = (spaceAnnot, JSUnaryOpTypeof a)
fixUnaryOp a (JSUnaryOpVoid _) = (spaceAnnot, JSUnaryOpVoid a)
fixUnaryOp a x = (emptyAnnot, fix a x)
instance MinifyJS JSAssignOp where
fix a (JSAssign _) = JSAssign a
fix a (JSTimesAssign _) = JSTimesAssign a
fix a (JSDivideAssign _) = JSDivideAssign a
fix a (JSModAssign _) = JSModAssign a
fix a (JSPlusAssign _) = JSPlusAssign a
fix a (JSMinusAssign _) = JSMinusAssign a
fix a (JSLshAssign _) = JSLshAssign a
fix a (JSRshAssign _) = JSRshAssign a
fix a (JSUrshAssign _) = JSUrshAssign a
fix a (JSBwAndAssign _) = JSBwAndAssign a
fix a (JSBwXorAssign _) = JSBwXorAssign a
fix a (JSBwOrAssign _) = JSBwOrAssign a
instance MinifyJS JSModuleItem where
fix _ (JSModuleImportDeclaration _ x1) = JSModuleImportDeclaration emptyAnnot (fixEmpty x1)
fix _ (JSModuleExportDeclaration _ x1) = JSModuleExportDeclaration emptyAnnot (fixEmpty x1)
fix a (JSModuleStatementListItem s) = JSModuleStatementListItem (fixStmt a noSemi s)
instance MinifyJS JSImportDeclaration where
fix _ (JSImportDeclaration imps from _) = JSImportDeclaration (fixEmpty imps) (fix annot from) noSemi
where
annot = case imps of
JSImportClauseDefault {} -> spaceAnnot
JSImportClauseNameSpace {} -> spaceAnnot
JSImportClauseNamed {} -> emptyAnnot
JSImportClauseDefaultNameSpace {} -> spaceAnnot
JSImportClauseDefaultNamed {} -> emptyAnnot
instance MinifyJS JSImportClause where
fix _ (JSImportClauseDefault n) = JSImportClauseDefault (fixSpace n)
fix _ (JSImportClauseNameSpace ns) = JSImportClauseNameSpace (fixSpace ns)
fix _ (JSImportClauseNamed named) = JSImportClauseNamed (fixEmpty named)
fix _ (JSImportClauseDefaultNameSpace def _ ns) = JSImportClauseDefaultNameSpace (fixSpace def) emptyAnnot (fixEmpty ns)
fix _ (JSImportClauseDefaultNamed def _ ns) = JSImportClauseDefaultNamed (fixSpace def) emptyAnnot (fixEmpty ns)
instance MinifyJS JSFromClause where
fix a (JSFromClause _ _ m) = JSFromClause a emptyAnnot m
instance MinifyJS JSImportNameSpace where
fix a (JSImportNameSpace _ _ ident) = JSImportNameSpace (JSBinOpTimes a) (JSBinOpAs spaceAnnot) (fixSpace ident)
instance MinifyJS JSImportsNamed where
fix _ (JSImportsNamed _ imps _) = JSImportsNamed emptyAnnot (fixEmpty imps) emptyAnnot
instance MinifyJS JSImportSpecifier where
fix _ (JSImportSpecifier x1) = JSImportSpecifier (fixEmpty x1)
fix _ (JSImportSpecifierAs x1 as x2) = JSImportSpecifierAs (fixEmpty x1) (fixSpace as) (fixSpace x2)
instance MinifyJS JSExportDeclaration where
fix _ (JSExportLocals _ x1 _ _) = JSExportLocals emptyAnnot (fixEmpty x1) emptyAnnot noSemi
fix _ (JSExport x1 _) = JSExport (fixStmt emptyAnnot noSemi x1) noSemi
instance MinifyJS JSExportLocalSpecifier where
fix _ (JSExportLocalSpecifier x1) = JSExportLocalSpecifier (fixEmpty x1)
fix _ (JSExportLocalSpecifierAs x1 as x2) = JSExportLocalSpecifierAs (fixEmpty x1) (fixSpace as) (fixSpace x2)
instance MinifyJS JSTryCatch where
fix a (JSCatch _ _ x1 _ x3) = JSCatch a emptyAnnot (fixEmpty x1) emptyAnnot (fixEmpty x3)
fix a (JSCatchIf _ _ x1 _ ex _ x3) = JSCatchIf a emptyAnnot (fixEmpty x1) spaceAnnot (fixSpace ex) emptyAnnot (fixEmpty x3)
instance MinifyJS JSTryFinally where
fix a (JSFinally _ x) = JSFinally a (fixEmpty x)
fix _ JSNoFinally = JSNoFinally
fixSwitchParts :: [JSSwitchParts] -> [JSSwitchParts]
fixSwitchParts parts =
case parts of
[] -> []
[x] -> [fixPart noSemi x]
(x:xs) -> fixPart semi x : fixSwitchParts xs
where
fixPart s (JSCase _ e _ ss) = JSCase emptyAnnot (fixCase e) emptyAnnot (fixStatementList s ss)
fixPart s (JSDefault _ _ ss) = JSDefault emptyAnnot emptyAnnot (fixStatementList s ss)
fixCase :: JSExpression -> JSExpression
fixCase (JSStringLiteral _ s) = JSStringLiteral emptyAnnot s
fixCase e = fix spaceAnnot e
instance MinifyJS JSBlock where
fix _ (JSBlock _ ss _) = JSBlock emptyAnnot (fixStatementList noSemi ss) emptyAnnot
instance MinifyJS JSObjectProperty where
fix a (JSPropertyAccessor s n _ ps _ b) = JSPropertyAccessor (fix a s) (fixSpace n) emptyAnnot (map fixEmpty ps) emptyAnnot (fixEmpty b)
fix a (JSPropertyNameandValue n _ vs) = JSPropertyNameandValue (fix a n) emptyAnnot (map fixEmpty vs)
instance MinifyJS JSPropertyName where
fix a (JSPropertyIdent _ s) = JSPropertyIdent a s
fix a (JSPropertyString _ s) = JSPropertyString a s
fix a (JSPropertyNumber _ s) = JSPropertyNumber a s
instance MinifyJS JSAccessor where
fix a (JSAccessorGet _) = JSAccessorGet a
fix a (JSAccessorSet _) = JSAccessorSet a
instance MinifyJS JSArrayElement where
fix _ (JSArrayElement e) = JSArrayElement (fixEmpty e)
fix _ (JSArrayComma _) = JSArrayComma emptyAnnot
instance MinifyJS a => MinifyJS (JSCommaList a) where
fix _ (JSLCons xs _ x) = JSLCons (fixEmpty xs) emptyAnnot (fixEmpty x)
fix _ (JSLOne a) = JSLOne (fixEmpty a)
fix _ JSLNil = JSLNil
instance MinifyJS a => MinifyJS (JSCommaTrailingList a) where
fix _ (JSCTLComma xs _) = JSCTLNone (fixEmpty xs)
fix _ (JSCTLNone xs) = JSCTLNone (fixEmpty xs)
instance MinifyJS JSIdent where
fix a (JSIdentName _ n) = JSIdentName a n
fix _ JSIdentNone = JSIdentNone
instance MinifyJS (Maybe JSExpression) where
fix a me = fix a <$> me
instance MinifyJS JSVarInitializer where
fix a (JSVarInit _ x) = JSVarInit a (fix emptyAnnot x)
fix _ JSVarInitNone = JSVarInitNone
spaceAnnot :: JSAnnot
spaceAnnot = JSAnnot tokenPosnEmpty [WhiteSpace tokenPosnEmpty " "]
emptyAnnot :: JSAnnot
emptyAnnot = JSNoAnnot
newlineAnnot :: JSAnnot
newlineAnnot = JSAnnot tokenPosnEmpty [WhiteSpace tokenPosnEmpty "\n"]
semi :: JSSemi
semi = JSSemi emptyAnnot
noSemi :: JSSemi
noSemi = JSSemiAuto