terryyin / lizard

A simple code complexity analyser without caring about the C/C++ header files or Java imports, supports most of the popular languages.
Other
1.85k stars 250 forks source link

Probably variadic template increases complexity metric in C++ #89

Open krzysztofjanski opened 8 years ago

krzysztofjanski commented 8 years ago

The following test does not pass:

diff --git a/test/testCyclomaticComplexity.py b/test/testCyclomaticComplexity.py
index c3ba2d2..c1f7465 100644
--- a/test/testCyclomaticComplexity.py
+++ b/test/testCyclomaticComplexity.py
@@ -27,6 +27,10 @@ class TestCyclomaticComplexity(unittest.TestCase):
         result = get_cpp_function_list("int fun(){if(a)b;else if (c) d;}")
         self.assertEqual(3, result[0].cyclomatic_complexity)

+    def test_one_function_with_forward(self):
+        result = get_cpp_function_list("template <template <typename...> class TemplateClass, typename... Args> TemplateClass<Args...> make(Args&&... args){}")
+        self.assertEqual(1, result[0].cyclomatic_complexity)
+
     def test_sharp_if_and_sharp_elif_counts_in_cc_number(self):
         result = get_cpp_function_list('''
                 int main(){
krzysztofjanski commented 8 years ago

The problem can be with r-value reference symbol in the condition_counter function: conditions = set(['if', 'for', 'while', '&&', '||', '?', 'catch', 'case'])

terryyin commented 8 years ago

@krzysztofjanski thanks for the report and the test. Yes, it's because of the &&. Let me fix this.

BTW, is it possible to use the r-value reference symbol inside the function body?

krzysztofjanski commented 8 years ago

Hello,

Yes, it's possible: http://en.cppreference.com/w/cpp/language/reference (see examples).

In my opinion, to do it properly, you would need to distinguish whether && is between a type and a name: The && as a logic operator can be used between names and as a r-value reference between a type and a name.

terryyin commented 8 years ago

I see. I will first do a quick fix for the situation that && is outside the function body.

For the situation that && is between a type and a name... let me think about it... It doesn't make sense to have a r-value && without assignment "=" inside a function body, right?

krzysztofjanski commented 8 years ago

You can have for example typedef: typedef int&& rref; or lambda: auto lambda_fun = [](std::string &&s){ cout << s << endl; }

terryyin commented 8 years ago

OK. I will make sure there's one test covering the typedef.

And for lambda... I think I should count lambda function as a nested function. If I implement that feature, then this problem is also solved, right?

krzysztofjanski commented 8 years ago

I think so :) , I do not recall any other case at the moment.

rakhimov commented 8 years ago

The title of this issue is misleading.