Remove JProgram.jsniMap in favor of local accounting.

http://gwt-code-reviews.appspot.com/1445801/

Review by: jbrosenberg@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10171 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
index d0563b9..ca36e85 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -311,8 +311,6 @@
    */
   public final List<List<JMethod>> entryMethods = new ArrayList<List<JMethod>>();
 
-  public final Map<String, JNode> jsniMap = new HashMap<String, JNode>();
-
   public final JTypeOracle typeOracle = new JTypeOracle(this);
 
   /**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniClassLiteral.java b/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniClassLiteral.java
new file mode 100644
index 0000000..c26a92d
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniClassLiteral.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.jjs.ast.js;
+
+import com.google.gwt.dev.jjs.SourceInfo;
+import com.google.gwt.dev.jjs.ast.JClassLiteral;
+import com.google.gwt.dev.jjs.ast.JType;
+
+/**
+ * JSNI reference to a Java class literal.
+ */
+public class JsniClassLiteral extends JClassLiteral {
+
+  private final String ident;
+
+  public JsniClassLiteral(SourceInfo info, String ident, JType type) {
+    super(info, type);
+    this.ident = ident;
+  }
+
+  public String getIdent() {
+    return ident;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniMethodBody.java b/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniMethodBody.java
index a64b394..0c2fcc4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniMethodBody.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniMethodBody.java
@@ -18,7 +18,6 @@
 import com.google.gwt.dev.jjs.SourceInfo;
 import com.google.gwt.dev.jjs.ast.Context;
 import com.google.gwt.dev.jjs.ast.JAbstractMethodBody;
-import com.google.gwt.dev.jjs.ast.JClassLiteral;
 import com.google.gwt.dev.jjs.ast.JVisitor;
 import com.google.gwt.dev.js.ast.JsContext;
 import com.google.gwt.dev.js.ast.JsFunction;
@@ -37,7 +36,7 @@
  */
 public class JsniMethodBody extends JAbstractMethodBody {
 
-  private List<JClassLiteral> classRefs = Collections.emptyList();
+  private List<JsniClassLiteral> classRefs = Collections.emptyList();
   private JsFunction jsFunction = null;
   private List<JsniFieldRef> jsniFieldRefs = Collections.emptyList();
   private List<JsniMethodRef> jsniMethodRefs = Collections.emptyList();
@@ -51,7 +50,7 @@
   /**
    * Adds a reference from this method to a Java class literal.
    */
-  public void addClassRef(JClassLiteral ref) {
+  public void addClassRef(JsniClassLiteral ref) {
     classRefs = Lists.add(classRefs, ref);
   }
 
@@ -72,7 +71,7 @@
   /**
    * Return this method's references to Java class literals.
    */
-  public List<JClassLiteral> getClassRefs() {
+  public List<JsniClassLiteral> getClassRefs() {
     return classRefs;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
index 75815f1..f732bc9 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -90,6 +90,7 @@
 import com.google.gwt.dev.jjs.ast.JVariable;
 import com.google.gwt.dev.jjs.ast.JVariableRef;
 import com.google.gwt.dev.jjs.ast.JWhileStatement;
+import com.google.gwt.dev.jjs.ast.js.JsniClassLiteral;
 import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
 import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
 import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
@@ -2843,8 +2844,9 @@
         });
       }
 
-      private void processClassLiteral(JClassLiteral classLiteral, JsContext ctx) {
+      private void processClassLiteral(JsNameRef nameRef, SourceInfo info, JType type, JsContext ctx) {
         assert !ctx.isLvalue();
+        JsniClassLiteral classLiteral = new JsniClassLiteral(info, nameRef.getIdent(), type);
         nativeMethodBody.addClassRef(classLiteral);
       }
 
@@ -2885,24 +2887,21 @@
         // TODO: make this tighter when we have real source info
         // JSourceInfo info = translateInfo(nameRef.getInfo());
         String ident = nameRef.getIdent();
-        JNode node = program.jsniMap.get(ident);
+        JNode node = jsniMap.get(ident);
         if (node == null) {
           node = findJsniRefTarget(info, ident);
           if (node == null) {
             return; // already reported error
           }
-          if (node instanceof JType) {
-            node = new JClassLiteral(info.makeChild(), (JType) node);
-          }
-          program.jsniMap.put(ident, node);
+          jsniMap.put(ident, node);
         }
 
         if (node instanceof JField) {
           processField(nameRef, info, (JField) node, ctx);
         } else if (node instanceof JMethod) {
           processMethod(nameRef, info, (JMethod) node, ctx);
-        } else if (node instanceof JClassLiteral) {
-          processClassLiteral((JClassLiteral) node, ctx);
+        } else if (node instanceof JType) {
+          processClassLiteral(nameRef, info, (JType) node, ctx);
         } else {
           throw new InternalCompilerException(node,
               "JSNI reference to something other than a class, field, or method?", null);
@@ -2912,6 +2911,8 @@
 
     private JDeclaredType currentClass;
 
+    private final Map<String, JNode> jsniMap = new HashMap<String, JNode>();
+
     private final Map<JsniMethodBody, AbstractMethodDeclaration> jsniMethodMap;
 
     private final JProgram program;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 66e372d..33bcd91 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -86,6 +86,8 @@
 import com.google.gwt.dev.jjs.ast.JVisitor;
 import com.google.gwt.dev.jjs.ast.JWhileStatement;
 import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
+import com.google.gwt.dev.jjs.ast.js.JsniClassLiteral;
+import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
 import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
 import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
 import com.google.gwt.dev.jjs.ast.js.JsonArray;
@@ -1312,6 +1314,17 @@
 
     @Override
     public boolean visit(JsniMethodBody x, Context ctx) {
+      final Map<String, JNode> jsniMap = new HashMap<String, JNode>();
+      for (JsniClassLiteral ref : x.getClassRefs()) {
+        jsniMap.put(ref.getIdent(), ref.getField());
+      }
+      for (JsniFieldRef ref : x.getJsniFieldRefs()) {
+        jsniMap.put(ref.getIdent(), ref.getField());
+      }
+      for (JsniMethodRef ref : x.getJsniMethodRefs()) {
+        jsniMap.put(ref.getIdent(), ref.getTarget());
+      }
+
       final JsFunction jsFunc = x.getFunc();
 
       // replace all JSNI idents with a real JsName now that we know it
@@ -1331,7 +1344,7 @@
             JsNameRef ref = (JsNameRef) x.getQualifier();
             String ident = ref.getIdent();
             if (isJsniIdent(ident)) {
-              JNode node = program.jsniMap.get(ident);
+              JNode node = jsniMap.get(ident);
               assert node instanceof JConstructor;
               assert ref.getQualifier() == null;
               JsName jsName = names.get(node);
@@ -1348,12 +1361,8 @@
         public void endVisit(JsNameRef x, JsContext ctx) {
           String ident = x.getIdent();
           if (isJsniIdent(ident)) {
-            JNode node = program.jsniMap.get(ident);
+            JNode node = jsniMap.get(ident);
             assert (node != null);
-            if (node instanceof JClassLiteral) {
-              node = ((JClassLiteral) node).getField();
-              assert node != null;
-            }
             if (node instanceof JField) {
               JField field = (JField) node;
               JsName jsName = names.get(field);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
index 0812f5b..aa7b0a4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -88,6 +88,7 @@
 import com.google.gwt.dev.jjs.ast.JUnaryOperator;
 import com.google.gwt.dev.jjs.ast.JVariable;
 import com.google.gwt.dev.jjs.ast.JWhileStatement;
+import com.google.gwt.dev.jjs.ast.js.JsniClassLiteral;
 import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
 import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
 import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
@@ -232,9 +233,6 @@
 
     /**
      * Resolves local references to function parameters, and JSNI references.
-     * 
-     * TODO: move more error reporting to
-     * {@link com.google.gwt.dev.javac.JsniChecker}.
      */
     private class JsniResolver extends JsModVisitor {
       private final JsniMethodBody nativeMethodBody;
@@ -253,7 +251,7 @@
             assert ident.startsWith("@null::");
           } else if (binding instanceof TypeBinding) {
             JType type = typeMap.get((TypeBinding) binding);
-            processClassLiteral(type, info, ctx);
+            processClassLiteral(x, info, type, ctx);
           } else if (binding instanceof FieldBinding) {
             JField field = typeMap.get((FieldBinding) binding);
             processField(x, info, field, ctx);
@@ -264,9 +262,9 @@
         }
       }
 
-      private void processClassLiteral(JType type, SourceInfo info, JsContext ctx) {
+      private void processClassLiteral(JsNameRef nameRef, SourceInfo info, JType type, JsContext ctx) {
         assert !ctx.isLvalue();
-        JClassLiteral classLiteral = new JClassLiteral(info, type);
+        JsniClassLiteral classLiteral = new JsniClassLiteral(info, nameRef.getIdent(), type);
         nativeMethodBody.addClassRef(classLiteral);
       }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
index 0b67077..a00ca3b 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
@@ -209,7 +209,6 @@
       if (isPruned(x.getField())) {
         String ident = x.getIdent();
         JField nullField = program.getNullField();
-        program.jsniMap.put(ident, nullField);
         JsniFieldRef nullFieldRef =
             new JsniFieldRef(x.getSourceInfo(), ident, nullField, x.getEnclosingType(), x
                 .isLvalue());
@@ -223,7 +222,6 @@
       if (isPruned(x.getTarget())) {
         String ident = x.getIdent();
         JMethod nullMethod = program.getNullMethod();
-        program.jsniMap.put(ident, nullMethod);
         JsniMethodRef nullMethodRef =
             new JsniMethodRef(x.getSourceInfo(), ident, nullMethod, program.getJavaScriptObject());
         ctx.replaceMe(nullMethodRef);