Mercurial > hg > graal-compiler
comparison mxtool/mx.py @ 6527:3c5b19e8f2a3
modified canonicalizeprojects to detect imprecise dependencies (e.g., A specifies that it depends on B but only imports packages from B's dependencies)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 08 Oct 2012 17:18:00 +0200 |
parents | 534c45127aad |
children | 250babea75d5 |
comparison
equal
deleted
inserted
replaced
6526:ee651c726397 | 6527:3c5b19e8f2a3 |
---|---|
310 classes.append(pkg + '.' + e[:-len('.class')]) | 310 classes.append(pkg + '.' + e[:-len('.class')]) |
311 elif e == basename + '.class': | 311 elif e == basename + '.class': |
312 classes.append(pkg + '.' + basename) | 312 classes.append(pkg + '.' + basename) |
313 return classes | 313 return classes |
314 | 314 |
315 def _init_packages_and_imports(self): | |
316 if not hasattr(self, '_defined_java_packages'): | |
317 packages = set() | |
318 depPackages = set() | |
319 for d in self.all_deps([], includeLibs=False, includeSelf=False): | |
320 depPackages.update(d.defined_java_packages()) | |
321 imports = set() | |
322 importRe = re.compile(r'import\s+(?:static\s+)?([^;]+);') | |
323 for sourceDir in self.source_dirs(): | |
324 for root, _, files in os.walk(sourceDir): | |
325 javaSources = [name for name in files if name.endswith('.java')] | |
326 if len(javaSources) != 0: | |
327 pkg = root[len(sourceDir) + 1:].replace(os.sep,'.') | |
328 if not pkg in depPackages: | |
329 packages.add(pkg) | |
330 else: | |
331 # A project imports a package already defined by one of it dependencies | |
332 imports.add(pkg) | |
333 | |
334 for n in javaSources: | |
335 with open(join(root, n)) as fp: | |
336 content = fp.read() | |
337 imports.update(importRe.findall(content)) | |
338 self._defined_java_packages = frozenset(packages) | |
339 | |
340 importedPackages = set() | |
341 for imp in imports: | |
342 name = imp | |
343 while not name in depPackages and len(name) > 0: | |
344 lastDot = name.rfind('.') | |
345 if lastDot == -1: | |
346 name = None | |
347 break | |
348 name = name[0:lastDot] | |
349 if name is not None: | |
350 importedPackages.add(name) | |
351 self._imported_java_packages = frozenset(importedPackages) | |
352 | |
353 def defined_java_packages(self): | |
354 """Get the immutable set of Java packages defined by the Java sources of this project""" | |
355 self._init_packages_and_imports() | |
356 return self._defined_java_packages | |
357 | |
358 def imported_java_packages(self): | |
359 """Get the immutable set of Java packages defined by other Java projects that are | |
360 imported by the Java sources of this project.""" | |
361 self._init_packages_and_imports() | |
362 return self._imported_java_packages | |
363 | |
315 | 364 |
316 class Library(Dependency): | 365 class Library(Dependency): |
317 def __init__(self, suite, name, path, mustExist, urls, sourcePath, sourceUrls): | 366 def __init__(self, suite, name, path, mustExist, urls, sourcePath, sourceUrls): |
318 Dependency.__init__(self, suite, name) | 367 Dependency.__init__(self, suite, name) |
319 self.path = path.replace('/', os.sep) | 368 self.path = path.replace('/', os.sep) |
1438 if not exists(projectsFile): | 1487 if not exists(projectsFile): |
1439 continue | 1488 continue |
1440 with open(projectsFile) as f: | 1489 with open(projectsFile) as f: |
1441 out = StringIO.StringIO() | 1490 out = StringIO.StringIO() |
1442 pattern = re.compile('project@([^@]+)@dependencies=.*') | 1491 pattern = re.compile('project@([^@]+)@dependencies=.*') |
1492 lineNo = 1 | |
1443 for line in f: | 1493 for line in f: |
1444 line = line.strip() | 1494 line = line.strip() |
1445 m = pattern.match(line) | 1495 m = pattern.match(line) |
1446 if m is None: | 1496 if m is None: |
1447 out.write(line + '\n') | 1497 out.write(line + '\n') |
1448 else: | 1498 else: |
1449 p = project(m.group(1)) | 1499 p = project(m.group(1)) |
1500 ignoredDeps = set([name for name in p.deps if project(name, False) is not None]) | |
1501 for pkg in p.imported_java_packages(): | |
1502 for name in p.deps: | |
1503 dep = project(name, False) | |
1504 if dep is None: | |
1505 ignoredDeps.discard(name) | |
1506 else: | |
1507 if pkg in dep.defined_java_packages(): | |
1508 ignoredDeps.discard(name) | |
1509 if len(ignoredDeps) != 0: | |
1510 candidates = set(); | |
1511 # Compute dependencies based on projects required by p | |
1512 for d in sorted_deps(): | |
1513 if not d.defined_java_packages().isdisjoint(p.imported_java_packages()): | |
1514 candidates.add(d) | |
1515 # Remove non-canonical candidates | |
1516 for c in list(candidates): | |
1517 candidates.difference_update(c.all_deps([], False, False)) | |
1518 candidates = [d.name for d in candidates] | |
1519 | |
1520 abort('{0}:{1}: {2} does not use any packages defined in these projects: {3}\nComputed project dependencies: {4}'.format( | |
1521 projectsFile, lineNo, p, ', '.join(ignoredDeps), ','.join(candidates))) | |
1522 | |
1450 out.write('project@' + m.group(1) + '@dependencies=' + ','.join(p.canonical_deps()) + '\n') | 1523 out.write('project@' + m.group(1) + '@dependencies=' + ','.join(p.canonical_deps()) + '\n') |
1524 lineNo = lineNo + 1 | |
1451 content = out.getvalue() | 1525 content = out.getvalue() |
1452 if update_file(projectsFile, content): | 1526 if update_file(projectsFile, content): |
1453 changedFiles += 1 | 1527 changedFiles += 1 |
1454 return changedFiles; | 1528 return changedFiles; |
1455 | 1529 |
2390 | 2464 |
2391 else: | 2465 else: |
2392 # no package description given | 2466 # no package description given |
2393 pass | 2467 pass |
2394 | 2468 |
2395 def packageinfo(args): | |
2396 """show Java packages defined by each project""" | |
2397 | |
2398 parser = ArgumentParser(prog='packageinfo') | |
2399 parser.add_argument('-l', action='store_true', help='show packages one per line') | |
2400 parser.add_argument('filters', nargs=REMAINDER, metavar='filters...', help='substrings filtering the projects processed') | |
2401 | |
2402 args = parser.parse_args(args) | |
2403 filters = args.filters | |
2404 | |
2405 projects = sorted_deps() | |
2406 | |
2407 projToPkgs = dict() | |
2408 pkgToProjs = dict() | |
2409 for p in projects: | |
2410 if len(filters) == 0 or len([f for f in filters if f in p.name]) != 0: | |
2411 pkgs = set() | |
2412 projToPkgs[p.name] = pkgs | |
2413 for sourceDir in p.source_dirs(): | |
2414 for root, _, files in os.walk(sourceDir): | |
2415 if len([name for name in files if name.endswith('.java')]) != 0: | |
2416 pkg = root[len(sourceDir) + 1:].replace(os.sep,'.') | |
2417 pkgs.add(pkg) | |
2418 pkgToProjs.setdefault(pkg, set()).add(p.name) | |
2419 | |
2420 for key,value in projToPkgs.iteritems(): | |
2421 if args.l: | |
2422 print key, 'defines packages:' | |
2423 for v in value: | |
2424 print ' ', v | |
2425 else: | |
2426 print key, 'defines packages:', ', '.join(value) | |
2427 | |
2428 for key,value in pkgToProjs.iteritems(): | |
2429 if len(value) > 1: | |
2430 print 'package', key, 'is defined by multiple projects:', ', '.join(value) | |
2431 | |
2432 def site(args): | 2469 def site(args): |
2433 """creates a website containing javadoc and the project dependency graph""" | 2470 """creates a website containing javadoc and the project dependency graph""" |
2434 | 2471 |
2435 parser = ArgumentParser(prog='site') | 2472 parser = ArgumentParser(prog='site') |
2436 parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>') | 2473 parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>') |
2634 'javap': [javap, ''], | 2671 'javap': [javap, ''], |
2635 'javadoc': [javadoc, '[options]'], | 2672 'javadoc': [javadoc, '[options]'], |
2636 'site': [site, '[options]'], | 2673 'site': [site, '[options]'], |
2637 'netbeansinit': [netbeansinit, ''], | 2674 'netbeansinit': [netbeansinit, ''], |
2638 'projects': [show_projects, ''], | 2675 'projects': [show_projects, ''], |
2639 'packageinfo': [packageinfo, '[options]'], | |
2640 } | 2676 } |
2641 | 2677 |
2642 _argParser = ArgParser() | 2678 _argParser = ArgParser() |
2643 | 2679 |
2644 def _findPrimarySuite(): | 2680 def _findPrimarySuite(): |