Exemple #1
0
 def testResolveName(self):
   module_block = _MakeModuleBlock()
   block_vars = {'foo': block.Var('foo', block.Var.TYPE_LOCAL)}
   func1_block = block.FunctionBlock(module_block, 'func1', block_vars, False)
   block_vars = {'bar': block.Var('bar', block.Var.TYPE_LOCAL)}
   func2_block = block.FunctionBlock(func1_block, 'func2', block_vars, False)
   block_vars = {'case': block.Var('case', block.Var.TYPE_LOCAL)}
   keyword_block = block.FunctionBlock(
       module_block, 'keyword_func', block_vars, False)
   class1_block = block.ClassBlock(module_block, 'Class1', set())
   class2_block = block.ClassBlock(func1_block, 'Class2', set())
   self.assertRegexpMatches(self._ResolveName(module_block, 'foo'),
                            r'ResolveGlobal\b.*foo')
   self.assertRegexpMatches(self._ResolveName(module_block, 'bar'),
                            r'ResolveGlobal\b.*bar')
   self.assertRegexpMatches(self._ResolveName(module_block, 'baz'),
                            r'ResolveGlobal\b.*baz')
   self.assertRegexpMatches(self._ResolveName(func1_block, 'foo'),
                            r'CheckLocal\b.*foo')
   self.assertRegexpMatches(self._ResolveName(func1_block, 'bar'),
                            r'ResolveGlobal\b.*bar')
   self.assertRegexpMatches(self._ResolveName(func1_block, 'baz'),
                            r'ResolveGlobal\b.*baz')
   self.assertRegexpMatches(self._ResolveName(func2_block, 'foo'),
                            r'CheckLocal\b.*foo')
   self.assertRegexpMatches(self._ResolveName(func2_block, 'bar'),
                            r'CheckLocal\b.*bar')
   self.assertRegexpMatches(self._ResolveName(func2_block, 'baz'),
                            r'ResolveGlobal\b.*baz')
   self.assertRegexpMatches(self._ResolveName(class1_block, 'foo'),
                            r'ResolveClass\(.*, nil, .*foo')
   self.assertRegexpMatches(self._ResolveName(class2_block, 'foo'),
                            r'ResolveClass\(.*, µfoo, .*foo')
   self.assertRegexpMatches(self._ResolveName(keyword_block, 'case'),
                            r'CheckLocal\b.*µcase, "case"')
Exemple #2
0
  def visit_ClassDef(self, node):
    # Since we only care about global vars, we end up throwing away the locals
    # collected by BlockVisitor. But use it anyway since it buys us detection of
    # assignment to vars that are later declared global.
    block_visitor = block.BlockVisitor()
    for child in node.body:
      block_visitor.visit(child)
    global_vars = {v.name for v in block_visitor.vars.values()
                   if v.type == block.Var.TYPE_GLOBAL}
    # Visit all the statements inside body of the class definition.
    body_visitor = StatementVisitor(block.ClassBlock(
        self.block, node.name, global_vars))
    # Indent so that the function body is aligned with the goto labels.
    with body_visitor.writer.indent_block():
      body_visitor._visit_each(node.body)  # pylint: disable=protected-access

    self._write_py_context(node.lineno)
    with self.block.alloc_temp('*πg.Dict') as cls, \
        self.block.alloc_temp() as mod_name, \
        self.block.alloc_temp('[]*πg.Object') as bases, \
        self.block.alloc_temp() as meta:
      self.writer.write('{} = make([]*πg.Object, {})'.format(
          bases.expr, len(node.bases)))
      for i, b in enumerate(node.bases):
        with self.expr_visitor.visit(b) as b:
          self.writer.write('{}[{}] = {}'.format(bases.expr, i, b.expr))
      self.writer.write('{} = πg.NewDict()'.format(cls.name))
      self.writer.write_checked_call2(
          mod_name, 'πF.Globals().GetItem(πF, {}.ToObject())',
          self.block.root.intern('__name__'))
      self.writer.write_checked_call1(
          '{}.SetItem(πF, {}.ToObject(), {})',
          cls.expr, self.block.root.intern('__module__'), mod_name.expr)
      tmpl = textwrap.dedent("""
          _, πE = πg.NewCode($name, $filename, nil, 0, func(πF *πg.Frame, _ []*πg.Object) (*πg.Object, *πg.BaseException) {
          \tπClass := $cls
          \t_ = πClass""")
      self.writer.write_tmpl(tmpl, name=util.go_str(node.name),
                             filename=util.go_str(self.block.root.filename),
                             cls=cls.expr)
      with self.writer.indent_block():
        self.writer.write_temp_decls(body_visitor.block)
        self.writer.write_block(body_visitor.block,
                                body_visitor.writer.getvalue())
      tmpl = textwrap.dedent("""\
          }).Eval(πF, πF.Globals(), nil, nil)
          if πE != nil {
          \tcontinue
          }
          if $meta, πE = $cls.GetItem(πF, $metaclass_str.ToObject()); πE != nil {
          \tcontinue
          }
          if $meta == nil {
          \t$meta = πg.TypeType.ToObject()
          }""")
      self.writer.write_tmpl(
          tmpl, meta=meta.name, cls=cls.expr,
          metaclass_str=self.block.root.intern('__metaclass__'))
      with self.block.alloc_temp() as type_:
        type_expr = ('{}.Call(πF, []*πg.Object{{πg.NewStr({}).ToObject(), '
                     'πg.NewTuple({}...).ToObject(), {}.ToObject()}}, nil)')
        self.writer.write_checked_call2(
            type_, type_expr, meta.expr,
            util.go_str(node.name), bases.expr, cls.expr)
        self.block.bind_var(self.writer, node.name, type_.expr)