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

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