Fix QN for Calls.
authorA. Unique TensorFlower <gardener@tensorflow.org>
Thu, 22 Mar 2018 15:19:21 +0000 (08:19 -0700)
committerTensorFlower Gardener <gardener@tensorflow.org>
Thu, 22 Mar 2018 15:21:54 +0000 (08:21 -0700)
PiperOrigin-RevId: 190067548

tensorflow/contrib/py2tf/pyct/qual_names.py
tensorflow/contrib/py2tf/pyct/qual_names_test.py
tensorflow/contrib/py2tf/pyct/static_analysis/activity.py

index 6bcbaeb..7dec13d 100644 (file)
@@ -169,14 +169,6 @@ class QnResolver(gast.NodeTransformer):
   Note: Not using NodeAnnos to avoid circular dependencies.
   """
 
-  def visit_Call(self, node):
-    node = self.generic_visit(node)
-    # This helps treat the following cases uniformly:
-    #   a = b[i]
-    #   a = b()[i]
-    anno.copyanno(node.func, node, anno.Basic.QN)
-    return node
-
   def visit_Name(self, node):
     node = self.generic_visit(node)
     anno.setanno(node, anno.Basic.QN, QN(node.id))
@@ -184,8 +176,9 @@ class QnResolver(gast.NodeTransformer):
 
   def visit_Attribute(self, node):
     node = self.generic_visit(node)
-    anno.setanno(node, anno.Basic.QN,
-                 QN(anno.getanno(node.value, anno.Basic.QN), attr=node.attr))
+    if anno.hasanno(node.value, anno.Basic.QN):
+      anno.setanno(node, anno.Basic.QN,
+                   QN(anno.getanno(node.value, anno.Basic.QN), attr=node.attr))
     return node
 
   def visit_Subscript(self, node):
@@ -201,9 +194,10 @@ class QnResolver(gast.NodeTransformer):
       subscript = QN(StringLiteral(s.value.s))
     else:
       subscript = anno.getanno(node.slice.value, anno.Basic.QN)
-    anno.setanno(node, anno.Basic.QN,
-                 QN(anno.getanno(node.value, anno.Basic.QN),
-                    subscript=subscript))
+    if anno.hasanno(node.value, anno.Basic.QN):
+      anno.setanno(node, anno.Basic.QN,
+                   QN(anno.getanno(node.value, anno.Basic.QN),
+                      subscript=subscript))
     return node
 
 
index f2cd8e9..6583fa2 100644 (file)
@@ -208,6 +208,24 @@ class QNResolverTest(test.TestCase):
     self.assertQNStringIs(nodes[8], 'a.b[c[d]].e.f')
     self.assertQNStringIs(nodes[9], 'a.b[c[d.e.f].g].h')
 
+  def test_function_calls(self):
+    samples = """
+      a.b
+      a.b()
+      a().b
+      z[i]
+      z[i]()
+      z()[i]
+    """
+    nodes = resolve(parser.parse_str(textwrap.dedent(samples)))
+    nodes = tuple(n.value for n in nodes.body)
+    self.assertQNStringIs(nodes[0], 'a.b')
+    self.assertQNStringIs(nodes[1].func, 'a.b')
+    self.assertQNStringIs(nodes[2].value.func, 'a')
+    self.assertQNStringIs(nodes[3], 'z[i]')
+    self.assertQNStringIs(nodes[4].func, 'z[i]')
+    self.assertQNStringIs(nodes[5].value.func, 'z')
+
 
 if __name__ == '__main__':
   test.main()
index 87fc8c9..716672a 100644 (file)
@@ -171,6 +171,10 @@ class ActivityAnalizer(transformer.Base):
     self._in_return_statement = False
 
   def _track_symbol(self, node):
+    # This can happen when we have an attribute (or subscript) on a function
+    # call.  Example: a().b
+    if not anno.hasanno(node, anno.Basic.QN):
+      return
     qn = anno.getanno(node, anno.Basic.QN)
 
     if isinstance(node.ctx, gast.Store):