Pārlūkot izejas kodu

Fixed matching of names of generics.

avkonst 10 gadi atpakaļ
vecāks
revīzija
a8e55ccaf7

+ 2 - 0
mainline/CHANGELOG.md

@@ -2,6 +2,8 @@
 - New metric: std.code.mi:simple - simple implemetation of maintainability index.
 - New configuration option for collect tool: --include-files (symetrical to --exclude-files)
 - New metrics: lines of code metrics per file
+- New metrics: std.code.member.* group
+- Fixed match of names of generic functions and classes 
 
 
 ## 1.3 (August, 2013)

+ 12 - 7
mainline/ext/std/code/cs.py

@@ -73,12 +73,14 @@ class CsCodeParser(object):
                        | (\s*[+-\\*/=<>!%&^|~,?.]{1,3})               # - other operators (from 1 to 3 symbols)
                                                                       #   NOTE: maybe dot and ? should not be in the list...
                       ))                                               
-                    | (([~]\s*)?[_a-zA-Z][_a-zA-Z0-9]*
-                       ([.][a-zA-Z_][a-zA-Z0-9_]*)*)                  # ... or function or constructor
+                    | (([~]\s*)?[_a-zA-Z][_a-zA-Z0-9]*                # ... or function or constructor
+                        (\s*[<]\s*[_a-zA-Z0-9]+\s*([,]\s*[_a-zA-Z0-9]+\s*)*[>])?       # NOTE: takes care of generics with multiple parameters
+                       (\s*[.]\s*[a-zA-Z_][a-zA-Z0-9_]*
+                        (\s*[<]\s*[_a-zA-Z0-9]+\s*([,]\s*[_a-zA-Z0-9]+\s*)*[>])?)*)    # NOTE: takes care of generics with multiple parameters
                                                                       # NOTE: C# destructor can have spaces in name after ~
                                                                       # NOTE: explicit interface implementation method has got a dot
                     | (?P<prop_setget>get|set)                        # ... or property setter/getter
