summaryrefslogtreecommitdiffstats
path: root/ppapi/generators/idl_propertynode.py
diff options
context:
space:
mode:
authornoelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-14 15:59:04 +0000
committernoelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-14 15:59:04 +0000
commitfaff5fc7665abfcbcf5ab497ca533d7d3d4e53ac (patch)
treeb6fd31f661c042ea2c7ed935d34c3d05f8d6164e /ppapi/generators/idl_propertynode.py
parent5dcc294d4a360c49923b6b079a4a3cfec6dca781 (diff)
downloadchromium_src-faff5fc7665abfcbcf5ab497ca533d7d3d4e53ac.zip
chromium_src-faff5fc7665abfcbcf5ab497ca533d7d3d4e53ac.tar.gz
chromium_src-faff5fc7665abfcbcf5ab497ca533d7d3d4e53ac.tar.bz2
Split property system into it's own file.
Split the property system into it's own file to make testing and updating easier. TEST= python idl_propertynode.py BUG= http://code.google.com/p/chromium/issues/detail?id=74634 R= sehr@google.com Review URL: http://codereview.chromium.org/7356008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92546 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/generators/idl_propertynode.py')
-rw-r--r--ppapi/generators/idl_propertynode.py196
1 files changed, 196 insertions, 0 deletions
diff --git a/ppapi/generators/idl_propertynode.py b/ppapi/generators/idl_propertynode.py
new file mode 100644
index 0000000..caf0974
--- /dev/null
+++ b/ppapi/generators/idl_propertynode.py
@@ -0,0 +1,196 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+""" Hierarchical property system for IDL AST """
+import re
+import sys
+
+from idl_log import ErrOut, InfoOut, WarnOut
+from idl_option import GetOption, Option, ParseOptions
+
+#
+# IDLPropertyNode
+#
+# A property node is a hierarchically aware system for mapping
+# keys to values, such that a local dictionary is search first,
+# followed by parent dictionaries in order.
+#
+class IDLPropertyNode(object):
+ def __init__(self):
+ self.parents = []
+ self.property_map = {}
+
+ def Error(self, msg):
+ name = self.GetProperty('NAME', 'Unknown')
+ parents = [parent.GetProperty('NAME', '???') for parent in self.parents]
+ ErrOut.Log('%s [%s] : %s' % (name, ' '.join(parents), msg))
+
+ def AddParent(self, parent):
+ assert parent
+ self.parents.append(parent)
+
+ def SetProperty(self, name, val):
+ self.property_map[name] = val
+
+ def _GetProperty_(self, name):
+ # Check locally for the property, and return it if found.
+ prop = self.property_map.get(name, None)
+ if prop is not None: return prop
+ # If not, seach parents in order
+ for parent in self.parents:
+ prop = parent.GetProperty(name)
+ if prop is not None: return prop
+ # Otherwise, it can not be found.
+ return None
+
+ def GetProperty(self, name, default=None):
+ prop = self._GetProperty_(name)
+ if prop is None:
+ return default
+ else:
+ return prop
+
+ def GetPropertyLocal(self, name, default=None):
+ # Search for the property, but only locally, returning the
+ # default if not found.
+ prop = self.property_map.get(name, default)
+ return prop
+
+ # Regular expression to parse property keys in a string such that a string
+ # "My string $NAME$" will find the key "NAME".
+ regex_var = re.compile('(?P<src>[^\\$]+)|(?P<key>\\$\\w+\\$)')
+
+ def GetPropertyList(self):
+ return self.property_map.keys()
+
+ # Recursively expands text keys in the form of $KEY$ with the value
+ # of the property of the same name. Since this is done recursively
+ # one property can be defined in terms of another.
+ def Replace(self, text):
+ itr = IDLPropertyNode.regex_var.finditer(text)
+ out = ''
+ for m in itr:
+ (start, stop) = m.span()
+ if m.lastgroup == 'src':
+ out += text[start:stop]
+ if m.lastgroup == 'key':
+ key = text[start+1:stop-1]
+ val = self.GetProperty(key, None)
+ if not val:
+ self.Error('No property "%s"' % key)
+ out += self.Replace(str(val))
+ return out
+
+
+#
+# Testing functions
+#
+
+# Build a property node, setting the properties including a name, and
+# associate the children with this new node.
+#
+def BuildNode(name, props, children=[], parents=[]):
+ node = IDLPropertyNode()
+ node.SetProperty('NAME', name)
+ for prop in props:
+ toks = prop.split('=')
+ node.SetProperty(toks[0], toks[1])
+ for child in children:
+ child.AddParent(node)
+ for parent in parents:
+ node.AddParent(parent)
+ return node
+
+def ExpectProp(node, name, val):
+ found = node.GetProperty(name)
+ if found != val:
+ ErrOut.Log('Got property %s expecting %s' % (found, val))
+ return 1
+ return 0
+
+#
+# Verify property inheritance
+#
+def PropertyTest():
+ errors = 0
+ left = BuildNode('Left', ['Left=Left'])
+ right = BuildNode('Right', ['Right=Right'])
+ top = BuildNode('Top', ['Left=Top', 'Right=Top'], [left, right])
+
+ errors += ExpectProp(top, 'Left', 'Top')
+ errors += ExpectProp(top, 'Right', 'Top')
+
+ errors += ExpectProp(left, 'Left', 'Left')
+ errors += ExpectProp(left, 'Right', 'Top')
+
+ errors += ExpectProp(right, 'Left', 'Top')
+ errors += ExpectProp(right, 'Right', 'Right')
+
+ if not errors: InfoOut.Log('Passed PropertyTest')
+ return errors
+
+
+def ExpectText(node, text, val):
+ found = node.Replace(text)
+ if found != val:
+ ErrOut.Log('Got replacement %s expecting %s' % (found, val))
+ return 1
+ return 0
+
+#
+# Verify text replacement
+#
+def ReplaceTest():
+ errors = 0
+ left = BuildNode('Left', ['Left=Left'])
+ right = BuildNode('Right', ['Right=Right'])
+ top = BuildNode('Top', ['Left=Top', 'Right=Top'], [left, right])
+
+ errors += ExpectText(top, '$Left$', 'Top')
+ errors += ExpectText(top, '$Right$', 'Top')
+
+ errors += ExpectText(left, '$Left$', 'Left')
+ errors += ExpectText(left, '$Right$', 'Top')
+
+ errors += ExpectText(right, '$Left$', 'Top')
+ errors += ExpectText(right, '$Right$', 'Right')
+
+ if not errors: InfoOut.Log('Passed ReplaceTest')
+ return errors
+
+
+def MultiParentTest():
+ errors = 0
+
+ parent1 = BuildNode('parent1', ['PARENT1=parent1', 'TOPMOST=$TOP$'])
+ parent2 = BuildNode('parent2', ['PARENT1=parent2', 'PARENT2=parent2'])
+ child = BuildNode('child', ['CHILD=child'], parents=[parent1, parent2])
+ BuildNode('top', ['TOP=top'], children=[parent1])
+
+ errors += ExpectText(child, '$CHILD$', 'child')
+ errors += ExpectText(child, '$PARENT1$', 'parent1')
+ errors += ExpectText(child, '$PARENT2$', 'parent2')
+
+ # Verify recursive resolution
+ errors += ExpectText(child, '$TOPMOST$', 'top')
+
+ if not errors: InfoOut.Log('Passed MultiParentTest')
+ return errors
+
+def Main():
+ errors = 0
+ errors += PropertyTest()
+ errors += ReplaceTest()
+ errors += MultiParentTest()
+
+ if errors:
+ ErrOut.Log('IDLNode failed with %d errors.' % errors)
+ return -1
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(Main())
+