| 455 | |
| 456 | |
| 457 | class TypeConverter(object): |
| 458 | |
| 459 | def __init__(self, namespace_stack): |
| 460 | self.namespace_stack = namespace_stack |
| 461 | |
| 462 | def _GetTemplateEnd(self, tokens, start): |
| 463 | count = 1 |
| 464 | end = start |
| 465 | while 1: |
| 466 | token = tokens[end] |
| 467 | end += 1 |
| 468 | if token.name == '<': |
| 469 | count += 1 |
| 470 | elif token.name == '>': |
| 471 | count -= 1 |
| 472 | if count == 0: |
| 473 | break |
| 474 | return tokens[start:end-1], end |
| 475 | |
| 476 | def ToType(self, tokens): |
| 477 | """Convert [Token,...] to [Class(...), ] useful for base classes. |
| 478 | For example, code like class Foo : public Bar<x, y> { ... }; |
| 479 | the "Bar<x, y>" portion gets converted to an AST. |
| 480 | |
| 481 | Returns: |
| 482 | [Class(...), ...] |
| 483 | """ |
| 484 | result = [] |
| 485 | name_tokens = [] |
| 486 | reference = pointer = array = False |
| 487 | |
| 488 | def AddType(templated_types): |
| 489 | # Partition tokens into name and modifier tokens. |
| 490 | names = [] |
| 491 | modifiers = [] |
| 492 | for t in name_tokens: |
| 493 | if keywords.IsKeyword(t.name): |
| 494 | modifiers.append(t.name) |
| 495 | else: |
| 496 | names.append(t.name) |
| 497 | name = ''.join(names) |
| 498 | result.append(Type(name_tokens[0].start, name_tokens[-1].end, |
| 499 | name, templated_types, modifiers, |
| 500 | reference, pointer, array)) |
| 501 | del name_tokens[:] |
| 502 | |
| 503 | i = 0 |
| 504 | end = len(tokens) |
| 505 | while i < end: |
| 506 | token = tokens[i] |
| 507 | if token.name == '<': |
| 508 | new_tokens, new_end = self._GetTemplateEnd(tokens, i+1) |
| 509 | AddType(self.ToType(new_tokens)) |
| 510 | # If there is a comma after the template, we need to consume |
| 511 | # that here otherwise it becomes part of the name. |
| 512 | i = new_end |
| 513 | reference = pointer = array = False |
| 514 | elif token.name == ',': |