| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Nodes for PPAPI IDL AST""" | 6 """Nodes for PPAPI IDL AST""" |
| 7 | 7 |
| 8 # | 8 # |
| 9 # IDL Node | 9 # IDL Node |
| 10 # | 10 # |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 NamedSet = set(['Enum', 'EnumItem', 'File', 'Function', 'Interface', | 51 NamedSet = set(['Enum', 'EnumItem', 'File', 'Function', 'Interface', |
| 52 'Member', 'Param', 'Struct', 'Type', 'Typedef']) | 52 'Member', 'Param', 'Struct', 'Type', 'Typedef']) |
| 53 | 53 |
| 54 def __init__(self, cls, filename, lineno, pos, children=None): | 54 def __init__(self, cls, filename, lineno, pos, children=None): |
| 55 # Initialize with no starting or ending Version | 55 # Initialize with no starting or ending Version |
| 56 IDLRelease.__init__(self, None, None) | 56 IDLRelease.__init__(self, None, None) |
| 57 | 57 |
| 58 self.cls = cls | 58 self.cls = cls |
| 59 self.lineno = lineno | 59 self.lineno = lineno |
| 60 self.pos = pos | 60 self.pos = pos |
| 61 self.filename = filename | 61 self._filename = filename |
| 62 self.filenode = None | 62 self._deps = {} |
| 63 self.deps = {} | |
| 64 self.errors = 0 | 63 self.errors = 0 |
| 65 self.namespace = None | 64 self.namespace = None |
| 66 self.typelist = None | 65 self.typelist = None |
| 67 self.parent = None | 66 self.parent = None |
| 68 self.property_node = IDLPropertyNode() | 67 self._property_node = IDLPropertyNode() |
| 69 self.unique_releases = None | 68 self._unique_releases = None |
| 70 | 69 |
| 71 # A list of unique releases for this node | 70 # A list of unique releases for this node |
| 72 self.releases = None | 71 self.releases = None |
| 73 | 72 |
| 74 # A map from any release, to the first unique release | 73 # A map from any release, to the first unique release |
| 75 self.first_release = None | 74 self.first_release = None |
| 76 | 75 |
| 77 # self.children is a list of children ordered as defined | 76 # self._children is a list of children ordered as defined |
| 78 self.children = [] | 77 self._children = [] |
| 79 # Process the passed in list of children, placing ExtAttributes into the | 78 # Process the passed in list of children, placing ExtAttributes into the |
| 80 # property dictionary, and nodes into the local child list in order. In | 79 # property dictionary, and nodes into the local child list in order. In |
| 81 # addition, add nodes to the namespace if the class is in the NamedSet. | 80 # addition, add nodes to the namespace if the class is in the NamedSet. |
| 82 if children: | 81 if children: |
| 83 for child in children: | 82 for child in children: |
| 84 if child.cls == 'ExtAttribute': | 83 if child.cls == 'ExtAttribute': |
| 85 self.SetProperty(child.name, child.value) | 84 self.SetProperty(child.name, child.value) |
| 86 else: | 85 else: |
| 87 self.AddChild(child) | 86 self.AddChild(child) |
| 88 | 87 |
| 89 # | |
| 90 # String related functions | |
| 91 # | |
| 92 # | |
| 93 | |
| 94 # Return a string representation of this node | |
| 95 def __str__(self): | 88 def __str__(self): |
| 96 name = self.GetName() | 89 name = self.GetName() |
| 97 if name is None: | 90 if name is None: |
| 98 name = '' | 91 name = '' |
| 99 return '%s(%s)' % (self.cls, name) | 92 return '%s(%s)' % (self.cls, name) |
| 100 | 93 |
| 101 # Return file and line number for where node was defined | |
| 102 def Location(self): | 94 def Location(self): |
| 103 return '%s(%d)' % (self.filename, self.lineno) | 95 """Return a file and line number for where this node was defined.""" |
| 96 return '%s(%d)' % (self._filename, self.lineno) |
| 104 | 97 |
| 105 # Log an error for this object | |
| 106 def Error(self, msg): | 98 def Error(self, msg): |
| 99 """Log an error for this object.""" |
| 107 self.errors += 1 | 100 self.errors += 1 |
| 108 ErrOut.LogLine(self.filename, self.lineno, 0, ' %s %s' % | 101 ErrOut.LogLine(self._filename, self.lineno, 0, ' %s %s' % |
| 109 (str(self), msg)) | 102 (str(self), msg)) |
| 110 if self.filenode: | 103 filenode = self.GetProperty('FILE') |
| 111 errcnt = self.filenode.GetProperty('ERRORS') | 104 if filenode: |
| 105 errcnt = filenode.GetProperty('ERRORS') |
| 112 if not errcnt: | 106 if not errcnt: |
| 113 errcnt = 0 | 107 errcnt = 0 |
| 114 self.filenode.SetProperty('ERRORS', errcnt + 1) | 108 filenode.SetProperty('ERRORS', errcnt + 1) |
| 115 | 109 |
| 116 # Log a warning for this object | |
| 117 def Warning(self, msg): | 110 def Warning(self, msg): |
| 118 WarnOut.LogLine(self.filename, self.lineno, 0, ' %s %s' % | 111 """Log a warning for this object.""" |
| 112 WarnOut.LogLine(self._filename, self.lineno, 0, ' %s %s' % |
| 119 (str(self), msg)) | 113 (str(self), msg)) |
| 120 | 114 |
| 121 def GetName(self): | 115 def GetName(self): |
| 122 return self.GetProperty('NAME') | 116 return self.GetProperty('NAME') |
| 123 | 117 |
| 124 # Dump this object and its children | |
| 125 def Dump(self, depth=0, comments=False, out=sys.stdout): | 118 def Dump(self, depth=0, comments=False, out=sys.stdout): |
| 119 """Dump this object and its children""" |
| 126 if self.cls in ['Comment', 'Copyright']: | 120 if self.cls in ['Comment', 'Copyright']: |
| 127 is_comment = True | 121 is_comment = True |
| 128 else: | 122 else: |
| 129 is_comment = False | 123 is_comment = False |
| 130 | 124 |
| 131 # Skip this node if it's a comment, and we are not printing comments | 125 # Skip this node if it's a comment, and we are not printing comments |
| 132 if not comments and is_comment: | 126 if not comments and is_comment: |
| 133 return | 127 return |
| 134 | 128 |
| 135 tab = ''.rjust(depth * 2) | 129 tab = ''.rjust(depth * 2) |
| 136 if is_comment: | 130 if is_comment: |
| 137 out.write('%sComment\n' % tab) | 131 out.write('%sComment\n' % tab) |
| 138 for line in self.GetName().split('\n'): | 132 for line in self.GetName().split('\n'): |
| 139 out.write('%s "%s"\n' % (tab, line)) | 133 out.write('%s "%s"\n' % (tab, line)) |
| 140 else: | 134 else: |
| 141 ver = IDLRelease.__str__(self) | 135 ver = IDLRelease.__str__(self) |
| 142 if self.releases: | 136 if self.releases: |
| 143 release_list = ': ' + ' '.join(self.releases) | 137 release_list = ': ' + ' '.join(self.releases) |
| 144 else: | 138 else: |
| 145 release_list = ': undefined' | 139 release_list = ': undefined' |
| 146 out.write('%s%s%s%s\n' % (tab, self, ver, release_list)) | 140 out.write('%s%s%s%s\n' % (tab, self, ver, release_list)) |
| 147 if self.typelist: | 141 if self.typelist: |
| 148 out.write('%s Typelist: %s\n' % (tab, self.typelist.GetReleases()[0])) | 142 out.write('%s Typelist: %s\n' % (tab, self.typelist.GetReleases()[0])) |
| 149 properties = self.property_node.GetPropertyList() | 143 properties = self._property_node.GetPropertyList() |
| 150 if properties: | 144 if properties: |
| 151 out.write('%s Properties\n' % tab) | 145 out.write('%s Properties\n' % tab) |
| 152 for p in properties: | 146 for p in properties: |
| 153 if is_comment and p == 'NAME': | 147 if is_comment and p == 'NAME': |
| 154 # Skip printing the name for comments, since we printed above already | 148 # Skip printing the name for comments, since we printed above already |
| 155 continue | 149 continue |
| 156 out.write('%s %s : %s\n' % (tab, p, self.GetProperty(p))) | 150 out.write('%s %s : %s\n' % (tab, p, self.GetProperty(p))) |
| 157 for child in self.children: | 151 for child in self._children: |
| 158 child.Dump(depth+1, comments=comments, out=out) | 152 child.Dump(depth+1, comments=comments, out=out) |
| 159 | 153 |
| 160 # | |
| 161 # Search related functions | |
| 162 # | |
| 163 # Check if node is of a given type | |
| 164 def IsA(self, *typelist): | 154 def IsA(self, *typelist): |
| 155 """Check if node is of a given type.""" |
| 165 return self.cls in typelist | 156 return self.cls in typelist |
| 166 | 157 |
| 167 # Get a list of objects for this key | |
| 168 def GetListOf(self, *keys): | 158 def GetListOf(self, *keys): |
| 159 """Get a list of objects for the given key(s).""" |
| 169 out = [] | 160 out = [] |
| 170 for child in self.children: | 161 for child in self._children: |
| 171 if child.cls in keys: | 162 if child.cls in keys: |
| 172 out.append(child) | 163 out.append(child) |
| 173 return out | 164 return out |
| 174 | 165 |
| 175 def GetOneOf(self, *keys): | 166 def GetOneOf(self, *keys): |
| 167 """Get an object for the given key(s).""" |
| 176 out = self.GetListOf(*keys) | 168 out = self.GetListOf(*keys) |
| 177 if out: | 169 if out: |
| 178 return out[0] | 170 return out[0] |
| 179 return None | 171 return None |
| 180 | 172 |
| 181 def SetParent(self, parent): | 173 def SetParent(self, parent): |
| 182 self.property_node.AddParent(parent) | 174 self._property_node.AddParent(parent) |
| 183 self.parent = parent | 175 self.parent = parent |
| 184 | 176 |
| 185 def AddChild(self, node): | 177 def AddChild(self, node): |
| 186 node.SetParent(self) | 178 node.SetParent(self) |
| 187 self.children.append(node) | 179 self._children.append(node) |
| 188 | 180 |
| 189 # Get a list of all children | 181 # Get a list of all children |
| 190 def GetChildren(self): | 182 def GetChildren(self): |
| 191 return self.children | 183 return self._children |
| 192 | 184 |
| 193 def GetType(self, release): | 185 def GetType(self, release): |
| 194 if not self.typelist: | 186 if not self.typelist: |
| 195 return None | 187 return None |
| 196 return self.typelist.FindRelease(release) | 188 return self.typelist.FindRelease(release) |
| 197 | 189 |
| 198 def GetDeps(self, release, visited=None): | 190 def GetDeps(self, release, visited=None): |
| 199 visited = visited or set() | 191 visited = visited or set() |
| 200 | 192 |
| 201 # If this release is not valid for this object, then done. | 193 # If this release is not valid for this object, then done. |
| 202 if not self.IsRelease(release) or self.IsA('Comment', 'Copyright'): | 194 if not self.IsRelease(release) or self.IsA('Comment', 'Copyright'): |
| 203 return set([]) | 195 return set([]) |
| 204 | 196 |
| 205 # If we have cached the info for this release, return the cached value | 197 # If we have cached the info for this release, return the cached value |
| 206 deps = self.deps.get(release, None) | 198 deps = self._deps.get(release, None) |
| 207 if deps is not None: | 199 if deps is not None: |
| 208 return deps | 200 return deps |
| 209 | 201 |
| 210 # If we are already visited, then return | 202 # If we are already visited, then return |
| 211 if self in visited: | 203 if self in visited: |
| 212 return set([self]) | 204 return set([self]) |
| 213 | 205 |
| 214 # Otherwise, build the dependency list | 206 # Otherwise, build the dependency list |
| 215 visited |= set([self]) | 207 visited |= set([self]) |
| 216 deps = set([self]) | 208 deps = set([self]) |
| 217 | 209 |
| 218 # Get child deps | 210 # Get child deps |
| 219 for child in self.GetChildren(): | 211 for child in self.GetChildren(): |
| 220 deps |= child.GetDeps(release, visited) | 212 deps |= child.GetDeps(release, visited) |
| 221 visited |= set(deps) | 213 visited |= set(deps) |
| 222 | 214 |
| 223 # Get type deps | 215 # Get type deps |
| 224 typeref = self.GetType(release) | 216 typeref = self.GetType(release) |
| 225 if typeref: | 217 if typeref: |
| 226 deps |= typeref.GetDeps(release, visited) | 218 deps |= typeref.GetDeps(release, visited) |
| 227 | 219 |
| 228 self.deps[release] = deps | 220 self._deps[release] = deps |
| 229 return deps | 221 return deps |
| 230 | 222 |
| 231 def GetVersion(self, release): | 223 def GetVersion(self, release): |
| 232 filenode = self.GetProperty('FILE') | 224 filenode = self.GetProperty('FILE') |
| 233 if not filenode: | 225 if not filenode: |
| 234 return None | 226 return None |
| 235 return filenode.release_map.GetVersion(release) | 227 return filenode.release_map.GetVersion(release) |
| 236 | 228 |
| 237 def GetUniqueReleases(self, releases): | 229 def GetUniqueReleases(self, releases): |
| 238 """Return the unique set of first releases corresponding to input | 230 """Return the unique set of first releases corresponding to input |
| 239 | 231 |
| 240 Since we are returning the corresponding 'first' version for a | 232 Since we are returning the corresponding 'first' version for a |
| 241 release, we may return a release version prior to the one in the list.""" | 233 release, we may return a release version prior to the one in the list.""" |
| 242 my_min, my_max = self.GetMinMax(releases) | 234 my_min, my_max = self.GetMinMax(releases) |
| 243 if my_min > releases[-1] or my_max < releases[0]: | 235 if my_min > releases[-1] or my_max < releases[0]: |
| 244 return [] | 236 return [] |
| 245 | 237 |
| 246 out = set() | 238 out = set() |
| 247 for rel in releases: | 239 for rel in releases: |
| 248 remapped = self.first_release[rel] | 240 remapped = self.first_release[rel] |
| 249 if not remapped: | 241 if not remapped: |
| 250 continue | 242 continue |
| 251 out |= set([remapped]) | 243 out |= set([remapped]) |
| 252 | 244 |
| 253 # Cache the most recent set of unique_releases | 245 # Cache the most recent set of unique_releases |
| 254 self.unique_releases = sorted(out) | 246 self._unique_releases = sorted(out) |
| 255 return self.unique_releases | 247 return self._unique_releases |
| 256 | 248 |
| 257 def LastRelease(self, release): | 249 def LastRelease(self, release): |
| 258 # Get the most recent release from the most recently generated set of | 250 # Get the most recent release from the most recently generated set of |
| 259 # cached unique releases. | 251 # cached unique releases. |
| 260 if self.unique_releases and self.unique_releases[-1] > release: | 252 if self._unique_releases and self._unique_releases[-1] > release: |
| 261 return False | 253 return False |
| 262 return True | 254 return True |
| 263 | 255 |
| 264 def GetRelease(self, version): | 256 def GetRelease(self, version): |
| 265 filenode = self.GetProperty('FILE') | 257 filenode = self.GetProperty('FILE') |
| 266 if not filenode: | 258 if not filenode: |
| 267 return None | 259 return None |
| 268 return filenode.release_map.GetRelease(version) | 260 return filenode.release_map.GetRelease(version) |
| 269 | 261 |
| 270 def _GetReleaseList(self, releases, visited=None): | 262 def _GetReleaseList(self, releases, visited=None): |
| (...skipping 22 matching lines...) Expand all Loading... |
| 293 # Files inherit all their releases from items in the file | 285 # Files inherit all their releases from items in the file |
| 294 if self.IsA('AST', 'File'): | 286 if self.IsA('AST', 'File'): |
| 295 my_releases = set() | 287 my_releases = set() |
| 296 | 288 |
| 297 # Visit all children | 289 # Visit all children |
| 298 child_releases = set() | 290 child_releases = set() |
| 299 | 291 |
| 300 # Exclude sibling results from parent visited set | 292 # Exclude sibling results from parent visited set |
| 301 cur_visits = visited | 293 cur_visits = visited |
| 302 | 294 |
| 303 for child in self.children: | 295 for child in self._children: |
| 304 child_releases |= set(child._GetReleaseList(releases, cur_visits)) | 296 child_releases |= set(child._GetReleaseList(releases, cur_visits)) |
| 305 visited |= set(child_releases) | 297 visited |= set(child_releases) |
| 306 | 298 |
| 307 # Visit my type | 299 # Visit my type |
| 308 type_releases = set() | 300 type_releases = set() |
| 309 if self.typelist: | 301 if self.typelist: |
| 310 type_list = self.typelist.GetReleases() | 302 type_list = self.typelist.GetReleases() |
| 311 for typenode in type_list: | 303 for typenode in type_list: |
| 312 type_releases |= set(typenode._GetReleaseList(releases, cur_visits)) | 304 type_releases |= set(typenode._GetReleaseList(releases, cur_visits)) |
| 313 | 305 |
| 314 type_release_list = sorted(type_releases) | 306 type_release_list = sorted(type_releases) |
| 315 if my_min < type_release_list[0]: | 307 if my_min < type_release_list[0]: |
| 316 type_node = type_list[0] | 308 type_node = type_list[0] |
| 317 self.Error('requires %s in %s which is undefined at %s.' % ( | 309 self.Error('requires %s in %s which is undefined at %s.' % ( |
| 318 type_node, type_node.filename, my_min)) | 310 type_node, type_node._filename, my_min)) |
| 319 | 311 |
| 320 for rel in child_releases | type_releases: | 312 for rel in child_releases | type_releases: |
| 321 if rel >= my_min and rel <= my_max: | 313 if rel >= my_min and rel <= my_max: |
| 322 my_releases |= set([rel]) | 314 my_releases |= set([rel]) |
| 323 | 315 |
| 324 self.releases = sorted(my_releases) | 316 self.releases = sorted(my_releases) |
| 325 return self.releases | 317 return self.releases |
| 326 | 318 |
| 327 def GetReleaseList(self): | |
| 328 return self.releases | |
| 329 | |
| 330 def BuildReleaseMap(self, releases): | 319 def BuildReleaseMap(self, releases): |
| 331 unique_list = self._GetReleaseList(releases) | 320 unique_list = self._GetReleaseList(releases) |
| 332 _, my_max = self.GetMinMax(releases) | 321 _, my_max = self.GetMinMax(releases) |
| 333 | 322 |
| 334 self.first_release = {} | 323 self.first_release = {} |
| 335 last_rel = None | 324 last_rel = None |
| 336 for rel in releases: | 325 for rel in releases: |
| 337 if rel in unique_list: | 326 if rel in unique_list: |
| 338 last_rel = rel | 327 last_rel = rel |
| 339 self.first_release[rel] = last_rel | 328 self.first_release[rel] = last_rel |
| 340 if rel == my_max: | 329 if rel == my_max: |
| 341 last_rel = None | 330 last_rel = None |
| 342 | 331 |
| 343 def SetProperty(self, name, val): | 332 def SetProperty(self, name, val): |
| 344 self.property_node.SetProperty(name, val) | 333 self._property_node.SetProperty(name, val) |
| 345 | 334 |
| 346 def GetProperty(self, name): | 335 def GetProperty(self, name): |
| 347 return self.property_node.GetProperty(name) | 336 return self._property_node.GetProperty(name) |
| 348 | 337 |
| 338 def GetPropertyLocal(self, name): |
| 339 return self._property_node.GetPropertyLocal(name) |
| 349 | 340 |
| 350 # | 341 # |
| 351 # IDLFile | 342 # IDLFile |
| 352 # | 343 # |
| 353 # A specialized version of IDLNode which tracks errors and warnings. | 344 # A specialized version of IDLNode which tracks errors and warnings. |
| 354 # | 345 # |
| 355 class IDLFile(IDLNode): | 346 class IDLFile(IDLNode): |
| 356 def __init__(self, name, children, errors=0): | 347 def __init__(self, name, children, errors=0): |
| 357 attrs = [IDLAttribute('NAME', name), | 348 attrs = [IDLAttribute('NAME', name), |
| 358 IDLAttribute('ERRORS', errors)] | 349 IDLAttribute('ERRORS', errors)] |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 errors += ChildTest() | 418 errors += ChildTest() |
| 428 | 419 |
| 429 if errors: | 420 if errors: |
| 430 ErrOut.Log('IDLNode failed with %d errors.' % errors) | 421 ErrOut.Log('IDLNode failed with %d errors.' % errors) |
| 431 return -1 | 422 return -1 |
| 432 return 0 | 423 return 0 |
| 433 | 424 |
| 434 if __name__ == '__main__': | 425 if __name__ == '__main__': |
| 435 sys.exit(Main()) | 426 sys.exit(Main()) |
| 436 | 427 |
| OLD | NEW |