<s> """<STR_LIT>""" <EOL> import ast <EOL> import collections <EOL> import pyfora . pyAst . NodeVisitorBases as NodeVisitorBases <EOL> import pyfora . Exceptions as Exceptions <EOL> import pyfora . pyAst . PyAstUtil as PyAstUtil <EOL> VarWithPosition = collections . namedtuple ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> class _CollectBoundValuesInScopeVisitor ( NodeVisitorBases . GenericInScopeVisitor ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , node ) : <EOL> super ( _CollectBoundValuesInScopeVisitor , self ) . __init__ ( node ) <EOL> self . _boundVarsWithPos = set ( ) <EOL> self . _boundNamesWithPos = set ( ) <EOL> def getBoundNames ( self ) : <EOL> self . _cachedCompute ( ) <EOL> return { var for ( var , _ ) in self . _boundNamesWithPos } <EOL> def getBoundVariables ( self ) : <EOL> self . _cachedCompute ( ) <EOL> return { var for ( var , _ ) in self . _boundVarsWithPos } <EOL> def getBoundValues ( self , getPositions = False ) : <EOL> self . _cachedCompute ( ) <EOL> if getPositions is True : <EOL> return self . _boundVarsWithPos . union ( self . _boundNamesWithPos ) <EOL> else : <EOL> return self . getBoundVariables ( ) . union ( self . getBoundNames ( ) ) <EOL> def visit_Module ( self , _ ) : <EOL> raise Exceptions . InternalError ( <EOL> "<STR_LIT>" % self . __class__ . __name__ ) <EOL> def visit_FunctionDef ( self , node ) : <EOL> if node . name != '<STR_LIT>' : <EOL> self . _boundNamesWithPos . add ( <EOL> VarWithPosition ( <EOL> var = node . name , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> def visit_ClassDef ( self , node ) : <EOL> self . _boundNamesWithPos . add ( <EOL> VarWithPosition ( <EOL> var = node . name , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> def visit_Lambda ( self , _ ) : <EOL> return <EOL> def visit_Name ( self , node ) : <EOL> if self . _isInDefinition : <EOL> self . _boundVarsWithPos . add ( <EOL> VarWithPosition ( <EOL> var = node . id , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> def visit_Attribute ( self , _ ) : <EOL> return <EOL> def visit_Global ( self , node ) : <EOL> raise Exceptions . PythonToForaConversionError ( <EOL> "<STR_LIT>" <EOL> % node . lineno ) <EOL> def visit_arguments ( self , node ) : <EOL> self . visit ( node . defaults ) <EOL> with self . _isInDefinitionMgr ( True ) : <EOL> self . visit ( node . args ) <EOL> if node . vararg is not None : <EOL> self . _boundVarsWithPos . add ( <EOL> VarWithPosition ( <EOL> var = node . vararg , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> if node . kwarg is not None : <EOL> self . _boundVarsWithPos . add ( <EOL> VarWithPosition ( <EOL> var = node . kwarg , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> def collectBoundValuesInScope ( pyAstNode , getPositions = False ) : <EOL> vis = _CollectBoundValuesInScopeVisitor ( pyAstNode ) <EOL> return vis . getBoundValues ( getPositions ) <EOL> def collectBoundVariablesInScope ( pyAstNode ) : <EOL> vis = _CollectBoundValuesInScopeVisitor ( pyAstNode ) <EOL> return vis . getBoundVariables ( ) <EOL> def collectBoundNamesInScope ( pyAstNode ) : <EOL> vis = _CollectBoundValuesInScopeVisitor ( pyAstNode ) <EOL> return vis . getBoundNames ( ) <EOL> class GenericBoundValuesScopedVisitor ( NodeVisitorBases . GenericScopedVisitor ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> scopeMgr = NodeVisitorBases . ScopedSaveRestoreComputedValue ( <EOL> self . getBoundValues , <EOL> self . _setBoundValues , <EOL> GenericBoundValuesScopedVisitor . _computeScopeBoundValues ) <EOL> super ( GenericBoundValuesScopedVisitor , self ) . __init__ ( scopeMgr ) <EOL> self . _boundValues = set ( ) <EOL> self . _boundInScopeSoFar = set ( ) <EOL> def getBoundValues ( self ) : <EOL> return ( self . _boundValues , self . _boundInScopeSoFar ) <EOL> def _setBoundValues ( self , valueSets ) : <EOL> ( self . _boundValues , self . _boundInScopeSoFar ) = valueSets <EOL> @ staticmethod <EOL> def _computeScopeBoundValues ( node , oldValueSets ) : <EOL> return ( oldValueSets [ <NUM_LIT:0> ] . union ( collectBoundValuesInScope ( node ) ) , set ( ) ) <EOL> def isBoundSoFar ( self , name ) : <EOL> return name in self . _boundValues or name in self . _boundInScopeSoFar <EOL> def visit_ClassDef ( self , node ) : <EOL> self . _boundValues . add ( node . name ) <EOL> NodeVisitorBases . GenericScopedVisitor . visit_ClassDef ( self , node ) <EOL> class _FreeVarsVisitor ( GenericBoundValuesScopedVisitor ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> super ( _FreeVarsVisitor , self ) . __init__ ( ) <EOL> self . _freeVarsWithPos = set ( ) <EOL> def getFreeVars ( self , getPositions = False ) : <EOL> if getPositions : <EOL> return self . _freeVarsWithPos <EOL> else : <EOL> return { var for ( var , _ ) in self . _freeVarsWithPos } <EOL> def visit_Name ( self , node ) : <EOL> identifier = node . id <EOL> if isinstance ( node . ctx , ast . Store ) : <EOL> self . _boundInScopeSoFar . add ( identifier ) <EOL> elif not self . isBoundSoFar ( identifier ) and isinstance ( node . ctx , ast . Load ) : <EOL> self . _freeVarsWithPos . add ( <EOL> VarWithPosition ( <EOL> var = identifier , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> def getFreeVariables ( pyAstNode , isClassContext = None , getPositions = False ) : <EOL> pyAstNode = PyAstUtil . getRootInContext ( pyAstNode , isClassContext ) <EOL> freeVarsVisitor = _FreeVarsVisitor ( ) <EOL> freeVarsVisitor . visit ( pyAstNode ) <EOL> return freeVarsVisitor . getFreeVars ( getPositions = getPositions ) <EOL> class _FreeVariableMemberAccessChainsVisitor ( GenericBoundValuesScopedVisitor ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , exclude_predicate = None ) : <EOL> super ( _FreeVariableMemberAccessChainsVisitor , self ) . __init__ ( ) <EOL> self . _freeVariableMemberAccessChainsWithPos = set ( ) <EOL> self . exclude_predicate = exclude_predicate <EOL> def getFreeVariablesMemeberAccessChains ( self , getPositions = False ) : <EOL> if getPositions : <EOL> return self . _freeVariableMemberAccessChainsWithPos <EOL> else : <EOL> return { chain for ( chain , _ ) in self . _freeVariableMemberAccessChainsWithPos } <EOL> def visit_Attribute ( self , node ) : <EOL> chainOrNone = _memberAccessChainOrNone ( node ) <EOL> if chainOrNone is not None : <EOL> if chainOrNone [ <NUM_LIT:0> ] not in self . _boundValues : <EOL> self . _freeVariableMemberAccessChainsWithPos . add ( <EOL> VarWithPosition ( <EOL> var = chainOrNone , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> else : <EOL> self . generic_visit ( node . value ) <EOL> def visit_Name ( self , node ) : <EOL> identifier = node . id <EOL> if isinstance ( node . ctx , ast . Store ) : <EOL> self . _boundInScopeSoFar . add ( identifier ) <EOL> elif not self . isBoundSoFar ( identifier ) and isinstance ( node . ctx , ast . Load ) : <EOL> self . _freeVariableMemberAccessChainsWithPos . add ( <EOL> VarWithPosition ( <EOL> var = ( identifier , ) , <EOL> pos = NodeVisitorBases . PositionInFile ( <EOL> lineno = node . lineno , <EOL> col_offset = node . col_offset <EOL> ) <EOL> ) <EOL> ) <EOL> def generic_visit ( self , node ) : <EOL> if self . exclude_predicate is None or not self . exclude_predicate ( node ) : <EOL> super ( _FreeVariableMemberAccessChainsVisitor , self ) . generic_visit ( node ) <EOL> def _memberAccessChainOrNone ( pyAstNode ) : <EOL> res = _memberAccessChainOrNoneImpl ( pyAstNode ) <EOL> if len ( res ) == <NUM_LIT:0> : <EOL> return None <EOL> return tuple ( res ) <EOL> def _memberAccessChainOrNoneImpl ( pyAstNode ) : <EOL> if isinstance ( pyAstNode , ast . Name ) : <EOL> return [ pyAstNode . id ] <EOL> if isinstance ( pyAstNode , ast . Expr ) : <EOL> return _memberAccessChainOrNoneImpl ( pyAstNode . value ) <EOL> if isinstance ( pyAstNode , ast . Attribute ) : <EOL> prefix = _memberAccessChainOrNoneImpl ( pyAstNode . value ) <EOL> if len ( prefix ) == <NUM_LIT:0> : <EOL> return [ ] <EOL> prefix . append ( pyAstNode . attr ) <EOL> return prefix <EOL> return [ ] <EOL> def getFreeVariableMemberAccessChains ( pyAstNode , <EOL> isClassContext = None , <EOL> getPositions = False , <EOL> exclude_predicate = None ) : <EOL> pyAstNode = PyAstUtil . getRootInContext ( pyAstNode , isClassContext ) <EOL> vis = _FreeVariableMemberAccessChainsVisitor ( exclude_predicate ) <EOL> vis . visit ( pyAstNode ) <EOL> return vis . getFreeVariablesMemeberAccessChains ( getPositions ) </s>
