1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
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 """
7import re
8import sys
9
10from idl_log import ErrOut, InfoOut, WarnOut
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#
19class IDLPropertyNode(object):
20  def __init__(self):
21    self.parents = []
22    self.property_map = {}
23
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
31  def GetProperty(self, name):
32    # Check locally for the property, and return it if found.
33    prop = self.property_map.get(name, None)
34    if prop is not None:
35      return prop
36    # If not, seach parents in order
37    for parent in self.parents:
38      prop = parent.GetProperty(name)
39      if prop is not None:
40        return prop
41    # Otherwise, it can not be found.
42    return None
43
44  def GetPropertyLocal(self, name):
45    # Search for the property, but only locally.
46    return self.property_map.get(name, None)
47
48  def GetPropertyList(self):
49    return self.property_map.keys()
50
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#
58def BuildNode(name, props, children=None, parents=None):
59  node = IDLPropertyNode()
60  node.SetProperty('NAME', name)
61  for prop in props:
62    toks = prop.split('=')
63    node.SetProperty(toks[0], toks[1])
64  if children:
65    for child in children:
66      child.AddParent(node)
67  if parents:
68    for parent in parents:
69      node.AddParent(parent)
70  return node
71
72def 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#
82def 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
97  if not errors:
98    InfoOut.Log('Passed PropertyTest')
99  return errors
100
101
102def Main():
103  errors = 0
104  errors += PropertyTest()
105
106  if errors:
107    ErrOut.Log('IDLNode failed with %d errors.' % errors)
108    return  -1
109  return 0
110
111
112if __name__ == '__main__':
113  sys.exit(Main())
114
115