diff options
Diffstat (limited to 'googlemock/scripts/generator/cpp')
-rwxr-xr-x | googlemock/scripts/generator/cpp/ast.py | 46 | ||||
-rwxr-xr-x | googlemock/scripts/generator/cpp/gmock_class.py | 114 | ||||
-rwxr-xr-x | googlemock/scripts/generator/cpp/gmock_class_test.py | 93 | ||||
-rwxr-xr-x | googlemock/scripts/generator/cpp/keywords.py | 39 | ||||
-rwxr-xr-x | googlemock/scripts/generator/cpp/tokenize.py | 39 | ||||
-rwxr-xr-x | googlemock/scripts/generator/cpp/utils.py | 40 |
6 files changed, 260 insertions, 111 deletions
diff --git a/googlemock/scripts/generator/cpp/ast.py b/googlemock/scripts/generator/cpp/ast.py index f14728b..77bbec9 100755 --- a/googlemock/scripts/generator/cpp/ast.py +++ b/googlemock/scripts/generator/cpp/ast.py @@ -17,10 +17,7 @@ """Generate an Abstract Syntax Tree (AST) for C++.""" -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - -# TODO: +# FIXME: # * Tokens should never be exported, need to convert to Nodes # (return types, parameters, etc.) # * Handle static class data for templatized classes @@ -338,7 +335,7 @@ class Class(_GenericDeclaration): # TODO(nnorwitz): handle namespaces, etc. if self.bases: for token_list in self.bases: - # TODO(nnorwitz): bases are tokens, do name comparison. + # TODO(nnorwitz): bases are tokens, do name comparision. for token in token_list: if token.name == node.name: return True @@ -381,7 +378,7 @@ class Function(_GenericDeclaration): def Requires(self, node): if self.parameters: - # TODO(nnorwitz): parameters are tokens, do name comparison. + # TODO(nnorwitz): parameters are tokens, do name comparision. for p in self.parameters: if p.name == node.name: return True @@ -739,6 +736,14 @@ class AstBuilder(object): if token.token_type == tokenize.NAME: if (keywords.IsKeyword(token.name) and not keywords.IsBuiltinType(token.name)): + if token.name == 'enum': + # Pop the next token and only put it back if it's not + # 'class'. This allows us to support the two-token + # 'enum class' keyword as if it were simply 'enum'. + next = self._GetNextToken() + if next.name != 'class': + self._AddBackToken(next) + method = getattr(self, 'handle_' + token.name) return method() elif token.name == self.in_class_name_only: @@ -754,7 +759,8 @@ class AstBuilder(object): # Handle data or function declaration/definition. syntax = tokenize.SYNTAX temp_tokens, last_token = \ - self._GetVarTokensUpTo(syntax, '(', ';', '{', '[') + self._GetVarTokensUpToIgnoringTemplates(syntax, + '(', ';', '{', '[') temp_tokens.insert(0, token) if last_token.name == '(': # If there is an assignment before the paren, @@ -858,7 +864,25 @@ class AstBuilder(object): last_token = self._GetNextToken() return tokens, last_token - # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necessary. + # Same as _GetVarTokensUpTo, but skips over '<...>' which could contain an + # expected token. + def _GetVarTokensUpToIgnoringTemplates(self, expected_token_type, + *expected_tokens): + last_token = self._GetNextToken() + tokens = [] + nesting = 0 + while (nesting > 0 or + last_token.token_type != expected_token_type or + last_token.name not in expected_tokens): + tokens.append(last_token) + last_token = self._GetNextToken() + if last_token.name == '<': + nesting += 1 + elif last_token.name == '>': + nesting -= 1 + return tokens, last_token + + # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary. def _IgnoreUpTo(self, token_type, token): unused_tokens = self._GetTokensUpTo(token_type, token) @@ -1264,9 +1288,6 @@ class AstBuilder(object): return self._GetNestedType(Union) def handle_enum(self): - token = self._GetNextToken() - if not (token.token_type == tokenize.NAME and token.name == 'class'): - self._AddBackToken(token) return self._GetNestedType(Enum) def handle_auto(self): @@ -1298,7 +1319,8 @@ class AstBuilder(object): if token2.token_type == tokenize.SYNTAX and token2.name == '~': return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None) assert token.token_type == tokenize.NAME or token.name == '::', token - return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(') # ) + return_type_and_name, _ = self._GetVarTokensUpToIgnoringTemplates( + tokenize.SYNTAX, '(') # ) return_type_and_name.insert(0, token) if token2 is not token: return_type_and_name.insert(1, token2) diff --git a/googlemock/scripts/generator/cpp/gmock_class.py b/googlemock/scripts/generator/cpp/gmock_class.py index f9966cb..86dcedb 100755 --- a/googlemock/scripts/generator/cpp/gmock_class.py +++ b/googlemock/scripts/generator/cpp/gmock_class.py @@ -1,18 +1,33 @@ #!/usr/bin/env python # -# Copyright 2008 Google Inc. All Rights Reserved. +# Copyright 2008, Google Inc. +# All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: # -# http://www.apache.org/licenses/LICENSE-2.0 +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Generate Google Mock classes from base classes. @@ -26,9 +41,6 @@ Usage: Output is sent to stdout. """ -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - import os import re import sys @@ -48,6 +60,50 @@ _VERSION = (1, 0, 1) # The version of this script. _INDENT = 2 +def _RenderType(ast_type): + """Renders the potentially recursively templated type into a string. + + Args: + ast_type: The AST of the type. + + Returns: + Rendered string and a boolean to indicate whether we have multiple args + (which is not handled correctly). + """ + has_multiarg_error = False + # Add modifiers like 'const'. + modifiers = '' + if ast_type.modifiers: + modifiers = ' '.join(ast_type.modifiers) + ' ' + return_type = modifiers + ast_type.name + if ast_type.templated_types: + # Collect template args. + template_args = [] + for arg in ast_type.templated_types: + rendered_arg, e = _RenderType(arg) + if e: has_multiarg_error = True + template_args.append(rendered_arg) + return_type += '<' + ', '.join(template_args) + '>' + # We are actually not handling multi-template-args correctly. So mark it. + if len(template_args) > 1: + has_multiarg_error = True + if ast_type.pointer: + return_type += '*' + if ast_type.reference: + return_type += '&' + return return_type, has_multiarg_error + + +def _GetNumParameters(parameters, source): + num_parameters = len(parameters) + if num_parameters == 1: + first_param = parameters[0] + if source[first_param.start:first_param.end].strip() == 'void': + # We must treat T(void) as a function with no parameters. + return 0 + return num_parameters + + def _GenerateMethods(output_lines, source, class_node): function_type = (ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | ast.FUNCTION_OVERRIDE) @@ -63,32 +119,16 @@ def _GenerateMethods(output_lines, source, class_node): const = '' if node.modifiers & ast.FUNCTION_CONST: const = 'CONST_' + num_parameters = _GetNumParameters(node.parameters, source) return_type = 'void' if node.return_type: - # Add modifiers like 'const'. - modifiers = '' - if node.return_type.modifiers: - modifiers = ' '.join(node.return_type.modifiers) + ' ' - return_type = modifiers + node.return_type.name - template_args = [arg.name for arg in node.return_type.templated_types] - if template_args: - return_type += '<' + ', '.join(template_args) + '>' - if len(template_args) > 1: - for line in [ - '// The following line won\'t really compile, as the return', - '// type has multiple template arguments. To fix it, use a', - '// typedef for the return type.']: - output_lines.append(indent + line) - if node.return_type.pointer: - return_type += '*' - if node.return_type.reference: - return_type += '&' - num_parameters = len(node.parameters) - if len(node.parameters) == 1: - first_param = node.parameters[0] - if source[first_param.start:first_param.end].strip() == 'void': - # We must treat T(void) as a function with no parameters. - num_parameters = 0 + return_type, has_multiarg_error = _RenderType(node.return_type) + if has_multiarg_error: + for line in [ + '// The following line won\'t really compile, as the return', + '// type has multiple template arguments. To fix it, use a', + '// typedef for the return type.']: + output_lines.append(indent + line) tmpl = '' if class_node.templated_types: tmpl = '_T' diff --git a/googlemock/scripts/generator/cpp/gmock_class_test.py b/googlemock/scripts/generator/cpp/gmock_class_test.py index c53e600..0505162 100755 --- a/googlemock/scripts/generator/cpp/gmock_class_test.py +++ b/googlemock/scripts/generator/cpp/gmock_class_test.py @@ -1,25 +1,36 @@ #!/usr/bin/env python # -# Copyright 2009 Neal Norwitz All Rights Reserved. -# Portions Copyright 2009 Google Inc. All Rights Reserved. +# Copyright 2009, Google Inc. +# All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: # -# http://www.apache.org/licenses/LICENSE-2.0 +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Tests for gmock.scripts.generator.cpp.gmock_class.""" -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - import os import sys import unittest @@ -444,19 +455,63 @@ void(const FooType& test_arg)); self.assertEqualIgnoreLeadingWhitespace( expected, self.GenerateMocks(source)) - def testEnumClass(self): + def testEnumType(self): source = """ class Test { public: - enum class Baz { BAZINGA }; - virtual void Bar(const FooType& test_arg); + enum Bar { + BAZ, QUX, QUUX, QUUUX + }; + virtual void Foo(); }; """ expected = """\ class MockTest : public Test { public: -MOCK_METHOD1(Bar, -void(const FooType& test_arg)); +MOCK_METHOD0(Foo, +void()); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + expected, self.GenerateMocks(source)) + + def testEnumClassType(self): + source = """ +class Test { + public: + enum class Bar { + BAZ, QUX, QUUX, QUUUX + }; + virtual void Foo(); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD0(Foo, +void()); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + expected, self.GenerateMocks(source)) + + def testStdFunction(self): + source = """ +class Test { + public: + Test(std::function<int(std::string)> foo) : foo_(foo) {} + + virtual std::function<int(std::string)> foo(); + + private: + std::function<int(std::string)> foo_; +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD0(foo, +std::function<int (std::string)>()); }; """ self.assertEqualIgnoreLeadingWhitespace( diff --git a/googlemock/scripts/generator/cpp/keywords.py b/googlemock/scripts/generator/cpp/keywords.py index f694450..8b75c2b 100755 --- a/googlemock/scripts/generator/cpp/keywords.py +++ b/googlemock/scripts/generator/cpp/keywords.py @@ -1,25 +1,36 @@ #!/usr/bin/env python # -# Copyright 2007 Neal Norwitz -# Portions Copyright 2007 Google Inc. +# Copyright 2007, Google Inc. +# All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: # -# http://www.apache.org/licenses/LICENSE-2.0 +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """C++ keywords and helper utilities for determining keywords.""" -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - try: # Python 3.x import builtins diff --git a/googlemock/scripts/generator/cpp/tokenize.py b/googlemock/scripts/generator/cpp/tokenize.py index 359d556..c64dcde 100755 --- a/googlemock/scripts/generator/cpp/tokenize.py +++ b/googlemock/scripts/generator/cpp/tokenize.py @@ -1,25 +1,36 @@ #!/usr/bin/env python # -# Copyright 2007 Neal Norwitz -# Portions Copyright 2007 Google Inc. +# Copyright 2007, Google Inc. +# All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: # -# http://www.apache.org/licenses/LICENSE-2.0 +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Tokenize C++ source code.""" -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - try: # Python 3.x import builtins diff --git a/googlemock/scripts/generator/cpp/utils.py b/googlemock/scripts/generator/cpp/utils.py index eab36ee..6945a78 100755 --- a/googlemock/scripts/generator/cpp/utils.py +++ b/googlemock/scripts/generator/cpp/utils.py @@ -1,28 +1,38 @@ #!/usr/bin/env python # -# Copyright 2007 Neal Norwitz -# Portions Copyright 2007 Google Inc. +# Copyright 2007, Google Inc. +# All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: # -# http://www.apache.org/licenses/LICENSE-2.0 +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Generic utilities for C++ parsing.""" -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - import sys - # Set to True to see the start/end token indices. DEBUG = True |