Sfoglia il codice sorgente

don't hold eclipse source types in ajstate

tags/POST_MEMORY_CHANGES
acolyer 18 anni fa
parent
commit
b03d4bb299

+ 26
- 2
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java Vedi File

@@ -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)

+ 199
- 65
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java Vedi File

@@ -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();
}
}

}

Loading…
Annulla
Salva