comparison mxtool/mx.py @ 5876:c21886d4e125

Annotation Processor support in mx : use annotationProcessorClasses property on projects that contain annotation processors and annotationProcessors on projects that require annotation processing
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 26 Jul 2012 14:51:13 +0200
parents 2c00c51357d8
children e952911afd2f
comparison
equal deleted inserted replaced
5875:000fb0550afe 5876:c21886d4e125
401 return [n.strip() for n in v.split(',')] 401 return [n.strip() for n in v.split(',')]
402 402
403 for name, attrs in projsMap.iteritems(): 403 for name, attrs in projsMap.iteritems():
404 srcDirs = pop_list(attrs, 'sourceDirs') 404 srcDirs = pop_list(attrs, 'sourceDirs')
405 deps = pop_list(attrs, 'dependencies') 405 deps = pop_list(attrs, 'dependencies')
406 ap = pop_list(attrs, 'annotationProcessors')
407 deps += ap
406 javaCompliance = attrs.pop('javaCompliance', None) 408 javaCompliance = attrs.pop('javaCompliance', None)
407 subDir = attrs.pop('subDir', None); 409 subDir = attrs.pop('subDir', None);
408 if subDir is None: 410 if subDir is None:
409 dir = join(self.dir, name) 411 dir = join(self.dir, name)
410 else: 412 else:
412 p = Project(self, name, srcDirs, deps, javaCompliance, dir) 414 p = Project(self, name, srcDirs, deps, javaCompliance, dir)
413 p.checkstyleProj = attrs.pop('checkstyle', name) 415 p.checkstyleProj = attrs.pop('checkstyle', name)
414 p.native = attrs.pop('native', '') == 'true' 416 p.native = attrs.pop('native', '') == 'true'
415 if not p.native and p.javaCompliance is None: 417 if not p.native and p.javaCompliance is None:
416 abort('javaCompliance property required for non-native project ' + name) 418 abort('javaCompliance property required for non-native project ' + name)
419 if len(ap) > 0:
420 p.annotationProcessors = ap
421 apc = pop_list(attrs, 'annotationProcessorClasses')
422 if len(apc) > 0:
423 p.annotationProcessorClasses = apc
417 p.__dict__.update(attrs) 424 p.__dict__.update(attrs)
418 self.projects.append(p) 425 self.projects.append(p)
419 426
420 for name, attrs in libsMap.iteritems(): 427 for name, attrs in libsMap.iteritems():
421 path = attrs.pop('path') 428 path = attrs.pop('path')
940 """ 947 """
941 class JavaConfig: 948 class JavaConfig:
942 def __init__(self, opts): 949 def __init__(self, opts):
943 self.jdk = opts.java_home 950 self.jdk = opts.java_home
944 self.debug_port = opts.java_dbg_port 951 self.debug_port = opts.java_dbg_port
945 self.java = exe_suffix(join(self.jdk, 'bin', 'java')) 952 self.jar = exe_suffix(join(self.jdk, 'bin', 'jar'))
953 self.java = exe_suffix(join(self.jdk, 'bin', 'java'))
946 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) 954 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac'))
947 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap')) 955 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap'))
948 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc')) 956 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc'))
949 self._bootclasspath = None 957 self._bootclasspath = None
950 958
1077 p, _ = currentSubprocess 1085 p, _ = currentSubprocess
1078 if get_os() == 'windows': 1086 if get_os() == 'windows':
1079 p.kill() 1087 p.kill()
1080 else: 1088 else:
1081 _kill_process_group(p.pid) 1089 _kill_process_group(p.pid)
1082 1090
1083 raise SystemExit(codeOrMessage) 1091 raise SystemExit(codeOrMessage)
1084 1092
1085 def download(path, urls, verbose=False): 1093 def download(path, urls, verbose=False):
1086 """ 1094 """
1087 Attempts to downloads content for each URL in a list, stopping after the first successful download. 1095 Attempts to downloads content for each URL in a list, stopping after the first successful download.
1318 argfileName = join(p.dir, 'javafilelist.txt') 1326 argfileName = join(p.dir, 'javafilelist.txt')
1319 argfile = open(argfileName, 'wb') 1327 argfile = open(argfileName, 'wb')
1320 argfile.write('\n'.join(javafilelist)) 1328 argfile.write('\n'.join(javafilelist))
1321 argfile.close() 1329 argfile.close()
1322 1330
1331 if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
1332 annotationProcessors = []
1333 for apProject in p.annotationProcessors:
1334 apClasses = project(apProject).annotationProcessorClasses
1335 if len(apClasses) == 0:
1336 abort("Project " + p + " specifies " + apProject + " as an annotation processor but " + apProject + " does not specifiy any annotation processor class")
1337 annotationProcessors += apClasses
1338
1339 apArgs = ['-processor', ",".join(annotationProcessors)]
1340 else:
1341 apArgs = []
1342
1323 toBeDeleted = [argfileName] 1343 toBeDeleted = [argfileName]
1324 try: 1344 try:
1325 if jdtJar is None: 1345 if jdtJar is None:
1326 log('Compiling Java sources for {0} with javac...'.format(p.name)) 1346 log('Compiling Java sources for {0} with javac...'.format(p.name))
1327 javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', args.compliance, '-classpath', cp, '-d', outputDir, '@' + argfile.name] 1347 javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', args.compliance, '-classpath', cp, '-d', outputDir] + apArgs + ['@' + argfile.name]
1328 if not args.warnAPI: 1348 if not args.warnAPI:
1329 javacCmd.append('-XDignore.symbol.file') 1349 javacCmd.append('-XDignore.symbol.file')
1330 run(javacCmd) 1350 run(javacCmd)
1331 else: 1351 else:
1332 log('Compiling Java sources for {0} with JDT...'.format(p.name)) 1352 log('Compiling Java sources for {0} with JDT...'.format(p.name))
1333 jdtArgs = [java().java, '-Xmx1g', '-jar', jdtJar, 1353 jdtArgs = [java().java, '-Xmx1g', '-jar', jdtJar,
1334 '-' + args.compliance, 1354 '-' + args.compliance,
1335 '-cp', cp, '-g', '-enableJavadoc', 1355 '-cp', cp, '-g', '-enableJavadoc',
1336 '-d', outputDir] 1356 '-d', outputDir] + apArgs
1337 jdtProperties = join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs') 1357 jdtProperties = join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs')
1338 if not exists(jdtProperties): 1358 if not exists(jdtProperties):
1339 # Try to fix a missing properties file by running eclipseinit 1359 # Try to fix a missing properties file by running eclipseinit
1340 eclipseinit([]) 1360 eclipseinit([])
1341 if not exists(jdtProperties): 1361 if not exists(jdtProperties):
1360 1380
1361 if suppliedParser: 1381 if suppliedParser:
1362 return args 1382 return args
1363 return None 1383 return None
1364 1384
1385 def processorjars(args):
1386 hasProcessorJars = []
1387
1388 for p in sorted_deps():
1389 if hasattr(p, 'annotationProcessorClasses') and len(p.annotationProcessorClasses) > 0:
1390 hasProcessorJars.append(p)
1391
1392 if len(hasProcessorJars) <= 0:
1393 return
1394
1395 build(['--projects', ",".join(map(lambda p: p.name, hasProcessorJars))])
1396
1397 for p in hasProcessorJars:
1398 spDir = join(p.output_dir(), 'META-INF', 'services')
1399 if not exists(spDir):
1400 os.makedirs(spDir)
1401 spFile = join(spDir, 'javax.annotation.processing.Processor')
1402 with open(spFile, 'w') as fp:
1403 fp.writelines(p.annotationProcessorClasses)
1404 created = False
1405 for dep in p.all_deps([], False):
1406 if created:
1407 cmd = 'uf'
1408 else:
1409 cmd = 'cf'
1410 created = True
1411 jarCmd = [java().jar, cmd, join(p.dir, p.name + 'AnnotationProcessor.jar'), '-C', dep.output_dir(), '.']
1412 subprocess.check_call(jarCmd)
1413 log('added ' + dep.name + ' to ' + p.name + '.jar');
1414
1415
1365 def canonicalizeprojects(args): 1416 def canonicalizeprojects(args):
1366 """process all project files to canonicalize the dependencies 1417 """process all project files to canonicalize the dependencies
1367 1418
1368 The exit code of this command reflects how many files were updated.""" 1419 The exit code of this command reflects how many files were updated."""
1369 1420
1693 def eclipseinit(args, suite=None): 1744 def eclipseinit(args, suite=None):
1694 """(re)generate Eclipse project configurations""" 1745 """(re)generate Eclipse project configurations"""
1695 1746
1696 if suite is None: 1747 if suite is None:
1697 suite = _mainSuite 1748 suite = _mainSuite
1749
1750 processorjars([])
1698 1751
1699 for p in projects(): 1752 for p in projects():
1700 if p.native: 1753 if p.native:
1701 continue 1754 continue
1702 1755
1819 os.mkdir(settingsDir) 1872 os.mkdir(settingsDir)
1820 1873
1821 eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings') 1874 eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings')
1822 if exists(eclipseSettingsDir): 1875 if exists(eclipseSettingsDir):
1823 for name in os.listdir(eclipseSettingsDir): 1876 for name in os.listdir(eclipseSettingsDir):
1877 if name == "org.eclipse.jdt.apt.core.prefs" and not (hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0):
1878 continue
1824 path = join(eclipseSettingsDir, name) 1879 path = join(eclipseSettingsDir, name)
1825 if isfile(path): 1880 if isfile(path):
1826 with open(join(eclipseSettingsDir, name)) as f: 1881 with open(join(eclipseSettingsDir, name)) as f:
1827 content = f.read() 1882 content = f.read()
1828 content = content.replace('${javaCompliance}', str(p.javaCompliance)) 1883 content = content.replace('${javaCompliance}', str(p.javaCompliance))
1829 update_file(join(settingsDir, name), content) 1884 update_file(join(settingsDir, name), content)
1885
1886 if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
1887 out = XMLDoc()
1888 out.open('factorypath')
1889 out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'})
1890 for ap in p.annotationProcessors:
1891 apProject = project(ap)
1892 out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + apProject.name + '/' + apProject.name + 'AnnotationProcessor.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'})
1893 for dep in apProject.all_deps([], True):
1894 if dep.isLibrary():
1895 if not hasattr(dep, 'eclipse.container') and not hasattr(dep, 'eclipse.project'):
1896 if dep.mustExist:
1897 path = dep.get_path(resolve=True)
1898 if not isabs(path):
1899 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
1900 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
1901 # safest to simply use absolute paths.
1902 path = join(suite.dir, path)
1903 out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'})
1904 out.close('factorypath')
1905 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n'))
1830 1906
1831 make_eclipse_attach('localhost', '8000', deps=projects()) 1907 make_eclipse_attach('localhost', '8000', deps=projects())
1832 1908
1833 def netbeansinit(args, suite=None): 1909 def netbeansinit(args, suite=None):
1834 """(re)generate NetBeans project configurations""" 1910 """(re)generate NetBeans project configurations"""