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.

CompilerRun.java 73KB

21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
20 years ago
21 years ago
20 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
20 years ago
21 years ago
21 years ago
20 years ago
20 years ago
21 years ago
21 years ago
20 years ago
20 years ago
20 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
20 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
20 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
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
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
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
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC),
  3. * 2003 Contributors.
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * Wes Isberg 2003 updates
  13. * ******************************************************************/
  14. package org.aspectj.testing.harness.bridge;
  15. import java.io.File;
  16. import java.io.FileFilter;
  17. import java.io.IOException;
  18. import java.io.PrintStream;
  19. import java.lang.reflect.Array;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.Collections;
  23. import java.util.Iterator;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.Set;
  27. import java.util.TreeMap;
  28. import org.aspectj.bridge.ICommand;
  29. import org.aspectj.bridge.IMessage;
  30. import org.aspectj.bridge.IMessageHandler;
  31. import org.aspectj.bridge.MessageHandler;
  32. import org.aspectj.bridge.MessageUtil;
  33. import org.aspectj.bridge.ReflectionFactory;
  34. import org.aspectj.testing.ajde.CompileCommand;
  35. import org.aspectj.testing.run.IRunIterator;
  36. import org.aspectj.testing.run.IRunStatus;
  37. import org.aspectj.testing.run.WrappedRunIterator;
  38. import org.aspectj.testing.taskdefs.AjcTaskCompileCommand;
  39. import org.aspectj.testing.util.options.Option;
  40. import org.aspectj.testing.util.options.Option.Family;
  41. import org.aspectj.testing.util.options.Option.InvalidInputException;
  42. import org.aspectj.testing.util.options.Options;
  43. import org.aspectj.testing.util.options.Values;
  44. import org.aspectj.testing.xml.SoftMessage;
  45. import org.aspectj.testing.xml.XMLWriter;
  46. import org.aspectj.util.FileUtil;
  47. import org.aspectj.util.LangUtil;
  48. /**
  49. * Run the compiler once.
  50. * The lifecycle is as follows:
  51. * <ul>
  52. * <li>Spec (specification) is created.</li>
  53. * <li>This is created using the Spec.</li>
  54. * <li>setupAjcRun(Sandbox, Validator) is invoked,
  55. * at which point this populates the shared sandbox
  56. * with values derived from the spec and also
  57. * sets up internal state based on both the sandbox
  58. * and the spec.</li>
  59. * <li>run(IRunStatus) is invoked, and this runs the compiler
  60. * based on internal state, the spec, and the sandbox.</li>
  61. * </ul>
  62. * Programmer notes:
  63. * <ul>
  64. * <li>Paths are resolved absolutely, which fails to test the
  65. * compiler's ability to find files relative to a source base</li>
  66. * <li>This does not enforce the lifecycle.</li>
  67. * <li>This must be used as the initial compile
  68. * before doing an incremental compile.
  69. * In that case, staging must be enabled.</li>
  70. * </ul>
  71. */
  72. public class CompilerRun implements IAjcRun {
  73. // static final String JAVAC_COMPILER
  74. // = JavacCompileCommand.class.getName();
  75. static final String[] RA_String = new String[0];
  76. static final String[] JAR_SUFFIXES = new String[] { ".jar", ".zip" };
  77. static final String[] SOURCE_SUFFIXES =
  78. (String[]) FileUtil.SOURCE_SUFFIXES.toArray(new String[0]);
  79. /** specifications, set on construction */
  80. Spec spec;
  81. //------------ calculated during setup
  82. /** get shared stuff during setup */
  83. Sandbox sandbox;
  84. /**
  85. * During run, these String are passed as the source and arg files to compile.
  86. * The list is set up in setupAjcRun(..), when arg files are prefixed with "@".
  87. */
  88. final List /*String*/
  89. arguments;
  90. /**
  91. * During run, these String are collapsed and passed as the injar option.
  92. * The list is set up in setupAjcRun(..).
  93. */
  94. final List /*String*/
  95. injars;
  96. /**
  97. * During run, these String are collapsed and passed as the inpath option.
  98. * The list is set up in setupAjcRun(..),
  99. * which extracts only directories from the files attribute.
  100. */
  101. final List inpaths;
  102. private CompilerRun(Spec spec) {
  103. if (null == spec) {
  104. throw new IllegalArgumentException("null spec");
  105. }
  106. this.spec = spec;
  107. arguments = new ArrayList();
  108. injars = new ArrayList();
  109. inpaths = new ArrayList();
  110. }
  111. /**
  112. * Select from input String[] if readable directories
  113. * @param inputs String[] of input - null ignored
  114. * @param baseDir the base directory of the input
  115. * @return String[] of input that end with any input
  116. */
  117. public static String[] selectDirectories(String[] inputs, File baseDir) {
  118. if (LangUtil.isEmpty(inputs)) {
  119. return new String[0];
  120. }
  121. ArrayList result = new ArrayList();
  122. for (int i = 0; i < inputs.length; i++) {
  123. String input = inputs[i];
  124. if (null == input) {
  125. continue;
  126. }
  127. File inputFile = new File(baseDir, input);
  128. if (inputFile.canRead() && inputFile.isDirectory()) {
  129. result.add(input);
  130. }
  131. }
  132. return (String[]) result.toArray(new String[0]);
  133. }
  134. /**
  135. * Select from input String[] based on suffix-matching
  136. * @param inputs String[] of input - null ignored
  137. * @param suffixes String[] of suffix selectors - null ignored
  138. * @param ignoreCase if true, ignore case
  139. * @return String[] of input that end with any input
  140. */
  141. public static String[] endsWith(String[] inputs, String[] suffixes, boolean ignoreCase) {
  142. if (LangUtil.isEmpty(inputs) || LangUtil.isEmpty(suffixes)) {
  143. return new String[0];
  144. }
  145. if (ignoreCase) {
  146. String[] temp = new String[suffixes.length];
  147. for (int i = 0; i < temp.length; i++) {
  148. String suff = suffixes[i];
  149. temp[i] = (null == suff ? null : suff.toLowerCase());
  150. }
  151. suffixes = temp;
  152. }
  153. ArrayList result = new ArrayList();
  154. for (int i = 0; i < inputs.length; i++) {
  155. String input = inputs[i];
  156. if (null == input) {
  157. continue;
  158. }
  159. if (!ignoreCase) {
  160. input = input.toLowerCase();
  161. }
  162. for (int j = 0; j < suffixes.length; j++) {
  163. String suffix = suffixes[j];
  164. if (null == suffix) {
  165. continue;
  166. }
  167. if (input.endsWith(suffix)) {
  168. result.add(input);
  169. break;
  170. }
  171. }
  172. }
  173. return (String[]) result.toArray(new String[0]);
  174. }
  175. /**
  176. * This checks that the spec is reasonable and does setup:
  177. * <ul>
  178. * <li>calculate and set sandbox testBaseSrcDir as {Sandbox.testBaseDir}/
  179. * {Spec.testSrcDirOffset}/<li>
  180. * <li>get the list of source File to compile as {Sandbox.testBaseSrcDir} /
  181. * {Spec.getPaths..}</li>
  182. * <li>get the list of extraClasspath entries to add to default classpath as
  183. * {Sandbox.testBaseSrcDir} / {Spec.classpath..}</li>
  184. * <li>get the list of aspectpath entries to use as the aspectpath as
  185. * {Sandbox. testBaseSrcDir} / {Spec.aspectpath..}</li>
  186. * </ul>
  187. * All sources must be readable at this time,
  188. * unless spec.badInput is true (for invalid-input tests).
  189. * If staging, the source files and source roots are copied
  190. * to a separate staging directory so they can be modified
  191. * for incremental tests. Note that (as of this writing) the
  192. * compiler only handles source roots for incremental tests.
  193. * @param classesDir the File
  194. * @see org.aspectj.testing.harness.bridge.AjcTest.IAjcRun#setup(File, File)
  195. * @throws AbortException containing IOException or IllegalArgumentException
  196. * if the staging operations fail
  197. */
  198. public boolean setupAjcRun(Sandbox sandbox, Validator validator) {
  199. if (!validator.nullcheck(spec.getOptionsArray(), "localOptions")
  200. || !validator.nullcheck(sandbox, "sandbox")
  201. || !validator.nullcheck(spec.compiler, "compilerName")
  202. || !validator.canRead(Globals.F_aspectjrt_jar, "aspectjrt.jar")
  203. || !validator.canRead(
  204. Globals.F_testingclient_jar,
  205. "testing-client.jar")) {
  206. return false;
  207. }
  208. this.sandbox = sandbox;
  209. String rdir = spec.testSrcDirOffset;
  210. File testBaseSrcDir;
  211. if ((null == rdir) || (0 == rdir.length())) {
  212. testBaseSrcDir = sandbox.testBaseDir;
  213. } else {
  214. testBaseSrcDir = new File(sandbox.testBaseDir, rdir);
  215. // XXX what if rdir is two levels deep?
  216. if (!validator
  217. .canReadDir(testBaseSrcDir, "sandbox.testBaseSrcDir")) {
  218. return false;
  219. }
  220. }
  221. // Sources come as relative paths - check read, copy if staging.
  222. // This renders paths absolute before run(RunStatusI) is called.
  223. // For a compile run to support relative paths + source base,
  224. // change so the run calculates the paths (differently when staging)
  225. final String[] inpathPaths;
  226. final String[] injarPaths;
  227. final String[] srcPaths;
  228. {
  229. final String[] paths = spec.getPathsArray();
  230. srcPaths =
  231. endsWith(
  232. paths,
  233. CompilerRun.SOURCE_SUFFIXES,
  234. true);
  235. injarPaths =
  236. endsWith(paths, CompilerRun.JAR_SUFFIXES, true);
  237. inpathPaths =
  238. selectDirectories(paths, testBaseSrcDir);
  239. if (!spec.badInput) {
  240. int found = inpathPaths.length + injarPaths.length + srcPaths.length;
  241. if (paths.length != found) {
  242. validator.fail("found " + found + " of " + paths.length + " sources");
  243. }
  244. }
  245. }
  246. // validate readable for sources
  247. if (!spec.badInput) {
  248. if (!validator.canRead(testBaseSrcDir, srcPaths, "sources")
  249. // see validation of inpathPaths below due to ambiguous base dir
  250. || !validator.canRead(
  251. testBaseSrcDir,
  252. spec.argfiles,
  253. "argfiles")
  254. || !validator.canRead(
  255. testBaseSrcDir,
  256. spec.classpath,
  257. "classpath")
  258. || !validator.canRead(
  259. testBaseSrcDir,
  260. spec.aspectpath,
  261. "aspectpath")
  262. || !validator.canRead(
  263. testBaseSrcDir,
  264. spec.sourceroots,
  265. "sourceroots")
  266. || !validator.canRead(
  267. testBaseSrcDir,
  268. spec.extdirs,
  269. "extdirs")) {
  270. return false;
  271. }
  272. }
  273. int numSources =
  274. srcPaths.length
  275. + injarPaths.length
  276. + inpathPaths.length
  277. + spec.argfiles.length
  278. + spec.sourceroots.length;
  279. if (!spec.badInput && (numSources < 1)) {
  280. validator.fail(
  281. "no input jars, arg files, or source files or roots");
  282. return false;
  283. }
  284. final File[] argFiles =
  285. FileUtil.getBaseDirFiles(testBaseSrcDir, spec.argfiles);
  286. final File[] injarFiles =
  287. FileUtil.getBaseDirFiles(testBaseSrcDir, injarPaths);
  288. final File[] inpathFiles =
  289. FileUtil.getBaseDirFiles(testBaseSrcDir, inpathPaths);
  290. final File[] aspectFiles =
  291. FileUtil.getBaseDirFiles(testBaseSrcDir, spec.aspectpath);
  292. final File[] extdirFiles =
  293. FileUtil.getBaseDirFiles(testBaseSrcDir, spec.extdirs);
  294. final File[] classFiles =
  295. FileUtil.getBaseDirFiles(testBaseSrcDir, spec.classpath);
  296. final File[] xlintFiles = (null == spec.xlintfile ? new File[0]
  297. : FileUtil.getBaseDirFiles(testBaseSrcDir, new String[] {spec.xlintfile}));
  298. // injars might be outjars in the classes dir...
  299. for (int i = 0; i < injarFiles.length; i++) {
  300. if (!injarFiles[i].exists()) {
  301. injarFiles[i] = new File(sandbox.classesDir, injarPaths[i]);
  302. }
  303. }
  304. for (int i = 0; i < inpathFiles.length; i++) {
  305. if (!inpathFiles[i].exists()) {
  306. inpathFiles[i] = new File(sandbox.classesDir, inpathPaths[i]);
  307. }
  308. }
  309. // moved after solving any injars that were outjars
  310. if (!validator.canRead(injarFiles, "injars")
  311. || !validator.canRead(injarFiles, "injars")) {
  312. return false;
  313. }
  314. // hmm - duplicates validation above, verifying getBaseDirFiles?
  315. if (!spec.badInput) {
  316. if (!validator.canRead(argFiles, "argFiles")
  317. || !validator.canRead(injarFiles, "injarFiles")
  318. || !validator.canRead(inpathFiles, "inpathFiles")
  319. || !validator.canRead(aspectFiles, "aspectFiles")
  320. || !validator.canRead(classFiles, "classFiles")
  321. || !validator.canRead(xlintFiles, "xlintFiles")) {
  322. return false;
  323. }
  324. }
  325. final File[] srcFiles;
  326. File[] sourcerootFiles = new File[0];
  327. // source text files are copied when staging incremental tests
  328. if (!spec.isStaging()) {
  329. // XXX why this? was always? || (testBaseSrcDir != sandbox.stagingDir))) {
  330. srcFiles =
  331. FileUtil.getBaseDirFiles(
  332. testBaseSrcDir,
  333. srcPaths,
  334. CompilerRun.SOURCE_SUFFIXES);
  335. if (!LangUtil.isEmpty(spec.sourceroots)) {
  336. sourcerootFiles =
  337. FileUtil.getBaseDirFiles(
  338. testBaseSrcDir,
  339. spec.sourceroots,
  340. null);
  341. }
  342. } else { // staging - copy files
  343. if (spec.badInput) {
  344. validator.info(
  345. "badInput ignored - files checked when staging");
  346. }
  347. try {
  348. // copy all files, then remove tagged ones
  349. // XXX make copyFiles support a filter?
  350. srcFiles =
  351. FileUtil.copyFiles(
  352. testBaseSrcDir,
  353. srcPaths,
  354. sandbox.stagingDir);
  355. if (!LangUtil.isEmpty(spec.sourceroots)) {
  356. sourcerootFiles =
  357. FileUtil.copyFiles(
  358. testBaseSrcDir,
  359. spec.sourceroots,
  360. sandbox.stagingDir);
  361. // delete incremental files in sourceroot after copying // XXX inefficient
  362. // an incremental file has an extra "." in name
  363. // most .java files don't, because they are named after
  364. // the principle type they contain, and simple type names
  365. // have no dots.
  366. FileFilter pickIncFiles = new FileFilter() {
  367. public boolean accept(File file) {
  368. if (file.isDirectory()) {
  369. // continue recursion
  370. return true;
  371. }
  372. String path = file.getPath();
  373. // only source files are relevant to staging
  374. if (!FileUtil.hasSourceSuffix(path)) {
  375. return false;
  376. }
  377. int first = path.indexOf(".");
  378. int last = path.lastIndexOf(".");
  379. return (first != last);
  380. }
  381. };
  382. for (int i = 0; i < sourcerootFiles.length; i++) {
  383. FileUtil.deleteContents(
  384. sourcerootFiles[i],
  385. pickIncFiles,
  386. false);
  387. }
  388. if (0 < sourcerootFiles.length) {
  389. FileUtil.sleepPastFinalModifiedTime(
  390. sourcerootFiles);
  391. }
  392. }
  393. File[] files =
  394. FileUtil.getBaseDirFiles(sandbox.stagingDir, srcPaths);
  395. if (0 < files.length) {
  396. FileUtil.sleepPastFinalModifiedTime(files);
  397. }
  398. } catch (IllegalArgumentException e) {
  399. validator.fail("staging - bad input", e);
  400. return false;
  401. } catch (IOException e) {
  402. validator.fail("staging - operations", e);
  403. return false;
  404. }
  405. }
  406. if (!spec.badInput
  407. && !validator.canRead(srcFiles, "copied paths")) {
  408. return false;
  409. }
  410. arguments.clear();
  411. if (!LangUtil.isEmpty(xlintFiles)) {
  412. arguments.add("-Xlintfile");
  413. String sr = FileUtil.flatten(xlintFiles, null);
  414. arguments.add(sr);
  415. }
  416. if (spec.outjar != null) {
  417. arguments.add("-outjar");
  418. arguments.add(new File(sandbox.classesDir,spec.outjar).getPath());
  419. }
  420. if (!LangUtil.isEmpty(extdirFiles)) {
  421. arguments.add("-extdirs");
  422. String sr = FileUtil.flatten(extdirFiles, null);
  423. arguments.add(sr);
  424. }
  425. if (!LangUtil.isEmpty(sourcerootFiles)) {
  426. arguments.add("-sourceroots");
  427. String sr = FileUtil.flatten(sourcerootFiles, null);
  428. arguments.add(sr);
  429. }
  430. if (!LangUtil.isEmpty(srcFiles)) {
  431. arguments.addAll(Arrays.asList(FileUtil.getPaths(srcFiles)));
  432. }
  433. injars.clear();
  434. if (!LangUtil.isEmpty(injarFiles)) {
  435. injars.addAll(Arrays.asList(FileUtil.getPaths(injarFiles)));
  436. }
  437. inpaths.clear();
  438. if (!LangUtil.isEmpty(inpathFiles)) {
  439. inpaths.addAll(Arrays.asList(FileUtil.getPaths(inpathFiles)));
  440. }
  441. if (!LangUtil.isEmpty(argFiles)) {
  442. String[] ra = FileUtil.getPaths(argFiles);
  443. for (int j = 0; j < ra.length; j++) {
  444. arguments.add("@" + ra[j]);
  445. }
  446. if (!spec.badInput && spec.isStaging) {
  447. validator.fail(
  448. "warning: files listed in argfiles not staged");
  449. }
  450. }
  451. // save classpath and aspectpath in sandbox for this and other clients
  452. final boolean checkReadable = !spec.badInput;
  453. int size = spec.includeClassesDir ? 3 : 2;
  454. File[] cp = new File[size + classFiles.length];
  455. System.arraycopy(classFiles, 0, cp, 0, classFiles.length);
  456. int index = classFiles.length;
  457. if (spec.includeClassesDir) {
  458. cp[index++] = sandbox.classesDir;
  459. }
  460. cp[index++] = Globals.F_aspectjrt_jar;
  461. cp[index++] = Globals.F_testingclient_jar;
  462. sandbox.compilerRunInit(this, testBaseSrcDir, aspectFiles,
  463. checkReadable, cp, checkReadable, null);
  464. // XXX todo set bootclasspath if set for forking?
  465. return true;
  466. }
  467. /**
  468. * Setup result evaluation and command line, run, and evaluate result.
  469. * <li>setup an AjcMessageHandler using the expected messages from
  470. * {@link Spec#getMessages()}.<li>
  471. * <li>heed any globals interpreted into a TestSetup by reading
  472. * {@link Spec@getOptions()}. For a list of supported globals, see
  473. * {@link setupArgs(ArrayList, IMessageHandler}.</li>
  474. * <li>construct a command line, using as classpath
  475. * {@link Sandbox.classpathToString()}<li>
  476. * <li>construct a compiler using {@link Spec#compiler}
  477. * or any overriding value set in TestSetup.<li>
  478. * <li>Just before running, set the compiler in the sandbox using
  479. * {@link Sandbox.setCompiler(ICommand)}.<li>
  480. * <li>After running, report AjcMessageHandler results to the status parameter.
  481. * If the AjcMessageHandler reports a failure, then send info messages
  482. * for the Spec, TestSetup, and command line.<li>
  483. * @see org.aspectj.testing.run.IRun#run(IRunStatus)
  484. */
  485. public boolean run(IRunStatus status) {
  486. if (null == spec.testSetup) {
  487. MessageUtil.abort(
  488. status,
  489. "no test setup - adoptParentValues not called");
  490. return false;
  491. } else if (!spec.testSetup.result) {
  492. MessageUtil.abort(status, spec.testSetup.failureReason);
  493. return false;
  494. }
  495. AjcMessageHandler handler =
  496. new AjcMessageHandler(spec.getMessages());
  497. handler.init();
  498. boolean handlerResult = false;
  499. boolean result = false;
  500. boolean commandResult = false;
  501. ArrayList argList = new ArrayList();
  502. final Spec.TestSetup setupResult = spec.testSetup;
  503. try {
  504. if (spec.outjar == null) {
  505. argList.add("-d");
  506. String outputDirPath = sandbox.classesDir.getAbsolutePath();
  507. try { // worth it to try for canonical?
  508. outputDirPath = sandbox.classesDir.getCanonicalPath();
  509. } catch (IOException e) {
  510. MessageUtil.abort(
  511. status,
  512. "canonical " + sandbox.classesDir,
  513. e);
  514. }
  515. argList.add(outputDirPath);
  516. }
  517. String path = sandbox.classpathToString(this);
  518. if (!LangUtil.isEmpty(path)) {
  519. argList.add("-classpath");
  520. argList.add(path);
  521. }
  522. path = sandbox.getBootclasspath(this);
  523. if (!LangUtil.isEmpty(path)) {
  524. argList.add("-bootclasspath");
  525. argList.add(path);
  526. }
  527. path = sandbox.aspectpathToString(this);
  528. if (!LangUtil.isEmpty(path)) {
  529. argList.add("-aspectpath");
  530. argList.add(path);
  531. }
  532. if (0 < injars.size()) {
  533. argList.add("-injars");
  534. argList.add(
  535. FileUtil.flatten(
  536. (String[]) injars.toArray(new String[0]),
  537. null));
  538. }
  539. if (0 < inpaths.size()) {
  540. argList.add("-inpath");
  541. argList.add(
  542. FileUtil.flatten(
  543. (String[]) inpaths.toArray(new String[0]),
  544. null));
  545. }
  546. // put specified arguments last, for better badInput tests
  547. argList.addAll(setupResult.commandOptions);
  548. // add both java/aspectj and argfiles
  549. argList.addAll(arguments);
  550. // XXX hack - seek on request as a side effect. reimplement as listener
  551. if (null != setupResult.seek) {
  552. String slopPrefix = Spec.SEEK_MESSAGE_PREFIX + " slop - ";
  553. PrintStream slop =
  554. MessageUtil.handlerPrintStream(
  555. status,
  556. IMessage.INFO,
  557. System.err,
  558. slopPrefix);
  559. List found =
  560. FileUtil.lineSeek(
  561. setupResult.seek,
  562. arguments,
  563. false,
  564. slop);
  565. if (!LangUtil.isEmpty(found)) {
  566. for (Iterator iter = found.iterator();
  567. iter.hasNext();
  568. ) {
  569. MessageUtil.info(
  570. status,
  571. Spec.SEEK_MESSAGE_PREFIX + iter.next());
  572. }
  573. }
  574. }
  575. ICommand compiler = spec.reuseCompiler
  576. // throws IllegalStateException if null
  577. ? sandbox.getCommand(this)
  578. : ReflectionFactory.makeCommand(setupResult.compilerName, status);
  579. DirChanges dirChanges = null;
  580. if (null == compiler) {
  581. MessageUtil.fail(
  582. status,
  583. "unable to make compiler " + setupResult.compilerName);
  584. return false;
  585. } else {
  586. if (setupResult.compilerName != Spec.DEFAULT_COMPILER) {
  587. MessageUtil.info(
  588. status,
  589. "compiler: " + setupResult.compilerName);
  590. }
  591. if (status.aborted()) {
  592. MessageUtil.debug(
  593. status,
  594. "aborted, but compiler valid?: " + compiler);
  595. } else {
  596. // same DirChanges handling for JavaRun, CompilerRun, IncCompilerRun
  597. // XXX around advice or template method/class
  598. if (!LangUtil.isEmpty(spec.dirChanges)) {
  599. LangUtil.throwIaxIfFalse(
  600. 1 == spec.dirChanges.size(),
  601. "expecting 0..1 dirChanges");
  602. dirChanges =
  603. new DirChanges(
  604. (DirChanges.Spec) spec.dirChanges.get(0));
  605. if (!dirChanges
  606. .start(status, sandbox.classesDir)) {
  607. return false; // setup failed
  608. }
  609. }
  610. MessageUtil.info(
  611. status,
  612. compiler + "(" + argList + ")");
  613. sandbox.setCommand(compiler, this);
  614. String[] args = (String[]) argList.toArray(RA_String);
  615. commandResult = compiler.runCommand(args, handler);
  616. }
  617. }
  618. handlerResult = handler.passed();
  619. if (!handlerResult) {
  620. return false;
  621. } else {
  622. result = (commandResult == handler.expectingCommandTrue());
  623. if (!result) {
  624. String m =
  625. commandResult
  626. ? "compile did not fail as expected"
  627. : "compile failed unexpectedly";
  628. MessageUtil.fail(status, m);
  629. } else if (null != dirChanges) {
  630. result = dirChanges.end(status, sandbox.testBaseDir);
  631. }
  632. }
  633. return result;
  634. } finally {
  635. if (!handlerResult) { // more debugging context in case of failure
  636. MessageUtil.info(handler, spec.toLongString());
  637. MessageUtil.info(handler, "" + argList);
  638. if (null != setupResult) {
  639. MessageUtil.info(handler, "" + setupResult);
  640. }
  641. }
  642. handler.report(status);
  643. // XXX weak - actual messages not reported in real-time, no fast-fail
  644. }
  645. }
  646. public String toString() {
  647. return "CompilerRun(" + spec + ")";
  648. }
  649. /**
  650. * Initializer/factory for CompilerRun
  651. * any path or file is relative to this test base dir
  652. */
  653. public static class Spec extends AbstractRunSpec {
  654. public static final String XMLNAME = "compile";
  655. public static final String DEFAULT_COMPILER =
  656. ReflectionFactory.ECLIPSE;
  657. static final String SEEK_PREFIX = "-seek:";
  658. static final String SEEK_MESSAGE_PREFIX = "found: ";
  659. private static final CRSOptions CRSOPTIONS = new CRSOptions();
  660. /**
  661. * Retitle description to title, paths to files, do comment,
  662. * staging, badInput,
  663. * do dirChanges, and print no chidren.
  664. */
  665. private static final AbstractRunSpec.XMLNames NAMES =
  666. new AbstractRunSpec.XMLNames(
  667. AbstractRunSpec.XMLNames.DEFAULT,
  668. "title",
  669. null,
  670. null,
  671. null,
  672. "files",
  673. null,
  674. null,
  675. null,
  676. false,
  677. false,
  678. true);
  679. /**
  680. * If the source version warrants, add a -bootclasspath
  681. * entry to the list of arguments to add.
  682. * This will fail and return an error String if the
  683. * required library is not found.
  684. * @param sourceVersion the String (if any) describing the -source option
  685. * (expecting one of [null, "1.3", "1.4", "1.5"].
  686. * @param compilerName the String name of the target compiler
  687. * @param toAdd the ArrayList to add -bootclasspath to
  688. * @return the String describing any errors, or null if no errors
  689. */
  690. private static String updateBootclasspathForSourceVersion(
  691. String sourceVersion,
  692. String compilerName,
  693. ArrayList toAdd) {
  694. if (null == sourceVersion) {
  695. return null;
  696. }
  697. if (3 != sourceVersion.length()) {
  698. throw new IllegalArgumentException(
  699. "bad version: " + sourceVersion);
  700. }
  701. if (null == toAdd) {
  702. throw new IllegalArgumentException("null toAdd");
  703. }
  704. int version = sourceVersion.charAt(2) - '0';
  705. switch (version) {
  706. case (3) :
  707. if (Globals.supportsJava("1.4")) {
  708. if (!FileUtil.canReadFile(Globals.J2SE13_RTJAR)) {
  709. return "no 1.3 libraries to handle -source 1.3";
  710. }
  711. toAdd.add("-bootclasspath");
  712. toAdd.add(Globals.J2SE13_RTJAR.getAbsolutePath());
  713. }
  714. break;
  715. case (4) :
  716. if (!Globals.supportsJava("1.4")) {
  717. if (ReflectionFactory
  718. .ECLIPSE
  719. .equals(compilerName)) {
  720. return "run eclipse under 1.4 to handle -source 1.4";
  721. }
  722. if (!FileUtil.canReadFile(Globals.J2SE14_RTJAR)) {
  723. return "no 1.4 libraries to handle -source 1.4";
  724. }
  725. toAdd.add("-bootclasspath");
  726. toAdd.add(Globals.J2SE14_RTJAR.getAbsolutePath());
  727. }
  728. break;
  729. case (5) :
  730. return "1.5 not supported in CompilerRun";
  731. case (0) :
  732. // ignore - no version specified
  733. break;
  734. default :
  735. throw new Error("unexpected version: " + version);
  736. }
  737. return null;
  738. }
  739. static CRSOptions testAccessToCRSOptions() {
  740. return CRSOPTIONS;
  741. }
  742. static Options testAccessToOptions() {
  743. return CRSOPTIONS.getOptions();
  744. }
  745. private static String[] copy(String[] input) {
  746. if (null == input) {
  747. return null;
  748. }
  749. String[] result = new String[input.length];
  750. System.arraycopy(input, 0, result, 0, input.length);
  751. return result;
  752. }
  753. protected String compiler;
  754. // use same command - see also IncCompiler.Spec.fresh
  755. protected boolean reuseCompiler;
  756. protected boolean permitAnyCompiler;
  757. protected boolean includeClassesDir;
  758. protected TestSetup testSetup;
  759. protected String[] argfiles = new String[0];
  760. protected String[] aspectpath = new String[0];
  761. protected String[] classpath = new String[0];
  762. protected String[] sourceroots = new String[0];
  763. protected String[] extdirs = new String[0];
  764. /** src path = {suiteParentDir}/{testBaseDirOffset}/{testSrcDirOffset}/{path} */
  765. protected String testSrcDirOffset;
  766. protected String xlintfile;
  767. protected String outjar;
  768. public Spec() {
  769. super(XMLNAME);
  770. setXMLNames(NAMES);
  771. compiler = DEFAULT_COMPILER;
  772. }
  773. protected void initClone(Spec spec)
  774. throws CloneNotSupportedException {
  775. super.initClone(spec);
  776. spec.argfiles = copy(argfiles);
  777. spec.aspectpath = copy(aspectpath);
  778. spec.classpath = copy(classpath);
  779. spec.compiler = compiler;
  780. spec.includeClassesDir = includeClassesDir;
  781. spec.reuseCompiler = reuseCompiler;
  782. spec.permitAnyCompiler = permitAnyCompiler;
  783. spec.sourceroots = copy(sourceroots);
  784. spec.extdirs = copy(extdirs);
  785. spec.outjar = outjar;
  786. spec.testSetup = null;
  787. if (null != testSetup) {
  788. spec.testSetup = (TestSetup) testSetup.clone();
  789. }
  790. spec.testSrcDirOffset = testSrcDirOffset;
  791. }
  792. public Object clone() throws CloneNotSupportedException {
  793. Spec result = new Spec();
  794. initClone(result);
  795. return result;
  796. }
  797. public void setIncludeClassesDir(boolean include) {
  798. this.includeClassesDir = include;
  799. }
  800. public void setReuseCompiler(boolean reuse) {
  801. this.reuseCompiler = reuse;
  802. }
  803. public void setPermitAnyCompiler(boolean permitAny) {
  804. this.permitAnyCompiler = permitAny;
  805. }
  806. public void setCompiler(String compilerName) {
  807. this.compiler = compilerName;
  808. }
  809. public void setTestSrcDirOffset(String s) {
  810. if (null != s) {
  811. testSrcDirOffset = s;
  812. }
  813. }
  814. /** override to set dirToken to Sandbox.CLASSES and default suffix to ".class" */
  815. public void addDirChanges(DirChanges.Spec spec) {
  816. if (null == spec) {
  817. return;
  818. }
  819. spec.setDirToken(Sandbox.CLASSES_DIR);
  820. spec.setDefaultSuffix(".class");
  821. super.addDirChanges(spec);
  822. }
  823. public String toLongString() {
  824. return getPrintName() + "(" + super.containedSummary() + ")";
  825. }
  826. public String toString() {
  827. return getPrintName() + "(" + super.containedSummary() + ")";
  828. }
  829. /** bean mapping for writers */
  830. public void setFiles(String paths) {
  831. addPaths(paths);
  832. }
  833. /**
  834. * Add to default classpath
  835. * (which includes aspectjrt.jar and testing-client.jar).
  836. * @param files comma-delimited list of classpath entries - ignored if
  837. * null or empty
  838. */
  839. public void setClasspath(String files) {
  840. if (!LangUtil.isEmpty(files)) {
  841. classpath = XMLWriter.unflattenList(files);
  842. }
  843. }
  844. /**
  845. * Set source roots, deleting any old ones
  846. * @param files comma-delimited list of directories
  847. * - ignored if null or empty
  848. */
  849. public void setSourceroots(String dirs) {
  850. if (!LangUtil.isEmpty(dirs)) {
  851. sourceroots = XMLWriter.unflattenList(dirs);
  852. }
  853. }
  854. public void setXlintfile(String path) {
  855. xlintfile = path;
  856. }
  857. public void setOutjar(String path) {
  858. outjar = path;
  859. }
  860. /**
  861. * Set extension dirs, deleting any old ones
  862. * @param files comma-delimited list of directories
  863. * - ignored if null or empty
  864. */
  865. public void setExtdirs(String dirs) {
  866. if (!LangUtil.isEmpty(dirs)) {
  867. extdirs = XMLWriter.unflattenList(dirs);
  868. }
  869. }
  870. /**
  871. * Set aspectpath, deleting any old ones
  872. * @param files comma-delimited list of aspect jars - ignored if null or
  873. * empty
  874. */
  875. public void setAspectpath(String files) {
  876. if (!LangUtil.isEmpty(files)) {
  877. aspectpath = XMLWriter.unflattenList(files);
  878. }
  879. }
  880. /**
  881. * Set argfiles, deleting any old ones
  882. * @param files comma-delimited list of argfiles - ignored if null or empty
  883. */
  884. public void setArgfiles(String files) {
  885. if (!LangUtil.isEmpty(files)) {
  886. argfiles = XMLWriter.unflattenList(files);
  887. }
  888. }
  889. /** @return String[] copy of argfiles array */
  890. public String[] getArgfilesArray() {
  891. String[] argfiles = this.argfiles;
  892. if (LangUtil.isEmpty(argfiles)) {
  893. return new String[0];
  894. }
  895. return (String[]) copy(argfiles);
  896. }
  897. /**
  898. * Make a copy of the array.
  899. * @return an array with the same component type as source
  900. * containing same elements, even if null.
  901. * @throws IllegalArgumentException if source is null
  902. */
  903. public static final Object[] copy(Object[] source) {
  904. LangUtil.throwIaxIfNull(source, "source");
  905. final Class c = source.getClass().getComponentType();
  906. Object[] result = (Object[]) Array.newInstance(c, source.length);
  907. System.arraycopy(source, 0, result, 0, result.length);
  908. return result;
  909. }
  910. /**
  911. * This implementation skips if:
  912. * <ul>
  913. * <li>incremental test, but using ajc (not eclipse)</li>
  914. * <li>usejavac, but javac is not available on the classpath</li>
  915. * <li>eclipse, but -usejavac or -preprocess test</li>
  916. * <li>-source 1.4, but running under 1.2 (XXX design)</li>
  917. * <li>local/global option conflicts (-lenient/-strict)</li>
  918. * <li>semantic conflicts (e.g., -lenient/-strict)</li>
  919. * </ul>
  920. * @return false if this wants to be skipped, true otherwise
  921. */
  922. protected boolean doAdoptParentValues(
  923. RT parentRuntime,
  924. IMessageHandler handler) {
  925. if (!super.doAdoptParentValues(parentRuntime, handler)) {
  926. return false;
  927. }
  928. testSetup = setupArgs(handler);
  929. if (!testSetup.result) {
  930. skipMessage(handler, testSetup.failureReason);
  931. }
  932. return testSetup.result;
  933. }
  934. private String getShortCompilerName() {
  935. String compilerClassName = compiler;
  936. if (null != testSetup) {
  937. compilerClassName = testSetup.compilerName;
  938. }
  939. if (null != compilerClassName) {
  940. int loc = compilerClassName.lastIndexOf(".");
  941. if (-1 != loc) {
  942. compilerClassName =
  943. compilerClassName.substring(loc + 1);
  944. }
  945. }
  946. return compilerClassName;
  947. }
  948. /** @return a CompilerRun with this as spec if setup completes successfully. */
  949. public IRunIterator makeRunIterator(
  950. Sandbox sandbox,
  951. Validator validator) {
  952. CompilerRun run = new CompilerRun(this);
  953. if (run.setupAjcRun(sandbox, validator)) {
  954. // XXX need name for compilerRun
  955. return new WrappedRunIterator(this, run);
  956. }
  957. return null;
  958. }
  959. protected String getPrintName() {
  960. return "CompilerRun.Spec " + getShortCompilerName();
  961. }
  962. /**
  963. * Each non-incremental run, fold the global flags in with
  964. * the run flags, which may involve adding or removing from
  965. * either list, depending on the flag prefix:
  966. * <ul>
  967. * <li>-foo: use -foo unless forced off.<li>
  968. * <li>^foo: (force off) remove any -foo option from the run flags</li>
  969. * <li>!foo: (force on) require the -foo flag </li>
  970. * </ul>
  971. * If there is a force conflict, then the test is skipped
  972. * ("skipping" info message, TestSetup.result is false).
  973. * This means an option local to the test which was specified
  974. * without forcing may be overridden by a globally-forced option.
  975. * <p>
  976. * There are some flags which are interpreted by the test
  977. * and removed from the list of flags passed to the command
  978. * (see testFlag()):
  979. * <ul>
  980. * <li>eclipse: use the new eclipse compiler (can force)</li>
  981. * <li>ajc: use the old ajc compiler (can force)</li>
  982. * <li>ignoreWarnings: ignore warnings in result evaluations (no force)</li>
  983. * </ul>
  984. * <p>
  985. * There are some flags which are inconsistent with each other.
  986. * These are treated as conflicts and the test is skipped:
  987. * <ul>
  988. * <li>lenient, strict</li>
  989. * </ul>
  990. * <p>
  991. * <p>
  992. * This also interprets any relevant System properties,
  993. * e.g., from <code>JavaRun.BOOTCLASSPATH_KEY</code>.
  994. * <p>
  995. * Finally, compiler limitations are enforced here by skipping
  996. * tests which the compiler cannot do:
  997. * <ul>
  998. * <li>eclipse does not do -lenient, -strict, -usejavac, -preprocess,
  999. * -XOcodeSize, -XSerializable, XaddSafePrefix,
  1000. * -XserializableAspects,-XtargetNearSource</li>
  1001. * <li>ajc does not run in incremental (staging) mode,
  1002. * nor with -usejavac if javac is not on the classpath</li>
  1003. * </ul>
  1004. * <u>Errors</u>:This will remove an arg not prefixed by [-|!|^] after
  1005. * providing an info message.
  1006. * <u>TestSetup Result</u>:
  1007. * If this completes successfully, then TestSetup.result is true,
  1008. * and commandOptions is not null, and any test flags (ignore warning,
  1009. * compiler) are reflected in the TestSetup.
  1010. * If this fails, then TestSetup.result is false,
  1011. * and a TestSetup.failreason is set.
  1012. * This means the test is skipped.
  1013. * @return TestSetup with results
  1014. * (TestSetup result=false if the run should not continue)
  1015. */
  1016. protected TestSetup setupArgs(IMessageHandler handler) {
  1017. // warning: HarnessSelectionTest checks for specific error wording
  1018. final Spec spec = this;
  1019. final TestSetup result = new TestSetup();
  1020. result.compilerName = spec.compiler;
  1021. // urk - s.b. null, but expected
  1022. Values values = gatherValues(result);
  1023. if ((null == values) || (null != result.failureReason)) {
  1024. return checkResult(result);
  1025. }
  1026. // send info messages about
  1027. // forced staging when -incremental
  1028. // or staging but no -incremental flag
  1029. Option.Family getFamily =
  1030. CRSOPTIONS.crsIncrementalOption.getFamily();
  1031. final boolean haveIncrementalFlag =
  1032. (null != values.firstInFamily(getFamily));
  1033. if (spec.isStaging()) {
  1034. if (!haveIncrementalFlag) {
  1035. MessageUtil.info(
  1036. handler,
  1037. "staging but no -incremental flag");
  1038. }
  1039. } else if (haveIncrementalFlag) {
  1040. spec.setStaging(true);
  1041. MessageUtil.info(handler, "-incremental forcing staging");
  1042. }
  1043. if (hasInvalidOptions(values, result)) {
  1044. return checkResult(result);
  1045. }
  1046. // set compiler in result
  1047. getFamily = CRSOPTIONS.ajccompilerOption.getFamily();
  1048. Option.Value compiler = values.firstInFamily(getFamily);
  1049. if (null != compiler) {
  1050. result.compilerName
  1051. = CRSOPTIONS.compilerClassName(compiler.option);
  1052. if (null == result.compilerName) {
  1053. result.failureReason =
  1054. "unable to get class name for " + compiler;
  1055. return checkResult(result);
  1056. }
  1057. }
  1058. String compilerName =
  1059. (null == result.compilerName
  1060. ? spec.compiler
  1061. : result.compilerName);
  1062. // check compiler semantics
  1063. if (hasCompilerSpecErrors(compilerName, values, result)) {
  1064. return checkResult(result);
  1065. }
  1066. // add toadd and finish result
  1067. ArrayList args = new ArrayList();
  1068. String[] rendered = values.render();
  1069. if (!LangUtil.isEmpty(rendered)) {
  1070. args.addAll(Arrays.asList(rendered));
  1071. }
  1072. // update bootclasspath
  1073. getFamily = CRSOPTIONS.crsSourceOption.getFamily();
  1074. Option.Value source = values.firstInFamily(getFamily);
  1075. if (null != source) {
  1076. String sourceVersion = source.unflatten()[1];
  1077. ArrayList toAdd = new ArrayList();
  1078. /*String err =*/
  1079. updateBootclasspathForSourceVersion(
  1080. sourceVersion,
  1081. spec.compiler,
  1082. toAdd);
  1083. args.addAll(toAdd);
  1084. }
  1085. result.commandOptions = args;
  1086. result.result = true;
  1087. return checkResult(result);
  1088. }
  1089. /**
  1090. * Ensure exit invariant:
  1091. * <code>result.result == (null == result.failureReason)
  1092. * == (null != result.commandOptions)</code>
  1093. * @param result the TestSetup to verify
  1094. * @return result
  1095. * @throws Error if invariant is not true
  1096. */
  1097. TestSetup checkResult(TestSetup result) {
  1098. String err = null;
  1099. if (null == result) {
  1100. err = "null result";
  1101. } else if (result.result != (null == result.failureReason)) {
  1102. err =
  1103. result.result
  1104. ? "expected no failure: " + result.failureReason
  1105. : "fail for no reason";
  1106. } else if (result.result != (null != result.commandOptions)) {
  1107. err =
  1108. result.result
  1109. ? "expected command options"
  1110. : "unexpected command options";
  1111. }
  1112. if (null != err) {
  1113. throw new Error(err);
  1114. }
  1115. return result;
  1116. }
  1117. boolean hasInvalidOptions(Values values, TestSetup result) {
  1118. // not supporting 1.0 options any more
  1119. for (Iterator iter = CRSOPTIONS.invalidOptions.iterator();
  1120. iter.hasNext();
  1121. ) {
  1122. Option option = (Option) iter.next();
  1123. if (null != values.firstOption(option)) {
  1124. result.failureReason =
  1125. "invalid option in harness: " + option;
  1126. return true;
  1127. }
  1128. }
  1129. return false;
  1130. }
  1131. boolean hasCompilerSpecErrors(
  1132. String compilerName,
  1133. Values values,
  1134. TestSetup result) {
  1135. /*
  1136. * Describe any semantic conflicts between options.
  1137. * This skips:
  1138. * - old 1.0 options, including lenient v. strict
  1139. * - old ajc options, include !incremental and usejavac w/o javac
  1140. * - invalid eclipse options (mostly ajc)
  1141. * @param compilerName the String name of the target compiler
  1142. * @return a String describing any conflicts, or null if none
  1143. */
  1144. if (!permitAnyCompiler
  1145. && (!(ReflectionFactory.ECLIPSE.equals(compilerName)
  1146. || ReflectionFactory.OLD_AJC.equals(compilerName)
  1147. || CRSOptions.AJDE_COMPILER.equals(compilerName)
  1148. || CRSOptions.AJCTASK_COMPILER.equals(compilerName)
  1149. || permitAnyCompiler
  1150. ))) {
  1151. //|| BUILDER_COMPILER.equals(compilerName))
  1152. result.failureReason =
  1153. "unrecognized compiler: " + compilerName;
  1154. return true;
  1155. }
  1156. // not supporting ajc right now
  1157. if (null
  1158. != values.firstOption(CRSOPTIONS.ajccompilerOption)) {
  1159. result.failureReason = "ajc not supported";
  1160. return true;
  1161. }
  1162. // not supporting 1.0 options any more
  1163. for (Iterator iter = CRSOPTIONS.ajc10Options.iterator();
  1164. iter.hasNext();
  1165. ) {
  1166. Option option = (Option) iter.next();
  1167. if (null != values.firstOption(option)) {
  1168. result.failureReason = "old ajc 1.0 option: " + option;
  1169. return true;
  1170. }
  1171. }
  1172. return false;
  1173. }
  1174. protected Values gatherValues(TestSetup result) {
  1175. final Spec spec = this;
  1176. // ---- local option values
  1177. final Values localValues;
  1178. final Options options = CRSOPTIONS.getOptions();
  1179. try {
  1180. String[] input = getOptionsArray();
  1181. // this handles reading options,
  1182. // flattening two-String options, etc.
  1183. localValues = options.acceptInput(input);
  1184. // all local values should be picked up
  1185. String err = Options.missedMatchError(input, localValues);
  1186. if (!LangUtil.isEmpty(err)) {
  1187. result.failureReason = err;
  1188. return null;
  1189. }
  1190. } catch (InvalidInputException e) {
  1191. result.failureReason = e.getFullMessage();
  1192. return null;
  1193. }
  1194. // ---- global option values
  1195. StringBuffer errs = new StringBuffer();
  1196. final Values globalValues =
  1197. spec.runtime.extractOptions(options, true, errs);
  1198. if (errs.length() > 0) {
  1199. result.failureReason = errs.toString();
  1200. return null;
  1201. }
  1202. final Values combined =
  1203. Values.wrapValues(
  1204. new Values[] { localValues, globalValues });
  1205. String err = combined.resolve();
  1206. if (null != err) {
  1207. result.failureReason = err;
  1208. return null;
  1209. }
  1210. return handleTestArgs(combined, result);
  1211. }
  1212. // final int len = globalValues.length() + localValues.length();
  1213. // final Option.Value[] combinedValues = new Option.Value[len];
  1214. // System.arraycopy(
  1215. // globalValues,
  1216. // 0,
  1217. // combinedValues,
  1218. // 0,
  1219. // globalValues.length());
  1220. // System.arraycopy(
  1221. // localValues,
  1222. // 0,
  1223. // combinedValues,
  1224. // globalValues.length(),
  1225. // localValues.length());
  1226. //
  1227. // result.compilerName = spec.compiler;
  1228. // if (0 < combinedValues.length) {
  1229. // // this handles option forcing, etc.
  1230. // String err = Options.resolve(combinedValues);
  1231. // if (null != err) {
  1232. // result.failureReason = err;
  1233. // return null;
  1234. // }
  1235. // if (!handleTestArgs(combinedValues, result)) {
  1236. // return null;
  1237. // }
  1238. // }
  1239. // return Values.wrapValues(combinedValues);
  1240. // }
  1241. /**
  1242. * This interprets and nullifies values for the test.
  1243. * @param values the Option.Value[] being processed
  1244. * @param result the TestSetup to modify
  1245. * @return false if error (caller should return), true otherwise
  1246. */
  1247. Values handleTestArgs(Values values, final TestSetup result) {
  1248. final Option.Family compilerFamily =
  1249. CRSOPTIONS.ajccompilerOption.getFamily();
  1250. Values.Selector selector = new Values.Selector() {
  1251. protected boolean accept(Option.Value value) {
  1252. if (null == value) {
  1253. return false;
  1254. }
  1255. Option option = value.option;
  1256. if (compilerFamily.sameFamily(option.getFamily())) {
  1257. if (value.prefix.isSet()) {
  1258. String compilerClass
  1259. = CRSOPTIONS.compilerClassName(option);
  1260. if (null == compilerClass) {
  1261. result.failureReason =
  1262. "unrecognized compiler: " + value;
  1263. throw Values.Selector.STOP;
  1264. }
  1265. if (!CRSOPTIONS.compilerIsLoadable(option)) {
  1266. result.failureReason =
  1267. "unable to load compiler: " + option;
  1268. throw Values.Selector.STOP;
  1269. }
  1270. result.compilerName = compilerClass;
  1271. }
  1272. return true;
  1273. } else if (
  1274. CRSOPTIONS.crsIgnoreWarnings.sameOptionIdentifier(
  1275. option)) {
  1276. result.ignoreWarnings = value.prefix.isSet();
  1277. result.ignoreWarningsSet = true;
  1278. return true;
  1279. }
  1280. return false;
  1281. }
  1282. };
  1283. return values.nullify(selector);
  1284. }
  1285. // /**
  1286. // * This interprets and nullifies values for the test.
  1287. // * @param values the Option.Value[] being processed
  1288. // * @param result the TestSetup to modify
  1289. // * @return false if error (caller should return), true otherwise
  1290. // */
  1291. // boolean handleTestArgs(Option.Value[] values, TestSetup result) {
  1292. // if (!LangUtil.isEmpty(values)) {
  1293. // for (int i = 0; i < values.length; i++) {
  1294. // Option.Value value = values[i];
  1295. // if (null == value) {
  1296. // continue;
  1297. // }
  1298. // Option option = value.option;
  1299. // if (option.sameOptionFamily(ECLIPSE_OPTION)) {
  1300. // if (!value.prefix.isSet()) {
  1301. // values[i] = null;
  1302. // continue;
  1303. // }
  1304. // String compilerClass =
  1305. // (String) COMPILER_OPTION_TO_CLASSNAME.get(
  1306. // option);
  1307. // if (null == compilerClass) {
  1308. // result.failureReason =
  1309. // "unrecognized compiler: " + value;
  1310. // return false;
  1311. // }
  1312. // result.compilerName = compilerClass;
  1313. // values[i] = null;
  1314. // } else if (
  1315. // option.sameOptionFamily(crsIgnoreWarnings)) {
  1316. // result.ignoreWarnings = value.prefix.isSet();
  1317. // result.ignoreWarningsSet = true;
  1318. // values[i] = null;
  1319. // }
  1320. // }
  1321. // }
  1322. // return true;
  1323. // }
  1324. // XXX need keys, cache...
  1325. /** @return index of global in argList, ignoring first char */
  1326. protected int indexOf(String global, ArrayList argList) {
  1327. int max = argList.size();
  1328. for (int i = 0; i < max; i++) {
  1329. if (global
  1330. .equals(((String) argList.get(i)).substring(1))) {
  1331. return i;
  1332. }
  1333. }
  1334. return -1;
  1335. }
  1336. /**
  1337. * Write this out as a compile element as defined in
  1338. * AjcSpecXmlReader.DOCTYPE.
  1339. * @see AjcSpecXmlReader#DOCTYPE
  1340. * @see IXmlWritable#writeXml(XMLWriter)
  1341. */
  1342. public void writeXml(XMLWriter out) {
  1343. out.startElement(xmlElementName, false);
  1344. if (!LangUtil.isEmpty(testSrcDirOffset)) {
  1345. out.printAttribute("dir", testSrcDirOffset);
  1346. }
  1347. super.writeAttributes(out);
  1348. if (!DEFAULT_COMPILER.equals(compiler)) {
  1349. out.printAttribute("compiler", compiler);
  1350. }
  1351. if (reuseCompiler) {
  1352. out.printAttribute("reuseCompiler", "true");
  1353. }
  1354. // test-only feature
  1355. // if (permitAnyCompiler) {
  1356. // out.printAttribute("permitAnyCompiler", "true");
  1357. // }
  1358. if (includeClassesDir) {
  1359. out.printAttribute("includeClassesDir", "true");
  1360. }
  1361. if (!LangUtil.isEmpty(argfiles)) {
  1362. out.printAttribute(
  1363. "argfiles",
  1364. XMLWriter.flattenFiles(argfiles));
  1365. }
  1366. if (!LangUtil.isEmpty(aspectpath)) {
  1367. out.printAttribute(
  1368. "aspectpath",
  1369. XMLWriter.flattenFiles(aspectpath));
  1370. }
  1371. if (!LangUtil.isEmpty(sourceroots)) {
  1372. out.printAttribute(
  1373. "sourceroots",
  1374. XMLWriter.flattenFiles(sourceroots));
  1375. }
  1376. if (!LangUtil.isEmpty(extdirs)) {
  1377. out.printAttribute(
  1378. "extdirs",
  1379. XMLWriter.flattenFiles(extdirs));
  1380. }
  1381. out.endAttributes();
  1382. if (!LangUtil.isEmpty(dirChanges)) {
  1383. DirChanges.Spec.writeXml(out, dirChanges);
  1384. }
  1385. SoftMessage.writeXml(out, getMessages());
  1386. out.endElement(xmlElementName);
  1387. }
  1388. /**
  1389. * Encapsulate the directives that can be set using
  1390. * global arguments supplied in {@link Spec.getOptions()}.
  1391. * This supports changing the compiler and ignoring warnings.
  1392. */
  1393. class TestSetup {
  1394. /** null unless overriding the compiler to be used */
  1395. String compilerName;
  1396. /**
  1397. * true if we should tell AjcMessageHandler whether
  1398. * to ignore warnings in its result evaluation
  1399. */
  1400. boolean ignoreWarningsSet;
  1401. /** if telling AjcMessageHandler, what we tell it */
  1402. boolean ignoreWarnings;
  1403. /** false if setup failed */
  1404. boolean result;
  1405. /** if setup failed, this has the reason why */
  1406. String failureReason;
  1407. /** beyond running test, also seek text in sources */
  1408. String seek;
  1409. /** if setup completed, this has the combined global/local options */
  1410. ArrayList commandOptions;
  1411. public Object clone() {
  1412. TestSetup testSetup = new TestSetup();
  1413. testSetup.compilerName = compilerName;
  1414. testSetup.ignoreWarnings = ignoreWarnings;
  1415. testSetup.ignoreWarningsSet = ignoreWarningsSet;
  1416. testSetup.result = result;
  1417. testSetup.failureReason = failureReason;
  1418. testSetup.seek = seek;
  1419. if (null != commandOptions) {
  1420. testSetup.commandOptions = new ArrayList();
  1421. testSetup.commandOptions.addAll(commandOptions);
  1422. }
  1423. return testSetup;
  1424. }
  1425. public String toString() {
  1426. return "TestSetup("
  1427. + (null == compilerName ? "" : compilerName + " ")
  1428. + (!ignoreWarningsSet
  1429. ? ""
  1430. : (ignoreWarnings ? "" : "do not ")
  1431. + "ignore warnings ")
  1432. + (result ? "" : "setup failed")
  1433. + ")";
  1434. }
  1435. }
  1436. /**
  1437. * Options-related stuff in the spec.
  1438. */
  1439. static class CRSOptions {
  1440. // static final String BUILDER_COMPILER =
  1441. // "org.aspectj.ajdt.internal.core.builder.Builder.Command";
  1442. static final String AJDE_COMPILER =
  1443. CompileCommand.class.getName();
  1444. static final String AJCTASK_COMPILER =
  1445. AjcTaskCompileCommand.class.getName();
  1446. private final Map compilerOptionToLoadable = new TreeMap();
  1447. /*
  1448. * The options field in a compiler test permits some arbitrary
  1449. * command-line options to be set. It does not permit things
  1450. * like classpath, aspectpath, files, etc. which are set
  1451. * using other fields in the test specification, so the options
  1452. * permitted are a subset of those permitted on the command-line.
  1453. *
  1454. * Global options specified on the harness command-line are
  1455. * adopted for the compiler command-line if they are permitted
  1456. * in the options field. That means we have to detect each
  1457. * permitted option, rather than just letting all through
  1458. * for the compiler.
  1459. *
  1460. * Conversely, some options are targeted not at the compiler,
  1461. * but at the test itself (e.g., to ignore warnings, or to
  1462. * select a compiler.
  1463. *
  1464. * The harness can run many compilers, and they differ in
  1465. * which options are permitted. You can specify a compiler
  1466. * as an option (e.g., -eclipse). So the set of constraints
  1467. * on the list of permitted options can differ from test to test.
  1468. *
  1469. * The following code sets up the lists of permitted options
  1470. * and breaks out subsets for different compiler-variant checks.
  1471. * Most options are created but not named, but some options
  1472. * are named to detect corresponding values for further
  1473. * processing. e.g., the compiler options are saved so
  1474. * we can do per-compiler option verification.
  1475. *
  1476. */
  1477. private final Options crsOptions;
  1478. private final Family compilerFamily;
  1479. private final Option crsIncrementalOption;
  1480. private final Option crsSourceOption;
  1481. // these are options handled/absorbed by CompilerRun
  1482. private final Option crsIgnoreWarnings;
  1483. private final Option eclipseOption;
  1484. private final Option buildercompilerOption;
  1485. private final Option ajdecompilerOption;
  1486. private final Option javacOption;
  1487. private final Option ajctaskcompilerOption;
  1488. private final Option ajccompilerOption;
  1489. private final Map compilerOptionToClassname;
  1490. private final Set compilerOptions;
  1491. // compiler verification - permit but flag ajc 1.0 options
  1492. private final List ajc10Options;
  1493. private final List invalidOptions;
  1494. private CRSOptions() {
  1495. crsOptions = new Options(true);
  1496. Option.Factory factory = new Option.Factory("CompilerRun");
  1497. // compiler options go in map
  1498. eclipseOption =
  1499. factory.create(
  1500. "eclipse",
  1501. "compiler",
  1502. Option.FORCE_PREFIXES,
  1503. false);
  1504. compilerFamily = eclipseOption.getFamily();
  1505. buildercompilerOption =
  1506. factory.create(
  1507. "builderCompiler",
  1508. "compiler",
  1509. Option.FORCE_PREFIXES,
  1510. false);
  1511. ajctaskcompilerOption =
  1512. factory.create(
  1513. "ajctaskCompiler",
  1514. "compiler",
  1515. Option.FORCE_PREFIXES,
  1516. false);
  1517. ajdecompilerOption =
  1518. factory.create(
  1519. "ajdeCompiler",
  1520. "compiler",
  1521. Option.FORCE_PREFIXES,
  1522. false);
  1523. ajccompilerOption =
  1524. factory.create(
  1525. "ajc",
  1526. "compiler",
  1527. Option.FORCE_PREFIXES,
  1528. false);
  1529. javacOption =
  1530. factory.create(
  1531. "javac",
  1532. "compiler",
  1533. Option.FORCE_PREFIXES,
  1534. false);
  1535. Map map = new TreeMap();
  1536. map.put(eclipseOption, ReflectionFactory.ECLIPSE);
  1537. //map.put(BUILDERCOMPILER_OPTION, BUILDER_COMPILER);
  1538. map.put(
  1539. ajctaskcompilerOption,
  1540. AJCTASK_COMPILER);
  1541. map.put(ajdecompilerOption, AJDE_COMPILER);
  1542. map.put(ajccompilerOption, ReflectionFactory.OLD_AJC);
  1543. //map.put(JAVAC_OPTION, "XXX javac option not supported");
  1544. compilerOptionToClassname =
  1545. Collections.unmodifiableMap(map);
  1546. compilerOptions =
  1547. Collections.unmodifiableSet(
  1548. compilerOptionToClassname.keySet());
  1549. // options not permitted in the harness
  1550. List list = new ArrayList();
  1551. list.add(factory.create("workingdir"));
  1552. list.add(factory.create("argfile"));
  1553. list.add(factory.create("sourceroots"));
  1554. list.add(factory.create("outjar"));
  1555. invalidOptions = Collections.unmodifiableList(list);
  1556. // other options added directly
  1557. crsIncrementalOption = factory.create("incremental");
  1558. crsIgnoreWarnings = factory.create("ignoreWarnings");
  1559. crsSourceOption =
  1560. factory
  1561. .create(
  1562. "source",
  1563. "source",
  1564. Option.FORCE_PREFIXES,
  1565. false,
  1566. new String[][] { new String[] { "1.3", "1.4", "1.5" }
  1567. });
  1568. // ajc 1.0 options
  1569. // workingdir above in invalid options
  1570. list = new ArrayList();
  1571. list.add(factory.create("usejavac"));
  1572. list.add(factory.create("preprocess"));
  1573. list.add(factory.create("nocomment"));
  1574. list.add(factory.create("porting"));
  1575. list.add(factory.create("XOcodeSize"));
  1576. list.add(factory.create("XTargetNearSource"));
  1577. list.add(factory.create("XaddSafePrefix"));
  1578. list.add(
  1579. factory.create(
  1580. "lenient",
  1581. "lenient",
  1582. Option.FORCE_PREFIXES,
  1583. false));
  1584. list.add(
  1585. factory.create(
  1586. "strict",
  1587. "lenient",
  1588. Option.FORCE_PREFIXES,
  1589. false));
  1590. ajc10Options = Collections.unmodifiableList(list);
  1591. // -warn:.. and -g/-g:.. are not exclusive
  1592. if (!(factory.setupFamily("debug", true)
  1593. && factory.setupFamily("warning", true))) {
  1594. System.err.println("CompilerRun debug/warning fail!");
  1595. }
  1596. Option[] options =
  1597. new Option[] {
  1598. crsIncrementalOption,
  1599. crsIgnoreWarnings,
  1600. crsSourceOption,
  1601. factory.create(
  1602. "Xlint",
  1603. "XLint",
  1604. Option.FORCE_PREFIXES,
  1605. true),
  1606. factory.create("verbose"),
  1607. factory.create("emacssym"),
  1608. factory.create("referenceInfo"),
  1609. factory.create("nowarn"),
  1610. factory.create("deprecation"),
  1611. factory.create("noImportError"),
  1612. factory.create("proceedOnError"),
  1613. factory.create("preserveAllLocals"),
  1614. factory.create(
  1615. "warn",
  1616. "warning",
  1617. Option.STANDARD_PREFIXES,
  1618. true),
  1619. factory.create(
  1620. "g",
  1621. "debug",
  1622. Option.STANDARD_PREFIXES,
  1623. false),
  1624. factory.create(
  1625. "g:",
  1626. "debug",
  1627. Option.STANDARD_PREFIXES,
  1628. true),
  1629. factory.create(
  1630. "1.3",
  1631. "compliance",
  1632. Option.FORCE_PREFIXES,
  1633. false),
  1634. factory.create(
  1635. "1.4",
  1636. "compliance",
  1637. Option.FORCE_PREFIXES,
  1638. false),
  1639. factory.create(
  1640. "1.5",
  1641. "compliance",
  1642. Option.FORCE_PREFIXES,
  1643. false),
  1644. factory
  1645. .create(
  1646. "target",
  1647. "target",
  1648. Option.FORCE_PREFIXES,
  1649. false,
  1650. new String[][] { new String[] {
  1651. "1.1",
  1652. "1.2",
  1653. "1.3",
  1654. "1.4",
  1655. "1.5" }}),
  1656. factory.create("XnoInline"),
  1657. factory.create("XterminateAfterCompilation"),
  1658. factory.create("Xreweavable"),
  1659. factory.create("XnotReweavable"),
  1660. factory.create("XserializableAspects")
  1661. };
  1662. // among options not permitted: extdirs...
  1663. for (int i = 0; i < options.length; i++) {
  1664. crsOptions.addOption(options[i]);
  1665. }
  1666. for (Iterator iter = compilerOptions.iterator();
  1667. iter.hasNext();
  1668. ) {
  1669. crsOptions.addOption((Option) iter.next());
  1670. }
  1671. // these are recognized but records with them are skipped
  1672. for (Iterator iter = ajc10Options.iterator();
  1673. iter.hasNext();
  1674. ) {
  1675. crsOptions.addOption((Option) iter.next());
  1676. }
  1677. crsOptions.freeze();
  1678. }
  1679. Options getOptions() {
  1680. return crsOptions;
  1681. }
  1682. /**
  1683. * @return unmodifiable Set of options sharing the
  1684. * family "compiler".
  1685. */
  1686. Set compilerOptions() {
  1687. return compilerOptions;
  1688. }
  1689. /**
  1690. * @param option the compiler Option to get name for
  1691. * @return null if option is null or not a compiler option,
  1692. * or the fully-qualified classname of the ICommand
  1693. * implementing the compiler.
  1694. */
  1695. String compilerClassName(Option option) {
  1696. if ((null == option)
  1697. || (!compilerFamily.sameFamily(option.getFamily()))) {
  1698. return null;
  1699. }
  1700. return (String) compilerOptionToClassname.get(option);
  1701. }
  1702. /**
  1703. * Check that the compiler class associated with a compiler
  1704. * option can be loaded. This check only happens once;
  1705. * the result is cached (by compilerOption key) for later calls.
  1706. * @param compilerOption the Option (family compiler) to check
  1707. * @return true if compiler class for this option can be loaded
  1708. */
  1709. boolean compilerIsLoadable(Option compilerOption) {
  1710. LangUtil.throwIaxIfNull(compilerOption, "compilerName");
  1711. synchronized (compilerOptionToLoadable) {
  1712. Boolean result =
  1713. (Boolean) compilerOptionToLoadable.get(
  1714. compilerOption);
  1715. if (null == result) {
  1716. MessageHandler sink = new MessageHandler();
  1717. String compilerClassname =
  1718. (String) compilerOptionToClassname.get(
  1719. compilerOption);
  1720. if (null == compilerClassname) {
  1721. result = Boolean.FALSE;
  1722. } else {
  1723. ICommand c =
  1724. ReflectionFactory.makeCommand(
  1725. compilerClassname,
  1726. sink);
  1727. if ((null == c)
  1728. || sink.hasAnyMessage(
  1729. IMessage.ERROR,
  1730. true)) {
  1731. result = Boolean.FALSE;
  1732. } else {
  1733. result = Boolean.TRUE;
  1734. }
  1735. }
  1736. compilerOptionToLoadable.put(
  1737. compilerOption,
  1738. result);
  1739. }
  1740. return result.booleanValue();
  1741. }
  1742. }
  1743. } // CompilerRun.Spec.CRSOptions
  1744. } // CompilerRun.Spec
  1745. } // CompilerRun