You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BuildArgParser.java 33KB

hace 21 años
hace 21 años
hace 21 años
hace 14 años
hace 21 años
hace 12 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 14 años
hace 14 años
hace 14 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 14 años
hace 14 años
hace 21 años
hace 14 años
hace 14 años
hace 21 años
hace 21 años
hace 21 años
hace 14 años
hace 14 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 14 años
hace 14 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 21 años
hace 14 años
hace 21 años
hace 21 años
hace 21 años
hace 14 años
hace 14 años
hace 21 años
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.ajc;
  13. import java.io.File;
  14. import java.io.IOException;
  15. import java.io.PrintWriter;
  16. import java.io.StringWriter;
  17. import java.util.ArrayList;
  18. import java.util.Arrays;
  19. import java.util.Collection;
  20. import java.util.LinkedList;
  21. import java.util.List;
  22. import java.util.Locale;
  23. import java.util.StringTokenizer;
  24. import org.aspectj.ajdt.internal.compiler.lookup.EclipseSourceLocation;
  25. import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
  26. import org.aspectj.bridge.CountingMessageHandler;
  27. import org.aspectj.bridge.IMessage;
  28. import org.aspectj.bridge.IMessageHandler;
  29. import org.aspectj.bridge.ISourceLocation;
  30. import org.aspectj.bridge.Message;
  31. import org.aspectj.bridge.MessageUtil;
  32. import org.aspectj.bridge.SourceLocation;
  33. import org.aspectj.bridge.Version;
  34. import org.aspectj.org.eclipse.jdt.core.compiler.CategorizedProblem;
  35. import org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.AptProblem;
  36. import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem;
  37. import org.aspectj.org.eclipse.jdt.internal.compiler.batch.Main;
  38. import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
  39. import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
  40. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
  41. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
  42. import org.aspectj.util.FileUtil;
  43. import org.aspectj.util.LangUtil;
  44. import org.aspectj.weaver.Constants;
  45. import org.aspectj.weaver.Dump;
  46. import org.aspectj.weaver.WeaverMessages;
  47. @SuppressWarnings("unchecked")
  48. public class BuildArgParser extends Main {
  49. private static final String BUNDLE_NAME = "org.aspectj.ajdt.ajc.messages";
  50. private static boolean LOADED_BUNDLE = false;
  51. static {
  52. Main.bundleName = BUNDLE_NAME;
  53. ResourceBundleFactory.getBundle(Locale.getDefault());
  54. if (!LOADED_BUNDLE) {
  55. LOADED_BUNDLE = true;
  56. }
  57. }
  58. /** to initialize super's PrintWriter but refer to underlying StringWriter */
  59. private static class StringPrintWriter extends PrintWriter {
  60. public final StringWriter stringWriter;
  61. StringPrintWriter(StringWriter sw) {
  62. super(sw);
  63. this.stringWriter = sw;
  64. }
  65. }
  66. /** @return multi-line String usage for the compiler */
  67. public static String getUsage() {
  68. return _bind("misc.usage", new String[] { _bind("compiler.name", (String[]) null) });
  69. }
  70. public static String getXOptionUsage() {
  71. return _bind("xoption.usage", new String[] { _bind("compiler.name", (String[]) null) });
  72. }
  73. /**
  74. * StringWriter sink for some errors. This only captures errors not handled by any IMessageHandler parameter and only when no
  75. * PrintWriter is set in the constructor. XXX This relies on (Sun's) implementation of StringWriter, which returns the actual
  76. * (not copy) internal StringBuffer.
  77. */
  78. private final StringBuffer errorSink;
  79. private IMessageHandler handler;
  80. /**
  81. * Overrides super's bundle.
  82. */
  83. public BuildArgParser(PrintWriter writer, IMessageHandler handler) {
  84. super(writer, writer, false, null, null);
  85. if (writer instanceof StringPrintWriter) {
  86. errorSink = ((StringPrintWriter) writer).stringWriter.getBuffer();
  87. } else {
  88. errorSink = null;
  89. }
  90. this.handler = handler;
  91. }
  92. /** Set up to capture messages using getOtherMessages(boolean) */
  93. public BuildArgParser(IMessageHandler handler) {
  94. this(new StringPrintWriter(new StringWriter()), handler);
  95. }
  96. /**
  97. * Generate build configuration for the input args, passing to handler any error messages.
  98. *
  99. * @param args the String[] arguments for the build configuration
  100. * @return AjBuildConfig per args, which will be invalid unless there are no handler errors.
  101. */
  102. public AjBuildConfig genBuildConfig(String[] args) {
  103. final AjBuildConfig config = new AjBuildConfig(this);
  104. populateBuildConfig(config, args, true, null);
  105. return config;
  106. }
  107. /**
  108. * Generate build configuration for the input arguments, passing to handler any error messages.
  109. *
  110. * @param args the String[] arguments for the build configuration
  111. * @param setClasspath determines if the classpath should be parsed and set on the build configuration
  112. * @param configFile can be null
  113. * @return AjBuildConfig per arguments, which will be invalid unless there are no handler errors.
  114. */
  115. public AjBuildConfig populateBuildConfig(AjBuildConfig buildConfig, String[] args, boolean setClasspath, File configFile) {
  116. Dump.saveCommandLine(args);
  117. buildConfig.setConfigFile(configFile);
  118. try {
  119. // sets filenames to be non-null in order to make sure that file parameters are ignored
  120. super.filenames = new String[] { "" };
  121. AjcConfigParser parser = new AjcConfigParser(buildConfig, handler);
  122. parser.parseCommandLine(args);
  123. boolean swi = buildConfig.getShowWeavingInformation();
  124. // Now jump through firey hoops to turn them on/off
  125. if (handler instanceof CountingMessageHandler) {
  126. IMessageHandler delegate = ((CountingMessageHandler) handler).delegate;
  127. if (swi) {
  128. delegate.dontIgnore(IMessage.WEAVEINFO);
  129. } else {
  130. delegate.ignore(IMessage.WEAVEINFO);
  131. }
  132. }
  133. boolean incrementalMode = buildConfig.isIncrementalMode() || buildConfig.isIncrementalFileMode();
  134. List<File> xmlfileList = new ArrayList<>(parser.getXmlFiles());
  135. List<File> fileList = new ArrayList<>();
  136. List<File> files = parser.getFiles();
  137. if (!LangUtil.isEmpty(files)) {
  138. if (incrementalMode) {
  139. MessageUtil.error(handler, "incremental mode only handles source files using -sourceroots");
  140. } else {
  141. fileList.addAll(files);
  142. }
  143. }
  144. List<String> javaArgList = new ArrayList<>();
  145. // disable all special eclipse warnings by default - why???
  146. // ??? might want to instead override getDefaultOptions()
  147. javaArgList.add("-warn:none");
  148. // these next four lines are some nonsense to fool the eclipse batch compiler
  149. // without these it will go searching for reasonable values from properties
  150. // TODO fix org.eclipse.jdt.internal.compiler.batch.Main so this hack isn't needed
  151. javaArgList.add("-classpath");
  152. javaArgList.add(parser.classpath == null ? System.getProperty("user.dir") : parser.classpath);
  153. // javaArgList.add("-bootclasspath");
  154. // javaArgList.add(parser.bootclasspath == null ? System.getProperty("user.dir") : parser.bootclasspath);
  155. javaArgList.addAll(parser.getUnparsedArgs());
  156. super.configure(javaArgList.toArray(new String[0]));
  157. if (parser.getModuleInfoArgument() != null) {
  158. IModule moduleDesc = super.getModuleDesc(parser.getModuleInfoArgument());
  159. buildConfig.setModuleDesc(moduleDesc);
  160. }
  161. if (!proceed) {
  162. buildConfig.doNotProceed();
  163. return buildConfig;
  164. }
  165. if (buildConfig.getSourceRoots() != null) {
  166. for (File file : buildConfig.getSourceRoots()) {
  167. fileList.addAll(collectSourceRootFiles(file));
  168. }
  169. }
  170. buildConfig.setXmlFiles(xmlfileList);
  171. buildConfig.setFiles(fileList);
  172. if (destinationPath != null) { // XXX ?? unparsed but set?
  173. buildConfig.setOutputDir(new File(destinationPath));
  174. }
  175. if (setClasspath) {
  176. // This computed classpaths will be missing aspectpaths, inpaths, add those first
  177. buildConfig.setClasspath(getClasspath(parser));
  178. // Implicit inclusion of jmods on module path
  179. if (checkVMVersion(ClassFileConstants.JDK9)) {
  180. // Add the default jmods path? javac seems to do this
  181. File jmods = new File(getJavaHome(),"jmods");
  182. parser.modulepath = (parser.modulepath == null)?jmods.getAbsolutePath():parser.modulepath+File.pathSeparator+jmods.getAbsolutePath();
  183. }
  184. buildConfig.setModulepath(getModulepath(parser));
  185. buildConfig.setModulepathClasspathEntries(handleModulepath(parser.modulepath));
  186. buildConfig.setModulesourcepath(getModulesourcepath(parser));
  187. buildConfig.setModulesourcepathClasspathEntries(handleModuleSourcepath(parser.modulesourcepath));
  188. buildConfig.setBootclasspath(getBootclasspath(parser));
  189. // TODO other paths (module/module source)
  190. }
  191. if (incrementalMode && (0 == buildConfig.getSourceRoots().size())) {
  192. MessageUtil.error(handler, "specify a source root when in incremental mode");
  193. }
  194. /*
  195. * Ensure we don't overwrite injars, inpath or aspectpath with outjar bug-71339
  196. */
  197. File outjar = buildConfig.getOutputJar();
  198. if (outjar != null) {
  199. for (File injar: buildConfig.getInJars()) {
  200. if (injar.equals(outjar)) {
  201. String message = WeaverMessages.format(WeaverMessages.OUTJAR_IN_INPUT_PATH);
  202. MessageUtil.error(handler, message);
  203. }
  204. }
  205. for (File inPathElement: buildConfig.getInpath()) {
  206. if (!inPathElement.isDirectory() && inPathElement.equals(outjar)) {
  207. String message = WeaverMessages.format(WeaverMessages.OUTJAR_IN_INPUT_PATH);
  208. MessageUtil.error(handler, message);
  209. }
  210. }
  211. for (File aspectPathElement: buildConfig.getAspectpath()) {
  212. if (!aspectPathElement.isDirectory() && aspectPathElement.equals(outjar)) {
  213. String message = WeaverMessages.format(WeaverMessages.OUTJAR_IN_INPUT_PATH);
  214. MessageUtil.error(handler, message);
  215. }
  216. }
  217. }
  218. setDebugOptions();
  219. buildConfig.getOptions().set(options);
  220. } catch (IllegalArgumentException iae) {
  221. ISourceLocation location = null;
  222. if (buildConfig.getConfigFile() != null) {
  223. location = new SourceLocation(buildConfig.getConfigFile(), 0);
  224. }
  225. IMessage m = new Message(iae.getMessage(), IMessage.ERROR, null, location);
  226. handler.handleMessage(m);
  227. }
  228. return buildConfig;
  229. }
  230. private void augmentCheckedClasspaths(List<File> extraPathEntries, String encoding) {
  231. if (extraPathEntries.size() == 0) {
  232. return;
  233. }
  234. ArrayList<String> asList = toArrayList(extraPathEntries);
  235. List<FileSystem.Classpath> newClasspathEntries = handleClasspath(asList, encoding);
  236. FileSystem.Classpath[] newCheckedClasspaths = new FileSystem.Classpath[checkedClasspaths.length + newClasspathEntries.size()];
  237. System.arraycopy(checkedClasspaths, 0, newCheckedClasspaths, 0, checkedClasspaths.length);
  238. for (int i = 0; i < newClasspathEntries.size();i++) {
  239. newCheckedClasspaths[i + checkedClasspaths.length] = newClasspathEntries.get(i);
  240. }
  241. checkedClasspaths = newCheckedClasspaths;
  242. }
  243. private ArrayList<String> toArrayList(java.util.List<File> files) {
  244. ArrayList<String> arrayList = new ArrayList<>();
  245. for (File file: files) {
  246. arrayList.add(file.getAbsolutePath());
  247. }
  248. return arrayList;
  249. }
  250. @Override
  251. public void printVersion() {
  252. final String version = bind("misc.version", //$NON-NLS-1$
  253. new String[] { bind("compiler.name"), //$NON-NLS-1$
  254. Version.getText() + " - Built: " + Version.getTimeText(), bind("compiler.version"), //$NON-NLS-1$
  255. bind("compiler.copyright") //$NON-NLS-1$
  256. });
  257. System.out.println(version);
  258. }
  259. @Override
  260. public void addExtraProblems(CategorizedProblem problem) {
  261. super.addExtraProblems(problem);
  262. if (problem instanceof AptProblem) {
  263. handler.handleMessage(newAptMessage((AptProblem)problem));
  264. }
  265. }
  266. private IMessage newAptMessage(AptProblem problem) {
  267. String message = problem.getMessage();
  268. boolean isError = problem.isError();
  269. if (problem._referenceContext != null) {
  270. return new Message(message,
  271. new EclipseSourceLocation(problem._referenceContext.compilationResult(), problem.getSourceStart(), problem.getSourceEnd()),
  272. isError);
  273. } else {
  274. return new Message(message, null, isError);
  275. }
  276. }
  277. @Override
  278. public void initializeAnnotationProcessorManager() {
  279. if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_6 || !this.compilerOptions.processAnnotations)
  280. return;
  281. super.initializeAnnotationProcessorManager();
  282. }
  283. @Override
  284. public void printUsage() {
  285. System.out.println(getUsage());
  286. System.out.flush();
  287. }
  288. /**
  289. * Get messages not dumped to handler or any PrintWriter.
  290. *
  291. * @param flush if true, empty errors
  292. * @return null if none, String otherwise
  293. * @see #BuildArgParser(IMessageHandler)
  294. */
  295. public String getOtherMessages(boolean flush) {
  296. if (null == errorSink) {
  297. return null;
  298. }
  299. String result = errorSink.toString().trim();
  300. if (0 == result.length()) {
  301. result = null;
  302. }
  303. if (flush) {
  304. errorSink.setLength(0);
  305. }
  306. return result;
  307. }
  308. private void setDebugOptions() {
  309. options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
  310. options.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
  311. options.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE);
  312. }
  313. private Collection collectSourceRootFiles(File dir) {
  314. return Arrays.asList(FileUtil.listFiles(dir, FileUtil.aspectjSourceFileFilter));
  315. }
  316. public List<String> getBootclasspath(AjcConfigParser parser) {
  317. List<String> ret = new ArrayList<>();
  318. if (parser.bootclasspath == null) {
  319. if (LangUtil.is9VMOrGreater()) {
  320. addClasspath(LangUtil.getJrtFsFilePath(),ret);
  321. } else {
  322. addClasspath(System.getProperty("sun.boot.class.path", ""), ret);
  323. }
  324. } else {
  325. addClasspath(parser.bootclasspath, ret);
  326. }
  327. return ret;
  328. }
  329. public List<String> getModulepath(AjcConfigParser parser) {
  330. List<String> ret = new ArrayList<>();
  331. addClasspath(parser.modulepath, ret);
  332. return ret;
  333. }
  334. public List<String> getModulesourcepath(AjcConfigParser parser) {
  335. List<String> ret = new ArrayList<>();
  336. addClasspath(parser.modulesourcepath, ret);
  337. return ret;
  338. }
  339. @Override
  340. public ArrayList<FileSystem.Classpath> handleClasspath(ArrayList<String> classpaths, String customEncoding) {
  341. return super.handleClasspath(classpaths, customEncoding);
  342. }
  343. /**
  344. * If the classpath is not set, we use the environment's java.class.path, but remove the aspectjtools.jar entry from that list
  345. * in order to prevent wierd bootstrap issues (refer to bug#39959).
  346. */
  347. public List getClasspath(AjcConfigParser parser) {
  348. List ret = new ArrayList();
  349. // if (parser.bootclasspath == null) {
  350. // addClasspath(System.getProperty("sun.boot.class.path", ""), ret);
  351. // } else {
  352. // addClasspath(parser.bootclasspath, ret);
  353. // }
  354. String extdirs = parser.extdirs;
  355. if (extdirs == null) {
  356. extdirs = System.getProperty("java.ext.dirs", "");
  357. }
  358. addExtDirs(extdirs, ret);
  359. if (parser.classpath == null) {
  360. addClasspath(System.getProperty("java.class.path", ""), ret);
  361. List fixedList = new ArrayList();
  362. for (Object o : ret) {
  363. String entry = (String) o;
  364. if (!entry.endsWith("aspectjtools.jar")) {
  365. fixedList.add(entry);
  366. }
  367. }
  368. ret = fixedList;
  369. } else {
  370. addClasspath(parser.classpath, ret);
  371. }
  372. // ??? eclipse seems to put outdir on the classpath
  373. // ??? we're brave and believe we don't need it
  374. return ret;
  375. }
  376. private void addExtDirs(String extdirs, List classpathCollector) {
  377. StringTokenizer tokenizer = new StringTokenizer(extdirs, File.pathSeparator);
  378. while (tokenizer.hasMoreTokens()) {
  379. // classpathCollector.add(tokenizer.nextToken());
  380. File dirFile = new File(tokenizer.nextToken());
  381. if (dirFile.canRead() && dirFile.isDirectory()) {
  382. File[] files = dirFile.listFiles(FileUtil.ZIP_FILTER);
  383. for (File file : files) {
  384. classpathCollector.add(file.getAbsolutePath());
  385. }
  386. } else {
  387. // XXX alert on invalid -extdirs entries
  388. }
  389. }
  390. }
  391. private void addClasspath(String classpath, List<String> classpathCollector) {
  392. if (classpath == null) {
  393. return;
  394. }
  395. StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
  396. while (tokenizer.hasMoreTokens()) {
  397. classpathCollector.add(tokenizer.nextToken());
  398. }
  399. }
  400. private class AjcConfigParser extends ConfigParser {
  401. private String bootclasspath = null;
  402. private String classpath = null;
  403. private String modulepath = null;
  404. private String modulesourcepath = null;
  405. private String extdirs = null;
  406. private List unparsedArgs = new ArrayList();
  407. private AjBuildConfig buildConfig;
  408. private IMessageHandler handler;
  409. private String moduleInfoArgument;
  410. public AjcConfigParser(AjBuildConfig buildConfig, IMessageHandler handler) {
  411. this.buildConfig = buildConfig;
  412. this.handler = handler;
  413. }
  414. public List getUnparsedArgs() {
  415. return unparsedArgs;
  416. }
  417. public String getModuleInfoArgument() {
  418. return this.moduleInfoArgument;
  419. }
  420. /**
  421. * Extract AspectJ-specific options (except for argfiles). Caller should warn when sourceroots is empty but in incremental
  422. * mode. Signals warnings or errors through handler set in constructor.
  423. */
  424. @Override
  425. public void parseOption(String arg, LinkedList<Arg> args) { // XXX use ListIterator.remove()
  426. int nextArgIndex = args.indexOf(arg) + 1; // XXX assumes unique
  427. // trim arg?
  428. buildConfig.setXlazyTjp(true); // now default - MINOR could be pushed down and made default at a lower level
  429. if (LangUtil.isEmpty(arg)) {
  430. showWarning("empty arg found");
  431. } else if (arg.endsWith("module-info.java")) {
  432. moduleInfoArgument = arg;
  433. } else if (arg.equals("-inpath")) {
  434. if (args.size() > nextArgIndex) {
  435. // buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_Inpath, CompilerOptions.PRESERVE);
  436. StringTokenizer st = new StringTokenizer(args.get(nextArgIndex).getValue(),
  437. File.pathSeparator);
  438. boolean inpathChange = false;
  439. while (st.hasMoreTokens()) {
  440. String filename = st.nextToken();
  441. File file = makeFile(filename);
  442. if (FileUtil.isZipFile(file)) {
  443. buildConfig.addToInpath(file);
  444. inpathChange = true;
  445. } else {
  446. if (file.isDirectory()) {
  447. buildConfig.addToInpath(file);
  448. inpathChange = true;
  449. } else {
  450. showWarning("skipping missing, empty or corrupt inpath entry: " + filename);
  451. }
  452. }
  453. }
  454. if (inpathChange) {
  455. buildConfig.processInPath();
  456. }
  457. args.remove(args.get(nextArgIndex));
  458. }
  459. } else if (arg.equals("-injars")) {
  460. if (args.size() > nextArgIndex) {
  461. // buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_InJARs, CompilerOptions.PRESERVE);
  462. StringTokenizer st = new StringTokenizer(args.get(nextArgIndex).getValue(),
  463. File.pathSeparator);
  464. while (st.hasMoreTokens()) {
  465. String filename = st.nextToken();
  466. File jarFile = makeFile(filename);
  467. if (FileUtil.isZipFile(jarFile)) {
  468. buildConfig.getInJars().add(jarFile);
  469. } else {
  470. File dirFile = makeFile(filename);
  471. if (dirFile.isDirectory()) {
  472. buildConfig.getInJars().add(dirFile);
  473. } else {
  474. showWarning("skipping missing, empty or corrupt injar: " + filename);
  475. }
  476. }
  477. }
  478. args.remove(args.get(nextArgIndex));
  479. }
  480. } else if (arg.equals("-aspectpath")) {
  481. if (args.size() > nextArgIndex) {
  482. StringTokenizer st = new StringTokenizer(args.get(nextArgIndex).getValue(),
  483. File.pathSeparator);
  484. while (st.hasMoreTokens()) {
  485. String filename = st.nextToken();
  486. File jarFile = makeFile(filename);
  487. if (FileUtil.isZipFile(jarFile) || jarFile.isDirectory()) {
  488. // buildConfig.getAspectpath().add(jarFile);
  489. buildConfig.addToAspectpath(jarFile);
  490. } else {
  491. showWarning("skipping missing, empty or corrupt aspectpath entry: " + filename);
  492. }
  493. }
  494. args.remove(args.get(nextArgIndex));
  495. }
  496. } else if (arg.equals("-makeAjReflectable")) {
  497. buildConfig.setMakeReflectable(true);
  498. } else if (arg.equals("-sourceroots")) {
  499. if (args.size() > nextArgIndex) {
  500. List<File> sourceRoots = new ArrayList<>();
  501. StringTokenizer st = new StringTokenizer(args.get(nextArgIndex).getValue(),
  502. File.pathSeparator);
  503. while (st.hasMoreTokens()) {
  504. File f = makeFile(st.nextToken());
  505. if (f.isDirectory() && f.canRead()) {
  506. sourceRoots.add(f);
  507. } else {
  508. showError("bad sourceroot: " + f);
  509. }
  510. }
  511. if (0 < sourceRoots.size()) {
  512. buildConfig.setSourceRoots(sourceRoots);
  513. }
  514. args.remove(args.get(nextArgIndex));
  515. } else {
  516. showError("-sourceroots requires list of directories");
  517. }
  518. } else if (arg.equals("-outjar")) {
  519. if (args.size() > nextArgIndex) {
  520. // buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_OutJAR, CompilerOptions.GENERATE);
  521. File jarFile = makeFile(args.get(nextArgIndex).getValue());
  522. if (!jarFile.isDirectory()) {
  523. try {
  524. if (!jarFile.exists()) {
  525. jarFile.createNewFile();
  526. }
  527. buildConfig.setOutputJar(jarFile);
  528. } catch (IOException ioe) {
  529. showError("unable to create outjar file: " + jarFile);
  530. }
  531. } else {
  532. showError("invalid -outjar file: " + jarFile);
  533. }
  534. args.remove(args.get(nextArgIndex));
  535. } else {
  536. showError("-outjar requires jar path argument");
  537. }
  538. } else if (arg.equals("-outxml")) {
  539. buildConfig.setOutxmlName(org.aspectj.bridge.Constants.AOP_AJC_XML);
  540. } else if (arg.equals("-outxmlfile")) {
  541. if (args.size() > nextArgIndex) {
  542. String name = args.get(nextArgIndex).getValue();
  543. buildConfig.setOutxmlName(name);
  544. args.remove(args.get(nextArgIndex));
  545. } else {
  546. showError("-outxmlfile requires file name argument");
  547. }
  548. } else if (arg.equals("-log")) {
  549. // remove it as it's already been handled in org.aspectj.tools.ajc.Main
  550. args.remove(args.get(nextArgIndex));
  551. } else if (arg.equals("-messageHolder")) {
  552. // remove it as it's already been handled in org.aspectj.tools.ajc.Main
  553. args.remove(args.get(nextArgIndex));
  554. } else if (arg.equals("-incremental")) {
  555. buildConfig.setIncrementalMode(true);
  556. } else if (arg.equals("-XincrementalFile")) {
  557. if (args.size() > nextArgIndex) {
  558. File file = makeFile(args.get(nextArgIndex).getValue());
  559. buildConfig.setIncrementalFile(file);
  560. if (!file.canRead()) {
  561. showError("bad -XincrementalFile : " + file);
  562. // if not created before recompile test, stop after first compile
  563. }
  564. args.remove(args.get(nextArgIndex));
  565. } else {
  566. showError("-XincrementalFile requires file argument");
  567. }
  568. } else if (arg.equals("-crossrefs")) {
  569. buildConfig.setGenerateCrossRefsMode(true);
  570. buildConfig.setGenerateModelMode(true);
  571. } else if (arg.startsWith("-checkRuntimeVersion:")) {
  572. String lcArg = arg.toLowerCase();
  573. if (lcArg.endsWith(":false")) {
  574. buildConfig.setCheckRuntimeVersion(false);
  575. } else if (lcArg.endsWith(":true")) {
  576. buildConfig.setCheckRuntimeVersion(true);
  577. } else {
  578. showError("bad value for -checkRuntimeVersion option, must be true or false");
  579. }
  580. } else if (arg.equals("-emacssym")) {
  581. buildConfig.setEmacsSymMode(true);
  582. buildConfig.setGenerateModelMode(true);
  583. } else if (arg.equals("-XjavadocsInModel")) {
  584. buildConfig.setGenerateModelMode(true);
  585. buildConfig.setGenerateJavadocsInModelMode(true);
  586. } else if (arg.equals("-Xdev:NoAtAspectJProcessing")) {
  587. buildConfig.setNoAtAspectJAnnotationProcessing(true);
  588. } else if (arg.equals("-XaddSerialVersionUID")) {
  589. buildConfig.setAddSerialVerUID(true);
  590. } else if (arg.equals("-xmlConfigured")) {
  591. buildConfig.setXmlConfigured(true);
  592. } else if (arg.equals("-Xdev:Pinpoint")) {
  593. buildConfig.setXdevPinpointMode(true);
  594. } else if (arg.startsWith("-Xjoinpoints:")) {
  595. buildConfig.setXJoinpoints(arg.substring(13));
  596. } else if (arg.equals("-noWeave") || arg.equals("-XnoWeave")) {
  597. showWarning("the noweave option is no longer required and is being ignored");
  598. } else if (arg.equals("-XterminateAfterCompilation")) {
  599. buildConfig.setTerminateAfterCompilation(true);
  600. } else if (arg.equals("-XserializableAspects")) {
  601. buildConfig.setXserializableAspects(true);
  602. } else if (arg.equals("-XlazyTjp")) {
  603. // do nothing as this is now on by default
  604. showWarning("-XlazyTjp should no longer be used, build tjps lazily is now the default");
  605. } else if (arg.startsWith("-Xreweavable")) {
  606. showWarning("-Xreweavable is on by default");
  607. if (arg.endsWith(":compress")) {
  608. showWarning("-Xreweavable:compress is no longer available - reweavable is now default");
  609. }
  610. } else if (arg.startsWith("-Xset:")) {
  611. buildConfig.setXconfigurationInfo(arg.substring(6));
  612. } else if (arg.startsWith("-aspectj.pushin=")) {
  613. // a little dirty but this should never be used in the IDE
  614. try {
  615. System.setProperty("aspectj.pushin", arg.substring(16));
  616. } catch (Exception e) {
  617. e.printStackTrace();
  618. }
  619. } else if (arg.startsWith("-XnotReweavable")) {
  620. buildConfig.setXnotReweavable(true);
  621. } else if (arg.equals("-XnoInline")) {
  622. buildConfig.setXnoInline(true);
  623. } else if (arg.equals("-XhasMember")) {
  624. buildConfig.setXHasMemberSupport(true);
  625. } else if (arg.startsWith("-showWeaveInfo")) {
  626. buildConfig.setShowWeavingInformation(true);
  627. } else if (arg.equals("-Xlintfile")) {
  628. if (args.size() > nextArgIndex) {
  629. File lintSpecFile = makeFile(args.get(nextArgIndex).getValue());
  630. // XXX relax restriction on props file suffix?
  631. if (lintSpecFile.canRead() && lintSpecFile.getName().endsWith(".properties")) {
  632. buildConfig.setLintSpecFile(lintSpecFile);
  633. } else {
  634. showError("bad -Xlintfile file: " + lintSpecFile);
  635. buildConfig.setLintSpecFile(null);
  636. }
  637. args.remove(args.get(nextArgIndex));
  638. } else {
  639. showError("-Xlintfile requires .properties file argument");
  640. }
  641. } else if (arg.equals("-Xlint")) {
  642. // buildConfig.getAjOptions().put(
  643. // AjCompilerOptions.OPTION_Xlint,
  644. // CompilerOptions.GENERATE);
  645. buildConfig.setLintMode(AjBuildConfig.AJLINT_DEFAULT);
  646. } else if (arg.startsWith("-Xlint:")) {
  647. if (7 < arg.length()) {
  648. buildConfig.setLintMode(arg.substring(7));
  649. } else {
  650. showError("invalid lint option " + arg);
  651. }
  652. } else if (arg.equals("-bootclasspath")) {
  653. if (args.size() > nextArgIndex) {
  654. String bcpArg = args.get(nextArgIndex).getValue();
  655. StringBuffer bcp = new StringBuffer();
  656. StringTokenizer strTok = new StringTokenizer(bcpArg, File.pathSeparator);
  657. while (strTok.hasMoreTokens()) {
  658. bcp.append(makeFile(strTok.nextToken()));
  659. if (strTok.hasMoreTokens()) {
  660. bcp.append(File.pathSeparator);
  661. }
  662. }
  663. bootclasspath = bcp.toString();
  664. args.remove(args.get(nextArgIndex));
  665. } else {
  666. showError("-bootclasspath requires classpath entries");
  667. }
  668. } else if (arg.equals("-classpath") || arg.equals("-cp")) {
  669. if (args.size() > nextArgIndex) {
  670. String cpArg = args.get(nextArgIndex).getValue();
  671. StringBuffer cp = new StringBuffer();
  672. StringTokenizer strTok = new StringTokenizer(cpArg, File.pathSeparator);
  673. while (strTok.hasMoreTokens()) {
  674. cp.append(makeFile(strTok.nextToken()));
  675. if (strTok.hasMoreTokens()) {
  676. cp.append(File.pathSeparator);
  677. }
  678. }
  679. classpath = cp.toString();
  680. args.remove(args.get(nextArgIndex));
  681. } else {
  682. showError("-classpath requires classpath entries");
  683. }
  684. } else if (arg.equals("--module-path") || arg.equals("-p")) {
  685. if (args.size() > nextArgIndex) {
  686. String mpArg = args.get(nextArgIndex).getValue();
  687. modulepath = mpArg;
  688. args.remove(args.get(nextArgIndex));
  689. } else {
  690. showError("--module-path requires modulepath entries");
  691. }
  692. } else if (arg.equals("--module-source-path") || arg.equals("-p")) {
  693. if (args.size() > nextArgIndex) {
  694. String mspArg = args.get(nextArgIndex).getValue();
  695. modulesourcepath = mspArg;
  696. args.remove(args.get(nextArgIndex));
  697. } else {
  698. showError("--module-source-path requires modulepath entries");
  699. }
  700. } else if (arg.equals("-extdirs")) {
  701. if (args.size() > nextArgIndex) {
  702. String extdirsArg = args.get(nextArgIndex).getValue();
  703. StringBuffer ed = new StringBuffer();
  704. StringTokenizer strTok = new StringTokenizer(extdirsArg, File.pathSeparator);
  705. while (strTok.hasMoreTokens()) {
  706. ed.append(makeFile(strTok.nextToken()));
  707. if (strTok.hasMoreTokens()) {
  708. ed.append(File.pathSeparator);
  709. }
  710. }
  711. extdirs = ed.toString();
  712. args.remove(args.get(nextArgIndex));
  713. } else {
  714. showError("-extdirs requires list of external directories");
  715. }
  716. // error on directory unless -d, -{boot}classpath, or -extdirs
  717. } else if (arg.equals("-d")) {
  718. dirLookahead(arg, args, nextArgIndex);
  719. // } else if (arg.equals("-classpath")) {
  720. // dirLookahead(arg, args, nextArgIndex);
  721. // } else if (arg.equals("-bootclasspath")) {
  722. // dirLookahead(arg, args, nextArgIndex);
  723. // } else if (arg.equals("-extdirs")) {
  724. // dirLookahead(arg, args, nextArgIndex);
  725. } else if (arg.equals("-proceedOnError")) {
  726. buildConfig.setProceedOnError(true);
  727. } else if (arg.equals("-processorpath")) { // -processorpath <directories and ZIP archives separated by pathseporator
  728. addPairToUnparsed(args, arg, nextArgIndex, "-processorpath requires list of external directories or zip archives");
  729. } else if (arg.equals("-processor")) { // -processor <class1[,class2,...]>
  730. addPairToUnparsed(args, arg, nextArgIndex, "-processor requires list of processors' classes");
  731. } else if (arg.equals("-s")) { // -s <dir> destination directory for generated source files
  732. addPairToUnparsed(args, arg, nextArgIndex, "-s requires directory");
  733. } else if (arg.equals("-classNames")) { // -classNames <className1[,className2,...]>
  734. addPairToUnparsed(args, arg, nextArgIndex, "-classNames requires list of classes");
  735. } else if (new File(arg).isDirectory()) {
  736. showError("dir arg not permitted: " + arg);
  737. } else if (arg.startsWith("-Xajruntimetarget")) {
  738. if (arg.endsWith(":1.2")) {
  739. buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_12);
  740. } else if (arg.endsWith(":1.5")) {
  741. buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_15);
  742. } else if (arg.endsWith(":1.9")) {
  743. buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_19);
  744. } else {
  745. showError("-Xajruntimetarget:<level> supports a target level of 1.2, 1.5, 1.9");
  746. }
  747. } else if (arg.equals("-timers")) {
  748. buildConfig.setTiming(true);
  749. // swallow - it is dealt with in Main.runMain()
  750. } else if (arg.equals("-1.3")) {
  751. buildConfig.setBehaveInJava5Way(false);
  752. unparsedArgs.add("-1.3");
  753. } else if (arg.equals("-1.4")) {
  754. buildConfig.setBehaveInJava5Way(false);
  755. unparsedArgs.add("-1.4");
  756. } else if (arg.equals("-source")) {
  757. if (args.size() > nextArgIndex) {
  758. String level = args.get(nextArgIndex).getValue();
  759. if (level.equals("1.3") || level.equals("1.4")) {
  760. buildConfig.setBehaveInJava5Way(false);
  761. }
  762. unparsedArgs.add("-source");
  763. unparsedArgs.add(level);
  764. args.remove(args.get(nextArgIndex));
  765. }
  766. } else {
  767. // argfile, @file parsed by superclass
  768. // no eclipse options parsed:
  769. // -d args, -help (handled),
  770. // -classpath, -target, -1.3, -1.4, -source [1.3|1.4]
  771. // -nowarn, -warn:[...], -deprecation, -noImportError,
  772. // -g:[...], -preserveAllLocals,
  773. // -referenceInfo, -encoding, -verbose, -log, -time
  774. // -noExit, -repeat
  775. // (Actually, -noExit grabbed by Main)
  776. unparsedArgs.add(arg);
  777. }
  778. }
  779. protected void dirLookahead(String arg, LinkedList argList, int nextArgIndex) {
  780. unparsedArgs.add(arg);
  781. ConfigParser.Arg next = (ConfigParser.Arg) argList.get(nextArgIndex);
  782. String value = next.getValue();
  783. if (!LangUtil.isEmpty(value)) {
  784. if (new File(value).isDirectory()) {
  785. unparsedArgs.add(value);
  786. argList.remove(next);
  787. return;
  788. }
  789. }
  790. }
  791. @Override
  792. public void showError(String message) {
  793. ISourceLocation location = null;
  794. if (buildConfig.getConfigFile() != null) {
  795. location = new SourceLocation(buildConfig.getConfigFile(), 0);
  796. }
  797. IMessage errorMessage = new Message(CONFIG_MSG + message, IMessage.ERROR, null, location);
  798. handler.handleMessage(errorMessage);
  799. // MessageUtil.error(handler, CONFIG_MSG + message);
  800. }
  801. @Override
  802. protected void showWarning(String message) {
  803. ISourceLocation location = null;
  804. if (buildConfig.getConfigFile() != null) {
  805. location = new SourceLocation(buildConfig.getConfigFile(), 0);
  806. }
  807. IMessage errorMessage = new Message(CONFIG_MSG + message, IMessage.WARNING, null, location);
  808. handler.handleMessage(errorMessage);
  809. // MessageUtil.warn(handler, message);
  810. }
  811. protected File makeFile(File dir, String name) {
  812. name = name.replace('/', File.separatorChar);
  813. File ret = new File(name);
  814. if (dir == null || ret.isAbsolute()) {
  815. return ret;
  816. }
  817. try {
  818. dir = dir.getCanonicalFile();
  819. } catch (IOException ioe) {
  820. }
  821. return new File(dir, name);
  822. }
  823. private void addPairToUnparsed(LinkedList<Arg> args, String arg, int nextArgIndex, String errorMessage) {
  824. if (args.size() <= nextArgIndex) {
  825. showError(errorMessage);
  826. return;
  827. }
  828. final Arg nextArg = args.get(nextArgIndex);
  829. args.remove(nextArg);
  830. unparsedArgs.add(arg);
  831. unparsedArgs.add(nextArg.getValue());
  832. }
  833. private int indexOf(Iterable<Arg> args, String arg) {
  834. int index = 0;
  835. for (Arg argument : args) {
  836. if (arg.equals(argument.getValue())) {
  837. return index;
  838. }
  839. index++;
  840. }
  841. return -1;
  842. }
  843. }
  844. @Override
  845. public boolean checkVMVersion(long minimalSupportedVersion) {
  846. return super.checkVMVersion(minimalSupportedVersion);
  847. }
  848. @Override
  849. public void initRootModules(LookupEnvironment environment, FileSystem fileSystem) {
  850. super.initRootModules(environment, fileSystem);
  851. }
  852. }