diff --git a/cpp/ast.py b/cpp/ast.py index f2a15b0..d4dc317 100644 --- a/cpp/ast.py +++ b/cpp/ast.py @@ -511,18 +511,15 @@ def declaration_to_parts(self, parts, needs_name_removed): if arrayBegin < arrayEnd: parts = parts[:arrayBegin] + parts[arrayEnd + 1:] - name = None - if needs_name_removed and len(parts) > 1: - name = parts.pop().name - modifiers = [] - type_name = [] + type_name = [''] + last_type = tokenize.SYNTAX templated_types = [] i = 0 end = len(parts) while i < end: p = parts[i] - if keywords.is_keyword(p.name): + if keywords.is_builtin_modifiers(p.name): modifiers.append(p.name) elif p.name == '<': templated_tokens, new_end = self._get_template_end( @@ -534,20 +531,21 @@ def declaration_to_parts(self, parts, needs_name_removed): if next_index < end and parts[next_index].name == '::': i += 1 elif p.name not in ('*', '&', '>'): - # Ensure that names have a space between them. - if (type_name and type_name[-1].token_type == tokenize.NAME and - p.token_type == tokenize.NAME): - type_name.append( - tokenize.Token( - tokenize.SYNTAX, - ' ', - 0, - 0)) - type_name.append(p) + if last_type == tokenize.NAME and p.token_type == tokenize.NAME: + type_name.append('') + type_name[-1] += p.name + last_type = p.token_type else: other_tokens.append(p) i += 1 - type_name = ''.join([t.name for t in type_name]) + + name = None + if len(type_name) == 1 or keywords.is_builtin_type(type_name[-1]): + needs_name_removed = False + if needs_name_removed: + name = type_name.pop() + + type_name = ' '.join([t for t in type_name]) return (name, type_name, templated_types, @@ -572,23 +570,9 @@ def add_parameter(): del default[0] # Remove flag. end = type_modifiers[-1].end - needs_name_removed = True - if len(type_modifiers) == 1: - needs_name_removed = False - else: - last = type_modifiers[-1].name - second_to_last = type_modifiers[-2].name - if ( - last == '>' or - keywords.is_builtin_type(last) or - second_to_last == '::' or - keywords.is_builtin_type_modifiers(second_to_last) - ): - needs_name_removed = False - (name, type_name, templated_types, modifiers, _, __) = self.declaration_to_parts(type_modifiers, - needs_name_removed) + True) parameter_type = Type(first_token.start, first_token.end, type_name, templated_types, modifiers, diff --git a/cpp/keywords.py b/cpp/keywords.py index f1be1aa..c40507f 100644 --- a/cpp/keywords.py +++ b/cpp/keywords.py @@ -27,16 +27,17 @@ TYPE_MODIFIERS = frozenset(['auto', 'register', 'const', 'inline', 'extern', 'static', 'virtual', 'volatile', 'mutable']) +OTHER_MODIFIERS = frozenset(['class', 'struct', 'union', 'enum']) + ACCESS = frozenset(['public', 'protected', 'private', 'friend']) CASTS = frozenset(['static_cast', 'const_cast', 'dynamic_cast', 'reinterpret_cast']) -OTHERS = frozenset(['true', 'false', 'asm', 'class', 'namespace', 'using', - 'explicit', 'this', 'operator', 'sizeof']) - -OTHER_TYPES = frozenset(['new', 'delete', 'typedef', 'struct', 'union', 'enum', - 'typeid', 'typename', 'template']) +OTHERS = frozenset(['true', 'false', 'asm', 'namespace', 'using', + 'explicit', 'this', 'operator', 'sizeof', + 'new', 'delete', 'typedef', 'typeid', + 'typename', 'template']) CONTROL = frozenset(['case', 'switch', 'default', 'if', 'else', 'return', 'goto']) @@ -45,8 +46,8 @@ LOOP = frozenset(['while', 'do', 'for', 'break', 'continue']) -ALL = (TYPES | TYPE_MODIFIERS | ACCESS | CASTS | OTHERS | OTHER_TYPES | - CONTROL | EXCEPTION | LOOP) +ALL = (TYPES | TYPE_MODIFIERS | OTHER_MODIFIERS | ACCESS | CASTS | + OTHERS | CONTROL | EXCEPTION | LOOP) def is_keyword(token): @@ -60,5 +61,7 @@ def is_builtin_type(token): return token in TYPES or token in TYPE_MODIFIERS -def is_builtin_type_modifiers(token): - return token in TYPE_MODIFIERS +def is_builtin_modifiers(token): + if token in ('auto'): + return False + return token in TYPE_MODIFIERS or token in OTHER_MODIFIERS diff --git a/test_ast.py b/test_ast.py index 392b31b..a69800f 100755 --- a/test_ast.py +++ b/test_ast.py @@ -598,7 +598,8 @@ def test_variable_initialization_with_complex_expression(self): def test_function_one_argument_with_name(self): for argument in ('Foo f', 'const Foo f', 'Foo& f', 'const Foo& f', - 'unsigned int f', 'ns::foo f', 'std::vector f'): + 'unsigned int f', 'ns::foo f', 'std::vector f', + 'const Foo* const f', 'auto f'): code = 'void fct(%s);' % argument nodes = list(MakeBuilder(code).generate()) self.assertEqual(1, len(nodes)) @@ -607,7 +608,8 @@ def test_function_one_argument_with_name(self): def test_function_one_argument_with_no_name(self): for argument in ('Foo', 'const Foo', 'Foo&', 'const Foo&', - 'unsigned int', 'ns::foo', 'std::vector'): + 'unsigned int', 'ns::foo', 'std::vector', + 'const Foo* const', 'auto int'): code = 'void fct(%s);' % argument nodes = list(MakeBuilder(code).generate()) self.assertEqual(1, len(nodes))