diff options
author | aclement <aclement> | 2008-08-29 00:00:16 +0000 |
---|---|---|
committer | aclement <aclement> | 2008-08-29 00:00:16 +0000 |
commit | 4ba9d260cc39de8dd5690dca13d999530bf14cbd (patch) | |
tree | 2d8beac1adb0fd639dd09edea72d71d211b6a8d5 /org.aspectj.ajdt.core | |
parent | f347528612a319c48dc16627449483c56cc0a543 (diff) | |
download | aspectj-4ba9d260cc39de8dd5690dca13d999530bf14cbd.tar.gz aspectj-4ba9d260cc39de8dd5690dca13d999530bf14cbd.zip |
245566: incremental magic
Diffstat (limited to 'org.aspectj.ajdt.core')
3 files changed, 411 insertions, 309 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java index dc495fead..9f55734c6 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java @@ -13,7 +13,6 @@ * Bugzilla #29768, 29769 * ******************************************************************/ - package org.aspectj.ajdt.internal.core.builder; import java.io.File; @@ -29,87 +28,89 @@ import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager; import org.aspectj.util.FileUtil; /** - * All configuration information needed to run the AspectJ compiler. - * Compiler options (as opposed to path information) are held in an AjCompilerOptions instance + * All configuration information needed to run the AspectJ compiler. Compiler options (as opposed to path information) are held in + * an AjCompilerOptions instance */ -public class AjBuildConfig { - +public class AjBuildConfig implements CompilerConfigurationChangeFlags { + private boolean shouldProceed = true; - + public static final String AJLINT_IGNORE = "ignore"; public static final String AJLINT_WARN = "warn"; public static final String AJLINT_ERROR = "error"; public static final String AJLINT_DEFAULT = "default"; - + private File outputDir; private File outputJar; private String outxmlName; private CompilationResultDestinationManager compilationResultDestinationManager = null; - private List/*File*/ sourceRoots = new ArrayList(); - private List/*File*/ files = new ArrayList(); - private List /*File*/ binaryFiles = new ArrayList(); // .class files in indirs... - private List/*File*/ inJars = new ArrayList(); - private List/*File*/ inPath = new ArrayList(); - private Map/*String->File*/ sourcePathResources = new HashMap(); - private List/*File*/ aspectpath = new ArrayList(); - private List/*String*/ classpath = new ArrayList(); - private List/*String*/ bootclasspath = new ArrayList(); - + private List/* File */sourceRoots = new ArrayList(); + private List/* File */changedFiles; + private List/* File */files = new ArrayList(); + private List /* File */binaryFiles = new ArrayList(); // .class files in indirs... + private List/* File */inJars = new ArrayList(); + private List/* File */inPath = new ArrayList(); + private Map/* String->File */sourcePathResources = new HashMap(); + private List/* File */aspectpath = new ArrayList(); + private List/* String */classpath = new ArrayList(); + private List/* String */bootclasspath = new ArrayList(); + private File configFile; private String lintMode = AJLINT_DEFAULT; private File lintSpecFile = null; - + + private int changes = EVERYTHING; // bitflags, see CompilerConfigurationChangeFlags + private AjCompilerOptions options; - - /** if true, then global values override local when joining */ - private boolean override = true; - - // incremental variants handled by the compiler client, but parsed here - private boolean incrementalMode; - private File incrementalFile; - + + /** if true, then global values override local when joining */ + private boolean override = true; + + // incremental variants handled by the compiler client, but parsed here + private boolean incrementalMode; + private File incrementalFile; + public String toString() { StringBuffer sb = new StringBuffer(); - sb.append("BuildConfig["+(configFile==null?"null":configFile.getAbsoluteFile().toString())+"] #Files="+files.size()); + sb.append("BuildConfig[" + (configFile == null ? "null" : configFile.getAbsoluteFile().toString()) + "] #Files=" + + files.size()); return sb.toString(); } - + public static class BinarySourceFile { public BinarySourceFile(File dir, File src) { this.fromInPathDirectory = dir; this.binSrc = src; } + public File fromInPathDirectory; public File binSrc; - + public boolean equals(Object obj) { - if ((obj instanceof BinarySourceFile) && - (obj != null)) { - BinarySourceFile other = (BinarySourceFile)obj; - return(binSrc.equals(other.binSrc)); + if (obj != null && (obj instanceof BinarySourceFile)) { + BinarySourceFile other = (BinarySourceFile) obj; + return (binSrc.equals(other.binSrc)); } return false; } + public int hashCode() { - return binSrc != null ? binSrc.hashCode() : 0; + return binSrc != null ? binSrc.hashCode() : 0; } } - + /** - * Intialises the javaOptions Map to hold the default - * JDT Compiler settings. Added by AMC 01.20.2003 in reponse - * to bug #29768 and enh. 29769. - * The settings here are duplicated from those set in - * org.eclipse.jdt.internal.compiler.batch.Main, but I've elected to - * copy them rather than refactor the JDT class since this keeps - * integration with future JDT releases easier (?). + * Intialises the javaOptions Map to hold the default JDT Compiler settings. Added by AMC 01.20.2003 in reponse to bug #29768 + * and enh. 29769. The settings here are duplicated from those set in org.eclipse.jdt.internal.compiler.batch.Main, but I've + * elected to copy them rather than refactor the JDT class since this keeps integration with future JDT releases easier (?). */ - public AjBuildConfig( ) { + public AjBuildConfig() { options = new AjCompilerOptions(); } /** - * returned files includes <ul> + * returned files includes + * <ul> * <li>files explicitly listed on command-line</li> * <li>files listed by reference in argument list files</li> * <li>files contained in sourceRootDir if that exists</li> @@ -117,23 +118,22 @@ public class AjBuildConfig { * * @return all source files that should be compiled. */ - public List/*File*/ getFiles() { + public List/* File */getFiles() { return files; } /** - * returned files includes all .class files found in - * a directory on the inpath, but does not include - * .class files contained within jars. + * returned files includes all .class files found in a directory on the inpath, but does not include .class files contained + * within jars. */ - public List/*BinarySourceFile*/ getBinaryFiles() { + public List/* BinarySourceFile */getBinaryFiles() { return binaryFiles; } - - public File getOutputDir() { + + public File getOutputDir() { return outputDir; } - + public CompilationResultDestinationManager getCompilationResultDestinationManager() { return this.compilationResultDestinationManager; } @@ -141,7 +141,7 @@ public class AjBuildConfig { public void setCompilationResultDestinationManager(CompilationResultDestinationManager mgr) { this.compilationResultDestinationManager = mgr; } - + public void setFiles(List files) { this.files = files; } @@ -164,11 +164,11 @@ public class AjBuildConfig { public void setClasspath(List classpath) { this.classpath = classpath; } - + public List getBootclasspath() { return bootclasspath; } - + public void setBootclasspath(List bootclasspath) { this.bootclasspath = bootclasspath; } @@ -180,13 +180,13 @@ public class AjBuildConfig { public String getOutxmlName() { return outxmlName; } - - public List/*File*/ getInpath() { + + public List/* File */getInpath() { // Elements of the list are either archives (jars/zips) or directories return inPath; } - public List/*File*/ getInJars() { + public List/* File */getInJars() { return inJars; } @@ -205,24 +205,25 @@ public class AjBuildConfig { public void setInJars(List sourceJars) { this.inJars = sourceJars; } - + public void setInPath(List dirsOrJars) { inPath = dirsOrJars; - + // remember all the class files in directories on the inpath binaryFiles = new ArrayList(); FileFilter filter = new FileFilter() { public boolean accept(File pathname) { return pathname.getPath().endsWith(".class"); - }}; + } + }; for (Iterator iter = dirsOrJars.iterator(); iter.hasNext();) { File inpathElement = (File) iter.next(); if (inpathElement.isDirectory()) { - File[] files = FileUtil.listFiles(inpathElement, filter); + File[] files = FileUtil.listFiles(inpathElement, filter); for (int i = 0; i < files.length; i++) { - binaryFiles.add(new BinarySourceFile(inpathElement,files[i])); + binaryFiles.add(new BinarySourceFile(inpathElement, files[i])); } - } + } } } @@ -242,47 +243,47 @@ public class AjBuildConfig { this.configFile = configFile; } - public void setIncrementalMode(boolean incrementalMode) { - this.incrementalMode = incrementalMode; - } - - public boolean isIncrementalMode() { - return incrementalMode; - } - - public void setIncrementalFile(File incrementalFile) { - this.incrementalFile = incrementalFile; - } - - public boolean isIncrementalFileMode() { - return (null != incrementalFile); - } - - /** - * @return List (String) classpath of bootclasspath, injars, inpath, aspectpath - * entries, specified classpath (extdirs, and classpath), and output dir or jar - */ - public List getFullClasspath() { - List full = new ArrayList(); - full.addAll(getBootclasspath()); // XXX Is it OK that boot classpath overrides inpath/injars/aspectpath? - for (Iterator i = inJars.iterator(); i.hasNext(); ) { - full.add(((File)i.next()).getAbsolutePath()); - } - for (Iterator i = inPath.iterator();i.hasNext();) { - full.add(((File)i.next()).getAbsolutePath()); - } - for (Iterator i = aspectpath.iterator(); i.hasNext(); ) { - full.add(((File)i.next()).getAbsolutePath()); - } - full.addAll(getClasspath()); -// if (null != outputDir) { -// full.add(outputDir.getAbsolutePath()); -// } else if (null != outputJar) { -// full.add(outputJar.getAbsolutePath()); -// } - return full; - } - + public void setIncrementalMode(boolean incrementalMode) { + this.incrementalMode = incrementalMode; + } + + public boolean isIncrementalMode() { + return incrementalMode; + } + + public void setIncrementalFile(File incrementalFile) { + this.incrementalFile = incrementalFile; + } + + public boolean isIncrementalFileMode() { + return (null != incrementalFile); + } + + /** + * @return List (String) classpath of bootclasspath, injars, inpath, aspectpath entries, specified classpath (extdirs, and + * classpath), and output dir or jar + */ + public List getFullClasspath() { + List full = new ArrayList(); + full.addAll(getBootclasspath()); // XXX Is it OK that boot classpath overrides inpath/injars/aspectpath? + for (Iterator i = inJars.iterator(); i.hasNext();) { + full.add(((File) i.next()).getAbsolutePath()); + } + for (Iterator i = inPath.iterator(); i.hasNext();) { + full.add(((File) i.next()).getAbsolutePath()); + } + for (Iterator i = aspectpath.iterator(); i.hasNext();) { + full.add(((File) i.next()).getAbsolutePath()); + } + full.addAll(getClasspath()); + // if (null != outputDir) { + // full.add(outputDir.getAbsolutePath()); + // } else if (null != outputJar) { + // full.add(outputJar.getAbsolutePath()); + // } + return full; + } + public File getLintSpecFile() { return lintSpecFile; } @@ -299,132 +300,127 @@ public class AjBuildConfig { this.aspectpath = aspectpath; } - /** @return true if any config file, sourceroots, sourcefiles, injars or inpath */ - public boolean hasSources() { - return ((null != configFile) - || (0 < sourceRoots.size()) - || (0 < files.size()) - || (0 < inJars.size()) - || (0 < inPath.size()) - ); - } - -// /** @return null if no errors, String errors otherwise */ -// public String configErrors() { -// StringBuffer result = new StringBuffer(); -// // ok, permit both. sigh. -//// if ((null != outputDir) && (null != outputJar)) { -//// result.append("specified both outputDir and outputJar"); -//// } -// // incremental => only sourceroots -// // -// return (0 == result.length() ? null : result.toString()); -// } - - /** - * Install global values into local config - * unless values conflict: - * <ul> - * <li>Collections are unioned</li> - * <li>values takes local value unless default and global set</li> - * <li>this only sets one of outputDir and outputJar as needed</li> - * <ul> - * This also configures super if javaOptions change. - * @param global the AjBuildConfig to read globals from - */ - public void installGlobals(AjBuildConfig global) { // XXX relies on default values - // don't join the options - they already have defaults taken care of. -// Map optionsMap = options.getMap(); -// join(optionsMap,global.getOptions().getMap()); -// options.set(optionsMap); - join(aspectpath, global.aspectpath); - join(classpath, global.classpath); - if (null == configFile) { - configFile = global.configFile; // XXX correct? - } - if (!isEmacsSymMode() && global.isEmacsSymMode()) { - setEmacsSymMode(true); - } - join(files, global.files); - if (!isGenerateModelMode() && global.isGenerateModelMode()) { - setGenerateModelMode(true); - } - if (null == incrementalFile) { - incrementalFile = global.incrementalFile; - } - if (!incrementalMode && global.incrementalMode) { - incrementalMode = true; - } - - if (isCheckRuntimeVersion() && !global.isCheckRuntimeVersion()) { - setCheckRuntimeVersion(false); - } - - join(inJars, global.inJars); - join(inPath, global.inPath); - if ((null == lintMode) - || (AJLINT_DEFAULT.equals(lintMode))) { - setLintMode(global.lintMode); - } - if (null == lintSpecFile) { - lintSpecFile = global.lintSpecFile; - } - if (!isTerminateAfterCompilation() && global.isTerminateAfterCompilation()) { - setTerminateAfterCompilation(true); - } - if ((null == outputDir) && (null == outputJar)) { - if (null != global.outputDir) { - outputDir = global.outputDir; - } - if (null != global.outputJar) { - outputJar = global.outputJar; - } - } - join(sourceRoots, global.sourceRoots); - if (!isXnoInline() && global.isXnoInline()) { - setXnoInline(true); - } - if (!isXserializableAspects() && global.isXserializableAspects()) { - setXserializableAspects(true); - } - if (!isXlazyTjp() && global.isXlazyTjp()) { - setXlazyTjp(true); - } - if (!getProceedOnError() && global.getProceedOnError()) { - setProceedOnError(true); - } - setTargetAspectjRuntimeLevel(global.getTargetAspectjRuntimeLevel()); - setXJoinpoints(global.getXJoinpoints()); - if (!isXHasMemberEnabled() && global.isXHasMemberEnabled()) { - setXHasMemberSupport(true); - } - if (!isXNotReweavable() && global.isXNotReweavable()) { - setXnotReweavable(true); - } - setOutxmlName(global.getOutxmlName()); - setXconfigurationInfo(global.getXconfigurationInfo()); - setAddSerialVerUID(global.isAddSerialVerUID()); - } - - void join(Collection local, Collection global) { - for (Iterator iter = global.iterator(); iter.hasNext();) { - Object next = iter.next(); - if (!local.contains(next)) { - local.add(next); - } - } - } - void join(Map local, Map global) { - for (Iterator iter = global.keySet().iterator(); iter.hasNext();) { - Object key = iter.next(); - if (override || (null == local.get(key))) { // - Object value = global.get(key); - if (null != value) { - local.put(key, value); - } - } - } - } + /** @return true if any config file, sourceroots, sourcefiles, injars or inpath */ + public boolean hasSources() { + return ((null != configFile) || (0 < sourceRoots.size()) || (0 < files.size()) || (0 < inJars.size()) || (0 < inPath.size())); + } + + // /** @return null if no errors, String errors otherwise */ + // public String configErrors() { + // StringBuffer result = new StringBuffer(); + // // ok, permit both. sigh. + // // if ((null != outputDir) && (null != outputJar)) { + // // result.append("specified both outputDir and outputJar"); + // // } + // // incremental => only sourceroots + // // + // return (0 == result.length() ? null : result.toString()); + // } + + /** + * Install global values into local config unless values conflict: + * <ul> + * <li>Collections are unioned</li> + * <li>values takes local value unless default and global set</li> + * <li>this only sets one of outputDir and outputJar as needed</li> + * <ul> + * This also configures super if javaOptions change. + * + * @param global the AjBuildConfig to read globals from + */ + public void installGlobals(AjBuildConfig global) { // XXX relies on default values + // don't join the options - they already have defaults taken care of. + // Map optionsMap = options.getMap(); + // join(optionsMap,global.getOptions().getMap()); + // options.set(optionsMap); + join(aspectpath, global.aspectpath); + join(classpath, global.classpath); + if (null == configFile) { + configFile = global.configFile; // XXX correct? + } + if (!isEmacsSymMode() && global.isEmacsSymMode()) { + setEmacsSymMode(true); + } + join(files, global.files); + if (!isGenerateModelMode() && global.isGenerateModelMode()) { + setGenerateModelMode(true); + } + if (null == incrementalFile) { + incrementalFile = global.incrementalFile; + } + if (!incrementalMode && global.incrementalMode) { + incrementalMode = true; + } + + if (isCheckRuntimeVersion() && !global.isCheckRuntimeVersion()) { + setCheckRuntimeVersion(false); + } + + join(inJars, global.inJars); + join(inPath, global.inPath); + if ((null == lintMode) || (AJLINT_DEFAULT.equals(lintMode))) { + setLintMode(global.lintMode); + } + if (null == lintSpecFile) { + lintSpecFile = global.lintSpecFile; + } + if (!isTerminateAfterCompilation() && global.isTerminateAfterCompilation()) { + setTerminateAfterCompilation(true); + } + if ((null == outputDir) && (null == outputJar)) { + if (null != global.outputDir) { + outputDir = global.outputDir; + } + if (null != global.outputJar) { + outputJar = global.outputJar; + } + } + join(sourceRoots, global.sourceRoots); + if (!isXnoInline() && global.isXnoInline()) { + setXnoInline(true); + } + if (!isXserializableAspects() && global.isXserializableAspects()) { + setXserializableAspects(true); + } + if (!isXlazyTjp() && global.isXlazyTjp()) { + setXlazyTjp(true); + } + if (!getProceedOnError() && global.getProceedOnError()) { + setProceedOnError(true); + } + setTargetAspectjRuntimeLevel(global.getTargetAspectjRuntimeLevel()); + setXJoinpoints(global.getXJoinpoints()); + if (!isXHasMemberEnabled() && global.isXHasMemberEnabled()) { + setXHasMemberSupport(true); + } + if (!isXNotReweavable() && global.isXNotReweavable()) { + setXnotReweavable(true); + } + setOutxmlName(global.getOutxmlName()); + setXconfigurationInfo(global.getXconfigurationInfo()); + setAddSerialVerUID(global.isAddSerialVerUID()); + } + + void join(Collection local, Collection global) { + for (Iterator iter = global.iterator(); iter.hasNext();) { + Object next = iter.next(); + if (!local.contains(next)) { + local.add(next); + } + } + } + + void join(Map local, Map global) { + for (Iterator iter = global.keySet().iterator(); iter.hasNext();) { + Object key = iter.next(); + if (override || (null == local.get(key))) { // + Object value = global.get(key); + if (null != value) { + local.put(key, value); + } + } + } + } public void setSourcePathResources(Map map) { sourcePathResources = map; @@ -444,7 +440,7 @@ public class AjBuildConfig { public String getLintMode() { return lintMode; } - + // options... public void setLintMode(String lintMode) { @@ -457,22 +453,22 @@ public class AjBuildConfig { } else if (AJLINT_ERROR.equals(lintMode)) { lintValue = AjCompilerOptions.ERROR; } - + if (lintValue != null) { Map lintOptions = new HashMap(); - lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportUnresolvableMember,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportShadowNotInStructure,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportUnresolvableMember, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportShadowNotInStructure, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField, lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion, lintValue); options.set(lintOptions); } } - + public boolean isTerminateAfterCompilation() { return options.terminateAfterCompilation; } @@ -488,11 +484,11 @@ public class AjBuildConfig { public void setXserializableAspects(boolean xserializableAspects) { options.xSerializableAspects = xserializableAspects; } - + public void setXJoinpoints(String jps) { options.xOptionalJoinpoints = jps; } - + public String getXJoinpoints() { return options.xOptionalJoinpoints; } @@ -504,7 +500,7 @@ public class AjBuildConfig { public void setXnoInline(boolean xnoInline) { options.xNoInline = xnoInline; } - + public boolean isXlazyTjp() { return options.xLazyThisJoinPoint; } @@ -516,37 +512,38 @@ public class AjBuildConfig { public void setXnotReweavable(boolean b) { options.xNotReweavable = b; } - + public void setXconfigurationInfo(String info) { options.xConfigurationInfo = info; } + public String getXconfigurationInfo() { return options.xConfigurationInfo; } - + public void setXHasMemberSupport(boolean enabled) { options.xHasMember = enabled; } - + public boolean isXHasMemberEnabled() { return options.xHasMember; } - + public void setXdevPinpointMode(boolean enabled) { options.xdevPinpoint = enabled; } - + public boolean isXdevPinpoint() { return options.xdevPinpoint; } - + public void setAddSerialVerUID(boolean b) { options.addSerialVerUID = b; } + public boolean isAddSerialVerUID() { return options.addSerialVerUID; } - public boolean isXNotReweavable() { return options.xNotReweavable; @@ -555,9 +552,8 @@ public class AjBuildConfig { public boolean isGenerateJavadocsInModelMode() { return options.generateJavaDocsInModel; } - - public void setGenerateJavadocsInModelMode( - boolean generateJavadocsInModelMode) { + + public void setGenerateJavadocsInModelMode(boolean generateJavadocsInModelMode) { options.generateJavaDocsInModel = generateJavadocsInModelMode; } @@ -572,11 +568,11 @@ public class AjBuildConfig { public boolean isCheckRuntimeVersion() { return options.checkRuntimeVersion; } - + public void setCheckRuntimeVersion(boolean on) { options.checkRuntimeVersion = on; } - + public boolean isEmacsSymMode() { return options.generateEmacsSymFiles; } @@ -592,27 +588,27 @@ public class AjBuildConfig { public void setGenerateModelMode(boolean structureModelMode) { options.generateModel = structureModelMode; } - + public boolean isNoAtAspectJAnnotationProcessing() { return options.noAtAspectJProcessing; } - + public void setNoAtAspectJAnnotationProcessing(boolean noProcess) { options.noAtAspectJProcessing = noProcess; } - + public void setShowWeavingInformation(boolean b) { options.showWeavingInformation = true; } - - public boolean getShowWeavingInformation() { + + public boolean getShowWeavingInformation() { return options.showWeavingInformation; } public void setProceedOnError(boolean b) { options.proceedOnError = b; } - + public boolean getProceedOnError() { return options.proceedOnError; } @@ -620,11 +616,11 @@ public class AjBuildConfig { public void setBehaveInJava5Way(boolean b) { options.behaveInJava5Way = b; } - + public boolean getBehaveInJava5Way() { return options.behaveInJava5Way; } - + public void setTargetAspectjRuntimeLevel(String level) { options.targetAspectjRuntimeLevel = level; } @@ -632,4 +628,31 @@ public class AjBuildConfig { public String getTargetAspectjRuntimeLevel() { return options.targetAspectjRuntimeLevel; } + + /** + * Indicates what has changed in this configuration compared to the last time it was used, allowing the state management logic + * to make intelligent optimizations and skip unnecessary work. + * + * @param changes set of bitflags, see {@link CompilerConfigurationChangeFlags} for flags + */ + public void setChanged(int changes) { + this.changes = changes; + } + + /** + * Return the bit flags indicating what has changed since the last time this config was used. + * + * @return the bitflags according too {@link CompilerConfigurationChangeFlags} + */ + public int getChanged() { + return this.changes; + } + + public void setModifiedFiles(List projectSourceFilesChanged) { + this.changedFiles = projectSourceFilesChanged; + } + + public List getModifiedFiles() { + return this.changedFiles; + } } 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 3a1c3a057..9ef6ddce4 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 @@ -21,6 +21,7 @@ import java.lang.ref.SoftReference; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; @@ -60,7 +61,7 @@ import org.aspectj.weaver.bcel.UnwovenClassFile; * lets just do it for all now) * */ -public class AjState { +public class AjState implements CompilerConfigurationChangeFlags { // SECRETAPI static so beware of multi-threading bugs... public static IStateListener stateListener = null; @@ -272,13 +273,18 @@ public class AjState { else qualifiedStrings.clear(); - Set oldFiles = new HashSet(buildConfig.getFiles()); - Set newFiles = new HashSet(newBuildConfig.getFiles()); + if ((newBuildConfig.getChanged() & PROJECTSOURCEFILES_CHANGED) == 0) { + addedFiles = Collections.EMPTY_SET; + deletedFiles = Collections.EMPTY_SET; + } else { + Set oldFiles = new HashSet(buildConfig.getFiles()); + Set newFiles = new HashSet(newBuildConfig.getFiles()); - addedFiles = new HashSet(newFiles); - addedFiles.removeAll(oldFiles); - deletedFiles = new HashSet(oldFiles); - deletedFiles.removeAll(newFiles); + addedFiles = new HashSet(newFiles); + addedFiles.removeAll(oldFiles); + deletedFiles = new HashSet(oldFiles); + deletedFiles.removeAll(newFiles); + } Set oldBinaryFiles = new HashSet(buildConfig.getBinaryFiles()); Set newBinaryFiles = new HashSet(newBuildConfig.getBinaryFiles()); @@ -334,18 +340,27 @@ public class AjState { Collection getModifiedFiles(long lastBuildTime) { Set ret = new HashSet(); - // not our job to account for new and deleted files - for (Iterator i = buildConfig.getFiles().iterator(); i.hasNext();) { - File file = (File) i.next(); - if (!file.exists()) - continue; - long modTime = file.lastModified(); - // System.out.println("check: " + file + " mod " + modTime + " build " + lastBuildTime); - // need to add 1000 since lastModTime is only accurate to a second on some (all?) platforms - if (modTime + 1000 > lastBuildTime) { - ret.add(file); + // Check if the build configuration knows what files have changed... + List/* File */modifiedFiles = buildConfig.getModifiedFiles(); + + if (modifiedFiles == null) { + // do not know, so need to go looking + // not our job to account for new and deleted files + for (Iterator i = buildConfig.getFiles().iterator(); i.hasNext();) { + File file = (File) i.next(); + if (!file.exists()) + continue; + + long modTime = file.lastModified(); + // System.out.println("check: " + file + " mod " + modTime + " build " + lastBuildTime); + // need to add 1000 since lastModTime is only accurate to a second on some (all?) platforms + if (modTime + 1000 > lastBuildTime) { + ret.add(file); + } } + } else { + ret.addAll(modifiedFiles); } ret.addAll(affectedFiles); return ret; @@ -658,34 +673,57 @@ public class AjState { return (strucModTime > lastSuccessfulBuildTime); } - private boolean pathChange(AjBuildConfig oldConfig, AjBuildConfig newConfig) { - boolean changed = false; + /** + * Determine if something has changed on the classpath/inpath/aspectpath and a full build is required rather than an incremental + * one. + * + * @param previousConfig the previous configuration used + * @param newConfig the new configuration being used + * @return true if full build required + */ + private boolean pathChange(AjBuildConfig previousConfig, AjBuildConfig newConfig) { + int changes = newConfig.getChanged(); - List oldOutputLocs = getOutputLocations(oldConfig); + // currently very coarse grained + if ((changes & (CLASSPATH_CHANGED | ASPECTPATH_CHANGED | INPATH_CHANGED | OUTPUTDESTINATIONS_CHANGED | INJARS_CHANGED)) != 0) { + List oldOutputLocs = getOutputLocations(previousConfig); - List oldClasspath = oldConfig.getClasspath(); - List newClasspath = newConfig.getClasspath(); - if (stateListener != null) - stateListener.aboutToCompareClasspaths(oldClasspath, newClasspath); - if (changedAndNeedsFullBuild(oldClasspath, newClasspath, true, oldOutputLocs)) - return true; - List oldAspectpath = oldConfig.getAspectpath(); - List newAspectpath = newConfig.getAspectpath(); - if (changedAndNeedsFullBuild(oldAspectpath, newAspectpath, true, oldOutputLocs)) - return true; - List oldInJars = oldConfig.getInJars(); - List newInJars = newConfig.getInJars(); - if (changedAndNeedsFullBuild(oldInJars, newInJars, false, oldOutputLocs)) - return true; - List oldInPath = oldConfig.getInpath(); - List newInPath = newConfig.getInpath(); - if (changedAndNeedsFullBuild(oldInPath, newInPath, false, oldOutputLocs)) - return true; - return changed; + List oldClasspath = previousConfig.getClasspath(); + List newClasspath = newConfig.getClasspath(); + if (stateListener != null) + stateListener.aboutToCompareClasspaths(oldClasspath, newClasspath); + if (changedAndNeedsFullBuild(oldClasspath, newClasspath, true, oldOutputLocs)) + return true; + + List oldAspectpath = previousConfig.getAspectpath(); + List newAspectpath = newConfig.getAspectpath(); + if (changedAndNeedsFullBuild(oldAspectpath, newAspectpath, true, oldOutputLocs)) + return true; + + List oldInPath = previousConfig.getInpath(); + List newInPath = newConfig.getInpath(); + if (changedAndNeedsFullBuild(oldInPath, newInPath, false, oldOutputLocs)) + return true; + + List oldInJars = previousConfig.getInJars(); + List newInJars = newConfig.getInJars(); + if (changedAndNeedsFullBuild(oldInJars, newInJars, false, oldOutputLocs)) + return true; + } + + return false; } + /** + * Return a list of the output locations - this includes any 'default' output location and then any known by a registered + * CompilationResultDestinationManager. + * + * @param config the build configuration for which the output locations should be determined + * @return a list of file objects + */ private List /* File */getOutputLocations(AjBuildConfig config) { List outputLocs = new ArrayList(); + // Is there a default location? if (config.getOutputDir() != null) { try { outputLocs.add(config.getOutputDir().getCanonicalFile()); @@ -697,10 +735,10 @@ public class AjState { for (Iterator iterator = dirs.iterator(); iterator.hasNext();) { File f = (File) iterator.next(); try { - if (!outputLocs.contains(f.getCanonicalFile())) { - outputLocs.add(f.getCanonicalFile()); + File cf = f.getCanonicalFile(); + if (!outputLocs.contains(cf)) { + outputLocs.add(cf); } - } catch (IOException e) { } } @@ -708,6 +746,17 @@ public class AjState { return outputLocs; } + /** + * Check the old and new paths, if they vary by length or individual elements then that is considered a change. Or if the last + * modified time of a path entry has changed (or last modified time of a classfile in that path entry has changed) then return + * true. The outputlocations are supplied so they can be 'ignored' in the comparison. + * + * @param oldPath + * @param newPath + * @param checkClassFiles whether to examine individual class files within directories + * @param outputLocs the output locations that should be ignored if they occur on the paths being compared + * @return true if a change is detected that requires a full build + */ private boolean changedAndNeedsFullBuild(List oldPath, List newPath, boolean checkClassFiles, List outputLocs) { if (oldPath == null) oldPath = new ArrayList(); @@ -731,7 +780,7 @@ public class AjState { if (f.exists() && !f.isDirectory() && (f.lastModified() >= lastSuccessfulBuildTime)) { return true; } - if (f.exists() && f.isDirectory() && checkClassFiles) { + if (checkClassFiles && f.exists() && f.isDirectory()) { boolean foundMatch = false; for (Iterator iterator = outputLocs.iterator(); iterator.hasNext();) { File dir = (File) iterator.next(); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java new file mode 100644 index 000000000..57a519fa2 --- /dev/null +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java @@ -0,0 +1,30 @@ +/******************************************************************** + * Copyright (c) 2008 Contributors. All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://eclipse.org/legal/epl-v10.html + * + * Contributors: Andy Clement + *******************************************************************/ +package org.aspectj.ajdt.internal.core.builder; + +/** + * Bit flags that can indicate what has changed in a configuration, see ICompilerConfiguration + */ +public interface CompilerConfigurationChangeFlags { + + int NO_CHANGES = 0x0000; + int PROJECTSOURCEFILES_CHANGED = 0x0001; + int JAVAOPTIONS_CHANGED = 0x0002; + int ASPECTPATH_CHANGED = 0x0004; + int CLASSPATH_CHANGED = 0x0008; + int INPATH_CHANGED = 0x0010; + int NONSTANDARDOPTIONS_CHANGED = 0x0020; + int OUTJAR_CHANGED = 0x0040; + int PROJECTSOURCERESOURCES_CHANGED = 0x0080; + int OUTPUTDESTINATIONS_CHANGED = 0x0100; + int INJARS_CHANGED = 0x0200; // deprecated, not in use any more + int EVERYTHING = 0xffff; + +} |