]> source.dussan.org Git - aspectj.git/commitdiff
245566: incremental magic
authoraclement <aclement>
Fri, 29 Aug 2008 00:00:16 +0000 (00:00 +0000)
committeraclement <aclement>
Fri, 29 Aug 2008 00:00:16 +0000 (00:00 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java [new file with mode: 0644]

index dc495fead3396190aa757bdbb9ba640f85adab26..9f55734c6899be11ff7bba9746d4b43920aca2b1 100644 (file)
@@ -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;
+       }
 }
index 3a1c3a0571f2725eb3640aaaeda7697d468f8444..9ef6ddce4b78534357e74fc110cfe333ea72e802 100644 (file)
@@ -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 (file)
index 0000000..57a519f
--- /dev/null
@@ -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;
+
+}