15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Nodes for PPAPI IDL AST.""" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_namespace import IDLNamespace 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)from idl_node import IDLNode 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_option import GetOption 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_visitor import IDLVisitor 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)from idl_release import IDLReleaseMap 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLLabelResolver 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A specialized visitor which traverses the AST, building a mapping of 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Release names to Versions numbers and calculating a min version. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The mapping is applied to the File nodes within the AST. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLLabelResolver(IDLVisitor): 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Depart(self, node, ignore, childdata): 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Build list of Release=Version 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.IsA('LabelItem'): 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (node.GetName(), node.GetProperty('VALUE')) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # On completion of the Label, apply to the parent File if the 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # name of the label matches the generation label. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.IsA('Label') and node.GetName() == GetOption('label'): 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) node.parent.release_map = IDLReleaseMap(childdata) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except Exception as err: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.Error('Unable to build release map: %s' % str(err)) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # For File objects, set the minimum version 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.IsA('File'): 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_min, _ = node.release_map.GetReleaseRange() 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.SetMin(file_min) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLNamespaceVersionResolver 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A specialized visitor which traverses the AST, building a namespace tree 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# as it goes. The namespace tree is mapping from a name to a version list. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Labels must already be resolved to use. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLNamespaceVersionResolver(IDLVisitor): 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct']) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # When we arrive at a node we must assign it a namespace and if the 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # node is named, then place it in the appropriate namespace. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Arrive(self, node, parent_namespace): 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If we are a File, grab the Min version and replease mapping 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.IsA('File'): 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.rmin = node.GetMinMax()[0] 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.release_map = node.release_map 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the min version on any non Label within the File 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not node.IsA('AST', 'File', 'Label', 'LabelItem'): 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) my_min, _ = node.GetMinMax() 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not my_min: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.SetMin(self.rmin) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If this object is not a namespace aware object, use the parent's one 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.cls not in self.NamespaceSet: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.namespace = parent_namespace 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # otherwise create one. 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node.namespace = IDLNamespace(parent_namespace) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If this node is named, place it in its parent's namespace 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if parent_namespace and node.cls in IDLNode.NamedSet: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set version min and max based on properties 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.release_map: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vmin = node.GetProperty('version') 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vmax = node.GetProperty('deprecate') 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If no min is available, the use the parent File's min 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if vmin == None: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rmin = self.rmin 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rmin = self.release_map.GetRelease(vmin) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rmax = self.release_map.GetRelease(vmax) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.SetReleaseRange(rmin, rmax) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_namespace.AddNode(node) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Pass this namespace to each child in case they inherit it 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return node.namespace 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLFileTypeRessolver 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A specialized visitor which traverses the AST and sets a FILE property 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# on all file nodes. In addition, searches the namespace resolving all 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# type references. The namespace tree must already have been populated 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# before this visitor is used. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLFileTypeResolver(IDLVisitor): 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def VisitFilter(self, node, data): 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return not node.IsA('Comment', 'Copyright') 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Arrive(self, node, filenode): 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Track the file node to update errors 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.IsA('File'): 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.SetProperty('FILE', node) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenode = node 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not node.IsA('AST'): 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_min, _ = filenode.release_map.GetReleaseRange() 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not file_min: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'Resetting min on %s to %s' % (node, file_min) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.SetMinRange(file_min) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If this node has a TYPEREF, resolve it to a version list 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typeref = node.GetPropertyLocal('TYPEREF') 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if typeref: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.typelist = node.parent.namespace.FindList(typeref) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not node.typelist: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.Error('Could not resolve %s.' % typeref) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.typelist = None 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return filenode 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLReleaseResolver 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A specialized visitor which will traverse the AST, and generate a mapping 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# from any release to the first release in which that version of the object 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# was generated. Types must already be resolved to use. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLReleaseResolver(IDLVisitor): 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Arrive(self, node, releases): 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.BuildReleaseMap(releases) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return releases 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLAst 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A specialized version of the IDLNode for containing the whole of the 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# AST. Construction of the AST object will cause resolution of the 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# tree including versions, types, etc... Errors counts will be collected 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# both per file, and on the AST itself. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLAst(IDLNode): 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, children): 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, children) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.Resolve() 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Resolve(self): 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the appropriate Release=Version mapping for each File 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDLLabelResolver().Visit(self, None) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Generate the Namesapce Tree 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self.namespace = IDLNamespace(None) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDLNamespaceVersionResolver().Visit(self, self.namespace) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Using the namespace, resolve type references 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDLFileTypeResolver().Visit(self, None) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Build an ordered list of all releases 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) releases = set() 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for filenode in self.GetListOf('File'): 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) releases |= set(filenode.release_map.GetReleases()) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Generate a per node list of releases and release mapping 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDLReleaseResolver().Visit(self, sorted(releases)) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for filenode in self.GetListOf('File'): 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) errors = filenode.GetProperty('ERRORS') 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if errors: 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self.errors += errors 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 178