Skip to content

Commit

Permalink
Handle nested template without space between angle bracket
Browse files Browse the repository at this point in the history
  • Loading branch information
r-e-d committed Jul 19, 2015
1 parent 536df96 commit 02db685
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
16 changes: 12 additions & 4 deletions cpp/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,12 @@ def _get_template_end(self, tokens, start):
count -= 1
if count == 0:
break
return tokens[start:end - 1], end
elif token.name == '>>':
t1 = tokenize.Token(tokenize.SYNTAX, '>', token.start, token.start + 1)
t2 = tokenize.Token(tokenize.SYNTAX, '>', token.start + 1, token.end)
tokens = tokens[:end - 1] + [t1, t2] + tokens[end:]
end -= 1
return tokens, end

def to_type(self, tokens):
"""Convert [Token,...] to [Class(...), ] useful for base classes.
Expand Down Expand Up @@ -449,7 +454,9 @@ def add_type(templated_types):
while i < end:
token = tokens[i]
if token.name == '<':
new_tokens, new_end = self._get_template_end(tokens, i + 1)
tokens, new_end = self._get_template_end(tokens, i + 1)
end = len(tokens)
new_tokens = tokens[i + 1:new_end - 1]
if new_end < end:
if tokens[new_end].name == '::':
name_tokens.append(tokens[new_end])
Expand Down Expand Up @@ -522,8 +529,9 @@ def declaration_to_parts(self, parts, needs_name_removed):
if keywords.is_builtin_modifiers(p.name):
modifiers.append(p.name)
elif p.name == '<':
templated_tokens, new_end = self._get_template_end(
parts, i + 1)
parts, new_end = self._get_template_end(parts, i + 1)
end = len(parts)
templated_tokens = parts[i + 1:new_end - 1]
templated_types = self.to_type(templated_tokens)
i = new_end - 1
elif p.name not in ('*', '&'):
Expand Down
18 changes: 18 additions & 0 deletions test_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,24 @@ def test_simple_template_begin(self):
self.assertEqual(False, results[1].type.reference)
self.assertEqual('bar', results[1].name)

def test_nested_template(self):
tokens = get_tokens('vector<pair<int, float>> data')
results = self.converter.to_parameters(list(tokens))
self.assertEqual(1, len(results), repr(results))

self.assertEqual([], results[0].type.modifiers)
self.assertEqual('vector', results[0].type.name)
self.assertEqual('data', results[0].name)

results = results[0].type.templated_types
self.assertEqual(1, len(results), repr(results))
self.assertEqual('pair', results[0].name)

results = results[0].templated_types
self.assertEqual(2, len(results), repr(results))
self.assertEqual('int', results[0].name)
self.assertEqual('float', results[1].name)

def test_simple_with_initializers(self):
tokens = get_tokens('Fool* data = NULL')
results = self.converter.to_parameters(list(tokens))
Expand Down

0 comments on commit 02db685

Please sign in to comment.