| #!/usr/bin/env python | |
| # Copyright (c) 2012 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 | |
| # | |
| # 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 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 GetPropertyLocal(self, name): | |
| # Search for the property, but only locally. | |
| return self.property_map.get(name, None) | |
| def GetPropertyList(self): | |
| return self.property_map.keys() | |
| # | |
| # 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=None, parents=None): | |
| node = IDLPropertyNode() | |
| node.SetProperty('NAME', name) | |
| for prop in props: | |
| toks = prop.split('=') | |
| node.SetProperty(toks[0], toks[1]) | |
| if children: | |
| for child in children: | |
| child.AddParent(node) | |
| if parents: | |
| 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 Main(): | |
| errors = 0 | |
| errors += PropertyTest() | |
| if errors: | |
| ErrOut.Log('IDLNode failed with %d errors.' % errors) | |
| return -1 | |
| return 0 | |
| if __name__ == '__main__': | |
| sys.exit(Main()) |