changeset 5762:b30cced39597

generalized functionality for finding classes based on searching for patterns in source code and moved it from commands.py to mx.py used above functionality to find classes manually excluded from JaCoCo processing
author Doug Simon <doug.simon@oracle.com>
date Wed, 04 Jul 2012 21:56:48 +0200
parents 856a54bae703
children a3d71693e0ce
files mx/commands.py mxtool/mx.py
diffstat 2 files changed, 50 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/mx/commands.py	Wed Jul 04 16:41:08 2012 +0200
+++ b/mx/commands.py	Wed Jul 04 21:56:48 2012 +0200
@@ -587,7 +587,9 @@
         # Exclude all compiler tests and snippets
         excludes = ['com.oracle.graal.compiler.tests.*']
         for p in mx.projects():
-            _find_classes_with_annotations(excludes, p, None, ['@Snippet', '@ClassSubstitution'], includeInnerClasses=True)
+            excludes += _find_classes_with_annotations(p, None, ['@Snippet', '@ClassSubstitution'], includeInnerClasses=True)
+            excludes += p.find_classes_with_matching_source_line(None, lambda line: 'JaCoCo Exclude' in line, includeInnerClasses=True)
+            
         agentOptions = {
                         'append' : 'true' if _jacoco == 'append' else 'false',
                         'bootclasspath' : 'true',
@@ -598,47 +600,15 @@
     exe = join(jdk, 'bin', mx.exe_suffix('java'))
     return mx.run([exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
 
-def _find_classes_with_annotations(classes, p, pkgRoot, annotations, includeInnerClasses=False):
+def _find_classes_with_annotations(p, pkgRoot, annotations, includeInnerClasses=False):
     """
     Scan the sources of project 'p' for Java source files containing a line starting with 'annotation'
-    (ignoring preceding whitespace) and add the fully qualified class name
-    to 'classes' for each Java source file matched.
+    (ignoring preceding whitespace) and return the fully qualified class name for each Java
+    source file matched in a list.
     """
-    for a in annotations:
-        assert a.startswith('@')
-    pkgDecl = re.compile(r"^package\s+([a-zA-Z_][\w\.]*)\s*;$")
-    for srcDir in p.source_dirs():
-        outputDir = p.output_dir()
-        for root, _, files in os.walk(srcDir):
-            for name in files:
-                if name.endswith('.java') and name != 'package-info.java':
-                    annotationFound = False
-                    with open(join(root, name)) as f:
-                        pkg = None
-                        for line in f:
-                            if line.startswith("package "):
-                                match = pkgDecl.match(line)
-                                if match:
-                                    pkg = match.group(1)
-                            else:
-                                stripped = line.strip()
-                                for a in annotations:
-                                    if stripped == a or stripped.startswith(a + '('):
-                                        annotationFound = True
-                                        break
-                                if annotationFound:
-                                    break
-                    if annotationFound:
-                        basename = name[:-len('.java')]
-                        assert pkg is not None
-                        if pkgRoot is None or pkg.startswith(pkgRoot):
-                            pkgOutputDir = join(outputDir, pkg.replace('.', os.path.sep))
-                            for e in os.listdir(pkgOutputDir):
-                                if includeInnerClasses:
-                                    if e.endswith('.class') and (e.startswith(basename) or e.startswith(basename + '$')):
-                                        classes.append(pkg + '.' + e[:-len('.class')])
-                                elif e == basename + '.class':
-                                    classes.append(pkg + '.' + basename)
+    
+    matches = lambda line : len([a for a in annotations if line == a or line.startswith(a + '(')]) != 0
+    return p.find_classes_with_matching_source_line(pkgRoot, matches, includeInnerClasses)
 
 def _run_tests(args, harnessName, harness):
     pos = [a for a in args if a[0] != '-' and a[0] != '@' ]
@@ -653,8 +623,7 @@
 
     for p in mx.projects():
         if getattr(p, 'testHarness', None) == harnessName:
-            classes = []
-            _find_classes_with_annotations(classes, p, None, ['@Test'])
+            classes = _find_classes_with_annotations(p, None, ['@Test'])
 
             if len(pos) != 0:
                 classes = [c for c in classes if containsAny(c, pos)]
--- a/mxtool/mx.py	Wed Jul 04 16:41:08 2012 +0200
+++ b/mxtool/mx.py	Wed Jul 04 21:56:48 2012 +0200
@@ -261,6 +261,46 @@
         if not self.native:
             cp.append(self.output_dir())
 
+    def find_classes_with_matching_source_line(self, pkgRoot, function, includeInnerClasses=False):
+        """
+        Scan the sources of this project for Java source files containing a line for which
+        'function' returns true. The fully qualified class name of each existing class
+        corresponding to a matched source file is returned in a list.
+        """
+        classes = []
+        pkgDecl = re.compile(r"^package\s+([a-zA-Z_][\w\.]*)\s*;$")
+        for srcDir in self.source_dirs():
+            outputDir = self.output_dir()
+            for root, _, files in os.walk(srcDir):
+                for name in files:
+                    if name.endswith('.java') and name != 'package-info.java':
+                        matchFound = False
+                        with open(join(root, name)) as f:
+                            pkg = None
+                            for line in f:
+                                if line.startswith("package "):
+                                    match = pkgDecl.match(line)
+                                    if match:
+                                        pkg = match.group(1)
+                                if function(line.strip()):
+                                    matchFound = True
+                                if pkg and matchFound:
+                                    break
+                                        
+                        if matchFound:
+                            basename = name[:-len('.java')]
+                            assert pkg is not None
+                            if pkgRoot is None or pkg.startswith(pkgRoot):
+                                pkgOutputDir = join(outputDir, pkg.replace('.', os.path.sep))
+                                for e in os.listdir(pkgOutputDir):
+                                    if includeInnerClasses:
+                                        if e.endswith('.class') and (e.startswith(basename) or e.startswith(basename + '$')):
+                                            classes.append(pkg + '.' + e[:-len('.class')])
+                                    elif e == basename + '.class':
+                                        classes.append(pkg + '.' + basename)
+        return classes
+    
+
 class Library(Dependency):
     def __init__(self, suite, name, path, mustExist, urls):
         Dependency.__init__(self, suite, name)