{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}

-- |
-- Module      : Jikka.RestrictedPython.Convert.UseAppend
-- Description : converts @xs = xs + [x]@ and @xs += [x]@ to @xs.append(x)@. / @xs = xs + [x]@ と @xs += [x]@ を @xs.append(x)@ に変換します。
-- Copyright   : (c) Kimiyuki Onaka, 2021
-- License     : Apache License 2.0
-- Maintainer  : kimiyuki95@gmail.com
-- Stability   : experimental
-- Portability : portable
module Jikka.RestrictedPython.Convert.UseAppend
  ( run,
  )
where

import Jikka.Common.Alpha
import Jikka.Common.Error
import Jikka.RestrictedPython.Language.Expr
import Jikka.RestrictedPython.Language.Util

runStatement :: Statement -> [Statement]
runStatement :: Statement -> [Statement]
runStatement = \case
  AugAssign Target'
xs Operator
Add (WithLoc' Maybe Loc
_ (List Type
t [WithLoc' Expr
x])) ->
    [WithLoc' Expr -> Statement
Expr' (Expr -> WithLoc' Expr
forall a. a -> WithLoc' a
withoutLoc (WithLoc' Expr -> [WithLoc' Expr] -> Expr
Call (Expr -> WithLoc' Expr
forall a. a -> WithLoc' a
withoutLoc (WithLoc' Expr -> Attribute' -> Expr
Attribute (Target' -> WithLoc' Expr
targetToExpr Target'
xs) (Attribute -> Attribute'
forall a. a -> WithLoc' a
withoutLoc (Type -> Attribute
BuiltinAppend Type
t)))) [WithLoc' Expr
x]))]
  AnnAssign Target'
xs Type
t1 (WithLoc' Maybe Loc
_ (BinOp WithLoc' Expr
xs' Operator
Add (WithLoc' Maybe Loc
_ (List Type
t2 [WithLoc' Expr
x]))))
    | WithLoc' Expr -> WithLoc' Expr
dropLocation (Target' -> WithLoc' Expr
targetToExpr Target'
xs) WithLoc' Expr -> WithLoc' Expr -> Bool
forall a. Eq a => a -> a -> Bool
== WithLoc' Expr -> WithLoc' Expr
dropLocation WithLoc' Expr
xs' ->
      let t :: Type
t = case Type
t1 of
            ListTy Type
t -> Type
t
            Type
_ -> Type
t2
       in [WithLoc' Expr -> Statement
Expr' (Expr -> WithLoc' Expr
forall a. a -> WithLoc' a
withoutLoc (WithLoc' Expr -> [WithLoc' Expr] -> Expr
Call (Expr -> WithLoc' Expr
forall a. a -> WithLoc' a
withoutLoc (WithLoc' Expr -> Attribute' -> Expr
Attribute (Target' -> WithLoc' Expr
targetToExpr Target'
xs) (Attribute -> Attribute'
forall a. a -> WithLoc' a
withoutLoc (Type -> Attribute
BuiltinAppend Type
t)))) [WithLoc' Expr
x]))]
  Statement
stmt -> [Statement
stmt]

-- | `run` converts @xs = xs + [x]@ and @xs += [x]@ to @xs.append(x)@.
--
-- == Examples
--
-- Before:
--
-- > xs = xs + [x]
-- > xs += [x]
-- > xs.append(x)
--
-- After:
--
-- > xs.append(x)
-- > xs.append(x)
-- > xs.append(x)
run :: (MonadAlpha m, MonadError Error m) => Program -> m Program
run :: Program -> m Program
run Program
prog = String -> m Program -> m Program
forall (m :: * -> *) a. MonadError Error m => String -> m a -> m a
wrapError' String
"Jikka.RestrictedPython.Convert.UseAppend" (m Program -> m Program) -> m Program -> m Program
forall a b. (a -> b) -> a -> b
$ do
  Program -> m Program
forall (m :: * -> *) a. Monad m => a -> m a
return (Program -> m Program) -> Program -> m Program
forall a b. (a -> b) -> a -> b
$ (Statement -> [Statement]) -> Program -> Program
mapStatement Statement -> [Statement]
runStatement Program
prog