Fixes ThreadLocalTreeLoggerProxy nesting problems by explicitly pushing and popping state.

Review by: bruce (pair prog)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1586 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java b/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
index 29a188e..01f4011 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
@@ -349,6 +349,8 @@
     }
   }
 
+  protected final ThreadLocalTreeLoggerProxy threadLogger = new ThreadLocalTreeLoggerProxy();
+
   private final CompilerImpl compiler;
 
   private final boolean doGenerateBytes;
@@ -359,8 +361,6 @@
 
   private final SourceOracle sourceOracle;
 
-  private final ThreadLocalTreeLoggerProxy threadLogger = new ThreadLocalTreeLoggerProxy();
-
   private final Map<String, ICompilationUnit> unitsByTypeName = new HashMap<String, ICompilationUnit>();
 
   protected AbstractCompiler(SourceOracle sourceOracle, boolean doGenerateBytes) {
@@ -420,12 +420,16 @@
     // Any additional compilation units that are found to be needed will be
     // pulled in while procssing compilation units. See CompilerImpl.process().
     //
-    threadLogger.set(logger);
-    Set<CompilationUnitDeclaration> cuds = new HashSet<CompilationUnitDeclaration>();
-    compiler.compile(units, cuds);
-    int size = cuds.size();
-    CompilationUnitDeclaration[] cudArray = new CompilationUnitDeclaration[size];
-    return cuds.toArray(cudArray);
+    TreeLogger oldLogger = threadLogger.push(logger);
+    try {
+      Set<CompilationUnitDeclaration> cuds = new HashSet<CompilationUnitDeclaration>();
+      compiler.compile(units, cuds);
+      int size = cuds.size();
+      CompilationUnitDeclaration[] cudArray = new CompilationUnitDeclaration[size];
+      return cuds.toArray(cudArray);
+    } finally {
+      threadLogger.pop(oldLogger);
+    }
   }
 
   protected void doAcceptResult(CompilationResult result) {
@@ -518,10 +522,6 @@
     return compiler.resolvePossiblyNestedType(typeName);
   }
 
-  protected void setLogger(TreeLogger logger) {
-    threadLogger.set(logger);
-  }
-
   SourceOracle getSourceOracle() {
     return sourceOracle;
   }
diff --git a/dev/core/src/com/google/gwt/dev/jdt/ByteCodeCompiler.java b/dev/core/src/com/google/gwt/dev/jdt/ByteCodeCompiler.java
index 6d144fe..f1d9c54 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/ByteCodeCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/ByteCodeCompiler.java
@@ -71,32 +71,37 @@
     //
     String msg = "Getting bytecode for '" + binaryTypeName + "'";
     logger = logger.branch(TreeLogger.SPAM, msg, null);
-    setLogger(logger);
 
-    // Check the bytecode cache in case we've already compiled it.
-    //
-    ByteCode byteCode = doGetByteCodeFromCache(logger, binaryTypeName);
-    if (byteCode != null) {
-      // We have it already.
+    TreeLogger oldLogger = threadLogger.push(logger);
+    try {
+
+      // Check the bytecode cache in case we've already compiled it.
       //
-      return byteCode.getBytes();
-    }
+      ByteCode byteCode = doGetByteCodeFromCache(logger, binaryTypeName);
+      if (byteCode != null) {
+        // We have it already.
+        //
+        return byteCode.getBytes();
+      }
 
-    // Need to compile it. It could be the case that we have tried before and
-    // failed, but on the off chance that it's been fixed since then, we adopt
-    // a policy of always trying to recompile if we don't have it cached.
-    //
-    ICompilationUnit start = getCompilationUnitForType(logger, binaryTypeName);
-    compile(logger, new ICompilationUnit[] {start});
+      // Need to compile it. It could be the case that we have tried before and
+      // failed, but on the off chance that it's been fixed since then, we adopt
+      // a policy of always trying to recompile if we don't have it cached.
+      //
+      ICompilationUnit start = getCompilationUnitForType(logger, binaryTypeName);
+      compile(logger, new ICompilationUnit[] {start});
 
-    // Check the cache again. If it's there now, we succeeded.
-    // If it isn't there now, we've already logged the error.
-    //
-    byteCode = doGetByteCodeFromCache(logger, binaryTypeName);
-    if (byteCode != null) {
-      return byteCode.getBytes();
-    } else {
-      throw new UnableToCompleteException();
+      // Check the cache again. If it's there now, we succeeded.
+      // If it isn't there now, we've already logged the error.
+      //
+      byteCode = doGetByteCodeFromCache(logger, binaryTypeName);
+      if (byteCode != null) {
+        return byteCode.getBytes();
+      } else {
+        throw new UnableToCompleteException();
+      }
+    } finally {
+      threadLogger.pop(oldLogger);
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java b/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
index 26dead5..8eb65b8 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java
@@ -103,7 +103,7 @@
 
       try {
         String[] resultTypes = rebindPermOracle.getAllPossibleRebindAnswers(
-            getLogger(), reqType);
+            logger, reqType);
         // Check that each result is instantiable.
         for (int i = 0; i < resultTypes.length; ++i) {
           String typeName = resultTypes[i];
diff --git a/dev/core/src/com/google/gwt/dev/util/log/ThreadLocalTreeLoggerProxy.java b/dev/core/src/com/google/gwt/dev/util/log/ThreadLocalTreeLoggerProxy.java
index d74216e..8b6f218 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/ThreadLocalTreeLoggerProxy.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/ThreadLocalTreeLoggerProxy.java
@@ -33,7 +33,7 @@
   }
 
   public ThreadLocalTreeLoggerProxy(TreeLogger logger) {
-    set(logger);
+    push(logger);
   }
 
   /**
@@ -75,10 +75,16 @@
     }
   }
 
+  public void pop(TreeLogger oldLogger) {
+    perThreadLogger.set(oldLogger);
+  }
+
   /**
    * Sets the logger to which calls are redirected for the current thread.
    */
-  public void set(TreeLogger logger) {
+  public TreeLogger push(TreeLogger logger) {
+    TreeLogger old = perThreadLogger.get();
     perThreadLogger.set(logger);
+    return old;
   }
 }