-                  )\s*(?(prop_setget)(?=[{])|[(<])
+                  )\s*(?(prop_setget)(?=[{])|[(])
                                                                       # LIMITATION: if there are comments after function name
                                                                       # and before '(', it is not detected
                                                                       # LIMITATION: if there are comments within operator definition,
@@ -86,9 +88,10 @@ class CsCodeParser(object):
                                                                       # LIMITATION: if there are comments after set|get keyword,
                                                                       # if may be not detected
                 | ((?P<block_type>\bclass|\bstruct|\bnamespace|\binterface)   # Match class or struct or interface or namespace
-                    (?P<block_name>(\s+[a-zA-Z_][a-zA-Z0-9_]*)([.][a-zA-Z_][a-zA-Z0-9_]*)*))
+                    (?P<block_name>(\s+[a-zA-Z_][a-zA-Z0-9_]*
+                        (\s*[<]\s*[_a-zA-Z0-9]+\s*([,]\s*[_a-zA-Z0-9]+\s*)*[>])?       # NOTE: takes care of generics with multiple parameters
+                    )))
                                                                       # NOTE: noname instances are impossible in C#
-                                                                      # NOTE: names can have sub-names separated by dots
                                                                       # LIMITATION: if there are comments between keyword and name,
                                                                       # it is not detected
                 | [\[\]{};]                                               # Match block start/end and statement separator
@@ -272,7 +275,8 @@ class CsCodeParser(object):
             elif m.group('block_type') != None:
                 if next_block['name'] == "":
                     # - 'name'
-                    next_block['name'] = m.group('block_name').strip()
+                    clearance_pattern = re.compile(r'\s+')
+                    next_block['name'] = clearance_pattern.sub('',m.group('block_name'))
                     # - 'cursor'
                     cursor_current += len(self.regex_ln.findall(text, cursor_last_pos, m.start('block_name')))
                     cursor_last_pos = m.start('block_name')
@@ -289,7 +293,8 @@ class CsCodeParser(object):
                 if blocks[curblk]['type'] != 'function' and (next_block['name'] == "") \
                        and next_block['inside_attribute'] == False:
                     # - 'name'
-                    next_block['name'] = m.group('fn_name').strip()
+                    clearance_pattern = re.compile(r'\s+')
+                    next_block['name'] = clearance_pattern.sub('', m.group('fn_name'))
                     # - 'cursor'
                     cursor_current += len(self.regex_ln.findall(text, cursor_last_pos, m.start('fn_name')))
                     cursor_last_pos = m.start('fn_name')

+ 20 - 20
mainline/tests/general/test_std_code_cs/test_parser_view_files_stdout.gold.txt

@@ -5,8 +5,8 @@
 	Line numbers   : 1-448
 	Modified       : None
 
-.   ./File.cs:21: info: Metrics per 'Microsoft.VisualBasic' region
-    	Region name    : Microsoft.VisualBasic
+.   ./File.cs:21: info: Metrics per 'Microsoft' region
+    	Region name    : Microsoft
     	Region type    : namespace
     	Offsets        : 855-9104
     	Line numbers   : 21-447
@@ -207,15 +207,15 @@
     	Line numbers   : 22-105
     	Modified       : None
 
-.   .   ./Generics.cs:24: info: Metrics per 'MyArray' region
-        	Region name    : MyArray
+.   .   ./Generics.cs:24: info: Metrics per 'MyArray<T>' region
+        	Region name    : MyArray<T>
         	Region type    : class
         	Offsets        : 1214-1664
         	Line numbers   : 24-57
         	Modified       : None
 
-.   .   .   ./Generics.cs:26: info: Metrics per 'NestedClass' region
-            	Region name    : NestedClass
+.   .   .   ./Generics.cs:26: info: Metrics per 'NestedClass<Y>' region
+            	Region name    : NestedClass<Y>
             	Region type    : class
             	Offsets        : 1243-1316
             	Line numbers   : 26-30
@@ -259,8 +259,8 @@
         	Line numbers   : 65-74
         	Modified       : None
 
-.   .   .   ./Generics.cs:71: info: Metrics per 'Generics.IInterface.Method2' region
-            	Region name    : Generics.IInterface.Method2
+.   .   .   ./Generics.cs:71: info: Metrics per 'Generics.IInterface.Method2<T>' region
+            	Region name    : Generics.IInterface.Method2<T>
             	Region type    : function
             	Offsets        : 1960-2081
             	Line numbers   : 70-73
@@ -274,32 +274,32 @@
         	Line numbers   : 76-82
         	Modified       : None
 
-.   .   .   ./Generics.cs:79: info: Metrics per 'Method1' region
-            	Region name    : Method1
+.   .   .   ./Generics.cs:79: info: Metrics per 'Method1<T>' region
+            	Region name    : Method1<T>
             	Region type    : function
             	Offsets        : 2130-2242
             	Line numbers   : 78-81
             	Modified       : None
             	std.code.complexity:cyclomatic: 0
 
-.   .   ./Generics.cs:92: info: Metrics per 'MethodWithConstraint' region
-        	Region name    : MethodWithConstraint
+.   .   ./Generics.cs:92: info: Metrics per 'MethodWithConstraint<T,S>' region
+        	Region name    : MethodWithConstraint<T,S>
         	Region type    : function
         	Offsets        : 2698-2798
         	Line numbers   : 92-94
         	Modified       : None
         	std.code.complexity:cyclomatic: 0
 
-.   .   ./Generics.cs:96: info: Metrics per 'MethodWithStructConstraint' region
-        	Region name    : MethodWithStructConstraint
+.   .   ./Generics.cs:96: info: Metrics per 'MethodWithStructConstraint<T>' region
+        	Region name    : MethodWithStructConstraint<T>
         	Region type    : function
         	Offsets        : 2802-2875
         	Line numbers   : 96-98
         	Modified       : None
         	std.code.complexity:cyclomatic: 0
 
-.   .   ./Generics.cs:100: info: Metrics per 'Dictionary' region
-        	Region name    : Dictionary
+.   .   ./Generics.cs:100: info: Metrics per 'GetEnumerator' region
+        	Region name    : GetEnumerator
         	Region type    : function
         	Offsets        : 2879-3131
         	Line numbers   : 100-104
@@ -323,8 +323,8 @@
 	Line numbers   : 1-219
 	Modified       : None
 
-.   ./interface.cs:22: info: Metrics per 'System.Runtime.Serialization' region
-    	Region name    : System.Runtime.Serialization
+.   ./interface.cs:22: info: Metrics per 'System' region
+    	Region name    : System
     	Region type    : namespace
     	Offsets        : 918-1139
     	Line numbers   : 22-37
@@ -337,8 +337,8 @@
         	Line numbers   : 25-35
         	Modified       : None
 
-.   ./interface.cs:61: info: Metrics per 'System.Globalization' region
-    	Region name    : System.Globalization
+.   ./interface.cs:61: info: Metrics per 'System' region
+    	Region name    : System
     	Region type    : namespace
     	Offsets        : 2040-6548
     	Line numbers   : 61-218

+ 44 - 0
mainline/tests/general/utest_std_code_cs.py

@@ -0,0 +1,44 @@
+#
+#    Metrix++, Copyright 2009-2013, Metrix++ Project
+#    Link: http://metrixplusplus.sourceforge.net
+#    
+#    This file is a part of Metrix++ Tool.
+#    
+#    Metrix++ is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, version 3 of the License.
+#    
+#    Metrix++ is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#    GNU General Public License for more details.
+#    
+#    You should have received a copy of the GNU General Public License
+#    along with Metrix++.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+import unittest
+import os
+
+import tests.common
+
+class Test(tests.common.TestCase):
+
+    def test_parser(self):
+        
+        runner = tests.common.ToolRunner('collect', ['--std.code.complexity.cyclomatic'])
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('view', ['--nest-regions', '--format=xml'])
+        self.assertExec(runner.run())
+
+        dirs_list = [os.path.join('.', each) for each in os.listdir(self.get_content_paths().cwd)]
+        runner = tests.common.ToolRunner('view',
+                                         opts_list=['--nest-regions', '--format=txt'],
+                                         dirs_list=dirs_list,
+                                         prefix='files')
+        self.assertExec(runner.run())
+
+if __name__ == '__main__':
+    unittest.main()

+ 140 - 0
mainline/tests/general/utest_std_code_cs/sources/sample.cs

@@ -0,0 +1,140 @@
+
+
+public class example
+{
+    protected List<int> testfunction1(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected List<T> testfunction2<T>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected int testfunction3<T>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected int testfunction4(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected int testfunction5<T, S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IDictionary<T, S> testfunction6<T, S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IDictionary<T, S> testfunction7<T,
+        S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IDictionary<T, IList<S>> testfunction8<T,
+        S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> testfunction9<T,    S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface.testfunction10<T, S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface<T>.testfunction11<T, S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface<T, S>.testfunction12(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface<T, S>.testfunction13<T>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface<T>.testfunction14<T, S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface<T,S>.testfunction15<T, S>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface<T, S>.testfunction16 <T>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    protected IList<T> Interface <T, S>. testfunction17<T>(string text1)
+    {
+        List<int> numbers = new List<int>();
+        return numbers;
+    }
+
+    class testClass1
+    {
+    }
+
+    class testClass2
+    {
+    }
+
+    class testClass3<T>
+    {
+    }
+
+    class testClass4 <T>
+    {
+    }
+
+    class testClass5<T, S>
+    {
+    }
+
+    class testClass6<T,
+        S>
+        where T: class
+        where S: class
+    {
+    }
+
+    class testClass7 < T>
+        where T : class
+    {
+    }
+}

+ 0 - 0
mainline/tests/general/utest_std_code_cs/test_parser_collect_default_stdout.gold.txt


+ 21 - 0
mainline/tests/general/utest_std_code_cs/test_parser_view_default_stdout.gold.txt

@@ -0,0 +1,21 @@
+<view>
+
+    <data>
+        <info id="1" path="./" />
+        <file-data />
+        <subfiles>
+            <subfile>sample.cs</subfile>
+        </subfiles>
+        <subdirs>
+        </subdirs>
+        <aggregated-data>
+            <std.code.complexity>
+                <cyclomatic avg="0.0" count="17" max="0" min="0" nonzero="False" sup="0" total="0.0">
+                    <distribution-bars>
+                        <distribution-bar count="17" metric="0" ratio="1.0" />
+                    </distribution-bars>
+                </cyclomatic>
+            </std.code.complexity>
+        </aggregated-data>
+    </data>
+</view>

+ 209 - 0
mainline/tests/general/utest_std_code_cs/test_parser_view_files_stdout.gold.txt

@@ -0,0 +1,209 @@
+./sample.cs:0: info: Metrics per '__global__' region
+	Region name    : __global__
+	Region type    : global
+	Offsets        : 0-2860
+	Line numbers   : 1-141
+	Modified       : None
+
+.   ./sample.cs:3: info: Metrics per 'example' region
+    	Region name    : example
+    	Region type    : class
+    	Offsets        : 2-2859
+    	Line numbers   : 3-140
+    	Modified       : None
+
+.   .   ./sample.cs:5: info: Metrics per 'testfunction1' region
+        	Region name    : testfunction1
+        	Region type    : function
+        	Offsets        : 29-157
+        	Line numbers   : 5-9
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:11: info: Metrics per 'testfunction2<T>' region
+        	Region name    : testfunction2<T>
+        	Region type    : function
+        	Offsets        : 163-292
+        	Line numbers   : 11-15
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:17: info: Metrics per 'testfunction3<T>' region
+        	Region name    : testfunction3<T>
+        	Region type    : function
+        	Offsets        : 298-423
+        	Line numbers   : 17-21
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:23: info: Metrics per 'testfunction4' region
+        	Region name    : testfunction4
+        	Region type    : function
+        	Offsets        : 429-551
+        	Line numbers   : 23-27
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:29: info: Metrics per 'testfunction5<T,S>' region
+        	Region name    : testfunction5<T,S>
+        	Region type    : function
+        	Offsets        : 557-685
+        	Line numbers   : 29-33
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:35: info: Metrics per 'testfunction6<T,S>' region
+        	Region name    : testfunction6<T,S>
+        	Region type    : function
+        	Offsets        : 691-833
+        	Line numbers   : 35-39
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:41: info: Metrics per 'testfunction7<T,S>' region
+        	Region name    : testfunction7<T,S>
+        	Region type    : function
+        	Offsets        : 839-989
+        	Line numbers   : 41-46
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:48: info: Metrics per 'testfunction8<T,S>' region
+        	Region name    : testfunction8<T,S>
+        	Region type    : function
+        	Offsets        : 995-1152
+        	Line numbers   : 48-53
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:55: info: Metrics per 'testfunction9<T,S>' region
+        	Region name    : testfunction9<T,S>
+        	Region type    : function
+        	Offsets        : 1158-1294
+        	Line numbers   : 55-59
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:61: info: Metrics per 'Interface.testfunction10<T,S>' region
+        	Region name    : Interface.testfunction10<T,S>
+        	Region type    : function
+        	Offsets        : 1300-1444
+        	Line numbers   : 61-65
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:67: info: Metrics per 'Interface<T>.testfunction11<T,S>' region
+        	Region name    : Interface<T>.testfunction11<T,S>
+        	Region type    : function
+        	Offsets        : 1450-1597
+        	Line numbers   : 67-71
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:73: info: Metrics per 'Interface<T,S>.testfunction12' region
+        	Region name    : Interface<T,S>.testfunction12
+        	Region type    : function
+        	Offsets        : 1603-1747
+        	Line numbers   : 73-77
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:79: info: Metrics per 'Interface<T,S>.testfunction13<T>' region
+        	Region name    : Interface<T,S>.testfunction13<T>
+        	Region type    : function
+        	Offsets        : 1753-1900
+        	Line numbers   : 79-83
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:85: info: Metrics per 'Interface<T>.testfunction14<T,S>' region
+        	Region name    : Interface<T>.testfunction14<T,S>
+        	Region type    : function
+        	Offsets        : 1906-2053
+        	Line numbers   : 85-89
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:91: info: Metrics per 'Interface<T,S>.testfunction15<T,S>' region
+        	Region name    : Interface<T,S>.testfunction15<T,S>
+        	Region type    : function
+        	Offsets        : 2059-2208
+        	Line numbers   : 91-95
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:97: info: Metrics per 'Interface<T,S>.testfunction16<T>' region
+        	Region name    : Interface<T,S>.testfunction16<T>
+        	Region type    : function
+        	Offsets        : 2214-2362
+        	Line numbers   : 97-101
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:103: info: Metrics per 'Interface<T,S>.testfunction17<T>' region
+        	Region name    : Interface<T,S>.testfunction17<T>
+        	Region type    : function
+        	Offsets        : 2368-2517
+        	Line numbers   : 103-107
+        	Modified       : None
+        	std.code.complexity:cyclomatic: 0
+
+.   .   ./sample.cs:109: info: Metrics per 'testClass1' region
+        	Region name    : testClass1
+        	Region type    : class
+        	Offsets        : 2523-2551
+        	Line numbers   : 109-111
+        	Modified       : None
+
+.   .   ./sample.cs:113: info: Metrics per 'testClass2' region
+        	Region name    : testClass2
+        	Region type    : class
+        	Offsets        : 2557-2585
+        	Line numbers   : 113-115
+        	Modified       : None
+
+.   .   ./sample.cs:117: info: Metrics per 'testClass3<T>' region
+        	Region name    : testClass3<T>
+        	Region type    : class
+        	Offsets        : 2591-2622
+        	Line numbers   : 117-119
+        	Modified       : None
+
+.   .   ./sample.cs:121: info: Metrics per 'testClass4<T>' region
+        	Region name    : testClass4<T>
+        	Region type    : class
+        	Offsets        : 2628-2660
+        	Line numbers   : 121-123
+        	Modified       : None
+
+.   .   ./sample.cs:125: info: Metrics per 'testClass5<T,S>' region
+        	Region name    : testClass5<T,S>
+        	Region type    : class
+        	Offsets        : 2666-2700
+        	Line numbers   : 125-127
+        	Modified       : None
+
+.   .   ./sample.cs:129: info: Metrics per 'testClass6<T,S>' region
+        	Region name    : testClass6<T,S>
+        	Region type    : class
+        	Offsets        : 2706-2794
+        	Line numbers   : 129-134
+        	Modified       : None
+
+.   .   ./sample.cs:136: info: Metrics per 'testClass7<T>' region
+        	Region name    : testClass7<T>
+        	Region type    : class
+        	Offsets        : 2800-2857
+        	Line numbers   : 136-139
+        	Modified       : None
+
+./sample.cs:: info: Overall metrics for 'std.code.complexity:cyclomatic' metric
+	Average        : 0.0
+	Minimum        : 0
+	Maximum        : 0
+	Total          : 0.0
+	Distribution   : 17 regions in total (including 0 suppressed)
+	  Metric value : Ratio : R-sum : Number of regions
+	             0 : 1.000 : 1.000 : 17	||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+