| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """Nodes for PPAPI IDL AST.""" | 7 """Nodes for PPAPI IDL AST.""" |
| 8 | 8 |
| 9 from idl_namespace import IDLNamespace, IDLVersionMap | 9 from idl_namespace import IDLNamespace |
| 10 from idl_node import IDLAttribute, IDLFile, IDLNode | 10 from idl_node import IDLAttribute, IDLFile, IDLNode |
| 11 from idl_option import GetOption | 11 from idl_option import GetOption |
| 12 from idl_visitor import IDLVisitor | 12 from idl_visitor import IDLVisitor |
| 13 from idl_release import IDLReleaseList, IDLReleaseMap |
| 13 | 14 |
| 14 # | 15 # |
| 15 # IDL Predefined types | 16 # IDL Predefined types |
| 16 # | 17 # |
| 17 BuiltIn = set(['int8_t', 'int16_t', 'int32_t', 'int64_t', 'uint8_t', | 18 BuiltIn = set(['int8_t', 'int16_t', 'int32_t', 'int64_t', 'uint8_t', |
| 18 'uint16_t', 'uint32_t', 'uint64_t', 'double_t', 'float_t', | 19 'uint16_t', 'uint32_t', 'uint64_t', 'double_t', 'float_t', |
| 19 'handle_t', 'interface_t', 'char', 'mem_t', 'str_t', 'void']) | 20 'handle_t', 'interface_t', 'char', 'mem_t', 'str_t', 'void']) |
| 20 | 21 |
| 21 | 22 |
| 22 # | 23 # |
| 23 # IDLNamespaceLabelResolver | 24 # IDLNamespaceLabelResolver |
| 24 # | 25 # |
| 25 # Once the AST is build, we need to resolve the namespace and version | 26 # Once the AST is build, we need to resolve the namespace and version |
| 26 # information. | 27 # information. |
| 27 # | 28 # |
| 28 class IDLNamespaceLabelResolver(IDLVisitor): | 29 class IDLNamespaceLabelResolver(IDLVisitor): |
| 29 NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct']) | 30 NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct']) |
| 30 # | 31 # |
| 31 # When we arrive at a node we must assign it a namespace and if the | 32 # When we arrive at a node we must assign it a namespace and if the |
| 32 # node is named, then place it in the appropriate namespace. | 33 # node is named, then place it in the appropriate namespace. |
| 33 # | 34 # |
| 34 def Arrive(self, node, parent_namespace): | 35 def Arrive(self, node, parent_namespace): |
| 35 # Set version min and max based on properties | 36 # If we are entering a parent, clear the local Label\ |
| 36 vmin = node.GetProperty('version') | 37 if node.IsA('File'): self.release_map = None |
| 37 vmax = node.GetProperty('deprecate') | |
| 38 node.SetVersionRange(vmin, vmax) | |
| 39 | 38 |
| 40 # If this object is not a namespace aware object, use the parent's one | 39 # If this object is not a namespace aware object, use the parent's one |
| 41 if node.cls not in self.NamespaceSet: | 40 if node.cls not in self.NamespaceSet: |
| 42 node.namespace = parent_namespace | 41 node.namespace = parent_namespace |
| 43 else: | 42 else: |
| 44 # otherwise create one. | 43 # otherwise create one. |
| 45 node.namespace = IDLNamespace(parent_namespace) | 44 node.namespace = IDLNamespace(parent_namespace) |
| 46 node.namespace.name = node.GetName() | 45 node.namespace.name = node.GetName() |
| 47 | 46 |
| 48 # If this node is named, place it in its parent's namespace | 47 # If this node is named, place it in its parent's namespace |
| 49 if parent_namespace and node.cls in IDLNode.NamedSet: | 48 if parent_namespace and node.cls in IDLNode.NamedSet: |
| 49 # Set version min and max based on properties |
| 50 if self.release_map: |
| 51 vmin = node.GetProperty('version') |
| 52 vmax = node.GetProperty('deprecate') |
| 53 rmin = self.release_map.GetRelease(vmin) |
| 54 rmax = self.release_map.GetRelease(vmax) |
| 55 node.SetReleaseRange(rmin, rmax) |
| 50 parent_namespace.AddNode(node) | 56 parent_namespace.AddNode(node) |
| 51 | 57 |
| 52 # Pass this namespace to each child in case they inherit it | 58 # Pass this namespace to each child in case they inherit it |
| 53 return node.namespace | 59 return node.namespace |
| 54 | 60 |
| 55 # | 61 # |
| 56 # As we return from a node, if the node is a LabelItem we pass back | 62 # As we return from a node, if the node is a LabelItem we pass back |
| 57 # the key=value pair representing the mapping of release to version. | 63 # the key=value pair representing the mapping of release to version. |
| 58 # If the node is a Label take the lists of mapping and generate a | 64 # If the node is a Label take the lists of mapping and generate a |
| 59 # version map which is assigned to the Labels parent as a property. | 65 # version map which is assigned to the Labels parent as a property. |
| 60 # | 66 # |
| 61 def Depart(self, node, data, childdata): | 67 def Depart(self, node, data, childdata): |
| 62 if node.IsA('LabelItem'): | 68 if node.IsA('LabelItem'): |
| 63 return (node.GetName(), node.GetProperty('VALUE')) | 69 return (node.GetName(), node.GetProperty('VALUE')) |
| 64 if node.IsA('Label') and node.GetName() == GetOption('label'): | 70 if node.IsA('Label') and node.GetName() == GetOption('label'): |
| 65 vmap = IDLVersionMap() | 71 try: |
| 66 for release, version in childdata: | 72 self.release_map = IDLReleaseMap(childdata) |
| 67 vmap.AddReleaseVersionMapping(release, float(version)) | 73 node.parent.release_map = self.release_map |
| 68 node.parent.SetProperty("LABEL", vmap) | 74 except Exception as err: |
| 75 node.Error('Unable to build release map: %s' % str(err)) |
| 69 return None | 76 return None |
| 70 | 77 |
| 71 | 78 |
| 72 class IDLFileTypeResolver(IDLVisitor): | 79 class IDLFileTypeResolver(IDLVisitor): |
| 73 def VisitFilter(self, node, data): | 80 def VisitFilter(self, node, data): |
| 74 return not node.IsA('Comment', 'Copyright') | 81 return not node.IsA('Comment', 'Copyright') |
| 75 | 82 |
| 76 def Arrive(self, node, filenode): | 83 def Arrive(self, node, filenode): |
| 77 # Track the file node to update errors | 84 # Track the file node to update errors |
| 78 if node.IsA('File'): | 85 if node.IsA('File'): |
| 79 node.SetProperty('FILE', node) | 86 node.SetProperty('FILE', node) |
| 80 | 87 |
| 81 # If this node has a TYPEREF, resolve it to a version list | 88 # If this node has a TYPEREF, resolve it to a version list |
| 82 typeref = node.property_node.GetPropertyLocal('TYPEREF') | 89 typeref = node.property_node.GetPropertyLocal('TYPEREF') |
| 83 if typeref: | 90 if typeref: |
| 84 node.typelist = node.parent.namespace.FindList(typeref) | 91 node.typelist = node.parent.namespace.FindList(typeref) |
| 85 if not node.typelist: | 92 if not node.typelist: |
| 86 node.Error('Could not resolve %s.' % typeref) | 93 node.Error('Could not resolve %s.' % typeref) |
| 87 else: | 94 else: |
| 88 node.typelist = None | 95 node.typelist = None |
| 89 return filenode | 96 return filenode |
| 90 | 97 |
| 91 | 98 |
| 92 class IDLReleaseResolver(IDLVisitor): | |
| 93 def VisitFilter(self, node, data): | |
| 94 return node.IsA('AST','File', 'Label') | |
| 95 | |
| 96 def Depart(self, node, data, childdata): | |
| 97 if node.IsA('Label'): | |
| 98 return set([child.name for child in GetListOf('LabelItem')]) | |
| 99 return childdata | |
| 100 | |
| 101 class IDLVersionMapDefault(IDLVersionMap): | |
| 102 def GetRelease(self, version): | |
| 103 return 'M13' | |
| 104 | |
| 105 def GetVersion(self, release): | |
| 106 return float(0.0) | |
| 107 | |
| 108 # | 99 # |
| 109 # IDLAst | 100 # IDLAst |
| 110 # | 101 # |
| 111 # A specialized version of the IDLNode for containing the whole of the | 102 # A specialized version of the IDLNode for containing the whole of the |
| 112 # AST. The specialized BuildTree function pulls the per file namespaces | 103 # AST. The specialized BuildTree function pulls the per file namespaces |
| 113 # into the global AST namespace and checks for collisions. | 104 # into the global AST namespace and checks for collisions. |
| 114 # | 105 # |
| 115 class IDLAst(IDLNode): | 106 class IDLAst(IDLNode): |
| 116 def __init__(self, children): | 107 def __init__(self, children): |
| 117 objs = [] | 108 objs = [] |
| 118 | 109 |
| 119 builtin = None | 110 builtin = None |
| 120 extranodes = [] | 111 extranodes = [] |
| 121 for filenode in children: | 112 for filenode in children: |
| 122 if filenode.GetProperty('NAME') == 'pp_stdint.idl': | 113 if filenode.GetProperty('NAME') == 'pp_stdint.idl': |
| 123 builtin = filenode | 114 builtin = filenode |
| 124 break | 115 break |
| 125 | 116 |
| 126 IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, extranodes + children) | 117 IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, extranodes + children) |
| 127 self.SetProperty('LABEL', IDLVersionMapDefault()) | |
| 128 self.Resolve() | 118 self.Resolve() |
| 129 | 119 |
| 130 def Resolve(self): | 120 def Resolve(self): |
| 131 self.namespace = IDLNamespace(None) | 121 self.namespace = IDLNamespace(None) |
| 132 self.namespace.name = 'AST' | 122 self.namespace.name = 'AST' |
| 133 IDLNamespaceLabelResolver().Visit(self, self.namespace) | 123 IDLNamespaceLabelResolver().Visit(self, self.namespace) |
| 134 IDLFileTypeResolver().Visit(self, None) | 124 IDLFileTypeResolver().Visit(self, None) |
| 135 | 125 |
| 136 # Build an ordered list of all releases | 126 # Build an ordered list of all releases |
| 137 self.releases = set() | 127 self.releases = set() |
| 138 for filenode in self.GetListOf('File'): | 128 for filenode in self.GetListOf('File'): |
| 139 vmap = filenode.GetProperty('LABEL') | 129 self.releases |= set(filenode.release_map.GetReleases()) |
| 140 self.releases |= set(vmap.releases) | |
| 141 self.releases = sorted(self.releases) | 130 self.releases = sorted(self.releases) |
| 142 | 131 |
| 143 def SetTypeInfo(self, name, properties): | 132 def SetTypeInfo(self, name, properties): |
| 144 node = self.namespace[name] | 133 node = self.namespace[name] |
| 145 for prop in properties: | 134 for prop in properties: |
| 146 node.properties[prop] = properties[prop] | 135 node.properties[prop] = properties[prop] |
| 147 | 136 |
| 148 | 137 |
| OLD | NEW |