summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraclement <aclement>2004-03-18 13:00:01 +0000
committeraclement <aclement>2004-03-18 13:00:01 +0000
commit183fc23883289ae42854ce9afcf2d3b0d29b7599 (patch)
tree4607522120a1a54b748d36f99f1afae1ee76502f
parentd91b72e7016a1ebbc3363fe8a57ec61c012deb99 (diff)
downloadaspectj-183fc23883289ae42854ce9afcf2d3b0d29b7599.tar.gz
aspectj-183fc23883289ae42854ce9afcf2d3b0d29b7599.zip
Fix for Bugzilla Bug 40192
build cancel during weaving
-rw-r--r--ajde/src/org/aspectj/ajde/internal/BuildNotifierAdapter.java9
-rw-r--r--ajde/testdata/BuildCancelling/A1.aj9
-rw-r--r--ajde/testdata/BuildCancelling/A2.aj9
-rw-r--r--ajde/testdata/BuildCancelling/A3.aj9
-rw-r--r--ajde/testdata/BuildCancelling/A4.aj9
-rw-r--r--ajde/testdata/BuildCancelling/Cl1.java4
-rw-r--r--ajde/testdata/BuildCancelling/Cl2.java4
-rw-r--r--ajde/testdata/BuildCancelling/Cl3.java4
-rw-r--r--ajde/testdata/BuildCancelling/EvenMoreCode.lst10
-rw-r--r--ajde/testdata/BuildCancelling/HW.java13
-rw-r--r--ajde/testdata/BuildCancelling/LoadsaCode.lst7
-rw-r--r--ajde/testsrc/org/aspectj/ajde/AjdeTests.java1
-rw-r--r--ajde/testsrc/org/aspectj/ajde/BuildCancellingTest.java410
-rw-r--r--bridge/src/org/aspectj/bridge/IProgressListener.java11
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java7
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverAdapter.java88
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java20
17 files changed, 610 insertions, 14 deletions
diff --git a/ajde/src/org/aspectj/ajde/internal/BuildNotifierAdapter.java b/ajde/src/org/aspectj/ajde/internal/BuildNotifierAdapter.java
index e1288e293..37a25f404 100644
--- a/ajde/src/org/aspectj/ajde/internal/BuildNotifierAdapter.java
+++ b/ajde/src/org/aspectj/ajde/internal/BuildNotifierAdapter.java
@@ -16,7 +16,6 @@ package org.aspectj.ajde.internal;
import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.BuildProgressMonitor;
import org.aspectj.ajdt.internal.core.builder.AjBuildManager;
-import org.aspectj.bridge.AbortException;
import org.aspectj.bridge.IProgressListener;
public class BuildNotifierAdapter implements IProgressListener {
@@ -50,4 +49,12 @@ public class BuildNotifierAdapter implements IProgressListener {
progressMonitor.setProgressText(text);
}
+ public void setCancelledRequested(boolean cancelRequested) {
+ this.cancelRequested = cancelRequested;
+ }
+
+ public boolean isCancelledRequested() {
+ return cancelRequested;
+ }
+
}
diff --git a/ajde/testdata/BuildCancelling/A1.aj b/ajde/testdata/BuildCancelling/A1.aj
new file mode 100644
index 000000000..1245cfff1
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/A1.aj
@@ -0,0 +1,9 @@
+
+public aspect A1 {
+
+ pointcut m1(): execution(* main(..));
+
+ before(): m1() {
+ System.err.println("Before main runs");
+ }
+} \ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/A2.aj b/ajde/testdata/BuildCancelling/A2.aj
new file mode 100644
index 000000000..4a2ee8189
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/A2.aj
@@ -0,0 +1,9 @@
+
+public aspect A2 {
+
+ pointcut m1(): execution(* main(..));
+
+ after(): m1() {
+ System.err.println("After main runs");
+ }
+}
diff --git a/ajde/testdata/BuildCancelling/A3.aj b/ajde/testdata/BuildCancelling/A3.aj
new file mode 100644
index 000000000..d9f7a6888
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/A3.aj
@@ -0,0 +1,9 @@
+
+public aspect A3 {
+
+ pointcut m1(): call(* *print*(..));
+
+ before(): m1() {
+ System.err.println("Calling print");
+ }
+} \ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/A4.aj b/ajde/testdata/BuildCancelling/A4.aj
new file mode 100644
index 000000000..5c475d4f2
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/A4.aj
@@ -0,0 +1,9 @@
+
+public aspect A4 {
+
+ pointcut m1(): call(* *print*(..));
+
+ after(): m1() {
+ System.err.println("After call to print");
+ }
+} \ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/Cl1.java b/ajde/testdata/BuildCancelling/Cl1.java
new file mode 100644
index 000000000..7652142c6
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/Cl1.java
@@ -0,0 +1,4 @@
+public class Cl1 {
+ public static void main(String[] args) {
+ }
+} \ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/Cl2.java b/ajde/testdata/BuildCancelling/Cl2.java
new file mode 100644
index 000000000..8ba3e49ed
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/Cl2.java
@@ -0,0 +1,4 @@
+public class Cl2 {
+ public static void main(String[] args) {
+ }
+} \ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/Cl3.java b/ajde/testdata/BuildCancelling/Cl3.java
new file mode 100644
index 000000000..0b3b301df
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/Cl3.java
@@ -0,0 +1,4 @@
+public class Cl3 {
+ public static void callPrint(String s) {
+ }
+} \ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/EvenMoreCode.lst b/ajde/testdata/BuildCancelling/EvenMoreCode.lst
new file mode 100644
index 000000000..cfd1cee3e
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/EvenMoreCode.lst
@@ -0,0 +1,10 @@
+A1.aj
+Cl1.java
+A2.aj
+Cl2.java
+HW.java
+A3.aj
+Cl3.java
+A4.aj
+-verbose
+-noExit
diff --git a/ajde/testdata/BuildCancelling/HW.java b/ajde/testdata/BuildCancelling/HW.java
new file mode 100644
index 000000000..3f8aaf831
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/HW.java
@@ -0,0 +1,13 @@
+
+public class HW {
+ public static void main(String[] args) {
+ callPrint("Hello");
+ callPrint(" ");
+ callPrint("World");
+ callPrint("\n");
+ }
+
+ public static void callPrint(String s) {
+ System.out.print(s);
+ }
+} \ No newline at end of file
diff --git a/ajde/testdata/BuildCancelling/LoadsaCode.lst b/ajde/testdata/BuildCancelling/LoadsaCode.lst
new file mode 100644
index 000000000..e313f343d
--- /dev/null
+++ b/ajde/testdata/BuildCancelling/LoadsaCode.lst
@@ -0,0 +1,7 @@
+A1.aj
+A2.aj
+HW.java
+A3.aj
+A4.aj
+-verbose
+-noExit
diff --git a/ajde/testsrc/org/aspectj/ajde/AjdeTests.java b/ajde/testsrc/org/aspectj/ajde/AjdeTests.java
index ecd8471ce..b66c019ed 100644
--- a/ajde/testsrc/org/aspectj/ajde/AjdeTests.java
+++ b/ajde/testsrc/org/aspectj/ajde/AjdeTests.java
@@ -35,6 +35,7 @@ public class AjdeTests extends TestCase {
suite.addTestSuite(ResourceCopyTestCase.class);
suite.addTestSuite(ModelPerformanceTest.class);
suite.addTestSuite(SavedModelConsistencyTest. class);
+ suite.addTestSuite(BuildCancellingTest.class);
suite.addTestSuite(JarManifestTest.class);
//$JUnit-END$
diff --git a/ajde/testsrc/org/aspectj/ajde/BuildCancellingTest.java b/ajde/testsrc/org/aspectj/ajde/BuildCancellingTest.java
new file mode 100644
index 000000000..5d07718e1
--- /dev/null
+++ b/ajde/testsrc/org/aspectj/ajde/BuildCancellingTest.java
@@ -0,0 +1,410 @@
+/* *******************************************************************
+ * Copyright (c) 2004 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Andy Clement Initial version
+ * ******************************************************************/
+
+package org.aspectj.ajde;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.ajde.internal.CompilerAdapter;
+import org.aspectj.util.FileUtil;
+
+/**
+ * It is now possible to cancel the compiler during either the
+ * compilation or weaving phases - this testcase verifies a few
+ * cases, making sure the process stops when expected. It can
+ * check the disk contents, but it doesn't right now.
+ *
+ * Two different .lst files are used during these tests: LoadsaCode.lst and
+ * EvenMoreCode.lst which contain mixes of aspects and classes
+ *
+ * Here are some things to think about that will help you understand what is
+ * on the disk when we cancel the compiler.
+ *
+ * There are 3 important phases worth remembering :
+ * - Compile all the types
+ * - Weave all the aspects
+ * - Weave all the classes
+ *
+ * Each of those steps goes through all the types. This
+ * means during the 'weave all the aspects' step we are
+ * jumping over classes and during the 'weave all the
+ * classes ' step we are jumping over aspects. Why is this important?
+ *
+ *
+ * We only write bytes out during the 'weave all the classes ' phase and it is even
+ * during that phase that we write out the bytes for aspects. This means if you cancel
+ * during compilation or during the weaving of aspects - there will be nothing on the
+ * disk. If you cancel whilst in the 'weave all the classes ' phase then the disk
+ * will contain anything finished with by the cancellation point.
+ */
+public class BuildCancellingTest extends AjdeTestCase {
+
+ private CompilerAdapter compilerAdapter;
+ public static final String PROJECT_DIR = "BuildCancelling";
+ public static final String binDir = "bin";
+
+ public BuildCancellingTest(String arg0) {
+ super(arg0);
+ }
+
+ // Ensure the output directory is clean
+ protected void setUp() throws Exception {
+ super.setUp(PROJECT_DIR);
+ FileUtil.deleteContents(openFile(binDir));
+ }
+
+
+
+ /**
+ * After first compilation message, get it to cancel, there should be one more warning
+ * message about cancelling the compile and their should be nothing on the disk.
+ */
+ public void testCancelFirstCompile() {
+ System.out.println("\n\n\ntestCancelFirstCompile: Building with LoadsaCode.lst");
+ compilerAdapter = new CompilerAdapter();
+ compilerAdapter.showInfoMessages(false);
+ BuildProgMon programmableBPM = new BuildProgMon();
+
+ programmableBPM.cancelOn("compiled:",1); // Force a cancel after the first compile occurs
+
+ compilerAdapter.compile(
+ (String) openFile("LoadsaCode.lst").getAbsolutePath(),
+ programmableBPM,
+ false);
+
+ assertTrue("Should have cancelled after first compile?:"+programmableBPM.numCompiledMessages,
+ programmableBPM.numCompiledMessages==1);
+
+// Comment out to check the disk contents
+// assertTrue("As weaving was cancelled, no files should have been written out, but I found:"+wovenClassesFound(),
+// wovenClassesFound()==0);
+
+ boolean expectedCancelMessageFound = checkFor("Compilation cancelled as requested");
+ if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+ assertTrue("Failed to get warning message about compilation being cancelled!", expectedCancelMessageFound);
+ }
+
+
+
+ /**
+ * After third compilation message, get it to cancel, there should be one more warning
+ * message about cancelling the compile and their should be nothing on the disk.
+ */
+ public void testCancelThirdCompile() {
+ System.out.println("\n\n\ntestCancelThirdCompile: Building with LoadsaCode.lst");
+ compilerAdapter = new CompilerAdapter();
+ compilerAdapter.showInfoMessages(false);
+ BuildProgMon programmableBPM = new BuildProgMon();
+
+ programmableBPM.cancelOn("compiled:",3); // Force a cancel after the third compile occurs
+
+ compilerAdapter.compile(
+ (String) openFile("LoadsaCode.lst").getAbsolutePath(),
+ programmableBPM,
+ false);
+
+ assertTrue("Should have cancelled after third compile?:"+programmableBPM.numCompiledMessages,
+ programmableBPM.numCompiledMessages==3);
+
+// Comment out to check the disk contents
+// assertTrue("As weaving was cancelled, no files should have been written out, but I found:"+wovenClassesFound(),
+// wovenClassesFound()==0);
+
+ boolean expectedCancelMessageFound = checkFor("Compilation cancelled as requested");
+ if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+ assertTrue("Failed to get warning message about compilation being cancelled!", expectedCancelMessageFound);
+ }
+
+
+ /**
+ * After first weave aspect message, get it to cancel, there should be one more warning
+ * message about cancelling the weave and their should be nothing on the disk.
+ */
+ public void testCancelFirstAspectWeave() {
+ System.out.println("\n\n\ntestCancelFirstAspectWeave: Building with LoadsaCode.lst");
+ compilerAdapter = new CompilerAdapter();
+ compilerAdapter.showInfoMessages(false);
+ BuildProgMon programmableBPM = new BuildProgMon();
+
+ programmableBPM.cancelOn("woven aspect ",1); // Force a cancel after the first weave aspect occurs
+
+ compilerAdapter.compile((String) openFile("LoadsaCode.lst").getAbsolutePath(),programmableBPM,false);
+
+ assertTrue("Should have cancelled after first aspect weave?:"+programmableBPM.numWovenAspectMessages,
+ programmableBPM.numWovenAspectMessages==1);
+
+// Comment out to check the disk contents
+// assertTrue("As weaving was cancelled, no files should have been written out?:"+wovenClassesFound(),
+// wovenClassesFound()==0);
+
+ boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+ if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+ assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+ }
+
+
+
+ /**
+ * After third weave aspect message, get it to cancel, there should be one more warning
+ * message about cancelling the weave and their should be nothing on the disk.
+ */
+ public void testCancelThirdAspectWeave() {
+ System.out.println("\n\n\ntestCancelThirdAspectWeave: Building with LoadsaCode.lst");
+ compilerAdapter = new CompilerAdapter();
+ compilerAdapter.showInfoMessages(false);
+
+ BuildProgMon programmableBPM = new BuildProgMon();
+ // Force a cancel after the third weave occurs.
+ // This should leave two class files on disk - I think?
+ programmableBPM.cancelOn("woven aspect ",3);
+
+ compilerAdapter.compile(
+ (String) openFile("LoadsaCode.lst").getAbsolutePath(),
+ programmableBPM,
+ false);
+
+ assertTrue("Should have cancelled after third weave?:"+programmableBPM.numWovenAspectMessages,
+ programmableBPM.numWovenAspectMessages==3);
+
+// Comment out to check disk contents
+// assertTrue("As weaving was cancelled, no files should have been written out?:"+wovenClassesFound(),
+// wovenClassesFound()==0);
+
+ boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+ if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+ assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+
+ }
+
+ /**
+ * After first weave class message, get it to cancel, there should be one more
+ * warning message about cancelling the weave and their should be nothing on the
+ * disk.
+ *
+ * EvenMoreCode.lst contains:
+ * A1.aj
+ * Cl1.java
+ * A2.aj
+ * Cl2.java
+ * HW.java
+ * A3.aj
+ * Cl3.java
+ * A4.aj
+ *
+ */
+ public void testCancelFirstClassWeave() {
+ System.out.println("testCancelFirstClassWeave: Building with EvenMoreCode.lst");
+ compilerAdapter = new CompilerAdapter();
+ compilerAdapter.showInfoMessages(false);
+ BuildProgMon programmableBPM = new BuildProgMon();
+
+ programmableBPM.cancelOn("woven class",1);
+
+ compilerAdapter.compile(
+ (String) openFile("EvenMoreCode.lst").getAbsolutePath(),
+ programmableBPM,
+ false);
+
+// Should just be A1 on the disk - uncomment this line to verify that!
+// assertTrue("Incorrect disk contents found",diskContents("A1"));
+
+ assertTrue("Should have cancelled after first class weave?:"+programmableBPM.numWovenClassMessages,
+ programmableBPM.numWovenClassMessages==1);
+
+ boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+ if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+ assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+ }
+
+
+ /**
+ * After first weave aspect message, get it to cancel, there should be one more
+ * warning message about cancelling the weave and their should be nothing on the
+ * disk.
+ *
+ * EvenMoreCode.lst contains:
+ * A1.aj
+ * Cl1.java
+ * A2.aj
+ * Cl2.java
+ * HW.java
+ * A3.aj
+ * Cl3.java
+ * A4.aj
+ *
+ */
+ public void testCancelSecondClassWeave() {
+ System.out.println("testCancelSecondClassWeave: Building with EvenMoreCode.lst");
+ compilerAdapter = new CompilerAdapter();
+ compilerAdapter.showInfoMessages(false);
+ BuildProgMon programmableBPM = new BuildProgMon();
+
+ programmableBPM.cancelOn("woven class",2);
+
+ compilerAdapter.compile(
+ (String) openFile("EvenMoreCode.lst").getAbsolutePath(),
+ programmableBPM,
+ false);
+
+// Uncomment this line to verify disk contents
+// assertTrue("Incorrect disk contents found",diskContents("A1 Cl1 A2"));
+
+ assertTrue("Should have cancelled after first class weave?:"+programmableBPM.numWovenClassMessages,
+ programmableBPM.numWovenClassMessages==2);
+
+ boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested");
+ if (!expectedCancelMessageFound) dumpTaskData(); // Useful for debugging
+ assertTrue("Failed to get warning message about weaving being cancelled!", expectedCancelMessageFound);
+
+ }
+
+
+ // ----
+ // Helper classes and methods
+
+
+ private class BuildProgMon implements BuildProgressMonitor {
+
+ public int numWovenClassMessages = 0;
+ public int numWovenAspectMessages = 0;
+ public int numCompiledMessages = 0;
+
+ private String programmableString;
+ private int count;
+ private List messagesReceived = new ArrayList();
+ private int currentVal;
+
+ public void start(String configFile) {
+ currentVal = 0;
+ }
+
+ public void cancelOn(String string,int count) {
+ programmableString = string;
+ this.count = count;
+ }
+
+ public void setProgressText(String text) {
+ String newText = text+" [Percentage="+currentVal+"%]";
+ messagesReceived.add(newText);
+ if (text.startsWith("woven aspect ")) numWovenAspectMessages++;
+ if (text.startsWith("woven class ")) numWovenClassMessages++;
+ if (text.startsWith("compiled:")) numCompiledMessages++;
+ if (programmableString != null
+ && text.indexOf(programmableString) != -1) {
+ count--;
+ if (count==0) {
+ System.out.println("Just got message '"+newText+"' - asking build to cancel");
+ compilerAdapter.requestCompileExit();
+ programmableString = null;
+ }
+ }
+ }
+
+ public boolean containsMessage(String prefix,String distinguishingMarks) {
+ for (Iterator iter = messagesReceived.iterator(); iter.hasNext();) {
+ String element = (String) iter.next();
+ if (element.startsWith(prefix) &&
+ element.indexOf(distinguishingMarks)!=-1) return true;
+ }
+ return false;
+ }
+
+ public void dumpMessages() {
+ System.out.println("ProgressMonitorMessages");
+ for (Iterator iter = messagesReceived.iterator(); iter.hasNext();) {
+ String element = (String) iter.next();
+ System.out.println(element);
+ }
+ }
+
+ public void setProgressBarVal(int newVal) {
+ this.currentVal = newVal;
+ }
+
+ public void incrementProgressBarVal() {
+ System.err.println("ipbv");
+ }
+
+ public void setProgressBarMax(int maxVal) {
+ System.err.println("spbm"+maxVal);
+ }
+
+ public int getProgressBarMax() {
+ return 100; // Causes setProgressBarVal() to be fed what are effectively percentages
+ }
+
+ public void finish() {
+ }
+
+ }
+
+ private boolean diskContents(String shouldExist) {
+ String[] fullList = new String[] { "A1","A2","A3","A4","Cl1","Cl2","Cl3","HW"};
+ boolean isOK = true;
+ for (int i = 0; i < fullList.length; i++) {
+ String file = fullList[i];
+ if (shouldExist.indexOf(file)!=-1) {
+ // There should be a class file called this
+ if (!openFile("bin/"+file+".class").exists()) {
+ isOK=false;
+ System.out.println("Couldn't find this expected file: "+file+".class");
+ }
+ } else {
+ // There should NOT be a class file called this
+ if (openFile("bin/"+file+".class").exists()) {
+ isOK=false;
+ System.out.println("Found this file when not expected: "+file+".class");
+ }
+ }
+ }
+ return isOK;
+ }
+
+ private int wovenClassesFound() {
+ int found = 0;
+ File fA1 = openFile("bin/A1.class");
+ File fA2 = openFile("bin/A2.class");
+ File fA3 = openFile("bin/A3.class");
+ File fA4 = openFile("bin/A4.class");
+ File fHW = openFile("bin/HW.class");
+
+ found+=(fA1.exists()?1:0);
+ found+=(fA2.exists()?1:0);
+ found+=(fA3.exists()?1:0);
+ found+=(fA4.exists()?1:0);
+ found+=(fHW.exists()?1:0);
+ return found;
+ }
+
+
+ private boolean checkFor(String what) {
+ List ll = ideManager.getCompilationSourceLineTasks();
+ for (Iterator iter = ll.iterator(); iter.hasNext();) {
+ Object element = (Object) iter.next();
+ if (element.toString().indexOf(what) != -1)
+ return true;
+ }
+ return false;
+ }
+
+ private void dumpTaskData() {
+ List ll = ideManager.getCompilationSourceLineTasks();
+ for (Iterator iter = ll.iterator(); iter.hasNext();) {
+ Object element = (Object) iter.next();
+ System.out.println("RecordedMessage>"+element);
+ }
+ }
+
+}
diff --git a/bridge/src/org/aspectj/bridge/IProgressListener.java b/bridge/src/org/aspectj/bridge/IProgressListener.java
index 1686c64b0..59d5f3366 100644
--- a/bridge/src/org/aspectj/bridge/IProgressListener.java
+++ b/bridge/src/org/aspectj/bridge/IProgressListener.java
@@ -26,4 +26,15 @@ public interface IProgressListener {
* @param percentDone how much work is completed so far
*/
public void setProgress(double percentDone);
+
+ /**
+ * @param cancelRequested true if the caller wants the current compilation to stop asap
+ */
+ public void setCancelledRequested(boolean cancelRequested);
+
+ /**
+ * @return true if the consumer of the progress info would like the compileation to stop
+ */
+ public boolean isCancelledRequested();
+
}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
index d679d12b9..a6eacc40a 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java
@@ -21,6 +21,7 @@ import java.util.Map;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IProgressListener;
import org.aspectj.weaver.bcel.BcelWeaver;
import org.aspectj.weaver.bcel.BcelWorld;
import org.eclipse.jdt.internal.compiler.CompilationResult;
@@ -44,6 +45,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
private boolean reportedErrors;
private boolean isXNoWeave;
private IIntermediateResultsRequestor intermediateResultsRequestor;
+ private IProgressListener progressListener;
private IOutputClassFileNameProvider outputFileNameProvider;
private WeaverMessageHandler weaverMessageHandler;
private List /* InterimCompilationResult */ binarySources = new ArrayList();
@@ -73,6 +75,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
BcelWeaver weaver,
EclipseFactory eFactory,
IIntermediateResultsRequestor intRequestor,
+ IProgressListener progressListener,
IOutputClassFileNameProvider outputFileNameProvider,
Map binarySourceEntries, /* fileName |-> List<UnwovenClassFile> */
Collection /* InterimCompilationResult */ resultSetForFullWeave,
@@ -81,6 +84,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
this.isBatchCompile = isBatchCompile;
this.weaver = weaver;
this.intermediateResultsRequestor = intRequestor;
+ this.progressListener = progressListener;
this.outputFileNameProvider = outputFileNameProvider;
this.isXNoWeave = isXNoWeave;
this.resultSetForFullWeave = resultSetForFullWeave;
@@ -130,6 +134,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
} else {
resultsPendingWeave.add(intRes);
}
+
}
public void beforeResolving(CompilationUnitDeclaration unit, ICompilationUnit sourceUnit, boolean verifyMethods, boolean analyzeCode, boolean generateCode) {
@@ -212,7 +217,7 @@ public class AjCompilerAdapter implements ICompilerAdapter {
addAllKnownClassesToWeaveList();
}
- weaver.weave(new WeaverAdapter(this,weaverMessageHandler));
+ weaver.weave(new WeaverAdapter(this,weaverMessageHandler,progressListener));
}
private void addAllKnownClassesToWeaveList() {
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverAdapter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverAdapter.java
index 6eead0082..345b928ad 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverAdapter.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverAdapter.java
@@ -14,9 +14,12 @@ import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
+import org.aspectj.bridge.IProgressListener;
import org.aspectj.weaver.IClassFileProvider;
import org.aspectj.weaver.IWeaveRequestor;
import org.aspectj.weaver.bcel.UnwovenClassFile;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
/**
* @author colyer
@@ -32,13 +35,24 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
private InterimCompilationResult nowProcessing;
private InterimCompilationResult lastReturnedResult;
private WeaverMessageHandler weaverMessageHandler;
+ private IProgressListener progressListener;
private boolean finalPhase = false;
+ private int localIteratorCounter;
+ // Fields related to progress monitoring
+ private int progressMaxTypes;
+ private String progressPhasePrefix;
+ private double fromPercent;
+ private double toPercent = 100.0;
+ private int progressCompletionCount;
+
public WeaverAdapter(AjCompilerAdapter forCompiler,
- WeaverMessageHandler weaverMessageHandler) {
- this.compilerAdapter = forCompiler;
+ WeaverMessageHandler weaverMessageHandler,
+ IProgressListener progressListener) {
+ this.compilerAdapter = forCompiler;
this.weaverMessageHandler = weaverMessageHandler;
+ this.progressListener = progressListener;
}
/* (non-Javadoc)
@@ -46,6 +60,7 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
*/
public Iterator getClassFileIterator() {
classFileIndex = 0;
+ localIteratorCounter = 0;
nowProcessing = null;
lastReturnedResult = null;
resultIterator = compilerAdapter.resultsPendingWeave.iterator();
@@ -98,8 +113,10 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
finishedWith(lastReturnedResult);
}
}
+ localIteratorCounter++;
lastReturnedResult = nowProcessing;
weaverMessageHandler.setCurrentResult(nowProcessing.result());
+ // weaverMessageHandler.handleMessage(new Message("weaving " + nowProcessing.fileName(),IMessage.INFO, null, null));
return nowProcessing.unwovenClassFiles()[classFileIndex++];
}
/* (non-Javadoc)
@@ -108,22 +125,50 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
public void remove() {
throw new UnsupportedOperationException();
}
-
+
// IWeaveRequestor
// =====================================================================================
-
+
// weave phases as indicated by bcelWeaver...
- public void processingReweavableState() {}
- public void addingTypeMungers() {}
- public void weavingAspects() {}
- public void weavingClasses() {finalPhase = true;}
+ public void processingReweavableState() {
+
+ // progress reporting logic
+ fromPercent = 50.0; // Assume weaving takes 50% of the progress bar...
+ recordProgress("processing reweavable state");
+ }
+
+ public void addingTypeMungers() {
+
+ // progress reporting logic
+ // At this point we have completed one iteration through all the classes/aspects
+ // we'll be dealing with, so let us remember this max value for localIteratorCounter
+ // (for accurate progress reporting)
+ recordProgress("adding type mungers");
+ progressMaxTypes = localIteratorCounter;
+ }
+
+ public void weavingAspects() {
+
+ // progress reporting logic
+ progressPhasePrefix="woven aspect ";
+ progressCompletionCount=0; // Start counting from *now*
+ }
+
+ public void weavingClasses() {
+ finalPhase = true;
+
+ // progress reporting logic
+ progressPhasePrefix="woven class ";
+ }
public void weaveCompleted() {
if ((lastReturnedResult != null) && (!lastReturnedResult.result().hasBeenAccepted)) {
finishedWith(lastReturnedResult);
}
}
+
+
/* (non-Javadoc)
* @see org.aspectj.weaver.IWeaveRequestor#acceptResult(org.aspectj.weaver.bcel.UnwovenClassFile)
@@ -135,6 +180,20 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
AjClassFile ajcf = new AjClassFile(className.toCharArray(),
result.getBytes());
lastReturnedResult.result().record(ajcf.fileName(),ajcf);
+
+ if (progressListener != null) {
+ progressCompletionCount++;
+
+ // Smoothly take progress from 'fromPercent' to 'toPercent'
+ recordProgress(
+ fromPercent
+ +((progressCompletionCount/(double)progressMaxTypes)*(toPercent-fromPercent)),
+ progressPhasePrefix+result.getClassName()+" (from "+nowProcessing.fileName()+")");
+
+ if (progressListener.isCancelledRequested()) {
+ throw new AbortCompilation(true,new OperationCanceledException("Weaving cancelled as requested"));
+ }
+ }
}
// helpers...
@@ -160,4 +219,17 @@ public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Itera
table.remove(victim);
}
}
+
+ private void recordProgress(String message) {
+ if (progressListener!=null) {
+ progressListener.setText(message);
+ }
+ }
+
+ private void recordProgress(double percentage,String message) {
+ if (progressListener!=null) {
+ progressListener.setProgress(percentage/100);
+ progressListener.setText(message);
+ }
+ }
} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
index f49ea9e3c..dc1eef8f5 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
@@ -31,6 +31,7 @@ import org.aspectj.bridge.*;
import org.aspectj.util.FileUtil;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.*;
+import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.batch.*;
@@ -38,6 +39,7 @@ import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
//import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
@@ -158,7 +160,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
for (int i = 0; (i < 5) && !files.isEmpty(); i++) {
// System.err.println("XXXX inc: " + files);
performCompilation(files);
- if (handler.hasErrors()) {
+ if (handler.hasErrors() || (progressListener!=null && progressListener.isCancelledRequested())) {
return false;
}
files = state.getFilesToCompile(false);
@@ -572,8 +574,11 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
options.produceReferenceInfo(true); //TODO turn off when not needed
- compiler.compile(getCompilationUnits(filenames, encodings));
-
+ try {
+ compiler.compile(getCompilationUnits(filenames, encodings));
+ } catch (OperationCanceledException oce) {
+ handler.handleMessage(new Message("build cancelled:"+oce.getMessage(),IMessage.WARNING,null,null));
+ }
// cleanup
environment.cleanup();
environment = null;
@@ -592,6 +597,11 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
progressListener.setText("compiled: " + result.fileName());
}
state.noteResult(result);
+
+ if (progressListener!=null && progressListener.isCancelledRequested()) {
+ throw new AbortCompilation(true,
+ new OperationCanceledException("Compilation cancelled as requested"));
+ }
}
};
}
@@ -853,7 +863,9 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda
return new AjCompilerAdapter(forCompiler,batchCompile,bcelWorld,bcelWeaver,
factory,
- getInterimResultRequestor(),this,
+ getInterimResultRequestor(),
+ progressListener,
+ this,
state.binarySourceFiles,
state.resultsFromFile.values(),
buildConfig.isNoWeave());