{-# language DataKinds, KindSignatures #-} {-# language TemplateHaskell #-} {-# language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-} {-| Module : Language.Python.Validate.Scope.Error Copyright : (C) CSIRO 2017-2019 License : BSD3 Maintainer : Isaac Elliott Stability : experimental Portability : non-portable -} module Language.Python.Validate.Scope.Error where import Control.Lens.TH import Language.Python.Syntax.Ident data ScopeError a -- | -- Using @nonlocal@ to modify function scopes makes scope checking intractible = FoundNonlocal a -- | -- Using @global@ to add identifiers to the global scope makes scope checking -- intractible | FoundGlobal a -- | -- Using @del@ to remove identifiers from scope makes scope checking intractible | DeletedIdent a -- | -- Variable assignments deep in control flow can modify the scope outside -- the control flow. For example: -- -- @ -- if a: -- x = 0 -- else: -- pass -- -- print(x) -- @ -- -- @x@ will be in scope if the @True@ branch was entered, but not if the @False@ -- branch was entered. This kind of behaviour makes scope checking intractible, so -- programs like this are considered scope errors. | FoundDynamic a (Ident '[] a) -- | An identifier is not in scope | NotInScope (Ident '[] a) -- | -- For loops don't execute in a fresh scope, so if the 'counter' of the loop -- shadows a variable, then that variable will be mutated. -- -- e.g. -- -- @ -- x = 0 -- for x in 1, 2, 3: -- pass -- print(x) -- @ -- -- outputs @3@ -- -- This error occurs when we spot this pattern. | BadShadowing (Ident '[] a) deriving (Eq, Show) makeClassyPrisms ''ScopeError