|
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862 |
- /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC),
- * 2003 Contributors.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * Wes Isberg 2003 updates
- * ******************************************************************/
-
- package org.aspectj.testing.harness.bridge;
-
- import java.io.File;
- import java.io.FileFilter;
- import java.io.IOException;
- import java.io.PrintStream;
- import java.lang.reflect.Array;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.TreeMap;
-
- import org.aspectj.bridge.ICommand;
- import org.aspectj.bridge.IMessage;
- import org.aspectj.bridge.IMessageHandler;
- import org.aspectj.bridge.MessageHandler;
- import org.aspectj.bridge.MessageUtil;
- import org.aspectj.bridge.ReflectionFactory;
- import org.aspectj.testing.ajde.CompileCommand;
- import org.aspectj.testing.run.IRunIterator;
- import org.aspectj.testing.run.IRunStatus;
- import org.aspectj.testing.run.WrappedRunIterator;
- import org.aspectj.testing.taskdefs.AjcTaskCompileCommand;
- import org.aspectj.testing.util.options.Option;
- import org.aspectj.testing.util.options.Option.Family;
- import org.aspectj.testing.util.options.Option.InvalidInputException;
- import org.aspectj.testing.util.options.Options;
- import org.aspectj.testing.util.options.Values;
- import org.aspectj.testing.xml.SoftMessage;
- import org.aspectj.testing.xml.XMLWriter;
- import org.aspectj.util.FileUtil;
- import org.aspectj.util.LangUtil;
-
- /**
- * Run the compiler once.
- * The lifecycle is as follows:
- * <ul>
- * <li>Spec (specification) is created.</li>
- * <li>This is created using the Spec.</li>
- * <li>setupAjcRun(Sandbox, Validator) is invoked,
- * at which point this populates the shared sandbox
- * with values derived from the spec and also
- * sets up internal state based on both the sandbox
- * and the spec.</li>
- * <li>run(IRunStatus) is invoked, and this runs the compiler
- * based on internal state, the spec, and the sandbox.</li>
- * </ul>
- * Programmer notes:
- * <ul>
- * <li>Paths are resolved absolutely, which fails to test the
- * compiler's ability to find files relative to a source base</li>
- * <li>This does not enforce the lifecycle.</li>
- * <li>This must be used as the initial compile
- * before doing an incremental compile.
- * In that case, staging must be enabled.</li>
- * </ul>
- */
- public class CompilerRun implements IAjcRun {
- // static final String JAVAC_COMPILER
- // = JavacCompileCommand.class.getName();
-
- static final String[] RA_String = new String[0];
-
- static final String[] JAR_SUFFIXES = new String[] { ".jar", ".zip" };
-
- static final String[] SOURCE_SUFFIXES =
- (String[]) FileUtil.SOURCE_SUFFIXES.toArray(new String[0]);
-
- /** specifications, set on construction */
- Spec spec;
-
- //------------ calculated during setup
- /** get shared stuff during setup */
- Sandbox sandbox;
-
- /**
- * During run, these String are passed as the source and arg files to compile.
- * The list is set up in setupAjcRun(..), when arg files are prefixed with "@".
- */
- final List /*String*/
- arguments;
-
- /**
- * During run, these String are collapsed and passed as the injar option.
- * The list is set up in setupAjcRun(..).
- */
- final List /*String*/
- injars;
-
- /**
- * During run, these String are collapsed and passed as the inpath option.
- * The list is set up in setupAjcRun(..),
- * which extracts only directories from the files attribute.
- */
- final List inpaths;
-
- private CompilerRun(Spec spec) {
- if (null == spec) {
- throw new IllegalArgumentException("null spec");
- }
- this.spec = spec;
- arguments = new ArrayList();
- injars = new ArrayList();
- inpaths = new ArrayList();
- }
-
-
- /**
- * Select from input String[] if readable directories
- * @param inputs String[] of input - null ignored
- * @param baseDir the base directory of the input
- * @return String[] of input that end with any input
- */
- public static String[] selectDirectories(String[] inputs, File baseDir) {
- if (LangUtil.isEmpty(inputs)) {
- return new String[0];
- }
- ArrayList result = new ArrayList();
- for (int i = 0; i < inputs.length; i++) {
- String input = inputs[i];
- if (null == input) {
- continue;
- }
- File inputFile = new File(baseDir, input);
- if (inputFile.canRead() && inputFile.isDirectory()) {
- result.add(input);
- }
- }
- return (String[]) result.toArray(new String[0]);
- }
-
- /**
- * Select from input String[] based on suffix-matching
- * @param inputs String[] of input - null ignored
- * @param suffixes String[] of suffix selectors - null ignored
- * @param ignoreCase if true, ignore case
- * @return String[] of input that end with any input
- */
- public static String[] endsWith(String[] inputs, String[] suffixes, boolean ignoreCase) {
- if (LangUtil.isEmpty(inputs) || LangUtil.isEmpty(suffixes)) {
- return new String[0];
- }
- if (ignoreCase) {
- String[] temp = new String[suffixes.length];
- for (int i = 0; i < temp.length; i++) {
- String suff = suffixes[i];
- temp[i] = (null == suff ? null : suff.toLowerCase());
- }
- suffixes = temp;
- }
- ArrayList result = new ArrayList();
- for (int i = 0; i < inputs.length; i++) {
- String input = inputs[i];
- if (null == input) {
- continue;
- }
- if (!ignoreCase) {
- input = input.toLowerCase();
- }
- for (int j = 0; j < suffixes.length; j++) {
- String suffix = suffixes[j];
- if (null == suffix) {
- continue;
- }
- if (input.endsWith(suffix)) {
- result.add(input);
- break;
- }
- }
- }
- return (String[]) result.toArray(new String[0]);
- }
-
- /**
- * This checks that the spec is reasonable and does setup:
- * <ul>
- * <li>calculate and set sandbox testBaseSrcDir as {Sandbox.testBaseDir}/
- * {Spec.testSrcDirOffset}/<li>
- * <li>get the list of source File to compile as {Sandbox.testBaseSrcDir} /
- * {Spec.getPaths..}</li>
- * <li>get the list of extraClasspath entries to add to default classpath as
- * {Sandbox.testBaseSrcDir} / {Spec.classpath..}</li>
- * <li>get the list of aspectpath entries to use as the aspectpath as
- * {Sandbox. testBaseSrcDir} / {Spec.aspectpath..}</li>
- * </ul>
- * All sources must be readable at this time,
- * unless spec.badInput is true (for invalid-input tests).
- * If staging, the source files and source roots are copied
- * to a separate staging directory so they can be modified
- * for incremental tests. Note that (as of this writing) the
- * compiler only handles source roots for incremental tests.
- * @param classesDir the File
- * @see org.aspectj.testing.harness.bridge.AjcTest.IAjcRun#setup(File, File)
- * @throws AbortException containing IOException or IllegalArgumentException
- * if the staging operations fail
- */
- public boolean setupAjcRun(Sandbox sandbox, Validator validator) {
-
- if (!validator.nullcheck(spec.getOptionsArray(), "localOptions")
- || !validator.nullcheck(sandbox, "sandbox")
- || !validator.nullcheck(spec.compiler, "compilerName")
- || !validator.canRead(Globals.F_aspectjrt_jar, "aspectjrt.jar")
- || !validator.canRead(
- Globals.F_testingclient_jar,
- "testing-client.jar")) {
- return false;
- }
-
- this.sandbox = sandbox;
-
- String rdir = spec.testSrcDirOffset;
- File testBaseSrcDir;
- if ((null == rdir) || (0 == rdir.length())) {
- testBaseSrcDir = sandbox.testBaseDir;
- } else {
- testBaseSrcDir = new File(sandbox.testBaseDir, rdir);
- // XXX what if rdir is two levels deep?
- if (!validator
- .canReadDir(testBaseSrcDir, "sandbox.testBaseSrcDir")) {
- return false;
- }
- }
-
- // Sources come as relative paths - check read, copy if staging.
- // This renders paths absolute before run(RunStatusI) is called.
- // For a compile run to support relative paths + source base,
- // change so the run calculates the paths (differently when staging)
-
- final String[] inpathPaths;
- final String[] injarPaths;
- final String[] srcPaths;
- {
- final String[] paths = spec.getPathsArray();
- srcPaths =
- endsWith(
- paths,
- CompilerRun.SOURCE_SUFFIXES,
- true);
- injarPaths =
- endsWith(paths, CompilerRun.JAR_SUFFIXES, true);
- inpathPaths =
- selectDirectories(paths, testBaseSrcDir);
- if (!spec.badInput) {
- int found = inpathPaths.length + injarPaths.length + srcPaths.length;
- if (paths.length != found) {
- validator.fail("found " + found + " of " + paths.length + " sources");
- }
- }
- }
-
- // validate readable for sources
- if (!spec.badInput) {
- if (!validator.canRead(testBaseSrcDir, srcPaths, "sources")
- // see validation of inpathPaths below due to ambiguous base dir
- || !validator.canRead(
- testBaseSrcDir,
- spec.argfiles,
- "argfiles")
- || !validator.canRead(
- testBaseSrcDir,
- spec.classpath,
- "classpath")
- || !validator.canRead(
- testBaseSrcDir,
- spec.aspectpath,
- "aspectpath")
- || !validator.canRead(
- testBaseSrcDir,
- spec.sourceroots,
- "sourceroots")
- || !validator.canRead(
- testBaseSrcDir,
- spec.extdirs,
- "extdirs")) {
- return false;
- }
- }
-
- int numSources =
- srcPaths.length
- + injarPaths.length
- + inpathPaths.length
- + spec.argfiles.length
- + spec.sourceroots.length;
- if (!spec.badInput && (numSources < 1)) {
- validator.fail(
- "no input jars, arg files, or source files or roots");
- return false;
- }
-
- final File[] argFiles =
- FileUtil.getBaseDirFiles(testBaseSrcDir, spec.argfiles);
- final File[] injarFiles =
- FileUtil.getBaseDirFiles(testBaseSrcDir, injarPaths);
- final File[] inpathFiles =
- FileUtil.getBaseDirFiles(testBaseSrcDir, inpathPaths);
- final File[] aspectFiles =
- FileUtil.getBaseDirFiles(testBaseSrcDir, spec.aspectpath);
- final File[] extdirFiles =
- FileUtil.getBaseDirFiles(testBaseSrcDir, spec.extdirs);
- final File[] classFiles =
- FileUtil.getBaseDirFiles(testBaseSrcDir, spec.classpath);
- final File[] xlintFiles = (null == spec.xlintfile ? new File[0]
- : FileUtil.getBaseDirFiles(testBaseSrcDir, new String[] {spec.xlintfile}));
-
- // injars might be outjars in the classes dir...
- for (int i = 0; i < injarFiles.length; i++) {
- if (!injarFiles[i].exists()) {
- injarFiles[i] = new File(sandbox.classesDir, injarPaths[i]);
- }
- }
- for (int i = 0; i < inpathFiles.length; i++) {
- if (!inpathFiles[i].exists()) {
- inpathFiles[i] = new File(sandbox.classesDir, inpathPaths[i]);
- }
- }
- // moved after solving any injars that were outjars
- if (!validator.canRead(injarFiles, "injars")
- || !validator.canRead(injarFiles, "injars")) {
- return false;
- }
-
- // hmm - duplicates validation above, verifying getBaseDirFiles?
- if (!spec.badInput) {
- if (!validator.canRead(argFiles, "argFiles")
- || !validator.canRead(injarFiles, "injarFiles")
- || !validator.canRead(inpathFiles, "inpathFiles")
- || !validator.canRead(aspectFiles, "aspectFiles")
- || !validator.canRead(classFiles, "classFiles")
- || !validator.canRead(xlintFiles, "xlintFiles")) {
- return false;
- }
- }
-
- final File[] srcFiles;
- File[] sourcerootFiles = new File[0];
- // source text files are copied when staging incremental tests
- if (!spec.isStaging()) {
- // XXX why this? was always? || (testBaseSrcDir != sandbox.stagingDir))) {
- srcFiles =
- FileUtil.getBaseDirFiles(
- testBaseSrcDir,
- srcPaths,
- CompilerRun.SOURCE_SUFFIXES);
- if (!LangUtil.isEmpty(spec.sourceroots)) {
- sourcerootFiles =
- FileUtil.getBaseDirFiles(
- testBaseSrcDir,
- spec.sourceroots,
- null);
- }
- } else { // staging - copy files
- if (spec.badInput) {
- validator.info(
- "badInput ignored - files checked when staging");
- }
- try {
- // copy all files, then remove tagged ones
- // XXX make copyFiles support a filter?
- srcFiles =
- FileUtil.copyFiles(
- testBaseSrcDir,
- srcPaths,
- sandbox.stagingDir);
- if (!LangUtil.isEmpty(spec.sourceroots)) {
- sourcerootFiles =
- FileUtil.copyFiles(
- testBaseSrcDir,
- spec.sourceroots,
- sandbox.stagingDir);
- // delete incremental files in sourceroot after copying // XXX inefficient
- // an incremental file has an extra "." in name
- // most .java files don't, because they are named after
- // the principle type they contain, and simple type names
- // have no dots.
- FileFilter pickIncFiles = new FileFilter() {
- public boolean accept(File file) {
- if (file.isDirectory()) {
- // continue recursion
- return true;
- }
- String path = file.getPath();
- // only source files are relevant to staging
- if (!FileUtil.hasSourceSuffix(path)) {
- return false;
- }
- int first = path.indexOf(".");
- int last = path.lastIndexOf(".");
- return (first != last);
- }
- };
- for (int i = 0; i < sourcerootFiles.length; i++) {
- FileUtil.deleteContents(
- sourcerootFiles[i],
- pickIncFiles,
- false);
- }
- if (0 < sourcerootFiles.length) {
- FileUtil.sleepPastFinalModifiedTime(
- sourcerootFiles);
- }
- }
- File[] files =
- FileUtil.getBaseDirFiles(sandbox.stagingDir, srcPaths);
- if (0 < files.length) {
- FileUtil.sleepPastFinalModifiedTime(files);
- }
- } catch (IllegalArgumentException e) {
- validator.fail("staging - bad input", e);
- return false;
- } catch (IOException e) {
- validator.fail("staging - operations", e);
- return false;
- }
- }
- if (!spec.badInput
- && !validator.canRead(srcFiles, "copied paths")) {
- return false;
- }
- arguments.clear();
-
- if (!LangUtil.isEmpty(xlintFiles)) {
- arguments.add("-Xlintfile");
- String sr = FileUtil.flatten(xlintFiles, null);
- arguments.add(sr);
- }
- if (spec.outjar != null) {
- arguments.add("-outjar");
- arguments.add(new File(sandbox.classesDir,spec.outjar).getPath());
- }
- if (!LangUtil.isEmpty(extdirFiles)) {
- arguments.add("-extdirs");
- String sr = FileUtil.flatten(extdirFiles, null);
- arguments.add(sr);
- }
- if (!LangUtil.isEmpty(sourcerootFiles)) {
- arguments.add("-sourceroots");
- String sr = FileUtil.flatten(sourcerootFiles, null);
- arguments.add(sr);
- }
- if (!LangUtil.isEmpty(srcFiles)) {
- arguments.addAll(Arrays.asList(FileUtil.getPaths(srcFiles)));
- }
- injars.clear();
- if (!LangUtil.isEmpty(injarFiles)) {
- injars.addAll(Arrays.asList(FileUtil.getPaths(injarFiles)));
- }
- inpaths.clear();
- if (!LangUtil.isEmpty(inpathFiles)) {
- inpaths.addAll(Arrays.asList(FileUtil.getPaths(inpathFiles)));
- }
- if (!LangUtil.isEmpty(argFiles)) {
- String[] ra = FileUtil.getPaths(argFiles);
- for (int j = 0; j < ra.length; j++) {
- arguments.add("@" + ra[j]);
- }
- if (!spec.badInput && spec.isStaging) {
- validator.fail(
- "warning: files listed in argfiles not staged");
- }
- }
-
- // save classpath and aspectpath in sandbox for this and other clients
- final boolean checkReadable = !spec.badInput;
- int size = spec.includeClassesDir ? 3 : 2;
- File[] cp = new File[size + classFiles.length];
- System.arraycopy(classFiles, 0, cp, 0, classFiles.length);
- int index = classFiles.length;
- if (spec.includeClassesDir) {
- cp[index++] = sandbox.classesDir;
- }
- cp[index++] = Globals.F_aspectjrt_jar;
- cp[index++] = Globals.F_testingclient_jar;
- sandbox.compilerRunInit(this, testBaseSrcDir, aspectFiles,
- checkReadable, cp, checkReadable, null);
-
- // XXX todo set bootclasspath if set for forking?
- return true;
- }
-
- /**
- * Setup result evaluation and command line, run, and evaluate result.
- * <li>setup an AjcMessageHandler using the expected messages from
- * {@link Spec#getMessages()}.<li>
- * <li>heed any globals interpreted into a TestSetup by reading
- * {@link Spec@getOptions()}. For a list of supported globals, see
- * {@link setupArgs(ArrayList, IMessageHandler}.</li>
- * <li>construct a command line, using as classpath
- * {@link Sandbox.classpathToString()}<li>
- * <li>construct a compiler using {@link Spec#compiler}
- * or any overriding value set in TestSetup.<li>
- * <li>Just before running, set the compiler in the sandbox using
- * {@link Sandbox.setCompiler(ICommand)}.<li>
- * <li>After running, report AjcMessageHandler results to the status parameter.
- * If the AjcMessageHandler reports a failure, then send info messages
- * for the Spec, TestSetup, and command line.<li>
- * @see org.aspectj.testing.run.IRun#run(IRunStatus)
- */
- public boolean run(IRunStatus status) {
- if (null == spec.testSetup) {
- MessageUtil.abort(
- status,
- "no test setup - adoptParentValues not called");
- return false;
- } else if (!spec.testSetup.result) {
- MessageUtil.abort(status, spec.testSetup.failureReason);
- return false;
- }
-
- AjcMessageHandler handler =
- new AjcMessageHandler(spec.getMessages());
- handler.init();
- boolean handlerResult = false;
- boolean result = false;
- boolean commandResult = false;
- ArrayList argList = new ArrayList();
- final Spec.TestSetup setupResult = spec.testSetup;
- try {
- if (spec.outjar == null) {
- argList.add("-d");
- String outputDirPath = sandbox.classesDir.getAbsolutePath();
- try { // worth it to try for canonical?
- outputDirPath = sandbox.classesDir.getCanonicalPath();
- } catch (IOException e) {
- MessageUtil.abort(
- status,
- "canonical " + sandbox.classesDir,
- e);
- }
- argList.add(outputDirPath);
- }
- String path = sandbox.classpathToString(this);
- if (!LangUtil.isEmpty(path)) {
- argList.add("-classpath");
- argList.add(path);
- }
- path = sandbox.getBootclasspath(this);
- if (!LangUtil.isEmpty(path)) {
- argList.add("-bootclasspath");
- argList.add(path);
- }
-
- path = sandbox.aspectpathToString(this);
- if (!LangUtil.isEmpty(path)) {
- argList.add("-aspectpath");
- argList.add(path);
- }
-
- if (0 < injars.size()) {
- argList.add("-injars");
- argList.add(
- FileUtil.flatten(
- (String[]) injars.toArray(new String[0]),
- null));
- }
-
- if (0 < inpaths.size()) {
- argList.add("-inpath");
- argList.add(
- FileUtil.flatten(
- (String[]) inpaths.toArray(new String[0]),
- null));
- }
-
- // put specified arguments last, for better badInput tests
- argList.addAll(setupResult.commandOptions);
-
- // add both java/aspectj and argfiles
- argList.addAll(arguments);
-
- // XXX hack - seek on request as a side effect. reimplement as listener
- if (null != setupResult.seek) {
- String slopPrefix = Spec.SEEK_MESSAGE_PREFIX + " slop - ";
- PrintStream slop =
- MessageUtil.handlerPrintStream(
- status,
- IMessage.INFO,
- System.err,
- slopPrefix);
- List found =
- FileUtil.lineSeek(
- setupResult.seek,
- arguments,
- false,
- slop);
- if (!LangUtil.isEmpty(found)) {
- for (Iterator iter = found.iterator();
- iter.hasNext();
- ) {
- MessageUtil.info(
- status,
- Spec.SEEK_MESSAGE_PREFIX + iter.next());
- }
- }
- }
- ICommand compiler = spec.reuseCompiler
- // throws IllegalStateException if null
- ? sandbox.getCommand(this)
- : ReflectionFactory.makeCommand(setupResult.compilerName, status);
- DirChanges dirChanges = null;
- if (null == compiler) {
- MessageUtil.fail(
- status,
- "unable to make compiler " + setupResult.compilerName);
- return false;
- } else {
- if (setupResult.compilerName != Spec.DEFAULT_COMPILER) {
- MessageUtil.info(
- status,
- "compiler: " + setupResult.compilerName);
- }
- if (status.aborted()) {
- MessageUtil.debug(
- status,
- "aborted, but compiler valid?: " + compiler);
- } else {
- // same DirChanges handling for JavaRun, CompilerRun, IncCompilerRun
- // XXX around advice or template method/class
- if (!LangUtil.isEmpty(spec.dirChanges)) {
- LangUtil.throwIaxIfFalse(
- 1 == spec.dirChanges.size(),
- "expecting 0..1 dirChanges");
- dirChanges =
- new DirChanges(
- (DirChanges.Spec) spec.dirChanges.get(0));
- if (!dirChanges
- .start(status, sandbox.classesDir)) {
- return false; // setup failed
- }
- }
- MessageUtil.info(
- status,
- compiler + "(" + argList + ")");
- sandbox.setCommand(compiler, this);
- String[] args = (String[]) argList.toArray(RA_String);
- commandResult = compiler.runCommand(args, handler);
- }
- }
- handlerResult = handler.passed();
- if (!handlerResult) {
- return false;
- } else {
- result = (commandResult == handler.expectingCommandTrue());
- if (!result) {
- String m =
- commandResult
- ? "compile did not fail as expected"
- : "compile failed unexpectedly";
- MessageUtil.fail(status, m);
- } else if (null != dirChanges) {
- result = dirChanges.end(status, sandbox.testBaseDir);
- }
- }
- return result;
- } finally {
- if (!handlerResult) { // more debugging context in case of failure
- MessageUtil.info(handler, spec.toLongString());
- MessageUtil.info(handler, "" + argList);
- if (null != setupResult) {
- MessageUtil.info(handler, "" + setupResult);
- }
- }
- handler.report(status);
- // XXX weak - actual messages not reported in real-time, no fast-fail
- }
- }
-
- public String toString() {
- return "CompilerRun(" + spec + ")";
- }
-
- /**
- * Initializer/factory for CompilerRun
- * any path or file is relative to this test base dir
- */
- public static class Spec extends AbstractRunSpec {
- public static final String XMLNAME = "compile";
- public static final String DEFAULT_COMPILER =
- ReflectionFactory.ECLIPSE;
- static final String SEEK_PREFIX = "-seek:";
- static final String SEEK_MESSAGE_PREFIX = "found: ";
-
- private static final CRSOptions CRSOPTIONS = new CRSOptions();
- /**
- * Retitle description to title, paths to files, do comment,
- * staging, badInput,
- * do dirChanges, and print no chidren.
- */
- private static final AbstractRunSpec.XMLNames NAMES =
- new AbstractRunSpec.XMLNames(
- AbstractRunSpec.XMLNames.DEFAULT,
- "title",
- null,
- null,
- null,
- "files",
- null,
- null,
- null,
- false,
- false,
- true);
-
- /**
- * If the source version warrants, add a -bootclasspath
- * entry to the list of arguments to add.
- * This will fail and return an error String if the
- * required library is not found.
- * @param sourceVersion the String (if any) describing the -source option
- * (expecting one of [null, "1.3", "1.4", "1.5"].
- * @param compilerName the String name of the target compiler
- * @param toAdd the ArrayList to add -bootclasspath to
- * @return the String describing any errors, or null if no errors
- */
- private static String updateBootclasspathForSourceVersion(
- String sourceVersion,
- String compilerName,
- ArrayList toAdd) {
- if (null == sourceVersion) {
- return null;
- }
- if (3 != sourceVersion.length()) {
- throw new IllegalArgumentException(
- "bad version: " + sourceVersion);
- }
- if (null == toAdd) {
- throw new IllegalArgumentException("null toAdd");
- }
- int version = sourceVersion.charAt(2) - '0';
- switch (version) {
- case (3) :
- if (Globals.supportsJava("1.4")) {
- if (!FileUtil.canReadFile(Globals.J2SE13_RTJAR)) {
- return "no 1.3 libraries to handle -source 1.3";
- }
- toAdd.add("-bootclasspath");
- toAdd.add(Globals.J2SE13_RTJAR.getAbsolutePath());
- }
- break;
- case (4) :
- if (!Globals.supportsJava("1.4")) {
- if (ReflectionFactory
- .ECLIPSE
- .equals(compilerName)) {
- return "run eclipse under 1.4 to handle -source 1.4";
- }
- if (!FileUtil.canReadFile(Globals.J2SE14_RTJAR)) {
- return "no 1.4 libraries to handle -source 1.4";
- }
- toAdd.add("-bootclasspath");
- toAdd.add(Globals.J2SE14_RTJAR.getAbsolutePath());
- }
- break;
- case (5) :
- return "1.5 not supported in CompilerRun";
- case (0) :
- // ignore - no version specified
- break;
- default :
- throw new Error("unexpected version: " + version);
- }
- return null;
- }
-
- static CRSOptions testAccessToCRSOptions() {
- return CRSOPTIONS;
- }
-
- static Options testAccessToOptions() {
- return CRSOPTIONS.getOptions();
- }
-
- private static String[] copy(String[] input) {
- if (null == input) {
- return null;
- }
- String[] result = new String[input.length];
- System.arraycopy(input, 0, result, 0, input.length);
- return result;
- }
-
- protected String compiler;
-
- // use same command - see also IncCompiler.Spec.fresh
- protected boolean reuseCompiler;
- protected boolean permitAnyCompiler;
- protected boolean includeClassesDir;
-
- protected TestSetup testSetup;
-
- protected String[] argfiles = new String[0];
- protected String[] aspectpath = new String[0];
- protected String[] classpath = new String[0];
- protected String[] sourceroots = new String[0];
- protected String[] extdirs = new String[0];
-
- /** src path = {suiteParentDir}/{testBaseDirOffset}/{testSrcDirOffset}/{path} */
- protected String testSrcDirOffset;
- protected String xlintfile;
- protected String outjar;
-
- public Spec() {
- super(XMLNAME);
- setXMLNames(NAMES);
- compiler = DEFAULT_COMPILER;
- }
-
- protected void initClone(Spec spec)
- throws CloneNotSupportedException {
- super.initClone(spec);
- spec.argfiles = copy(argfiles);
- spec.aspectpath = copy(aspectpath);
- spec.classpath = copy(classpath);
- spec.compiler = compiler;
- spec.includeClassesDir = includeClassesDir;
- spec.reuseCompiler = reuseCompiler;
- spec.permitAnyCompiler = permitAnyCompiler;
- spec.sourceroots = copy(sourceroots);
- spec.extdirs = copy(extdirs);
- spec.outjar = outjar;
- spec.testSetup = null;
- if (null != testSetup) {
- spec.testSetup = (TestSetup) testSetup.clone();
- }
- spec.testSrcDirOffset = testSrcDirOffset;
- }
-
- public Object clone() throws CloneNotSupportedException {
- Spec result = new Spec();
- initClone(result);
- return result;
- }
-
- public void setIncludeClassesDir(boolean include) {
- this.includeClassesDir = include;
- }
- public void setReuseCompiler(boolean reuse) {
- this.reuseCompiler = reuse;
- }
-
- public void setPermitAnyCompiler(boolean permitAny) {
- this.permitAnyCompiler = permitAny;
- }
-
- public void setCompiler(String compilerName) {
- this.compiler = compilerName;
- }
-
- public void setTestSrcDirOffset(String s) {
- if (null != s) {
- testSrcDirOffset = s;
- }
- }
-
- /** override to set dirToken to Sandbox.CLASSES and default suffix to ".class" */
- public void addDirChanges(DirChanges.Spec spec) {
- if (null == spec) {
- return;
- }
- spec.setDirToken(Sandbox.CLASSES_DIR);
- spec.setDefaultSuffix(".class");
- super.addDirChanges(spec);
- }
-
- public String toLongString() {
- return getPrintName() + "(" + super.containedSummary() + ")";
- }
-
- public String toString() {
- return getPrintName() + "(" + super.containedSummary() + ")";
- }
-
- /** bean mapping for writers */
- public void setFiles(String paths) {
- addPaths(paths);
- }
-
- /**
- * Add to default classpath
- * (which includes aspectjrt.jar and testing-client.jar).
- * @param files comma-delimited list of classpath entries - ignored if
- * null or empty
- */
- public void setClasspath(String files) {
- if (!LangUtil.isEmpty(files)) {
- classpath = XMLWriter.unflattenList(files);
- }
- }
-
- /**
- * Set source roots, deleting any old ones
- * @param files comma-delimited list of directories
- * - ignored if null or empty
- */
- public void setSourceroots(String dirs) {
- if (!LangUtil.isEmpty(dirs)) {
- sourceroots = XMLWriter.unflattenList(dirs);
- }
- }
- public void setXlintfile(String path) {
- xlintfile = path;
- }
-
- public void setOutjar(String path) {
- outjar = path;
- }
-
- /**
- * Set extension dirs, deleting any old ones
- * @param files comma-delimited list of directories
- * - ignored if null or empty
- */
- public void setExtdirs(String dirs) {
- if (!LangUtil.isEmpty(dirs)) {
- extdirs = XMLWriter.unflattenList(dirs);
- }
- }
-
- /**
- * Set aspectpath, deleting any old ones
- * @param files comma-delimited list of aspect jars - ignored if null or
- * empty
- */
- public void setAspectpath(String files) {
- if (!LangUtil.isEmpty(files)) {
- aspectpath = XMLWriter.unflattenList(files);
- }
- }
-
- /**
- * Set argfiles, deleting any old ones
- * @param files comma-delimited list of argfiles - ignored if null or empty
- */
- public void setArgfiles(String files) {
- if (!LangUtil.isEmpty(files)) {
- argfiles = XMLWriter.unflattenList(files);
- }
- }
-
- /** @return String[] copy of argfiles array */
- public String[] getArgfilesArray() {
- String[] argfiles = this.argfiles;
- if (LangUtil.isEmpty(argfiles)) {
- return new String[0];
- }
- return (String[]) copy(argfiles);
- }
-
- /**
- * Make a copy of the array.
- * @return an array with the same component type as source
- * containing same elements, even if null.
- * @throws IllegalArgumentException if source is null
- */
- public static final Object[] copy(Object[] source) {
- LangUtil.throwIaxIfNull(source, "source");
- final Class c = source.getClass().getComponentType();
- Object[] result = (Object[]) Array.newInstance(c, source.length);
- System.arraycopy(source, 0, result, 0, result.length);
- return result;
- }
-
- /**
- * This implementation skips if:
- * <ul>
- * <li>incremental test, but using ajc (not eclipse)</li>
- * <li>usejavac, but javac is not available on the classpath</li>
- * <li>eclipse, but -usejavac or -preprocess test</li>
- * <li>-source 1.4, but running under 1.2 (XXX design)</li>
- * <li>local/global option conflicts (-lenient/-strict)</li>
- * <li>semantic conflicts (e.g., -lenient/-strict)</li>
- * </ul>
- * @return false if this wants to be skipped, true otherwise
- */
- protected boolean doAdoptParentValues(
- RT parentRuntime,
- IMessageHandler handler) {
- if (!super.doAdoptParentValues(parentRuntime, handler)) {
- return false;
- }
- testSetup = setupArgs(handler);
- if (!testSetup.result) {
- skipMessage(handler, testSetup.failureReason);
- }
- return testSetup.result;
- }
-
- private String getShortCompilerName() {
- String compilerClassName = compiler;
- if (null != testSetup) {
- compilerClassName = testSetup.compilerName;
- }
- if (null != compilerClassName) {
- int loc = compilerClassName.lastIndexOf(".");
- if (-1 != loc) {
- compilerClassName =
- compilerClassName.substring(loc + 1);
- }
- }
- return compilerClassName;
- }
-
- /** @return a CompilerRun with this as spec if setup completes successfully. */
- public IRunIterator makeRunIterator(
- Sandbox sandbox,
- Validator validator) {
- CompilerRun run = new CompilerRun(this);
- if (run.setupAjcRun(sandbox, validator)) {
- // XXX need name for compilerRun
- return new WrappedRunIterator(this, run);
- }
- return null;
- }
-
- protected String getPrintName() {
- return "CompilerRun.Spec " + getShortCompilerName();
- }
-
- /**
- * Each non-incremental run, fold the global flags in with
- * the run flags, which may involve adding or removing from
- * either list, depending on the flag prefix:
- * <ul>
- * <li>-foo: use -foo unless forced off.<li>
- * <li>^foo: (force off) remove any -foo option from the run flags</li>
- * <li>!foo: (force on) require the -foo flag </li>
- * </ul>
- * If there is a force conflict, then the test is skipped
- * ("skipping" info message, TestSetup.result is false).
- * This means an option local to the test which was specified
- * without forcing may be overridden by a globally-forced option.
- * <p>
- * There are some flags which are interpreted by the test
- * and removed from the list of flags passed to the command
- * (see testFlag()):
- * <ul>
- * <li>eclipse: use the new eclipse compiler (can force)</li>
- * <li>ajc: use the old ajc compiler (can force)</li>
- * <li>ignoreWarnings: ignore warnings in result evaluations (no force)</li>
- * </ul>
- * <p>
- * There are some flags which are inconsistent with each other.
- * These are treated as conflicts and the test is skipped:
- * <ul>
- * <li>lenient, strict</li>
- * </ul>
- * <p>
- * <p>
- * This also interprets any relevant System properties,
- * e.g., from <code>JavaRun.BOOTCLASSPATH_KEY</code>.
- * <p>
- * Finally, compiler limitations are enforced here by skipping
- * tests which the compiler cannot do:
- * <ul>
- * <li>eclipse does not do -lenient, -strict, -usejavac, -preprocess,
- * -XOcodeSize, -XSerializable, XaddSafePrefix,
- * -XserializableAspects,-XtargetNearSource</li>
- * <li>ajc does not run in incremental (staging) mode,
- * nor with -usejavac if javac is not on the classpath</li>
- * </ul>
- * <u>Errors</u>:This will remove an arg not prefixed by [-|!|^] after
- * providing an info message.
- * <u>TestSetup Result</u>:
- * If this completes successfully, then TestSetup.result is true,
- * and commandOptions is not null, and any test flags (ignore warning,
- * compiler) are reflected in the TestSetup.
- * If this fails, then TestSetup.result is false,
- * and a TestSetup.failreason is set.
- * This means the test is skipped.
- * @return TestSetup with results
- * (TestSetup result=false if the run should not continue)
- */
- protected TestSetup setupArgs(IMessageHandler handler) {
- // warning: HarnessSelectionTest checks for specific error wording
- final Spec spec = this;
- final TestSetup result = new TestSetup();
- result.compilerName = spec.compiler;
- // urk - s.b. null, but expected
- Values values = gatherValues(result);
-
- if ((null == values) || (null != result.failureReason)) {
- return checkResult(result);
- }
-
- // send info messages about
- // forced staging when -incremental
- // or staging but no -incremental flag
- Option.Family getFamily =
- CRSOPTIONS.crsIncrementalOption.getFamily();
- final boolean haveIncrementalFlag =
- (null != values.firstInFamily(getFamily));
-
- if (spec.isStaging()) {
- if (!haveIncrementalFlag) {
- MessageUtil.info(
- handler,
- "staging but no -incremental flag");
- }
- } else if (haveIncrementalFlag) {
- spec.setStaging(true);
- MessageUtil.info(handler, "-incremental forcing staging");
- }
-
- if (hasInvalidOptions(values, result)) {
- return checkResult(result);
- }
-
- // set compiler in result
- getFamily = CRSOPTIONS.ajccompilerOption.getFamily();
- Option.Value compiler = values.firstInFamily(getFamily);
- if (null != compiler) {
- result.compilerName
- = CRSOPTIONS.compilerClassName(compiler.option);
- if (null == result.compilerName) {
- result.failureReason =
- "unable to get class name for " + compiler;
- return checkResult(result);
- }
- }
- String compilerName =
- (null == result.compilerName
- ? spec.compiler
- : result.compilerName);
- // check compiler semantics
- if (hasCompilerSpecErrors(compilerName, values, result)) {
- return checkResult(result);
- }
- // add toadd and finish result
- ArrayList args = new ArrayList();
- String[] rendered = values.render();
- if (!LangUtil.isEmpty(rendered)) {
- args.addAll(Arrays.asList(rendered));
- }
- // update bootclasspath
- getFamily = CRSOPTIONS.crsSourceOption.getFamily();
- Option.Value source = values.firstInFamily(getFamily);
- if (null != source) {
- String sourceVersion = source.unflatten()[1];
- ArrayList toAdd = new ArrayList();
- /*String err =*/
- updateBootclasspathForSourceVersion(
- sourceVersion,
- spec.compiler,
- toAdd);
- args.addAll(toAdd);
- }
- result.commandOptions = args;
- result.result = true;
- return checkResult(result);
- }
-
- /**
- * Ensure exit invariant:
- * <code>result.result == (null == result.failureReason)
- * == (null != result.commandOptions)</code>
- * @param result the TestSetup to verify
- * @return result
- * @throws Error if invariant is not true
- */
- TestSetup checkResult(TestSetup result) {
- String err = null;
- if (null == result) {
- err = "null result";
- } else if (result.result != (null == result.failureReason)) {
- err =
- result.result
- ? "expected no failure: " + result.failureReason
- : "fail for no reason";
- } else if (result.result != (null != result.commandOptions)) {
- err =
- result.result
- ? "expected command options"
- : "unexpected command options";
- }
- if (null != err) {
- throw new Error(err);
- }
- return result;
- }
-
- boolean hasInvalidOptions(Values values, TestSetup result) {
- // not supporting 1.0 options any more
- for (Iterator iter = CRSOPTIONS.invalidOptions.iterator();
- iter.hasNext();
- ) {
- Option option = (Option) iter.next();
- if (null != values.firstOption(option)) {
- result.failureReason =
- "invalid option in harness: " + option;
- return true;
- }
- }
- return false;
- }
-
- boolean hasCompilerSpecErrors(
- String compilerName,
- Values values,
- TestSetup result) {
- /*
- * Describe any semantic conflicts between options.
- * This skips:
- * - old 1.0 options, including lenient v. strict
- * - old ajc options, include !incremental and usejavac w/o javac
- * - invalid eclipse options (mostly ajc)
- * @param compilerName the String name of the target compiler
- * @return a String describing any conflicts, or null if none
- */
- if (!permitAnyCompiler
- && (!(ReflectionFactory.ECLIPSE.equals(compilerName)
- || ReflectionFactory.OLD_AJC.equals(compilerName)
- || CRSOptions.AJDE_COMPILER.equals(compilerName)
- || CRSOptions.AJCTASK_COMPILER.equals(compilerName)
- || permitAnyCompiler
- ))) {
- //|| BUILDER_COMPILER.equals(compilerName))
- result.failureReason =
- "unrecognized compiler: " + compilerName;
- return true;
- }
- // not supporting ajc right now
- if (null
- != values.firstOption(CRSOPTIONS.ajccompilerOption)) {
- result.failureReason = "ajc not supported";
- return true;
- }
- // not supporting 1.0 options any more
- for (Iterator iter = CRSOPTIONS.ajc10Options.iterator();
- iter.hasNext();
- ) {
- Option option = (Option) iter.next();
- if (null != values.firstOption(option)) {
- result.failureReason = "old ajc 1.0 option: " + option;
- return true;
- }
- }
-
- return false;
- }
-
- protected Values gatherValues(TestSetup result) {
- final Spec spec = this;
- // ---- local option values
- final Values localValues;
- final Options options = CRSOPTIONS.getOptions();
- try {
- String[] input = getOptionsArray();
- // this handles reading options,
- // flattening two-String options, etc.
- localValues = options.acceptInput(input);
- // all local values should be picked up
- String err = Options.missedMatchError(input, localValues);
- if (!LangUtil.isEmpty(err)) {
- result.failureReason = err;
- return null;
- }
- } catch (InvalidInputException e) {
- result.failureReason = e.getFullMessage();
- return null;
- }
-
- // ---- global option values
- StringBuffer errs = new StringBuffer();
- final Values globalValues =
- spec.runtime.extractOptions(options, true, errs);
- if (errs.length() > 0) {
- result.failureReason = errs.toString();
- return null;
- }
- final Values combined =
- Values.wrapValues(
- new Values[] { localValues, globalValues });
-
- String err = combined.resolve();
- if (null != err) {
- result.failureReason = err;
- return null;
- }
-
- return handleTestArgs(combined, result);
- }
-
- // final int len = globalValues.length() + localValues.length();
- // final Option.Value[] combinedValues = new Option.Value[len];
- // System.arraycopy(
- // globalValues,
- // 0,
- // combinedValues,
- // 0,
- // globalValues.length());
- // System.arraycopy(
- // localValues,
- // 0,
- // combinedValues,
- // globalValues.length(),
- // localValues.length());
- //
- // result.compilerName = spec.compiler;
- // if (0 < combinedValues.length) {
- // // this handles option forcing, etc.
- // String err = Options.resolve(combinedValues);
- // if (null != err) {
- // result.failureReason = err;
- // return null;
- // }
- // if (!handleTestArgs(combinedValues, result)) {
- // return null;
- // }
- // }
- // return Values.wrapValues(combinedValues);
- // }
- /**
- * This interprets and nullifies values for the test.
- * @param values the Option.Value[] being processed
- * @param result the TestSetup to modify
- * @return false if error (caller should return), true otherwise
- */
- Values handleTestArgs(Values values, final TestSetup result) {
- final Option.Family compilerFamily =
- CRSOPTIONS.ajccompilerOption.getFamily();
- Values.Selector selector = new Values.Selector() {
- protected boolean accept(Option.Value value) {
- if (null == value) {
- return false;
- }
- Option option = value.option;
- if (compilerFamily.sameFamily(option.getFamily())) {
- if (value.prefix.isSet()) {
- String compilerClass
- = CRSOPTIONS.compilerClassName(option);
- if (null == compilerClass) {
- result.failureReason =
- "unrecognized compiler: " + value;
- throw Values.Selector.STOP;
- }
- if (!CRSOPTIONS.compilerIsLoadable(option)) {
- result.failureReason =
- "unable to load compiler: " + option;
- throw Values.Selector.STOP;
- }
- result.compilerName = compilerClass;
- }
- return true;
- } else if (
- CRSOPTIONS.crsIgnoreWarnings.sameOptionIdentifier(
- option)) {
- result.ignoreWarnings = value.prefix.isSet();
- result.ignoreWarningsSet = true;
- return true;
- }
- return false;
- }
- };
- return values.nullify(selector);
- }
-
- // /**
- // * This interprets and nullifies values for the test.
- // * @param values the Option.Value[] being processed
- // * @param result the TestSetup to modify
- // * @return false if error (caller should return), true otherwise
- // */
- // boolean handleTestArgs(Option.Value[] values, TestSetup result) {
- // if (!LangUtil.isEmpty(values)) {
- // for (int i = 0; i < values.length; i++) {
- // Option.Value value = values[i];
- // if (null == value) {
- // continue;
- // }
- // Option option = value.option;
- // if (option.sameOptionFamily(ECLIPSE_OPTION)) {
- // if (!value.prefix.isSet()) {
- // values[i] = null;
- // continue;
- // }
- // String compilerClass =
- // (String) COMPILER_OPTION_TO_CLASSNAME.get(
- // option);
- // if (null == compilerClass) {
- // result.failureReason =
- // "unrecognized compiler: " + value;
- // return false;
- // }
- // result.compilerName = compilerClass;
- // values[i] = null;
- // } else if (
- // option.sameOptionFamily(crsIgnoreWarnings)) {
- // result.ignoreWarnings = value.prefix.isSet();
- // result.ignoreWarningsSet = true;
- // values[i] = null;
- // }
- // }
- // }
- // return true;
- // }
-
- // XXX need keys, cache...
- /** @return index of global in argList, ignoring first char */
- protected int indexOf(String global, ArrayList argList) {
- int max = argList.size();
- for (int i = 0; i < max; i++) {
- if (global
- .equals(((String) argList.get(i)).substring(1))) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Write this out as a compile element as defined in
- * AjcSpecXmlReader.DOCTYPE.
- * @see AjcSpecXmlReader#DOCTYPE
- * @see IXmlWritable#writeXml(XMLWriter)
- */
- public void writeXml(XMLWriter out) {
- out.startElement(xmlElementName, false);
- if (!LangUtil.isEmpty(testSrcDirOffset)) {
- out.printAttribute("dir", testSrcDirOffset);
- }
- super.writeAttributes(out);
- if (!DEFAULT_COMPILER.equals(compiler)) {
- out.printAttribute("compiler", compiler);
- }
- if (reuseCompiler) {
- out.printAttribute("reuseCompiler", "true");
- }
- // test-only feature
- // if (permitAnyCompiler) {
- // out.printAttribute("permitAnyCompiler", "true");
- // }
- if (includeClassesDir) {
- out.printAttribute("includeClassesDir", "true");
- }
- if (!LangUtil.isEmpty(argfiles)) {
- out.printAttribute(
- "argfiles",
- XMLWriter.flattenFiles(argfiles));
- }
- if (!LangUtil.isEmpty(aspectpath)) {
- out.printAttribute(
- "aspectpath",
- XMLWriter.flattenFiles(aspectpath));
- }
- if (!LangUtil.isEmpty(sourceroots)) {
- out.printAttribute(
- "sourceroots",
- XMLWriter.flattenFiles(sourceroots));
- }
- if (!LangUtil.isEmpty(extdirs)) {
- out.printAttribute(
- "extdirs",
- XMLWriter.flattenFiles(extdirs));
- }
- out.endAttributes();
- if (!LangUtil.isEmpty(dirChanges)) {
- DirChanges.Spec.writeXml(out, dirChanges);
- }
- SoftMessage.writeXml(out, getMessages());
- out.endElement(xmlElementName);
- }
-
- /**
- * Encapsulate the directives that can be set using
- * global arguments supplied in {@link Spec.getOptions()}.
- * This supports changing the compiler and ignoring warnings.
- */
- class TestSetup {
- /** null unless overriding the compiler to be used */
- String compilerName;
- /**
- * true if we should tell AjcMessageHandler whether
- * to ignore warnings in its result evaluation
- */
- boolean ignoreWarningsSet;
-
- /** if telling AjcMessageHandler, what we tell it */
- boolean ignoreWarnings;
-
- /** false if setup failed */
- boolean result;
-
- /** if setup failed, this has the reason why */
- String failureReason;
-
- /** beyond running test, also seek text in sources */
- String seek;
-
- /** if setup completed, this has the combined global/local options */
- ArrayList commandOptions;
-
- public Object clone() {
- TestSetup testSetup = new TestSetup();
- testSetup.compilerName = compilerName;
- testSetup.ignoreWarnings = ignoreWarnings;
- testSetup.ignoreWarningsSet = ignoreWarningsSet;
- testSetup.result = result;
- testSetup.failureReason = failureReason;
- testSetup.seek = seek;
- if (null != commandOptions) {
- testSetup.commandOptions = new ArrayList();
- testSetup.commandOptions.addAll(commandOptions);
- }
- return testSetup;
- }
- public String toString() {
- return "TestSetup("
- + (null == compilerName ? "" : compilerName + " ")
- + (!ignoreWarningsSet
- ? ""
- : (ignoreWarnings ? "" : "do not ")
- + "ignore warnings ")
- + (result ? "" : "setup failed")
- + ")";
- }
- }
-
- /**
- * Options-related stuff in the spec.
- */
- static class CRSOptions {
- // static final String BUILDER_COMPILER =
- // "org.aspectj.ajdt.internal.core.builder.Builder.Command";
- static final String AJDE_COMPILER =
- CompileCommand.class.getName();
-
- static final String AJCTASK_COMPILER =
- AjcTaskCompileCommand.class.getName();
-
- private final Map compilerOptionToLoadable = new TreeMap();
- /*
- * The options field in a compiler test permits some arbitrary
- * command-line options to be set. It does not permit things
- * like classpath, aspectpath, files, etc. which are set
- * using other fields in the test specification, so the options
- * permitted are a subset of those permitted on the command-line.
- *
- * Global options specified on the harness command-line are
- * adopted for the compiler command-line if they are permitted
- * in the options field. That means we have to detect each
- * permitted option, rather than just letting all through
- * for the compiler.
- *
- * Conversely, some options are targeted not at the compiler,
- * but at the test itself (e.g., to ignore warnings, or to
- * select a compiler.
- *
- * The harness can run many compilers, and they differ in
- * which options are permitted. You can specify a compiler
- * as an option (e.g., -eclipse). So the set of constraints
- * on the list of permitted options can differ from test to test.
- *
- * The following code sets up the lists of permitted options
- * and breaks out subsets for different compiler-variant checks.
- * Most options are created but not named, but some options
- * are named to detect corresponding values for further
- * processing. e.g., the compiler options are saved so
- * we can do per-compiler option verification.
- *
- */
- private final Options crsOptions;
- private final Family compilerFamily;
- private final Option crsIncrementalOption;
- private final Option crsSourceOption;
- // these are options handled/absorbed by CompilerRun
- private final Option crsIgnoreWarnings;
- private final Option eclipseOption;
- private final Option buildercompilerOption;
- private final Option ajdecompilerOption;
- private final Option javacOption;
- private final Option ajctaskcompilerOption;
- private final Option ajccompilerOption;
- private final Map compilerOptionToClassname;
- private final Set compilerOptions;
- // compiler verification - permit but flag ajc 1.0 options
- private final List ajc10Options;
- private final List invalidOptions;
-
- private CRSOptions() {
- crsOptions = new Options(true);
- Option.Factory factory = new Option.Factory("CompilerRun");
- // compiler options go in map
- eclipseOption =
- factory.create(
- "eclipse",
- "compiler",
- Option.FORCE_PREFIXES,
- false);
- compilerFamily = eclipseOption.getFamily();
- buildercompilerOption =
- factory.create(
- "builderCompiler",
- "compiler",
- Option.FORCE_PREFIXES,
- false);
- ajctaskcompilerOption =
- factory.create(
- "ajctaskCompiler",
- "compiler",
- Option.FORCE_PREFIXES,
- false);
- ajdecompilerOption =
- factory.create(
- "ajdeCompiler",
- "compiler",
- Option.FORCE_PREFIXES,
- false);
- ajccompilerOption =
- factory.create(
- "ajc",
- "compiler",
- Option.FORCE_PREFIXES,
- false);
- javacOption =
- factory.create(
- "javac",
- "compiler",
- Option.FORCE_PREFIXES,
- false);
-
- Map map = new TreeMap();
- map.put(eclipseOption, ReflectionFactory.ECLIPSE);
- //map.put(BUILDERCOMPILER_OPTION, BUILDER_COMPILER);
- map.put(
- ajctaskcompilerOption,
- AJCTASK_COMPILER);
- map.put(ajdecompilerOption, AJDE_COMPILER);
- map.put(ajccompilerOption, ReflectionFactory.OLD_AJC);
- //map.put(JAVAC_OPTION, "XXX javac option not supported");
- compilerOptionToClassname =
- Collections.unmodifiableMap(map);
-
- compilerOptions =
- Collections.unmodifiableSet(
- compilerOptionToClassname.keySet());
- // options not permitted in the harness
- List list = new ArrayList();
- list.add(factory.create("workingdir"));
- list.add(factory.create("argfile"));
- list.add(factory.create("sourceroots"));
- list.add(factory.create("outjar"));
- invalidOptions = Collections.unmodifiableList(list);
-
- // other options added directly
- crsIncrementalOption = factory.create("incremental");
-
- crsIgnoreWarnings = factory.create("ignoreWarnings");
-
- crsSourceOption =
- factory
- .create(
- "source",
- "source",
- Option.FORCE_PREFIXES,
- false,
- new String[][] { new String[] { "1.3", "1.4", "1.5" }
- });
-
- // ajc 1.0 options
- // workingdir above in invalid options
- list = new ArrayList();
- list.add(factory.create("usejavac"));
- list.add(factory.create("preprocess"));
- list.add(factory.create("nocomment"));
- list.add(factory.create("porting"));
- list.add(factory.create("XOcodeSize"));
- list.add(factory.create("XTargetNearSource"));
- list.add(factory.create("XaddSafePrefix"));
- list.add(
- factory.create(
- "lenient",
- "lenient",
- Option.FORCE_PREFIXES,
- false));
- list.add(
- factory.create(
- "strict",
- "lenient",
- Option.FORCE_PREFIXES,
- false));
- ajc10Options = Collections.unmodifiableList(list);
-
- // -warn:.. and -g/-g:.. are not exclusive
- if (!(factory.setupFamily("debug", true)
- && factory.setupFamily("warning", true))) {
- System.err.println("CompilerRun debug/warning fail!");
- }
- Option[] options =
- new Option[] {
- crsIncrementalOption,
- crsIgnoreWarnings,
- crsSourceOption,
- factory.create(
- "Xlint",
- "XLint",
- Option.FORCE_PREFIXES,
- true),
- factory.create("verbose"),
- factory.create("emacssym"),
- factory.create("referenceInfo"),
- factory.create("nowarn"),
- factory.create("deprecation"),
- factory.create("noImportError"),
- factory.create("proceedOnError"),
- factory.create("preserveAllLocals"),
- factory.create(
- "warn",
- "warning",
- Option.STANDARD_PREFIXES,
- true),
- factory.create(
- "g",
- "debug",
- Option.STANDARD_PREFIXES,
- false),
- factory.create(
- "g:",
- "debug",
- Option.STANDARD_PREFIXES,
- true),
- factory.create(
- "1.3",
- "compliance",
- Option.FORCE_PREFIXES,
- false),
- factory.create(
- "1.4",
- "compliance",
- Option.FORCE_PREFIXES,
- false),
- factory.create(
- "1.5",
- "compliance",
- Option.FORCE_PREFIXES,
- false),
- factory
- .create(
- "target",
- "target",
- Option.FORCE_PREFIXES,
- false,
- new String[][] { new String[] {
- "1.1",
- "1.2",
- "1.3",
- "1.4",
- "1.5" }}),
- factory.create("XnoInline"),
- factory.create("XterminateAfterCompilation"),
- factory.create("Xreweavable"),
- factory.create("XnotReweavable"),
- factory.create("XserializableAspects")
- };
-
- // among options not permitted: extdirs...
-
- for (int i = 0; i < options.length; i++) {
- crsOptions.addOption(options[i]);
- }
- for (Iterator iter = compilerOptions.iterator();
- iter.hasNext();
- ) {
- crsOptions.addOption((Option) iter.next());
- }
- // these are recognized but records with them are skipped
- for (Iterator iter = ajc10Options.iterator();
- iter.hasNext();
- ) {
- crsOptions.addOption((Option) iter.next());
- }
- crsOptions.freeze();
- }
-
- Options getOptions() {
- return crsOptions;
- }
-
- /**
- * @return unmodifiable Set of options sharing the
- * family "compiler".
- */
- Set compilerOptions() {
- return compilerOptions;
- }
-
- /**
- * @param option the compiler Option to get name for
- * @return null if option is null or not a compiler option,
- * or the fully-qualified classname of the ICommand
- * implementing the compiler.
- */
- String compilerClassName(Option option) {
- if ((null == option)
- || (!compilerFamily.sameFamily(option.getFamily()))) {
- return null;
- }
- return (String) compilerOptionToClassname.get(option);
- }
-
- /**
- * Check that the compiler class associated with a compiler
- * option can be loaded. This check only happens once;
- * the result is cached (by compilerOption key) for later calls.
- * @param compilerOption the Option (family compiler) to check
- * @return true if compiler class for this option can be loaded
- */
- boolean compilerIsLoadable(Option compilerOption) {
- LangUtil.throwIaxIfNull(compilerOption, "compilerName");
- synchronized (compilerOptionToLoadable) {
- Boolean result =
- (Boolean) compilerOptionToLoadable.get(
- compilerOption);
- if (null == result) {
- MessageHandler sink = new MessageHandler();
- String compilerClassname =
- (String) compilerOptionToClassname.get(
- compilerOption);
- if (null == compilerClassname) {
- result = Boolean.FALSE;
- } else {
- ICommand c =
- ReflectionFactory.makeCommand(
- compilerClassname,
- sink);
-
- if ((null == c)
- || sink.hasAnyMessage(
- IMessage.ERROR,
- true)) {
- result = Boolean.FALSE;
- } else {
- result = Boolean.TRUE;
- }
- }
- compilerOptionToLoadable.put(
- compilerOption,
- result);
- }
- return result.booleanValue();
- }
- }
- } // CompilerRun.Spec.CRSOptions
- } // CompilerRun.Spec
- } // CompilerRun
|