# HG changeset patch # User Doug Simon # Date 1341431808 -7200 # Node ID b30cced39597bb0cb518b305eab646a6d1e0267e # Parent 856a54bae703e5d823a105cb7dee25d02589af41 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 diff -r 856a54bae703 -r b30cced39597 mx/commands.py --- 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)] diff -r 856a54bae703 -r b30cced39597 mxtool/mx.py --- 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)