"""Nodes for PPAPI IDL AST."""
from __future__ import print_function
from idl_namespace import IDLNamespace
from idl_node import IDLNode
from idl_option import GetOption
from idl_visitor import IDLVisitor
from idl_release import IDLReleaseMap
class IDLLabelResolver(IDLVisitor):
def Depart(self, node, ignore, childdata):
if node.IsA('LabelItem'):
channel = node.GetProperty('channel')
if not channel:
channel = 'stable'
return (node.GetName(), node.GetProperty('VALUE'), channel)
if node.IsA('Label') and node.GetName() == GetOption('label'):
try:
node.parent.release_map = IDLReleaseMap(childdata)
except Exception as err:
node.Error('Unable to build release map: %s' % str(err))
if node.IsA('File'):
file_min, _ = node.release_map.GetReleaseRange()
node.SetMin(file_min)
return None
class IDLNamespaceVersionResolver(IDLVisitor):
NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct'])
def Arrive(self, node, parent_namespace):
if node.IsA('File'):
self.rmin = node.GetMinMax()[0]
self.release_map = node.release_map
if not node.IsA('AST', 'File', 'Label', 'LabelItem'):
my_min, _ = node.GetMinMax()
if not my_min:
node.SetMin(self.rmin)
if node.cls not in self.NamespaceSet:
node.namespace = parent_namespace
else:
node.namespace = IDLNamespace(parent_namespace)
if parent_namespace and node.cls in IDLNode.NamedSet:
if self.release_map:
vmin = node.GetProperty('dev_version')
if vmin == None:
vmin = node.GetProperty('version')
vmax = node.GetProperty('deprecate')
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)
return node.namespace
class IDLFileTypeResolver(IDLVisitor):
def VisitFilter(self, node, data):
return not node.IsA('Comment', 'Copyright')
def Arrive(self, node, filenode):
if node.IsA('File'):
node.SetProperty('FILE', node)
filenode = node
if not node.IsA('AST'):
file_min, _ = filenode.release_map.GetReleaseRange()
if not file_min:
print('Resetting min on %s to %s' % (node, file_min))
node.SetMinRange(file_min)
typeref = node.GetPropertyLocal('TYPEREF')
if typeref:
node.typelist = node.parent.namespace.FindList(typeref)
if not node.typelist:
node.Error('Could not resolve %s.' % typeref)
else:
node.typelist = None
return filenode
class IDLReleaseResolver(IDLVisitor):
def Arrive(self, node, releases):
node.BuildReleaseMap(releases)
return releases
class IDLAst(IDLNode):
def __init__(self, children):
IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, children)
self.Resolve()
def Resolve(self):
IDLLabelResolver().Visit(self, None)
self.namespace = IDLNamespace(None)
IDLNamespaceVersionResolver().Visit(self, self.namespace)
IDLFileTypeResolver().Visit(self, None)
releases = set()
for filenode in self.GetListOf('File'):
releases |= set(filenode.release_map.GetReleases())
IDLReleaseResolver().Visit(self, sorted(releases))
for filenode in self.GetListOf('File'):
errors = filenode.GetProperty('ERRORS')
if errors:
self.errors += errors