Commit b7c56ce3 authored by Stefan Behnel's avatar Stefan Behnel

support 'and' operator and boolean attribute values in TreePath predicates

parent 8b5d1ff0
......@@ -68,6 +68,13 @@ class TestTreePath(TransformTest):
self.assertEquals(0, len(find_all(t, "//NameNode[not(@name)]")))
self.assertEquals(2, len(find_all(t, "//NameNode[not(@honking)]")))
def test_node_path_and(self):
t = self._build_tree()
self.assertEquals(1, len(find_all(t, "//DefNode[.//ReturnStatNode and .//NameNode]")))
self.assertEquals(0, len(find_all(t, "//NameNode[@honking and @name]")))
self.assertEquals(0, len(find_all(t, "//NameNode[@name and @honking]")))
self.assertEquals(2, len(find_all(t, "//DefNode[.//NameNode[@name] and @name]")))
def test_node_path_attribute_string_predicate(self):
t = self._build_tree()
self.assertEquals(1, len(find_all(t, "//NameNode[@name = 'decorator']")))
......
......@@ -167,14 +167,20 @@ def handle_attribute(next, token):
def parse_path_value(next):
token = next()
value = token[0]
if value[:1] == "'" or value[:1] == '"':
value = value[1:-1]
else:
if value:
if value[:1] == "'" or value[:1] == '"':
return value[1:-1]
try:
value = int(value)
return int(value)
except ValueError:
raise ValueError("Invalid attribute predicate: '%s'" % value)
return value
pass
else:
name = token[1].lower()
if name == 'true':
return True
elif name == 'false':
return False
raise ValueError("Invalid attribute predicate: '%s'" % value)
def handle_predicate(next, token):
token = next()
......@@ -189,6 +195,9 @@ def handle_predicate(next, token):
if token[0] == "/":
token = next()
if not token[0] and token[1] == 'and':
return logical_and(selector, handle_predicate(next, token))
def select(result):
for node in result:
subresult = iter((node,))
......@@ -199,6 +208,20 @@ def handle_predicate(next, token):
yield node
return select
def logical_and(lhs_selects, rhs_select):
def select(result):
for node in result:
subresult = iter((node,))
for select in lhs_selects:
subresult = select(subresult)
predicate_result = _get_first_or_none(subresult)
subresult = iter((node,))
if predicate_result is not None:
for result_node in rhs_select(subresult):
yield node
return select
operations = {
"@": handle_attribute,
"": handle_name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment