aboutsummaryrefslogtreecommitdiffstats
path: root/org.aspectj.ajdt.core
diff options
context:
space:
mode:
authoracolyer <acolyer>2006-02-10 17:53:34 +0000
committeracolyer <acolyer>2006-02-10 17:53:34 +0000
commitb03d4bb299917983d2c104e818f014e3743f4c17 (patch)
tree60f151a5106f1029273ddc7918a860f1b31ad91d /org.aspectj.ajdt.core
parent5f41f5d56a7c6a4b76660697848177aea06273a0 (diff)
downloadaspectj-b03d4bb299917983d2c104e818f014e3743f4c17.tar.gz
aspectj-b03d4bb299917983d2c104e818f014e3743f4c17.zip
don't hold eclipse source types in ajstate
Diffstat (limited to 'org.aspectj.ajdt.core')
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java28
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java264
2 files changed, 225 insertions, 67 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
index caa4f2d7e..4e5230a91 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
@@ -44,6 +44,7 @@ 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;
@@ -176,6 +177,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc
if (baseHandler instanceof ILifecycleAware) {
((ILifecycleAware)baseHandler).buildStarting(!batch);
}
+ CompilationAndWeavingContext.reset();
int phase = batch ? CompilationAndWeavingContext.BATCH_BUILD : CompilationAndWeavingContext.INCREMENTAL_BUILD;
ContextToken ct = CompilationAndWeavingContext.enteringPhase(phase ,buildConfig);
try {
@@ -260,6 +262,11 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc
CompilationAndWeavingContext.leavingPhase(ct);
return false;
}
+
+ if (state.requiresFullBatchBuild()) {
+ return batchBuild(buildConfig, baseHandler);
+ }
+
binarySourcesForTheNextCompile = state.getBinaryFilesToCompile(false);
files = state.getFilesToCompile(false);
hereWeGoAgain = !(files.isEmpty() && binarySourcesForTheNextCompile.isEmpty());
@@ -829,6 +836,8 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc
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;
}
@@ -1108,6 +1117,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc
*/
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());
@@ -1134,10 +1144,24 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc
this, // IOutputFilenameProvider
this, // IBinarySourceProvider
state.getBinarySourceMap(),
- state.getResultSetToUseForFullWeave(),
buildConfig.isNoWeave(),
buildConfig.getProceedOnError(),
- buildConfig.isNoAtAspectJAnnotationProcessing());
+ buildConfig.isNoAtAspectJAnnotationProcessing(),
+ 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)
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
index 48f0f28ef..e47215ace 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
@@ -15,6 +15,7 @@ package org.aspectj.ajdt.internal.core.builder;
import java.io.File;
import java.io.FileFilter;
+import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -38,6 +39,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatExcepti
import org.aspectj.org.eclipse.jdt.internal.core.builder.ReferenceCollection;
import org.aspectj.org.eclipse.jdt.internal.core.builder.StringSet;
import org.aspectj.util.FileUtil;
+import org.aspectj.weaver.IWeaver;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.bcel.BcelWeaver;
import org.aspectj.weaver.bcel.BcelWorld;
@@ -64,29 +66,27 @@ public class AjState {
private AjBuildConfig buildConfig;
+ private boolean batchBuildRequiredThisTime = false;
+
/**
- * Holds the CompilationResult produced by JDT as a result of compiling the given
- * source file. InterimCompilationResults are *very* memory intensive and we would
- * like to release them as soon as possible (currently they are retained in memory
- * until the next full build).
- *
- * Populated in noteResult which adds an InterimCompilationResult (post JDT compile,
- * but pre-weave).
- *
- * The values() of this Map are passed to AjCompilerAdaptor as the result set to
- * use if the weaver indicates that a full weave is required.
+ * Keeps a list of (FQN,Filename) pairs (as ClassFile objects)
+ * for types that resulted from the compilation of the given
+ * File.
*
- * In incremental building, used by addDependentsOf(File) to compute the compile set
- * when a given file has been added or modified.
+ * Populated in noteResult and used in addDependentsOf(File)
*
- * When processing deleted files, this map is used to see if any of the compilation units
- * that came from that file were aspects, and if so, to trigger a full build.
+ * Added by AMC during state refactoring, 1Q06.
+ */
+ private Map/*<File, List<ClassFile>*/ fullyQualifiedTypeNamesResultingFromCompilationUnit = new HashMap();
+
+ /**
+ * Source files defining aspects
*
- * When deleting class files in preparation for a full build, entries are removed
- * from the map.
+ * Populated in noteResult and used in processDeletedFiles
*
+ * Added by AMC during state refactoring, 1Q06.
*/
- private Map/*<File, InterimCompilationResult*/ resultsFromFile = new HashMap();
+ private Set sourceFilesDefiningAspects = new HashSet();
/**
* Populated in noteResult to record the set of types that should be recompiled if
@@ -163,6 +163,11 @@ public class AjState {
boolean prepareForNextBuild(AjBuildConfig newBuildConfig) {
currentBuildTime = System.currentTimeMillis();
+ if (this.batchBuildRequiredThisTime) {
+ this.batchBuildRequiredThisTime = false;
+ return false;
+ }
+
if (lastSuccessfulBuildTime == -1 || buildConfig == null) {
structuralChangesSinceLastFullBuild.clear();
return false;
@@ -224,20 +229,10 @@ public class AjState {
private boolean processDeletedFiles(Set deletedFiles) {
for (Iterator iter = deletedFiles.iterator(); iter.hasNext();) {
File aDeletedFile = (File ) iter.next();
- InterimCompilationResult cr = (InterimCompilationResult)resultsFromFile.get(aDeletedFile);
- if (cr!=null) {
- Map compiledTypes = cr.result().compiledTypes;
- if (compiledTypes!=null) {
- for (Iterator iterator = compiledTypes.keySet().iterator(); iterator.hasNext();) {
- char[] className = (char[])iterator.next();
- ResolvedType rt = world.resolve(new String(className).replace('/','.'));
- if (rt.isAspect()) {
- removeAllResultsOfLastBuild();
- if (stateListener!=null) stateListener.detectedAspectDeleted(aDeletedFile);
- return false;
- }
- }
- }
+ if (this.sourceFilesDefiningAspects.contains(aDeletedFile)) {
+ removeAllResultsOfLastBuild();
+ if (stateListener!=null) stateListener.detectedAspectDeleted(aDeletedFile);
+ return false;
}
}
return true;
@@ -470,15 +465,18 @@ public class AjState {
private void deleteClassFiles() {
for (Iterator i = deletedFiles.iterator(); i.hasNext(); ) {
File deletedFile = (File)i.next();
- //System.out.println("deleting: " + deletedFile);
addDependentsOf(deletedFile);
- InterimCompilationResult intRes = (InterimCompilationResult) resultsFromFile.get(deletedFile);
- resultsFromFile.remove(deletedFile);
- //System.out.println("deleting: " + unwovenClassFiles);
- if (intRes == null) continue;
- for (int j=0; j<intRes.unwovenClassFiles().length; j++ ) {
- deleteClassFile(intRes.unwovenClassFiles()[j]);
+
+ List cfs = (List) this.fullyQualifiedTypeNamesResultingFromCompilationUnit.get(deletedFile);
+ this.fullyQualifiedTypeNamesResultingFromCompilationUnit.remove(deletedFile);
+
+ if (cfs != null) {
+ for (Iterator iter = cfs.iterator(); iter.hasNext();) {
+ ClassFile cf = (ClassFile) iter.next();
+ deleteClassFile(cf);
+ }
}
+
}
}
@@ -488,7 +486,13 @@ public class AjState {
AjBuildConfig.BinarySourceFile deletedFile = (AjBuildConfig.BinarySourceFile) iter.next();
List ucfs = (List) binarySourceFiles.get(deletedFile.binSrc.getPath());
binarySourceFiles.remove(deletedFile.binSrc.getPath());
- deleteClassFile((UnwovenClassFile)ucfs.get(0));
+
+ // AMC temp during refactoring
+ UnwovenClassFile ucf = (UnwovenClassFile) ucfs.get(0);
+ ClassFile cf = new ClassFile(ucf.getClassName(),new File(ucf.getFilename()));
+ // end temp
+
+ deleteClassFile(cf);
}
}
@@ -552,16 +556,10 @@ public class AjState {
}
}
-
- private void deleteClassFile(UnwovenClassFile classFile) {
- classesFromName.remove(classFile.getClassName());
-
- weaver.deleteClassFile(classFile.getClassName());
- try {
- classFile.deleteRealFile();
- } catch (IOException e) {
- //!!! might be okay to ignore
- }
+ private void deleteClassFile(ClassFile cf) {
+ classesFromName.remove(cf.fullyQualifiedTypeName);
+ weaver.deleteClassFile(cf.fullyQualifiedTypeName);
+ cf.deleteFromFileSystem();
}
private UnwovenClassFile createUnwovenClassFile(AjBuildConfig.BinarySourceFile bsf) {
@@ -584,23 +582,122 @@ public class AjState {
references.put(sourceFile, new ReferenceCollection(cr.qualifiedReferences, cr.simpleNameReferences));
}
- InterimCompilationResult previous = (InterimCompilationResult) resultsFromFile.get(sourceFile);
UnwovenClassFile[] unwovenClassFiles = result.unwovenClassFiles();
for (int i = 0; i < unwovenClassFiles.length; i++) {
- UnwovenClassFile lastTimeRound = removeFromPreviousIfPresent(unwovenClassFiles[i],previous);
+ UnwovenClassFile lastTimeRound = (UnwovenClassFile) classesFromName.get(unwovenClassFiles[i].getClassName());
recordClassFile(unwovenClassFiles[i],lastTimeRound);
classesFromName.put(unwovenClassFiles[i].getClassName(),unwovenClassFiles[i]);
}
- if (previous != null) {
- for (int i = 0; i < previous.unwovenClassFiles().length; i++) {
- if (previous.unwovenClassFiles()[i] != null) {
- deleteClassFile(previous.unwovenClassFiles()[i]);
- }
+ // need to do this before types are deleted from the World...
+ recordWhetherCompilationUnitDefinedAspect(sourceFile,cr);
+ deleteTypesThatWereInThisCompilationUnitLastTimeRoundButHaveBeenDeletedInThisIncrement(sourceFile, unwovenClassFiles);
+
+ recordFQNsResultingFromCompilationUnit(sourceFile,result);
+ }
+
+ /**
+ * Currently unused, if we ditch classesFromName, we might need this.... (in noteResult)
+ * @param file
+ * @return
+ */
+ private UnwovenClassFile maybeGetExistingClassFileFor(UnwovenClassFile classFile) {
+ File existing = new File(classFile.getFilename());
+ if (!existing.exists()) {
+ return null;
+ }
+ else {
+ try {
+ return new UnwovenClassFile(classFile.getFilename(),FileUtil.readAsByteArray(existing));
+ }
+ catch (IOException ex) {
+ throw new IllegalStateException("Unable to read contents of '" + classFile.getFilename() + "' " +
+ "from last compile cycle");
+ }
+ }
+ }
+
+ /**
+ * @param sourceFile
+ * @param unwovenClassFiles
+ */
+ private void deleteTypesThatWereInThisCompilationUnitLastTimeRoundButHaveBeenDeletedInThisIncrement(File sourceFile, UnwovenClassFile[] unwovenClassFiles) {
+ List classFiles = (List) this.fullyQualifiedTypeNamesResultingFromCompilationUnit.get(sourceFile);
+ if (classFiles != null) {
+ for (int i = 0; i < unwovenClassFiles.length; i++) {
+ // deleting also deletes types from the weaver... don't do this if they are
+ // still present this time around...
+ removeFromClassFilesIfPresent(unwovenClassFiles[i].getClassName(),classFiles);
+ }
+ for (Iterator iter = classFiles.iterator(); iter.hasNext();) {
+ ClassFile cf = (ClassFile) iter.next();
+ deleteClassFile(cf);
+ }
+ }
+ }
+
+
+ private void removeFromClassFilesIfPresent(String className, List classFiles) {
+ ClassFile victim = null;
+ for (Iterator iter = classFiles.iterator(); iter.hasNext();) {
+ ClassFile cf = (ClassFile) iter.next();
+ if (cf.fullyQualifiedTypeName.equals(className)) {
+ victim = cf;
+ break;
}
}
- resultsFromFile.put(sourceFile, result);
+ if (victim != null) {
+ classFiles.remove(victim);
+ }
+ }
+
+ /**
+ * Record the fully-qualified names of the types that were declared in the given
+ * source file.
+ *
+ * @param sourceFile, the compilation unit
+ * @param icr, the CompilationResult from compiling it
+ */
+ private void recordFQNsResultingFromCompilationUnit(File sourceFile, InterimCompilationResult icr) {
+ List classFiles = new ArrayList();
+ UnwovenClassFile[] types = icr.unwovenClassFiles();
+ for (int i = 0; i < types.length; i++) {
+ classFiles.add(new ClassFile(types[i].getClassName(),new File(types[i].getFilename())));
+ }
+ this.fullyQualifiedTypeNamesResultingFromCompilationUnit.put(sourceFile,classFiles);
+ }
+
+ /**
+ * If this compilation unit defined an aspect, we need to know in case it is
+ * modified in a future increment.
+ *
+ * @param sourceFile
+ * @param cr
+ */
+ private void recordWhetherCompilationUnitDefinedAspect(File sourceFile, CompilationResult cr) {
+ this.sourceFilesDefiningAspects.remove(sourceFile);
+
+ if (cr!=null) {
+ Map compiledTypes = cr.compiledTypes;
+ if (compiledTypes!=null) {
+ for (Iterator iterator = compiledTypes.keySet().iterator(); iterator.hasNext();) {
+ char[] className = (char[])iterator.next();
+ String typeName = new String(className).replace('/','.');
+ if (typeName.indexOf(IWeaver.SYNTHETIC_CLASS_POSTFIX) == -1) {
+ ResolvedType rt = world.resolve(typeName);
+ if (rt.isMissing()) {
+ throw new IllegalStateException("Type '" + rt.getSignature() + "' not found in world!");
+ }
+ if (rt.isAspect()) {
+ this.sourceFilesDefiningAspects.add(sourceFile);
+ break;
+ }
+ }
+ }
+ }
+ }
+
}
private UnwovenClassFile removeFromPreviousIfPresent(UnwovenClassFile cf, InterimCompilationResult previous) {
@@ -791,12 +888,15 @@ public class AjState {
}
protected void addDependentsOf(File sourceFile) {
- InterimCompilationResult intRes = (InterimCompilationResult)resultsFromFile.get(sourceFile);
- if (intRes == null) return;
+ List cfs = (List) this.fullyQualifiedTypeNamesResultingFromCompilationUnit.get(sourceFile);
- for (int i = 0; i < intRes.unwovenClassFiles().length; i++) {
- addDependentsOf(intRes.unwovenClassFiles()[i].getClassName());
+ if (cfs != null) {
+ for (Iterator iter = cfs.iterator(); iter.hasNext();) {
+ ClassFile cf = (ClassFile) iter.next();
+ addDependentsOf(cf.fullyQualifiedTypeName);
+ }
}
+
}
public void setStructureModel(IHierarchy model) {
@@ -837,10 +937,6 @@ public class AjState {
return this.buildConfig;
}
- public Collection getResultSetToUseForFullWeave() {
- return this.resultsFromFile.values();
- }
-
public void clearBinarySourceFiles() {
this.binarySourceFiles = new HashMap();
}
@@ -878,4 +974,42 @@ public class AjState {
public Set getDeletedFiles() {
return this.deletedFiles;
}
+
+ public void forceBatchBuildNextTimeAround() {
+ this.batchBuildRequiredThisTime = true;
+ }
+
+ public boolean requiresFullBatchBuild() {
+ return this.batchBuildRequiredThisTime;
+ }
+
+ private static class ClassFile {
+ public String fullyQualifiedTypeName;
+ public File locationOnDisk;
+
+ public ClassFile(String fqn, File location) {
+ this.fullyQualifiedTypeName = fqn;
+ this.locationOnDisk = location;
+ }
+
+ public void deleteFromFileSystem() {
+ String namePrefix = locationOnDisk.getName();
+ namePrefix = namePrefix.substring(0,namePrefix.lastIndexOf('.'));
+ final String targetPrefix = namePrefix + IWeaver.CLOSURE_CLASS_PREFIX;
+ File dir = locationOnDisk.getParentFile();
+ if (dir != null) {
+ File[] weaverGenerated = dir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.startsWith(targetPrefix);
+ }});
+ if (weaverGenerated!=null) {
+ for (int i = 0; i < weaverGenerated.length; i++) {
+ weaverGenerated[i].delete();
+ }
+ }
+ }
+ locationOnDisk.delete();
+ }
+ }
+
}