diff options
author | noelallen@chromium.org <noelallen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-23 18:10:02 +0000 |
---|---|---|
committer | noelallen@chromium.org <noelallen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-23 18:10:02 +0000 |
commit | 98cfdfce60a0a155ada3b5c952ec0358e5933484 (patch) | |
tree | efd6f8b65498a5bfc5335d1c54d40fd56ee2a2af /ppapi/generators/idl_ast.py | |
parent | ccec4adb0558007d00b89da348ff49a10d113e9c (diff) | |
download | chromium_src-98cfdfce60a0a155ada3b5c952ec0358e5933484.zip chromium_src-98cfdfce60a0a155ada3b5c952ec0358e5933484.tar.gz chromium_src-98cfdfce60a0a155ada3b5c952ec0358e5933484.tar.bz2 |
Change the way we generate versions.
Changes (sehr)
Remove hashes used to determine 'unique' versions.
Build release lists for versionable nodes
Build mapping for any release to first release
Added support to treat interface as type
Cleanup (sehr)
Removed verbose output from pnacl wrapper.
Cleanup use of "private" members
Add better error recovery on parsing to prevent deadlock.
Fix parser tests.
To prevent growing this CL, additional cleanup in BUG=157025
PPAPI (brettw)
api/private/*.idl + c/private/*.h
Fix IDL use of net_address_private prior to definition
Date change on ppapi headers to pass presubmit
BUG=156719
TEST=idl_parser.py --test
Review URL: https://chromiumcodereview.appspot.com/11235016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163603 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/generators/idl_ast.py')
-rw-r--r-- | ppapi/generators/idl_ast.py | 146 |
1 files changed, 108 insertions, 38 deletions
diff --git a/ppapi/generators/idl_ast.py b/ppapi/generators/idl_ast.py index b7ad6f0..2765892 100644 --- a/ppapi/generators/idl_ast.py +++ b/ppapi/generators/idl_ast.py @@ -19,28 +19,76 @@ BuiltIn = set(['int8_t', 'int16_t', 'int32_t', 'int64_t', 'uint8_t', # -# IDLNamespaceLabelResolver +# IDLLabelResolver # -# Once the AST is build, we need to resolve the namespace and version -# information. +# A specialized visitor which traverses the AST, building a mapping of +# Release names to Versions numbers and calculating a min version. +# The mapping is applied to the File nodes within the AST. # -class IDLNamespaceLabelResolver(IDLVisitor): +class IDLLabelResolver(IDLVisitor): + def Arrive(self, node, ignore): + # If we are entering a File, clear the visitor local mapping + if node.IsA('File'): + self.release_map = None + self.filenode = node + # For any non AST node, the filenode is the last known file + if not node.IsA('AST'): + node.filenode = self.filenode + return ignore + + def Depart(self, node, ignore, childdata): + # Build list of Release=Version + if node.IsA('LabelItem'): + return (node.GetName(), node.GetProperty('VALUE')) + + # On completion of the Label, apply to the parent File if the + # name of the label matches the generation label. + if node.IsA('Label') and node.GetName() == GetOption('label'): + try: + self.release_map = IDLReleaseMap(childdata) + node.parent.release_map = self.release_map + except Exception as err: + node.Error('Unable to build release map: %s' % str(err)) + + # For File objects, set the minimum version + if node.IsA('File'): + file_min, file_max = node.release_map.GetReleaseRange() + node.SetMin(file_min) + + return None + + +# +# IDLNamespaceVersionResolver +# +# A specialized visitor which traverses the AST, building a namespace tree +# as it goes. The namespace tree is mapping from a name to a version list. +# Labels must already be resolved to use. +# +class IDLNamespaceVersionResolver(IDLVisitor): NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct']) # # When we arrive at a node we must assign it a namespace and if the # node is named, then place it in the appropriate namespace. # def Arrive(self, node, parent_namespace): - # If we are entering a parent, clear the local Label\ - if node.IsA('File'): self.release_map = None + # If we are a File, grab the Min version and replease mapping + if node.IsA('File'): + self.rmin = node.GetMinMax()[0] + self.release_map = node.release_map + + # Set the min version on any non Label within the File + if not node.IsA('AST', 'File', 'Label', 'LabelItem'): + my_min, my_max = node.GetMinMax() + if not my_min: + node.SetMin(self.rmin) # If this object is not a namespace aware object, use the parent's one if node.cls not in self.NamespaceSet: node.namespace = parent_namespace else: # otherwise create one. - node.namespace = IDLNamespace(parent_namespace) - node.namespace.name = node.GetName() + node.namespace = IDLNamespace(parent_namespace, node.GetName()) # If this node is named, place it in its parent's namespace if parent_namespace and node.cls in IDLNode.NamedSet: @@ -48,7 +96,11 @@ class IDLNamespaceLabelResolver(IDLVisitor): if self.release_map: vmin = node.GetProperty('version') vmax = node.GetProperty('deprecate') - rmin = self.release_map.GetRelease(vmin) + # If no min is available, the use the parent File's min + if vmin == None: + rmin = self.rmin + else: + rmin = self.release_map.GetRelease(vmin) rmax = self.release_map.GetRelease(vmax) node.SetReleaseRange(rmin, rmax) parent_namespace.AddNode(node) @@ -56,24 +108,15 @@ class IDLNamespaceLabelResolver(IDLVisitor): # Pass this namespace to each child in case they inherit it return node.namespace - # - # As we return from a node, if the node is a LabelItem we pass back - # the key=value pair representing the mapping of release to version. - # If the node is a Label take the lists of mapping and generate a - # version map which is assigned to the Labels parent as a property. - # - def Depart(self, node, data, childdata): - if node.IsA('LabelItem'): - return (node.GetName(), node.GetProperty('VALUE')) - if node.IsA('Label') and node.GetName() == GetOption('label'): - try: - self.release_map = IDLReleaseMap(childdata) - node.parent.release_map = self.release_map - except Exception as err: - node.Error('Unable to build release map: %s' % str(err)) - return None - +# +# IDLFileTypeRessolver +# +# A specialized visitor which traverses the AST and sets a FILE property +# on all file nodes. In addition, searches the namespace resolving all +# type references. The namespace tree must already have been populated +# before this visitor is used. +# class IDLFileTypeResolver(IDLVisitor): def VisitFilter(self, node, data): return not node.IsA('Comment', 'Copyright') @@ -82,6 +125,13 @@ class IDLFileTypeResolver(IDLVisitor): # Track the file node to update errors if node.IsA('File'): node.SetProperty('FILE', node) + filenode = node + + if not node.IsA('AST'): + file_min, file_max = filenode.release_map.GetReleaseRange() + if not file_min: + print 'Resetting min on %s to %s' % (node, file_min) + node.SetMinRange(file_min) # If this node has a TYPEREF, resolve it to a version list typeref = node.property_node.GetPropertyLocal('TYPEREF') @@ -93,13 +143,26 @@ class IDLFileTypeResolver(IDLVisitor): node.typelist = None return filenode +# +# IDLReleaseResolver +# +# A specialized visitor which will traverse the AST, and generate a mapping +# from any release to the first release in which that version of the object +# was generated. Types must already be resolved to use. +# +class IDLReleaseResolver(IDLVisitor): + def Arrive(self, node, releases): + node.BuildReleaseMap(releases) + return releases + # # IDLAst # # A specialized version of the IDLNode for containing the whole of the -# AST. The specialized BuildTree function pulls the per file namespaces -# into the global AST namespace and checks for collisions. +# AST. Construction of the AST object will cause resolution of the +# tree including versions, types, etc... Errors counts will be collected +# both per file, and on the AST itself. # class IDLAst(IDLNode): def __init__(self, children): @@ -107,18 +170,25 @@ class IDLAst(IDLNode): self.Resolve() def Resolve(self): - self.namespace = IDLNamespace(None) - self.namespace.name = 'AST' - IDLNamespaceLabelResolver().Visit(self, self.namespace) + # Set the appropriate Release=Version mapping for each File + IDLLabelResolver().Visit(self, None) + + # Generate the Namesapce Tree + self.namespace = IDLNamespace(None, 'AST') + IDLNamespaceVersionResolver().Visit(self, self.namespace) + + # Using the namespace, resolve type references IDLFileTypeResolver().Visit(self, None) # Build an ordered list of all releases - self.releases = set() + releases = set() for filenode in self.GetListOf('File'): - self.releases |= set(filenode.release_map.GetReleases()) - self.releases = sorted(self.releases) + releases |= set(filenode.release_map.GetReleases()) + + # Generate a per node list of releases and release mapping + IDLReleaseResolver().Visit(self, sorted(releases)) + + for filenode in self.GetListOf('File'): + self.errors += int(filenode.GetProperty('ERRORS', 0)) + - def SetTypeInfo(self, name, properties): - node = self.namespace[name] - for prop in properties: - node.properties[prop] = properties[prop] |