[email protected] | 2ec654a | 2012-01-10 17:47:00 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | |
| 6 | """ Hierarchical property system for IDL AST """ |
| 7 | import re |
| 8 | import sys |
| 9 | |
| 10 | from idl_log import ErrOut, InfoOut, WarnOut |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 11 | |
| 12 | # |
| 13 | # IDLPropertyNode |
| 14 | # |
| 15 | # A property node is a hierarchically aware system for mapping |
| 16 | # keys to values, such that a local dictionary is search first, |
| 17 | # followed by parent dictionaries in order. |
| 18 | # |
| 19 | class IDLPropertyNode(object): |
| 20 | def __init__(self): |
| 21 | self.parents = [] |
| 22 | self.property_map = {} |
| 23 | |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 24 | def AddParent(self, parent): |
| 25 | assert parent |
| 26 | self.parents.append(parent) |
| 27 | |
| 28 | def SetProperty(self, name, val): |
| 29 | self.property_map[name] = val |
| 30 | |
[email protected] | ad10f33 | 2013-12-02 23:00:59 | [diff] [blame] | 31 | def GetProperty(self, name): |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 32 | # Check locally for the property, and return it if found. |
| 33 | prop = self.property_map.get(name, None) |
[email protected] | ad10f33 | 2013-12-02 23:00:59 | [diff] [blame] | 34 | if prop is not None: |
| 35 | return prop |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 36 | # If not, seach parents in order |
| 37 | for parent in self.parents: |
| 38 | prop = parent.GetProperty(name) |
[email protected] | ad10f33 | 2013-12-02 23:00:59 | [diff] [blame] | 39 | if prop is not None: |
| 40 | return prop |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 41 | # Otherwise, it can not be found. |
| 42 | return None |
| 43 | |
[email protected] | ad10f33 | 2013-12-02 23:00:59 | [diff] [blame] | 44 | def GetPropertyLocal(self, name): |
| 45 | # Search for the property, but only locally. |
| 46 | return self.property_map.get(name, None) |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 47 | |
| 48 | def GetPropertyList(self): |
| 49 | return self.property_map.keys() |
| 50 | |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 51 | # |
| 52 | # Testing functions |
| 53 | # |
| 54 | |
| 55 | # Build a property node, setting the properties including a name, and |
| 56 | # associate the children with this new node. |
| 57 | # |
[email protected] | ad10f33 | 2013-12-02 23:00:59 | [diff] [blame] | 58 | def BuildNode(name, props, children=None, parents=None): |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 59 | node = IDLPropertyNode() |
| 60 | node.SetProperty('NAME', name) |
| 61 | for prop in props: |
| 62 | toks = prop.split('=') |
| 63 | node.SetProperty(toks[0], toks[1]) |
[email protected] | ad10f33 | 2013-12-02 23:00:59 | [diff] [blame] | 64 | if children: |
| 65 | for child in children: |
| 66 | child.AddParent(node) |
| 67 | if parents: |
| 68 | for parent in parents: |
| 69 | node.AddParent(parent) |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 70 | return node |
| 71 | |
| 72 | def ExpectProp(node, name, val): |
| 73 | found = node.GetProperty(name) |
| 74 | if found != val: |
| 75 | ErrOut.Log('Got property %s expecting %s' % (found, val)) |
| 76 | return 1 |
| 77 | return 0 |
| 78 | |
| 79 | # |
| 80 | # Verify property inheritance |
| 81 | # |
| 82 | def PropertyTest(): |
| 83 | errors = 0 |
| 84 | left = BuildNode('Left', ['Left=Left']) |
| 85 | right = BuildNode('Right', ['Right=Right']) |
| 86 | top = BuildNode('Top', ['Left=Top', 'Right=Top'], [left, right]) |
| 87 | |
| 88 | errors += ExpectProp(top, 'Left', 'Top') |
| 89 | errors += ExpectProp(top, 'Right', 'Top') |
| 90 | |
| 91 | errors += ExpectProp(left, 'Left', 'Left') |
| 92 | errors += ExpectProp(left, 'Right', 'Top') |
| 93 | |
| 94 | errors += ExpectProp(right, 'Left', 'Top') |
| 95 | errors += ExpectProp(right, 'Right', 'Right') |
| 96 | |
[email protected] | ad10f33 | 2013-12-02 23:00:59 | [diff] [blame] | 97 | if not errors: |
| 98 | InfoOut.Log('Passed PropertyTest') |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 99 | return errors |
| 100 | |
[email protected] | 2ec654a | 2012-01-10 17:47:00 | [diff] [blame] | 101 | |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 102 | def Main(): |
| 103 | errors = 0 |
| 104 | errors += PropertyTest() |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 105 | |
| 106 | if errors: |
| 107 | ErrOut.Log('IDLNode failed with %d errors.' % errors) |
| 108 | return -1 |
| 109 | return 0 |
| 110 | |
[email protected] | 2ec654a | 2012-01-10 17:47:00 | [diff] [blame] | 111 | |
[email protected] | faff5fc7 | 2011-07-14 15:59:04 | [diff] [blame] | 112 | if __name__ == '__main__': |
| 113 | sys.exit(Main()) |
[email protected] | 98cfdfc | 2012-10-23 18:10:02 | [diff] [blame] | 114 | |