class_docstr: Gather aliasing informations across nodes
  
  As a result, each node from the module is associated to a set of node or
  Intrinsic to which it *may* alias to.
class_docstr_tok: ["Gather","aliasing","informations","across","nodes","As","a","result",",","each","node","from","the","module","is","associated","to","a","set","of","node","or","Intrinsic","to","which","it","*","may","*","alias","to","."]
docstr: Resulting node alias stores the subscript relationship if we don't know
  anything about the subscripted node.
  
  >>> from pythran import passmanager
  >>> pm = passmanager.PassManager('demo')
  >>> module = ast.parse('def foo(a): return a[0]')
  >>> result = pm.gather(Aliases, module)
  >>> Aliases.dump(result, filter=ast.Subscript)
  a[0] => ['a[0]']
  
  If we know something about the container, e.g. in case of a list, we
  can use this information to get more accurate informations:
  
  >>> module = ast.parse('def foo(a, b, c): return [a, b][c]')
  >>> result = pm.gather(Aliases, module)
  >>> Aliases.dump(result, filter=ast.Subscript)
  [a, b][c] => ['a', 'b']
  
  Moreover, in case of a tuple indexed by a constant value, we can
  further refine the aliasing information:
  
  >>> fun = """
  ... def f(a, b): return a, b
  ... def foo(a, b): return f(a, b)[0]"""
  >>> module = ast.parse(fun)
  >>> result = pm.gather(Aliases, module)
  >>> Aliases.dump(result, filter=ast.Subscript)
  f(a, b)[0] => ['a']
  
  Nothing is done for slices, even if the indices are known :-/
  
  >>> module = ast.parse('def foo(a, b, c): return [a, b, c][1:]')
  >>> result = pm.gather(Aliases, module)
  >>> Aliases.dump(result, filter=ast.Subscript)
  [a, b, c][1:] => ['<unbound-value>']
docstr_tok: ["Resulting","node","alias","stores","the","subscript","relationship","if","we","do","n't","know","anything","about","the","subscripted","node",".",">",">",">","from","pythran","import","passmanager",">",">",">","pm","=","passmanager.PassManager","(","'demo","'",")",">",">",">","module","=","ast.parse","(","'def","foo","(","a",")",":","return","a","[","0","]","'",")",">",">",">","result","=","pm.gather","(","Aliases",",","module",")",">",">",">","Aliases.dump","(","result",",","filter=ast.Subscript",")","a","[","0","]","=",">","[","'","a","[","0","]","'","]","If","we","know","something","about","the","container",",","e.g",".","in","case","of","a","list",",","we","can","use","this","information","to","get","more","accurate","informations",":",">",">",">","module","=","ast.parse","(","'def","foo","(","a",",","b",",","c",")",":","return","[","a",",","b","]","[","c","]","'",")",">",">",">","result","=","pm.gather","(","Aliases",",","module",")",">",">",">","Aliases.dump","(","result",",","filter=ast.Subscript",")","[","a",",","b","]","[","c","]","=",">","[","'","a","'",",","'","b","'","]","Moreover",",","in","case","of","a","tuple","indexed","by","a","constant","value",",","we","can","further","refine","the","aliasing","information",":",">",">",">","fun","=","``","''","''","...","def","f","(","a",",","b",")",":","return","a",",","b","...","def","foo","(","a",",","b",")",":","return","f","(","a",",","b",")","[","0","]","''","''","''",">",">",">","module","=","ast.parse","(","fun",")",">",">",">","result","=","pm.gather","(","Aliases",",","module",")",">",">",">","Aliases.dump","(","result",",","filter=ast.Subscript",")","f","(","a",",","b",")","[","0","]","=",">","[","'","a","'","]","Nothing","is","done","for","slices",",","even","if","the","indices","are","known",":","-\/",">",">",">","module","=","ast.parse","(","'def","foo","(","a",",","b",",","c",")",":","return","[","a",",","b",",","c","]","[","1",":","]","'",")",">",">",">","result","=","pm.gather","(","Aliases",",","module",")",">",">",">","Aliases.dump","(","result",",","filter=ast.Subscript",")","[","a",",","b",",","c","]","[","1",":","]","=",">","[","'","<","unbound-value",">","'","]"]
code: def visit_Subscript(self, node):
      '''
      Resulting node alias stores the subscript relationship if we don't know
      anything about the subscripted node.
  
      >>> from pythran import passmanager
      >>> pm = passmanager.PassManager('demo')
      >>> module = ast.parse('def foo(a): return a[0]')
      >>> result = pm.gather(Aliases, module)
      >>> Aliases.dump(result, filter=ast.Subscript)
      a[0] => ['a[0]']
  
      If we know something about the container, e.g. in case of a list, we
      can use this information to get more accurate informations:
  
      >>> module = ast.parse('def foo(a, b, c): return [a, b][c]')
      >>> result = pm.gather(Aliases, module)
      >>> Aliases.dump(result, filter=ast.Subscript)
      [a, b][c] => ['a', 'b']
  
      Moreover, in case of a tuple indexed by a constant value, we can
      further refine the aliasing information:
  
      >>> fun = """
      ... def f(a, b): return a, b
      ... def foo(a, b): return f(a, b)[0]"""
      >>> module = ast.parse(fun)
      >>> result = pm.gather(Aliases, module)
      >>> Aliases.dump(result, filter=ast.Subscript)
      f(a, b)[0] => ['a']
  
      Nothing is done for slices, even if the indices are known :-/
  
      >>> module = ast.parse('def foo(a, b, c): return [a, b, c][1:]')
      >>> result = pm.gather(Aliases, module)
      >>> Aliases.dump(result, filter=ast.Subscript)
      [a, b, c][1:] => ['<unbound-value>']
      '''
      if isinstance(node.slice, ast.Tuple):
          # could be enhanced through better handling of containers
          self.visit(node.value)
          for elt in node.slice.elts:
              self.visit(elt)
          aliases = None
      else:
          aliases = set()
          self.visit(node.slice)
          value_aliases = self.visit(node.value)
          for alias in value_aliases:
              if isinstance(alias, ContainerOf):
                  if isinstance(node.slice, ast.Slice):
                      continue
                  if isnum(node.slice):
                      if node.slice.value != alias.index:
                          continue
                  # FIXME: what if the index is a slice variable...
                  aliases.update(alias.containees)
              elif isinstance(
                  getattr(alias, "ctx", None), (ast.Param, ast.Store)
              ):
                  aliases.add(
                      ast.Subscript(alias, node.slice, node.ctx)
                  )
          if not aliases:
              aliases = None
      return self.add(node, aliases)
  
imports: from pythran.analyses.global_declarations import GlobalDeclarations
  from pythran.intrinsic import Intrinsic, Class, UnboundValue
  from pythran.passmanager import ModuleAnalysis
  from pythran.tables import functions, methods, MODULES
  from pythran.unparse import Unparser
  from pythran.conversion import demangle
  import pythran.metadata
  from pythran.utils import isnum
  from pythran.syntax import PythranSyntaxError
  import gast
  from copy import deepcopy
  from itertools import product
  import io
label_desc: Use image node_id 15 for calling the Aliases obj's underlying member method code with example usage: obj.visit_Subscript(node) and returns: self