1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555 |
- /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * 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:
- * PARC initial implementation
- * ******************************************************************/
-
- package org.aspectj.ajdt.internal.core.builder;
-
- import java.io.BufferedOutputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileFilter;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.PrintStream;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Set;
- import java.util.jar.Attributes;
- import java.util.jar.JarFile;
- import java.util.jar.JarInputStream;
- import java.util.jar.JarOutputStream;
- import java.util.jar.Manifest;
- import java.util.zip.ZipEntry;
-
- import org.aspectj.ajdt.ajc.BuildArgParser;
- import org.aspectj.ajdt.internal.compiler.AjCompilerAdapter;
- import org.aspectj.ajdt.internal.compiler.AjPipeliningCompilerAdapter;
- import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager;
- import org.aspectj.ajdt.internal.compiler.IBinarySourceProvider;
- import org.aspectj.ajdt.internal.compiler.ICompilerAdapter;
- import org.aspectj.ajdt.internal.compiler.ICompilerAdapterFactory;
- import org.aspectj.ajdt.internal.compiler.IIntermediateResultsRequestor;
- import org.aspectj.ajdt.internal.compiler.IOutputClassFileNameProvider;
- import org.aspectj.ajdt.internal.compiler.InterimCompilationResult;
- import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
- import org.aspectj.ajdt.internal.compiler.lookup.AnonymousClassPublisher;
- import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
- import org.aspectj.ajdt.internal.compiler.problem.AjProblemReporter;
- import org.aspectj.asm.AsmManager;
- import org.aspectj.asm.IHierarchy;
- import org.aspectj.asm.IProgramElement;
- import org.aspectj.asm.internal.ProgramElement;
- import org.aspectj.bridge.AbortException;
- import org.aspectj.bridge.CountingMessageHandler;
- import org.aspectj.bridge.ILifecycleAware;
- import org.aspectj.bridge.IMessage;
- import org.aspectj.bridge.IMessageHandler;
- import org.aspectj.bridge.IProgressListener;
- import org.aspectj.bridge.ISourceLocation;
- import org.aspectj.bridge.Message;
- import org.aspectj.bridge.MessageUtil;
- import org.aspectj.bridge.SourceLocation;
- import org.aspectj.bridge.Version;
- import org.aspectj.bridge.context.CompilationAndWeavingContext;
- import org.aspectj.bridge.context.ContextFormatter;
- import org.aspectj.bridge.context.ContextToken;
- import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
- import org.aspectj.org.eclipse.jdt.core.compiler.IProblem;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
- import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
- import org.aspectj.org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ICompilerRequestor;
- import org.aspectj.org.eclipse.jdt.internal.compiler.IProblemFactory;
- import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathLocation;
- import org.aspectj.org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
- import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem;
- import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment;
- import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
- import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
- import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
- import org.aspectj.org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
- import org.aspectj.tools.ajc.Main;
- import org.aspectj.util.FileUtil;
- import org.aspectj.weaver.CustomMungerFactory;
- import org.aspectj.weaver.Dump;
- import org.aspectj.weaver.ResolvedType;
- import org.aspectj.weaver.World;
- import org.aspectj.weaver.bcel.BcelWeaver;
- import org.aspectj.weaver.bcel.BcelWorld;
- import org.aspectj.weaver.bcel.UnwovenClassFile;
- import org.eclipse.core.runtime.OperationCanceledException;
-
- public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySourceProvider, ICompilerAdapterFactory {
- private static final String CROSSREFS_FILE_NAME = "build.lst";
- private static final String CANT_WRITE_RESULT = "unable to write compilation result";
- private static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
- public static boolean COPY_INPATH_DIR_RESOURCES = false;
- // AJDT doesn't want this check, so Main enables it.
- private static boolean DO_RUNTIME_VERSION_CHECK = false;
- // If runtime version check fails, warn or fail? (unset?)
- static final boolean FAIL_IF_RUNTIME_NOT_FOUND = false;
-
- private static final FileFilter binarySourceFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return f.getName().endsWith(".class");
- }
- };
-
- /**
- * This builder is static so that it can be subclassed and reset. However, note that there is only one builder present, so if
- * two extendsion reset it, only the latter will get used.
- */
- public static AsmHierarchyBuilder asmHierarchyBuilder = new AsmHierarchyBuilder();
-
- static {
- // CompilationAndWeavingContext.setMultiThreaded(false);
- CompilationAndWeavingContext.registerFormatter(CompilationAndWeavingContext.BATCH_BUILD, new AjBuildContexFormatter());
- CompilationAndWeavingContext
- .registerFormatter(CompilationAndWeavingContext.INCREMENTAL_BUILD, new AjBuildContexFormatter());
- }
-
- private IProgressListener progressListener = null;
-
- private boolean environmentSupportsIncrementalCompilation = false;
- private int compiledCount;
- private int sourceFileCount;
-
- private JarOutputStream zos;
- private boolean batchCompile = true;
- private INameEnvironment environment;
-
- private Map<String, List<UnwovenClassFile>> /* String -> List<UCF> */binarySourcesForTheNextCompile = new HashMap<String, List<UnwovenClassFile>>();
-
- // FIXME asc should this really be in here?
- // private AsmManager structureModel;
- public AjBuildConfig buildConfig;
- private boolean ignoreOutxml;
- private boolean wasFullBuild = true; // true if last build was a full build rather than an incremental build
-
- AjState state = new AjState(this);
-
- /**
- * Enable check for runtime version, used only by Ant/command-line Main.
- *
- * @param caller Main unused except to limit to non-null clients.
- */
- public static void enableRuntimeVersionCheck(Main caller) {
- DO_RUNTIME_VERSION_CHECK = null != caller;
- }
-
- public BcelWeaver getWeaver() {
- return state.getWeaver();
- }
-
- public BcelWorld getBcelWorld() {
- return state.getBcelWorld();
- }
-
- public CountingMessageHandler handler;
- private CustomMungerFactory customMungerFactory;
-
- public AjBuildManager(IMessageHandler holder) {
- super();
- this.handler = CountingMessageHandler.makeCountingMessageHandler(holder);
- }
-
- public void environmentSupportsIncrementalCompilation(boolean itDoes) {
- this.environmentSupportsIncrementalCompilation = itDoes;
- if (itDoes) {
- org.aspectj.weaver.loadtime.definition.DocumentParser.deactivateCaching();
- }
- }
-
- /** @return true if we should generate a model as a side-effect */
- public boolean doGenerateModel() {
- return buildConfig.isGenerateModelMode();
- }
-
- public boolean batchBuild(AjBuildConfig buildConfig, IMessageHandler baseHandler) throws IOException, AbortException {
- return performBuild(buildConfig, baseHandler, true);
- }
-
- public boolean incrementalBuild(AjBuildConfig buildConfig, IMessageHandler baseHandler) throws IOException, AbortException {
- return performBuild(buildConfig, baseHandler, false);
- }
-
- /**
- * Perform a build.
- *
- * @return true if the build was successful (ie. no errors)
- */
- private boolean performBuild(AjBuildConfig buildConfig, IMessageHandler baseHandler, boolean isFullBuild) throws IOException,
- AbortException {
- boolean ret = true;
- batchCompile = isFullBuild;
- wasFullBuild = isFullBuild;
- if (baseHandler instanceof ILifecycleAware) {
- ((ILifecycleAware) baseHandler).buildStarting(!isFullBuild);
- }
- CompilationAndWeavingContext.reset();
- final int phase = isFullBuild ? CompilationAndWeavingContext.BATCH_BUILD : CompilationAndWeavingContext.INCREMENTAL_BUILD;
- final ContextToken ct = CompilationAndWeavingContext.enteringPhase(phase, buildConfig);
- try {
- if (isFullBuild) {
- this.state = new AjState(this);
- }
-
- this.state.setCouldBeSubsequentIncrementalBuild(this.environmentSupportsIncrementalCompilation);
-
- final boolean canIncremental = state.prepareForNextBuild(buildConfig);
- if (!canIncremental && !isFullBuild) { // retry as batch?
- CompilationAndWeavingContext.leavingPhase(ct);
- if (state.listenerDefined()) {
- state.getListener().recordDecision("Falling back to batch compilation");
- }
- return performBuild(buildConfig, baseHandler, true);
- }
- this.handler = CountingMessageHandler.makeCountingMessageHandler(baseHandler);
-
- if (buildConfig == null || buildConfig.isCheckRuntimeVersion()) {
- if (DO_RUNTIME_VERSION_CHECK) {
- final String check = checkRtJar(buildConfig);
- if (check != null) {
- if (FAIL_IF_RUNTIME_NOT_FOUND) {
- MessageUtil.error(handler, check);
- CompilationAndWeavingContext.leavingPhase(ct);
- return false;
- } else {
- MessageUtil.warn(handler, check);
- }
- }
- }
- }
-
- // if (batch) {
- setBuildConfig(buildConfig);
- // }
- if (isFullBuild || !AsmManager.attemptIncrementalModelRepairs) {
- // if (buildConfig.isEmacsSymMode() || buildConfig.isGenerateModelMode()) {
- setupModel(buildConfig);
- // }
- }
- if (isFullBuild) {
- initBcelWorld(handler);
- }
-
- if (handler.hasErrors()) {
- CompilationAndWeavingContext.leavingPhase(ct);
- return false;
- }
-
- if (buildConfig.getOutputJar() != null) {
- if (!openOutputStream(buildConfig.getOutputJar())) {
- CompilationAndWeavingContext.leavingPhase(ct);
- return false;
- }
- }
-
- if (isFullBuild) {
- // System.err.println("XXXX batch: " + buildConfig.getFiles());
- if (buildConfig.isEmacsSymMode() || buildConfig.isGenerateModelMode()) {
- AsmManager.setLastActiveStructureModel(state.getStructureModel());
- getWorld().setModel(state.getStructureModel());
- // in incremental build, only get updated model?
- }
- binarySourcesForTheNextCompile = state.getBinaryFilesToCompile(true);
- performCompilation(buildConfig.getFiles());
- state.clearBinarySourceFiles(); // we don't want these hanging around...
- if (!proceedOnError() && handler.hasErrors()) {
- CompilationAndWeavingContext.leavingPhase(ct);
- if (AsmManager.isReporting()) {
- state.getStructureModel().reportModelInfo("After a batch build");
- }
- return false;
- }
-
- if (AsmManager.isReporting()) {
- state.getStructureModel().reportModelInfo("After a batch build");
- }
-
- } else {
- // done already?
- // if (buildConfig.isEmacsSymMode() || buildConfig.isGenerateModelMode()) {
- // bcelWorld.setModel(StructureModelManager.INSTANCE.getStructureModel());
- // }
- // System.err.println("XXXX start inc ");
- AsmManager.setLastActiveStructureModel(state.getStructureModel());
- binarySourcesForTheNextCompile = state.getBinaryFilesToCompile(true);
- Set<File> files = state.getFilesToCompile(true);
- if (buildConfig.isEmacsSymMode() || buildConfig.isGenerateModelMode()) {
- if (AsmManager.attemptIncrementalModelRepairs) {
- state.getStructureModel().resetDeltaProcessing();
- state.getStructureModel().processDelta(files, state.getAddedFiles(), state.getDeletedFiles());
- }
- }
- boolean hereWeGoAgain = !(files.isEmpty() && binarySourcesForTheNextCompile.isEmpty());
- for (int i = 0; (i < 5) && hereWeGoAgain; i++) {
- if (state.listenerDefined()) {
- state.getListener()
- .recordInformation("Starting incremental compilation loop " + (i + 1) + " of possibly 5");
- // System.err.println("XXXX inc: " + files);
- }
-
- performCompilation(files);
- if ((!proceedOnError() && handler.hasErrors())
- || (progressListener != null && progressListener.isCancelledRequested())) {
- CompilationAndWeavingContext.leavingPhase(ct);
- return false;
- }
-
- if (state.requiresFullBatchBuild()) {
- if (state.listenerDefined()) {
- state.getListener().recordInformation(" Dropping back to full build");
- }
- return batchBuild(buildConfig, baseHandler);
- }
-
- binarySourcesForTheNextCompile = state.getBinaryFilesToCompile(false);
- files = state.getFilesToCompile(false);
- hereWeGoAgain = !(files.isEmpty() && binarySourcesForTheNextCompile.isEmpty());
- // TODO Andy - Needs some thought here...
- // I think here we might want to pass empty addedFiles/deletedFiles as they were
- // dealt with on the first call to processDelta - we are going through this loop
- // again because in compiling something we found something else we needed to
- // rebuild. But what case causes this?
- if (hereWeGoAgain) {
- if (buildConfig.isEmacsSymMode() || buildConfig.isGenerateModelMode()) {
- if (AsmManager.attemptIncrementalModelRepairs) {
- state.getStructureModel().processDelta(files, state.getAddedFiles(), state.getDeletedFiles());
- }
- }
- }
- }
- if (!files.isEmpty()) {
- CompilationAndWeavingContext.leavingPhase(ct);
- return batchBuild(buildConfig, baseHandler);
- } else {
- if (AsmManager.isReporting()) {
- state.getStructureModel().reportModelInfo("After an incremental build");
- }
- }
- }
-
- // XXX not in Mik's incremental
- if (buildConfig.isEmacsSymMode()) {
- new org.aspectj.ajdt.internal.core.builder.EmacsStructureModelManager().externalizeModel(state.getStructureModel());
- }
-
- // for bug 113554: support ajsym file generation for command line builds
- if (buildConfig.isGenerateCrossRefsMode()) {
- final File configFileProxy = new File(buildConfig.getOutputDir(), CROSSREFS_FILE_NAME);
- state.getStructureModel().writeStructureModel(configFileProxy.getAbsolutePath());
- }
-
- // have to tell state we succeeded or next is not incremental
- state.successfulCompile(buildConfig, isFullBuild);
-
- // For a full compile, copy resources to the destination
- // - they should not get deleted on incremental and AJDT
- // will handle changes to them that require a recopying
- if (isFullBuild) {
- copyResourcesToDestination();
- }
-
- if (buildConfig.getOutxmlName() != null) {
- writeOutxmlFile();
- }
-
- /* boolean weaved = */// weaveAndGenerateClassFiles();
- // if not weaved, then no-op build, no model changes
- // but always returns true
- // XXX weaved not in Mik's incremental
- if (buildConfig.isGenerateModelMode()) {
- state.getStructureModel().fireModelUpdated();
- }
- CompilationAndWeavingContext.leavingPhase(ct);
-
- } finally {
- if (baseHandler instanceof ILifecycleAware) {
- ((ILifecycleAware) baseHandler).buildFinished(!isFullBuild);
- }
- if (zos != null) {
- closeOutputStream(buildConfig.getOutputJar());
- }
- ret = !handler.hasErrors();
- if (getBcelWorld() != null) {
- final BcelWorld bcelWorld = getBcelWorld();
- bcelWorld.reportTimers();
- bcelWorld.tidyUp();
- }
- if (getWeaver() != null) {
- getWeaver().tidyUp();
- // bug 59895, don't release reference to handler as may be needed by a nested call
- // handler = null;
- }
- }
- return ret;
- }
-
- /**
- * Open an output jar file in which to write the compiler output.
- *
- * @param outJar the jar file to open
- * @return true if successful
- */
- private boolean openOutputStream(File outJar) {
- try {
- OutputStream os = FileUtil.makeOutputStream(buildConfig.getOutputJar());
- zos = new JarOutputStream(os, getWeaver().getManifest(true));
- } catch (IOException ex) {
- IMessage message = new Message("Unable to open outjar " + outJar.getPath() + "(" + ex.getMessage() + ")",
- new SourceLocation(outJar, 0), true);
- handler.handleMessage(message);
- return false;
- }
- return true;
- }
-
- private void closeOutputStream(File outJar) {
- try {
- if (zos != null) {
- zos.close();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- buildConfig.getCompilationResultDestinationManager().reportFileWrite(outJar.getPath(),
- CompilationResultDestinationManager.FILETYPE_OUTJAR);
- }
- }
- zos = null;
-
- /* Ensure we don't write an incomplete JAR bug-71339 */
- if (handler.hasErrors()) {
- outJar.delete();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- buildConfig.getCompilationResultDestinationManager().reportFileRemove(outJar.getPath(),
- CompilationResultDestinationManager.FILETYPE_OUTJAR);
- }
- }
- } catch (IOException ex) {
- IMessage message = new Message("Unable to write outjar " + outJar.getPath() + "(" + ex.getMessage() + ")",
- new SourceLocation(outJar, 0), true);
- handler.handleMessage(message);
- }
- }
-
- private void copyResourcesToDestination() throws IOException {
- // resources that we need to copy are contained in the injars and inpath only
- for (Iterator i = buildConfig.getInJars().iterator(); i.hasNext();) {
- File inJar = (File) i.next();
- copyResourcesFromJarFile(inJar);
- }
-
- for (Iterator i = buildConfig.getInpath().iterator(); i.hasNext();) {
- File inPathElement = (File) i.next();
- if (inPathElement.isDirectory()) {
- copyResourcesFromDirectory(inPathElement);
- } else {
- copyResourcesFromJarFile(inPathElement);
- }
- }
-
- if (buildConfig.getSourcePathResources() != null) {
- for (Iterator i = buildConfig.getSourcePathResources().keySet().iterator(); i.hasNext();) {
- String resource = (String) i.next();
- File from = buildConfig.getSourcePathResources().get(resource);
- copyResourcesFromFile(from, resource, from);
- }
- }
-
- writeManifest();
- }
-
- private void copyResourcesFromJarFile(File jarFile) throws IOException {
- JarInputStream inStream = null;
- try {
- inStream = new JarInputStream(new FileInputStream(jarFile));
- while (true) {
- ZipEntry entry = inStream.getNextEntry();
- if (entry == null) {
- break;
- }
-
- String filename = entry.getName();
- // System.out.println("? copyResourcesFromJarFile() filename='" + filename +"'");
- if (entry.isDirectory()) {
- writeDirectory(filename, jarFile);
- } else if (acceptResource(filename, false)) {
- byte[] bytes = FileUtil.readAsByteArray(inStream);
- writeResource(filename, bytes, jarFile);
- }
-
- inStream.closeEntry();
- }
- } finally {
- if (inStream != null) {
- inStream.close();
- }
- }
- }
-
- private void copyResourcesFromDirectory(File dir) throws IOException {
- if (!COPY_INPATH_DIR_RESOURCES) {
- return;
- }
- // Get a list of all files (i.e. everything that isnt a directory)
- File[] files = FileUtil.listFiles(dir, new FileFilter() {
- @Override
- public boolean accept(File f) {
- boolean accept = !(f.isDirectory() || f.getName().endsWith(".class"));
- return accept;
- }
- });
-
- // For each file, add it either as a real .class file or as a resource
- for (int i = 0; i < files.length; i++) {
- // ASSERT: files[i].getAbsolutePath().startsWith(inFile.getAbsolutePath()
- // or we are in trouble...
- String filename = files[i].getAbsolutePath().substring(dir.getAbsolutePath().length() + 1);
- copyResourcesFromFile(files[i], filename, dir);
- }
- }
-
- private void copyResourcesFromFile(File f, String filename, File src) throws IOException {
- if (!acceptResource(filename, true)) {
- return;
- }
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(f);
- byte[] bytes = FileUtil.readAsByteArray(fis);
- // String relativePath = files[i].getPath();
-
- writeResource(filename, bytes, src);
- } catch (FileNotFoundException fnfe) {
- // pr359332: looks like the file moved (refactoring?) just as this copy was starting
- // that is OK
- } finally {
- if (fis != null) {
- fis.close();
- }
- }
- }
-
- /**
- * Add a directory entry to the output zip file. Don't do anything if not writing out to a zip file. A directory entry is one
- * whose filename ends with '/'
- *
- * @param directory the directory path
- * @param srcloc the src of the directory entry, for use when creating a warning message
- * @throws IOException if something goes wrong creating the new zip entry
- */
- private void writeDirectory(String directory, File srcloc) throws IOException {
- if (state.hasResource(directory)) {
- IMessage msg = new Message("duplicate resource: '" + directory + "'", IMessage.WARNING, null, new SourceLocation(
- srcloc, 0));
- handler.handleMessage(msg);
- return;
- }
- if (zos != null) {
- ZipEntry newEntry = new ZipEntry(directory);
- zos.putNextEntry(newEntry);
- zos.closeEntry();
- state.recordResource(directory, srcloc);
- }
- // Nothing to do if not writing to a zip file
- }
-
- private void writeResource(String filename, byte[] content, File srcLocation) throws IOException {
- if (state.hasResource(filename)) {
- IMessage msg = new Message("duplicate resource: '" + filename + "'", IMessage.WARNING, null, new SourceLocation(
- srcLocation, 0));
- handler.handleMessage(msg);
- return;
- }
- if (filename.equals(buildConfig.getOutxmlName())) {
- ignoreOutxml = true;
- IMessage msg = new Message("-outxml/-outxmlfile option ignored because resource already exists: '" + filename + "'",
- IMessage.WARNING, null, new SourceLocation(srcLocation, 0));
- handler.handleMessage(msg);
- }
- if (zos != null) {
- ZipEntry newEntry = new ZipEntry(filename); // ??? get compression scheme right
- zos.putNextEntry(newEntry);
- zos.write(content);
- zos.closeEntry();
- } else {
- File destDir = buildConfig.getOutputDir();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- destDir = buildConfig.getCompilationResultDestinationManager().getOutputLocationForResource(srcLocation);
- }
- try {
- File outputLocation = new File(destDir, filename);
- OutputStream fos = FileUtil.makeOutputStream(outputLocation);
- fos.write(content);
- fos.close();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- buildConfig.getCompilationResultDestinationManager().reportFileWrite(outputLocation.getPath(),
- CompilationResultDestinationManager.FILETYPE_RESOURCE);
- }
- } catch (FileNotFoundException fnfe) {
- IMessage msg = new Message("unable to copy resource to output folder: '" + filename + "' - reason: "
- + fnfe.getMessage(), IMessage.ERROR, null, new SourceLocation(srcLocation, 0));
- handler.handleMessage(msg);
- }
- }
- state.recordResource(filename, srcLocation);
- }
-
- /*
- * If we are writing to an output directory copy the manifest but only if we already have one
- */
- private void writeManifest() throws IOException {
- Manifest manifest = getWeaver().getManifest(false);
- if (manifest != null && zos == null) {
- File outputDir = buildConfig.getOutputDir();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- // Manifests are only written if we have a jar on the inpath. Therefore,
- // we write the manifest to the defaultOutputLocation because this is
- // where we sent the classes that were on the inpath
- outputDir = buildConfig.getCompilationResultDestinationManager().getDefaultOutputLocation();
- }
- if (outputDir == null) {
- return;
- }
- File outputLocation = new File(outputDir, MANIFEST_NAME);
- OutputStream fos = FileUtil.makeOutputStream(outputLocation);
- manifest.write(fos);
- fos.close();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- buildConfig.getCompilationResultDestinationManager().reportFileWrite(outputLocation.getPath(),
- CompilationResultDestinationManager.FILETYPE_RESOURCE);
- }
- }
- }
-
- private boolean acceptResource(String resourceName, boolean fromFile) {
- if ((resourceName.startsWith("CVS/")) || (resourceName.indexOf("/CVS/") != -1) || (resourceName.endsWith("/CVS"))
- || (resourceName.endsWith(".class")) || (resourceName.startsWith(".svn/"))
- || (resourceName.indexOf("/.svn/") != -1) || (resourceName.endsWith("/.svn")) ||
- // Do not copy manifests if either they are coming from a jar or we are writing to a jar
- (resourceName.toUpperCase().equals(MANIFEST_NAME) && (!fromFile || zos != null))) {
- return false;
- } else {
- return true;
- }
- }
-
- private void writeOutxmlFile() throws IOException {
- if (ignoreOutxml) {
- return;
- }
-
- String filename = buildConfig.getOutxmlName();
- // System.err.println("? AjBuildManager.writeOutxmlFile() outxml=" + filename);
-
- Map<File, List<String>> outputDirsAndAspects = findOutputDirsForAspects();
- Set<Map.Entry<File, List<String>>> outputDirs = outputDirsAndAspects.entrySet();
- for (Iterator<Map.Entry<File, List<String>>> iterator = outputDirs.iterator(); iterator.hasNext();) {
- Map.Entry<File, List<String>> entry = iterator.next();
- File outputDir = entry.getKey();
- List<String> aspects = entry.getValue();
- ByteArrayOutputStream baos = getOutxmlContents(aspects);
- if (zos != null) {
- ZipEntry newEntry = new ZipEntry(filename);
-
- zos.putNextEntry(newEntry);
- zos.write(baos.toByteArray());
- zos.closeEntry();
- } else {
- File outputFile = new File(outputDir, filename);
- OutputStream fos = FileUtil.makeOutputStream(outputFile);
- fos.write(baos.toByteArray());
- fos.close();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- buildConfig.getCompilationResultDestinationManager().reportFileWrite(outputFile.getPath(),
- CompilationResultDestinationManager.FILETYPE_RESOURCE);
- }
- }
- }
- }
-
- private ByteArrayOutputStream getOutxmlContents(List aspectNames) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(baos);
- ps.println("<aspectj>");
- ps.println("<aspects>");
- if (aspectNames != null) {
- for (Iterator i = aspectNames.iterator(); i.hasNext();) {
- String name = (String) i.next();
- ps.println("<aspect name=\"" + name + "\"/>");
- }
- }
- ps.println("</aspects>");
- ps.println("</aspectj>");
- ps.println();
- ps.close();
- return baos;
- }
-
- /**
- * Returns a map where the keys are File objects corresponding to all the output directories and the values are a list of
- * aspects which are sent to that ouptut directory
- */
- private Map<File, List<String>> findOutputDirsForAspects() {
- Map<File, List<String>> outputDirsToAspects = new HashMap<File, List<String>>();
- Map<String, char[]> aspectNamesToFileNames = state.getAspectNamesToFileNameMap();
- if (buildConfig.getCompilationResultDestinationManager() == null
- || buildConfig.getCompilationResultDestinationManager().getAllOutputLocations().size() == 1) {
- // we only have one output directory...which simplifies things
- File outputDir = buildConfig.getOutputDir();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- outputDir = buildConfig.getCompilationResultDestinationManager().getDefaultOutputLocation();
- }
- List<String> aspectNames = new ArrayList<String>();
- if (aspectNamesToFileNames != null) {
- Set<String> keys = aspectNamesToFileNames.keySet();
- for (String name : keys) {
- aspectNames.add(name);
- }
- }
- outputDirsToAspects.put(outputDir, aspectNames);
- } else {
- List outputDirs = buildConfig.getCompilationResultDestinationManager().getAllOutputLocations();
- for (Iterator iterator = outputDirs.iterator(); iterator.hasNext();) {
- File outputDir = (File) iterator.next();
- outputDirsToAspects.put(outputDir, new ArrayList<String>());
- }
- if (aspectNamesToFileNames != null) {
- Set<Map.Entry<String, char[]>> entrySet = aspectNamesToFileNames.entrySet();
- for (Iterator<Map.Entry<String, char[]>> iterator = entrySet.iterator(); iterator.hasNext();) {
- Map.Entry<String, char[]> entry = iterator.next();
- String aspectName = entry.getKey();
- char[] fileName = entry.getValue();
- File outputDir = buildConfig.getCompilationResultDestinationManager().getOutputLocationForClass(
- new File(new String(fileName)));
- if (!outputDirsToAspects.containsKey(outputDir)) {
- outputDirsToAspects.put(outputDir, new ArrayList<String>());
- }
- ((List) outputDirsToAspects.get(outputDir)).add(aspectName);
- }
- }
- }
- return outputDirsToAspects;
- }
-
- // public static void dumprels() {
- // IRelationshipMap irm = AsmManager.getDefault().getRelationshipMap();
- // int ctr = 1;
- // Set entries = irm.getEntries();
- // for (Iterator iter = entries.iterator(); iter.hasNext();) {
- // String hid = (String) iter.next();
- // List rels = irm.get(hid);
- // for (Iterator iterator = rels.iterator(); iterator.hasNext();) {
- // IRelationship ir = (IRelationship) iterator.next();
- // List targets = ir.getTargets();
- // for (Iterator iterator2 = targets.iterator();
- // iterator2.hasNext();
- // ) {
- // String thid = (String) iterator2.next();
- // System.err.println("Hid:"+(ctr++)+":(targets="+targets.size()+") "+hid+" ("+ir.getName()+") "+thid);
- // }
- // }
- // }
- // }
-
- /**
- * Responsible for managing the ASM model between builds. Contains the policy for maintaining the persistance of elements in the
- * model.
- *
- * This code is driven before each 'fresh' (batch) build to create a new model.
- */
- private void setupModel(AjBuildConfig config) {
- if (!(config.isEmacsSymMode() || config.isGenerateModelMode())) {
- return;
- }
- // AsmManager.setCreatingModel(config.isEmacsSymMode() || config.isGenerateModelMode());
- // if (!AsmManager.isCreatingModel())
- // return;
-
- CompilationResultDestinationManager crdm = config.getCompilationResultDestinationManager();
- AsmManager structureModel = AsmManager.createNewStructureModel(crdm == null ? Collections.EMPTY_MAP : crdm.getInpathMap());
- // AsmManager.getDefault().getRelationshipMap().clear();
- IHierarchy model = structureModel.getHierarchy();
- String rootLabel = "<root>";
-
- IProgramElement.Kind kind = IProgramElement.Kind.FILE_JAVA;
- if (buildConfig.getConfigFile() != null) {
- rootLabel = buildConfig.getConfigFile().getName();
- model.setConfigFile(buildConfig.getConfigFile().getAbsolutePath());
- kind = IProgramElement.Kind.FILE_LST;
- }
- model.setRoot(new ProgramElement(structureModel, rootLabel, kind, new ArrayList()));
-
- model.setFileMap(new HashMap<String, IProgramElement>());
- // setStructureModel(model);
- state.setStructureModel(structureModel);
- // state.setRelationshipMap(AsmManager.getDefault().getRelationshipMap());
- }
-
- //
- // private void dumplist(List l) {
- // System.err.println("---- "+l.size());
- // for (int i =0 ;i<l.size();i++) System.err.println(i+"\t "+l.get(i));
- // }
- // private void accumulateFileNodes(IProgramElement ipe,List store) {
- // if (ipe.getKind()==IProgramElement.Kind.FILE_JAVA ||
- // ipe.getKind()==IProgramElement.Kind.FILE_ASPECTJ) {
- // if (!ipe.getName().equals("<root>")) {
- // store.add(ipe);
- // return;
- // }
- // }
- // for (Iterator i = ipe.getChildren().iterator();i.hasNext();) {
- // accumulateFileNodes((IProgramElement)i.next(),store);
- // }
- // }
-
- // LTODO delegate to BcelWeaver?
- // XXX hideous, should not be Object
- public void setCustomMungerFactory(Object o) {
- customMungerFactory = (CustomMungerFactory) o;
- }
-
- public Object getCustomMungerFactory() {
- return customMungerFactory;
- }
-
- /** init only on initial batch compile? no file-specific options */
- private void initBcelWorld(IMessageHandler handler) throws IOException {
- List cp = buildConfig.getFullClasspath(); // pr145693
- // buildConfig.getBootclasspath();
- // cp.addAll(buildConfig.getClasspath());
- BcelWorld bcelWorld = new BcelWorld(cp, handler, null);
- bcelWorld.setBehaveInJava5Way(buildConfig.getBehaveInJava5Way());
- bcelWorld.setTiming(buildConfig.isTiming(), false);
- bcelWorld.setAddSerialVerUID(buildConfig.isAddSerialVerUID());
- bcelWorld.setXmlConfigured(buildConfig.isXmlConfigured());
- bcelWorld.setXmlFiles(buildConfig.getXmlFiles());
- bcelWorld.performExtraConfiguration(buildConfig.getXconfigurationInfo());
- bcelWorld.setTargetAspectjRuntimeLevel(buildConfig.getTargetAspectjRuntimeLevel());
- bcelWorld.setOptionalJoinpoints(buildConfig.getXJoinpoints());
- bcelWorld.setXnoInline(buildConfig.isXnoInline());
- bcelWorld.setXlazyTjp(buildConfig.isXlazyTjp());
- bcelWorld.setXHasMemberSupportEnabled(buildConfig.isXHasMemberEnabled());
- bcelWorld.setPinpointMode(buildConfig.isXdevPinpoint());
- bcelWorld.setErrorAndWarningThreshold(buildConfig.getOptions().errorThreshold.isSet(24), buildConfig.getOptions().warningThreshold.isSet(24));
- BcelWeaver bcelWeaver = new BcelWeaver(bcelWorld);
- bcelWeaver.setCustomMungerFactory(customMungerFactory);
- state.setWorld(bcelWorld);
- state.setWeaver(bcelWeaver);
- state.clearBinarySourceFiles();
-
- if (buildConfig.getLintMode().equals(AjBuildConfig.AJLINT_DEFAULT)) {
- bcelWorld.getLint().loadDefaultProperties();
- } else {
- bcelWorld.getLint().setAll(buildConfig.getLintMode());
- }
- if (buildConfig.getLintOptionsMap() != null) {
- bcelWorld.getLint().setFromMap(buildConfig.getLintOptionsMap());
- }
- if (buildConfig.getLintSpecFile() != null) {
- bcelWorld.getLint().setFromProperties(buildConfig.getLintSpecFile());
- }
-
- for (File f: buildConfig.getAspectpath()) {
- if (!f.exists()) {
- IMessage message = new Message("invalid aspectpath entry: " + f.getName(), null, true);
- handler.handleMessage(message);
- } else {
- bcelWeaver.addLibraryJarFile(f);
- }
- }
-
- // String lintMode = buildConfig.getLintMode();
-
- File outputDir = buildConfig.getOutputDir();
- if (outputDir == null && buildConfig.getCompilationResultDestinationManager() != null) {
- // send all output from injars and inpath to the default output location
- // (will also later send the manifest there too)
- outputDir = buildConfig.getCompilationResultDestinationManager().getDefaultOutputLocation();
- }
- // ??? incremental issues
- for (File inJar : buildConfig.getInJars()) {
- List<UnwovenClassFile> unwovenClasses = bcelWeaver.addJarFile(inJar, outputDir, false);
- state.recordBinarySource(inJar.getPath(), unwovenClasses);
- }
-
- for (File inPathElement : buildConfig.getInpath()) {
- if (!inPathElement.isDirectory()) {
- // its a jar file on the inpath
- // the weaver method can actually handle dirs, but we don't call it, see next block
- List<UnwovenClassFile> unwovenClasses = bcelWeaver.addJarFile(inPathElement, outputDir, true);
- state.recordBinarySource(inPathElement.getPath(), unwovenClasses);
- } else {
- // add each class file in an in-dir individually, this gives us the best error reporting
- // (they are like 'source' files then), and enables a cleaner incremental treatment of
- // class file changes in indirs.
- File[] binSrcs = FileUtil.listFiles(inPathElement, binarySourceFilter);
- for (int j = 0; j < binSrcs.length; j++) {
- UnwovenClassFile ucf = bcelWeaver.addClassFile(binSrcs[j], inPathElement, outputDir);
- List<UnwovenClassFile> ucfl = new ArrayList<UnwovenClassFile>();
- ucfl.add(ucf);
- state.recordBinarySource(binSrcs[j].getPath(), ucfl);
- }
- }
- }
-
- bcelWeaver.setReweavableMode(buildConfig.isXNotReweavable());
-
- // check for org.aspectj.runtime.JoinPoint
- ResolvedType joinPoint = bcelWorld.resolve("org.aspectj.lang.JoinPoint");
- if (joinPoint.isMissing()) {
- IMessage message = new Message(
- "classpath error: unable to find org.aspectj.lang.JoinPoint (check that aspectjrt.jar is in your classpath)",
- null, true);
- handler.handleMessage(message);
- }
- }
-
- public World getWorld() {
- return getBcelWorld();
- }
-
- // void addAspectClassFilesToWeaver(List addedClassFiles) throws IOException {
- // for (Iterator i = addedClassFiles.iterator(); i.hasNext();) {
- // UnwovenClassFile classFile = (UnwovenClassFile) i.next();
- // getWeaver().addClassFile(classFile);
- // }
- // }
-
- public FileSystem getLibraryAccess(String[] classpaths, String[] filenames) {
- String defaultEncoding = buildConfig.getOptions().defaultEncoding;
- if ("".equals(defaultEncoding)) {//$NON-NLS-1$
- defaultEncoding = null;
- }
- // Bug 46671: We need an array as long as the number of elements in the classpath - *even though* not every
- // element of the classpath is likely to be a directory. If we ensure every element of the array is set to
- // only look for BINARY, then we make sure that for any classpath element that is a directory, we won't build
- // a classpathDirectory object that will attempt to look for source when it can't find binary.
- // int[] classpathModes = new int[classpaths.length];
- // for (int i =0 ;i<classpaths.length;i++) classpathModes[i]=ClasspathDirectory.BINARY;
-
- FileSystem nameEnvironment = null;
- // TODO J9 The compiler likes to work in terms of checked classpath objects - these will be different
- // depending on where the code came from (classpath, modulepath). If working with just the raw
- // 'classpaths' object it isn't recording where the code came from. This will be an issue later for
- // weaving, the distinction will need to be maintained for proper 'module aware/respecting' weaving.
- if (buildConfig.getCheckedClasspaths() == null) {
- nameEnvironment = new FileSystem(classpaths, filenames, defaultEncoding, ClasspathLocation.BINARY, null);
- } else {
- nameEnvironment = new FileSystem(buildConfig.getCheckedClasspaths(), filenames, false, null);
- }
- nameEnvironment.module = buildConfig.getModuleDesc();
- return nameEnvironment;
- }
-
- public IProblemFactory getProblemFactory() {
- return new DefaultProblemFactory(Locale.getDefault());
- }
-
- /*
- * Build the set of compilation source units
- */
- public CompilationUnit[] getCompilationUnits(String[] filenames) {
- int fileCount = filenames.length;
- CompilationUnit[] units = new CompilationUnit[fileCount];
- // HashtableOfObject knownFileNames = new HashtableOfObject(fileCount);
-
- String defaultEncoding = buildConfig.getOptions().defaultEncoding;
- if ("".equals(defaultEncoding)) {//$NON-NLS-1$
- defaultEncoding = null;
- }
- CompilationUnit moduleCU = null;
-
- // TODO building with multiple module-infos?
- int moduleIndex = -1;
- IModule moduleDesc = buildConfig.getModuleDesc();
- String moduleName = moduleDesc == null? null: new String(moduleDesc.name());
- for (int i=0;i<fileCount;i++) {
- if (filenames[i].endsWith("module-info.java")) {
- moduleIndex = i;
- moduleCU = new CompilationUnit(null, filenames[i], defaultEncoding, null, false, moduleName);
- }
- }
-
- for (int i = 0; i < fileCount; i++) {
- // units[i] = new CompilationUnit(null, filenames[i], defaultEncoding);
- if (i == moduleIndex) {
- units[i] = moduleCU;
- } else {
- units[i] = new CompilationUnit(null, filenames[i], defaultEncoding, null, false, moduleName);
- // With Java 10 changes the modulebinding is fetched from the rootenvironment
- // this.moduleBinding = rootEnvironment.getModule(this.module);
- // rather than using the moduleCU:
- // if (this.modCU != null)
- // return this.moduleBinding = this.modCU.module(rootEnvironment);
- // units[i].setModule(moduleCU);
- }
- // new CompilationUnit(null, fileName, encoding, this.destinationPaths[i],
- // shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, fileName.toCharArray()),
- // this.modNames[i]);
- }
- return units;
- }
-
- public String extractDestinationPathFromSourceFile(CompilationResult result) {
- ICompilationUnit compilationUnit = result.compilationUnit;
- if (compilationUnit != null) {
- char[] fileName = compilationUnit.getFileName();
- int lastIndex = CharOperation.lastIndexOf(java.io.File.separatorChar, fileName);
- if (lastIndex == -1) {
- return System.getProperty("user.dir"); //$NON-NLS-1$
- }
- return new String(CharOperation.subarray(fileName, 0, lastIndex));
- }
- return System.getProperty("user.dir"); //$NON-NLS-1$
- }
-
- public void performCompilation(Collection<File> files) {
- if (progressListener != null) {
- compiledCount = 0;
- sourceFileCount = files.size();
- progressListener.setText("compiling source files");
- }
-
- // Translate from strings to File objects
- String[] filenames = new String[files.size()];
- int idx = 0;
- for (Iterator<File> fIterator = files.iterator(); fIterator.hasNext();) {
- File f = fIterator.next();
- filenames[idx++] = f.getPath();
- }
-
- environment = state.getNameEnvironment();
-
- boolean environmentNeedsRebuilding = false;
-
- // Might be a bit too cautious, but let us see how it goes
- if (buildConfig.getChanged() != AjBuildConfig.NO_CHANGES) {
- environmentNeedsRebuilding = true;
- }
-
- if (environment == null || environmentNeedsRebuilding) {
- List<String> cps = buildConfig.getFullClasspath();
- Dump.saveFullClasspath(cps);
- String[] classpaths = new String[cps.size()];
- for (int i = 0; i < cps.size(); i++) {
- classpaths[i] = cps.get(i);
- }
- FileSystem fileSystem = getLibraryAccess(classpaths, filenames);
- environment = new StatefulNameEnvironment(fileSystem, state.getClassNameToFileMap(), state);
- state.setFileSystem(fileSystem);
- state.setNameEnvironment(environment);
- } else {
- ((StatefulNameEnvironment) environment).update(state.getClassNameToFileMap(), state.deltaAddedClasses);
- state.deltaAddedClasses.clear();
- }
-
- org.aspectj.ajdt.internal.compiler.CompilerAdapter.setCompilerAdapterFactory(this);
- final Map<String, String> settings = buildConfig.getOptions().getMap();
- final BuildArgParser bMain = buildConfig.getBuildArgParser();
-
- final org.aspectj.org.eclipse.jdt.internal.compiler.Compiler compiler = new org.aspectj.org.eclipse.jdt.internal.compiler.Compiler(
- environment, DefaultErrorHandlingPolicies.proceedWithAllProblems(), settings,
- getBatchRequestor(), getProblemFactory());
- bMain.compilerOptions = compiler.options;
- bMain.batchCompiler = compiler;
- bMain.initializeAnnotationProcessorManager();
- compiler.options.produceReferenceInfo = true; // TODO turn off when not needed
-
-
- if (bMain.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_6
- && bMain.compilerOptions.processAnnotations) {
- // need this too?
- // if (bMain.checkVMVersion(ClassFileConstants.JDK1_6)) {
- // initializeAnnotationProcessorManager();
- // if (this.classNames != null) {
- // this.batchCompiler.setBinaryTypes(processClassNames(this.batchCompiler.lookupEnvironment));
- // }
- // } else {
- // // report a warning
- // this.logger.logIncorrectVMVersionForAnnotationProcessing();
- // }
- if (bMain.checkVMVersion(ClassFileConstants.JDK9)) {
- try {
- bMain.initRootModules(bMain.batchCompiler.lookupEnvironment, state.getFileSystem());
- } catch (IllegalArgumentException iae) {
- ISourceLocation location = null;
- if (buildConfig.getConfigFile() != null) {
- location = new SourceLocation(buildConfig.getConfigFile(), 0);
- }
- IMessage m = new Message(iae.getMessage(), IMessage.ERROR, null, location);
- handler.handleMessage(m);
- }
- }
- }
-
- try {
- compiler.compile(getCompilationUnits(filenames));
- } catch (OperationCanceledException oce) {
- handler.handleMessage(new Message("build cancelled:" + oce.getMessage(), IMessage.WARNING, null, null));
- }
- // cleanup
- org.aspectj.ajdt.internal.compiler.CompilerAdapter.setCompilerAdapterFactory(null);
- AnonymousClassPublisher.aspectOf().setAnonymousClassCreationListener(null);
- environment.cleanup();
- // environment = null;
- }
-
- public void cleanupEnvironment() {
- if (environment != null) {
- environment.cleanup();
- environment = null;
- // le = null;
- }
- }
-
- /*
- * Answer the component to which will be handed back compilation results from the compiler
- */
- public IIntermediateResultsRequestor getInterimResultRequestor() {
- return new IIntermediateResultsRequestor() {
- @Override
- public void acceptResult(InterimCompilationResult result) {
- if (progressListener != null) {
- compiledCount++;
- progressListener.setProgress((compiledCount / 2.0) / sourceFileCount);
- progressListener.setText("compiled: " + result.fileName());
- }
- state.noteResult(result);
-
- if (progressListener != null && progressListener.isCancelledRequested()) {
- throw new AbortCompilation(true, new OperationCanceledException("Compilation cancelled as requested"));
- }
- }
- };
- }
-
- public ICompilerRequestor getBatchRequestor() {
- return new ICompilerRequestor() {
- @Override
- public void acceptResult(CompilationResult unitResult) {
- // end of compile, must now write the results to the output destination
- // this is either a jar file or a file in a directory
- boolean hasErrors = unitResult.hasErrors();
- if (!hasErrors || proceedOnError()) {
- Collection<ClassFile> classFiles = unitResult.compiledTypes.values();
- boolean shouldAddAspectName = (buildConfig.getOutxmlName() != null);
- for (Iterator<ClassFile> iter = classFiles.iterator(); iter.hasNext();) {
- ClassFile classFile = iter.next();
- String filename = new String(classFile.fileName());
- String classname = filename.replace('/', '.');
- filename = filename.replace('/', File.separatorChar) + ".class";
-
- try {
- if (buildConfig.getOutputJar() == null) {
- String outfile = writeDirectoryEntry(unitResult, classFile, filename);
- getWorld().classWriteEvent(classFile.getCompoundName());
- if (environmentSupportsIncrementalCompilation) {
- if (!classname.endsWith("$ajcMightHaveAspect")) {
- ResolvedType type = getBcelWorld().resolve(classname);
- if (type.isAspect()) {
- state.recordAspectClassFile(outfile);
- }
- }
- }
- } else {
- writeZipEntry(classFile, filename);
- }
- if (shouldAddAspectName && !classname.endsWith("$ajcMightHaveAspect")) {
- addAspectName(classname, unitResult.getFileName());
- }
- } catch (IOException ex) {
- IMessage message = EclipseAdapterUtils.makeErrorMessage(new String(unitResult.fileName),
- CANT_WRITE_RESULT, ex);
- handler.handleMessage(message);
- }
-
- }
- state.noteNewResult(unitResult);
- unitResult.compiledTypes.clear(); // free up references to AjClassFile instances
- }
-
- if (unitResult.hasProblems() || unitResult.hasTasks()) {
- IProblem[] problems = unitResult.getAllProblems();
- for (int i = 0; i < problems.length; i++) {
- IMessage message = EclipseAdapterUtils.makeMessage(unitResult.compilationUnit, problems[i], getBcelWorld(),
- progressListener);
- handler.handleMessage(message);
- }
- }
-
- }
-
- private String writeDirectoryEntry(CompilationResult unitResult, ClassFile classFile, String filename)
- throws IOException {
- File destinationPath = buildConfig.getOutputDir();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- destinationPath = buildConfig.getCompilationResultDestinationManager().getOutputLocationForClass(
- new File(new String(unitResult.fileName)));
- }
- String outFile;
- if (destinationPath == null) {
- outFile = new File(filename).getName();
- outFile = new File(extractDestinationPathFromSourceFile(unitResult), outFile).getPath();
- } else {
- outFile = new File(destinationPath, filename).getPath();
- }
-
- try {
- BufferedOutputStream os = FileUtil.makeOutputStream(new File(outFile));
- os.write(classFile.getBytes());
- os.close();
- } catch (FileNotFoundException fnfe) {
- IMessage msg = new Message("unable to write out class file: '" + filename + "' - reason: " + fnfe.getMessage(),
- IMessage.ERROR, null, new SourceLocation(new File(outFile), 0));
- handler.handleMessage(msg);
- }
-
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- buildConfig.getCompilationResultDestinationManager().reportFileWrite(outFile,
- CompilationResultDestinationManager.FILETYPE_CLASS);
- }
- return outFile;
- }
-
- private void writeZipEntry(ClassFile classFile, String name) throws IOException {
- name = name.replace(File.separatorChar, '/');
- ZipEntry newEntry = new ZipEntry(name); // ??? get compression scheme right
-
- zos.putNextEntry(newEntry);
- zos.write(classFile.getBytes());
- zos.closeEntry();
- }
-
- private void addAspectName(String name, char[] fileContainingAspect) {
- BcelWorld world = getBcelWorld();
- ResolvedType type = world.resolve(name);
- // System.err.println("? writeAspectName() type=" + type);
- if (type.isAspect()) {
- if (state.getAspectNamesToFileNameMap() == null) {
- state.initializeAspectNamesToFileNameMap();
- }
- if (!state.getAspectNamesToFileNameMap().containsKey(name)) {
- state.getAspectNamesToFileNameMap().put(name, fileContainingAspect);
- }
- }
- }
- };
- }
-
- protected boolean proceedOnError() {
- return buildConfig.getProceedOnError();
- }
-
- // public void noteClassFiles(AjCompiler.InterimResult result) {
- // if (result == null) return;
- // CompilationResult unitResult = result.result;
- // String sourceFileName = result.fileName();
- // if (!(unitResult.hasErrors() && !proceedOnError())) {
- // List unwovenClassFiles = new ArrayList();
- // Enumeration classFiles = unitResult.compiledTypes.elements();
- // while (classFiles.hasMoreElements()) {
- // ClassFile classFile = (ClassFile) classFiles.nextElement();
- // String filename = new String(classFile.fileName());
- // filename = filename.replace('/', File.separatorChar) + ".class";
- //
- // File destinationPath = buildConfig.getOutputDir();
- // if (destinationPath == null) {
- // filename = new File(filename).getName();
- // filename = new File(extractDestinationPathFromSourceFile(unitResult), filename).getPath();
- // } else {
- // filename = new File(destinationPath, filename).getPath();
- // }
- //
- // //System.out.println("classfile: " + filename);
- // unwovenClassFiles.add(new UnwovenClassFile(filename, classFile.getBytes()));
- // }
- // state.noteClassesFromFile(unitResult, sourceFileName, unwovenClassFiles);
- // // System.out.println("file: " + sourceFileName);
- // // for (int i=0; i < unitResult.simpleNameReferences.length; i++) {
- // // System.out.println("simple: " + new String(unitResult.simpleNameReferences[i]));
- // // }
- // // for (int i=0; i < unitResult.qualifiedReferences.length; i++) {
- // // System.out.println("qualified: " +
- // // new String(CharOperation.concatWith(unitResult.qualifiedReferences[i], '/')));
- // // }
- // } else {
- // state.noteClassesFromFile(null, sourceFileName, Collections.EMPTY_LIST);
- // }
- // }
- //
-
- private void setBuildConfig(AjBuildConfig buildConfig) {
- this.buildConfig = buildConfig;
- if (!this.environmentSupportsIncrementalCompilation) {
- this.environmentSupportsIncrementalCompilation = (buildConfig.isIncrementalMode() || buildConfig
- .isIncrementalFileMode());
- }
- handler.reset();
- }
-
- String makeClasspathString(AjBuildConfig buildConfig) {
- if (buildConfig == null || buildConfig.getFullClasspath() == null) {
- return "";
- }
- StringBuffer buf = new StringBuffer();
- boolean first = true;
- for (Iterator it = buildConfig.getFullClasspath().iterator(); it.hasNext();) {
- if (first) {
- first = false;
- } else {
- buf.append(File.pathSeparator);
- }
- buf.append(it.next().toString());
- }
- return buf.toString();
- }
-
- /**
- * This will return null if aspectjrt.jar is present and has the correct version. Otherwise it will return a string message
- * indicating the problem.
- */
- private String checkRtJar(AjBuildConfig buildConfig) {
- // omitting dev info
- if (Version.text.equals(Version.DEVELOPMENT)) {
- // in the development version we can't do this test usefully
- // MessageUtil.info(holder, "running development version of aspectj compiler");
- return null;
- }
-
- if (buildConfig == null || buildConfig.getFullClasspath() == null) {
- return "no classpath specified";
- }
-
- String ret = null;
- for (Iterator it = buildConfig.getFullClasspath().iterator(); it.hasNext();) {
- File p = new File((String) it.next());
- // pr112830, allow variations on aspectjrt.jar of the form aspectjrtXXXXXX.jar
- if (p.isFile() && p.getName().startsWith("aspectjrt") && p.getName().endsWith(".jar")) {
-
- try {
- String version = null;
- Manifest manifest = new JarFile(p).getManifest();
- if (manifest == null) {
- ret = "no manifest found in " + p.getAbsolutePath() + ", expected " + Version.text;
- continue;
- }
- Attributes attr = manifest.getAttributes("org/aspectj/lang/");
- if (null != attr) {
- version = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
- if (null != version) {
- version = version.trim();
- }
- }
- // assume that users of development aspectjrt.jar know what they're doing
- if (Version.DEVELOPMENT.equals(version)) {
- // MessageUtil.info(holder,
- // "running with development version of aspectjrt.jar in " +
- // p.getAbsolutePath());
- return null;
- } else if (!Version.text.equals(version)) {
- ret = "bad version number found in " + p.getAbsolutePath() + " expected " + Version.text + " found "
- + version;
- continue;
- }
- } catch (IOException ioe) {
- ret = "bad jar file found in " + p.getAbsolutePath() + " error: " + ioe;
- }
- return null; // this is the "OK" return value!
- } else if (p.isFile() && p.getName().indexOf("org.aspectj.runtime") != -1) {
- // likely to be a variant from the springsource bundle repo b272591
- return null;
- } else {
- // might want to catch other classpath errors
- }
- }
-
- if (ret != null) {
- return ret; // last error found in potentially matching jars...
- }
-
- return "couldn't find aspectjrt.jar on classpath, checked: " + makeClasspathString(buildConfig);
- }
-
- @Override
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append("AjBuildManager(");
- buf.append(")");
- return buf.toString();
- }
-
- //
- // public void setStructureModel(IHierarchy structureModel) {
- // this.structureModel = structureModel;
- // }
-
- /**
- * Returns null if there is no structure model
- */
- public AsmManager getStructureModel() {
- return (state == null ? null : state.getStructureModel());
- }
-
- public IProgressListener getProgressListener() {
- return progressListener;
- }
-
- public void setProgressListener(IProgressListener progressListener) {
- this.progressListener = progressListener;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.aspectj.ajdt.internal.compiler.AjCompiler.IOutputClassFileNameProvider#getOutputClassFileName(char[])
- */
- @Override
- public String getOutputClassFileName(char[] eclipseClassFileName, CompilationResult result) {
- String filename = new String(eclipseClassFileName);
- filename = filename.replace('/', File.separatorChar) + ".class";
- File destinationPath = buildConfig.getOutputDir();
- if (buildConfig.getCompilationResultDestinationManager() != null) {
- File f = new File(new String(result.getFileName()));
- destinationPath = buildConfig.getCompilationResultDestinationManager().getOutputLocationForClass(f);
- }
- String outFile;
- if (destinationPath == null) {
- outFile = new File(filename).getName();
- outFile = new File(extractDestinationPathFromSourceFile(result), outFile).getPath();
- } else {
- outFile = new File(destinationPath, filename).getPath();
- }
- return outFile;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jdt.internal.compiler.ICompilerAdapterFactory#getAdapter(org.eclipse.jdt.internal.compiler.Compiler)
- */
- @Override
- public ICompilerAdapter getAdapter(org.aspectj.org.eclipse.jdt.internal.compiler.Compiler forCompiler) {
- // complete compiler config and return a suitable adapter...
- populateCompilerOptionsFromLintSettings(forCompiler);
- AjProblemReporter pr = new AjProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(), forCompiler.options,
- getProblemFactory());
-
- forCompiler.problemReporter = pr;
-
- AjLookupEnvironment le = new AjLookupEnvironment(forCompiler, forCompiler.options, pr, environment);
- EclipseFactory factory = new EclipseFactory(le, this);
- le.factory = factory;
- pr.factory = factory;
-
- forCompiler.lookupEnvironment = le;
-
- forCompiler.parser = new Parser(pr, forCompiler.options.parseLiteralExpressionsAsConstants);
- if (getBcelWorld().shouldPipelineCompilation()) {
- IMessage message = MessageUtil.info("Pipelining compilation");
- handler.handleMessage(message);
- return new AjPipeliningCompilerAdapter(forCompiler, batchCompile, getBcelWorld(), getWeaver(), factory,
- getInterimResultRequestor(), progressListener,
- this, // IOutputFilenameProvider
- this, // IBinarySourceProvider
- state.getBinarySourceMap(), buildConfig.isTerminateAfterCompilation(), buildConfig.getProceedOnError(),
- buildConfig.isNoAtAspectJAnnotationProcessing(), buildConfig.isMakeReflectable(), state);
- } else {
- return new AjCompilerAdapter(forCompiler, batchCompile, getBcelWorld(), getWeaver(), factory,
- getInterimResultRequestor(), progressListener,
- this, // IOutputFilenameProvider
- this, // IBinarySourceProvider
- state.getBinarySourceMap(), buildConfig.isTerminateAfterCompilation(), buildConfig.getProceedOnError(),
- buildConfig.isNoAtAspectJAnnotationProcessing(), buildConfig.isMakeReflectable(), state);
- }
- }
-
- /**
- * Some AspectJ lint options need to be known about in the compiler. This is how we pass them over...
- *
- * @param forCompiler
- */
- private void populateCompilerOptionsFromLintSettings(org.aspectj.org.eclipse.jdt.internal.compiler.Compiler forCompiler) {
- BcelWorld world = this.state.getBcelWorld();
- IMessage.Kind swallowedExceptionKind = world.getLint().swallowedExceptionInCatchBlock.getKind();
- Map optionsMap = new HashMap();
- optionsMap.put(CompilerOptions.OPTION_ReportSwallowedExceptionInCatchBlock, swallowedExceptionKind == null ? "ignore"
- : swallowedExceptionKind.toString());
- forCompiler.options.set(optionsMap);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.aspectj.ajdt.internal.compiler.IBinarySourceProvider#getBinarySourcesForThisWeave()
- */
- @Override
- public Map<String, List<UnwovenClassFile>> getBinarySourcesForThisWeave() {
- return binarySourcesForTheNextCompile;
- }
-
- public static AsmHierarchyBuilder getAsmHierarchyBuilder() {
- return asmHierarchyBuilder;
- }
-
- /**
- * Override the the default hierarchy builder.
- */
- public static void setAsmHierarchyBuilder(AsmHierarchyBuilder newBuilder) {
- asmHierarchyBuilder = newBuilder;
- }
-
- public AjState getState() {
- return state;
- }
-
- public void setState(AjState buildState) {
- state = buildState;
- }
-
- private static class AjBuildContexFormatter implements ContextFormatter {
-
- @Override
- public String formatEntry(int phaseId, Object data) {
- StringBuffer sb = new StringBuffer();
- if (phaseId == CompilationAndWeavingContext.BATCH_BUILD) {
- sb.append("batch building ");
- } else {
- sb.append("incrementally building ");
- }
- AjBuildConfig config = (AjBuildConfig) data;
- List classpath = config.getClasspath();
- sb.append("with classpath: ");
- for (Iterator iter = classpath.iterator(); iter.hasNext();) {
- sb.append(iter.next().toString());
- sb.append(File.pathSeparator);
- }
- return sb.toString();
- }
-
- }
-
- public boolean wasFullBuild() {
- return wasFullBuild;
- }
- }
|