Ensure that CompiledClass does not keep a live reference to a NameEnvironment.

With the update to JDT 3.13 NameEnvironments keep references to the compiler
object. The compiler object in GWT keeps references to the unit cache which
is a sizeable object.

Change-Id: Ib7c77a1e010e6044450041dab0e67806c947e45c
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java b/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
index e53bbde..1803307 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
@@ -26,6 +26,7 @@
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 
 import java.io.Serializable;
+import java.lang.ref.SoftReference;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -77,7 +78,7 @@
   private CompiledClass enclosingClass;
   private final String internalName;
   private final boolean isLocal;
-  private transient NameEnvironmentAnswer nameEnvironmentAnswer;
+  private transient SoftReference<NameEnvironmentAnswer> nameEnvironmentAnswerReference;
   private String signatureHash;
 
   private final String sourceName;
@@ -192,10 +193,13 @@
   }
 
   NameEnvironmentAnswer getNameEnvironmentAnswer() throws ClassFormatException {
+    NameEnvironmentAnswer nameEnvironmentAnswer = nameEnvironmentAnswerReference == null
+        ? null : nameEnvironmentAnswerReference.get();
     if (nameEnvironmentAnswer == null) {
       ClassFileReader cfr =
           new ClassFileReader(getBytes(), unit.getResourceLocation().toCharArray(), true);
       nameEnvironmentAnswer = new NameEnvironmentAnswer(cfr, null);
+      nameEnvironmentAnswerReference = new SoftReference<>(nameEnvironmentAnswer);
     }
     return nameEnvironmentAnswer;
   }