partial patch for inner class method search

Per Bothner per@bothner.com
Sat Apr 21 17:34:00 GMT 2001


While attempting to compile Jigsaw, I got a a number of errors like this:

./NegotiatedFrame.java: In class `org.w3c.jigsaw.frames.NegotiatedFrame':
./NegotiatedFrame.java: In method `org.w3c.jigsaw.frames.NegotiatedFrame.negotiateContentEncoding(java.util.Vector,org.w3c.jigsaw.http.Request)':
./NegotiatedFrame.java:471: Can't find method `getResource()' in type `org.w3c.jigsaw.frames.NegotiatedFrame$VariantState'. Candidates are:
  `org.w3c.jigsaw.frames.NegotiatedFrame$VariantState.getResource()' in `org.w3c.jigsaw.frames.NegotiatedFrame$VariantState'
  `org.w3c.tools.resources.ResourceFrame.getResource()' in `org.w3c.tools.resources.ResourceFrame'.
                ResourceReference rr  = state.getResource();

Looking at the code, it is clear that the first candidate is the
correct one, and the second is bogus.  The problem is in the function
find_applicable_accessible_methods_list, which searches the
surrounding classes of an inner class.  This is contrary to the JLS,
but is fixed by my patch to find_applicable_accessible_methods_list,
which I'm fairly confident about.  However, to compensate we need to
impleement the case that a MethodName is an Identifier, as specified
in JLS (2nd ed) 15.12.1.  I've tried to do that below in
patch_method_invocation, but I suspect it is not correct.  For one
thing, the new code should only run when the MethodName *is* an
Identifier, and I'm not sure how to do that.  (I haven't run the
testcase, as I think it likely the code is wrong/incomplete as is.)
Alex, could you take a look?

Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.97.2.10
diff -u -p -r1.97.2.10 java-tree.h
--- java-tree.h	2001/04/21 00:06:04	1.97.2.10
+++ java-tree.h	2001/04/22 00:15:31
@@ -958,6 +958,7 @@ extern tree lookup_java_constructor PARA
 extern tree lookup_java_method PARAMS ((tree, tree, tree));
 extern tree lookup_argument_method PARAMS ((tree, tree, tree));
 extern tree lookup_argument_method2 PARAMS ((tree, tree, tree));
+extern int has_method PARAMS ((tree, tree));
 extern tree promote_type PARAMS ((tree));
 extern tree get_constant PARAMS ((struct JCF*, int));
 extern tree get_name_constant PARAMS ((struct JCF*, int));
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.251.2.18
diff -u -p -r1.251.2.18 parse.y
--- parse.y	2001/04/20 15:53:11	1.251.2.18
+++ parse.y	2001/04/22 00:15:40
@@ -9897,7 +9897,27 @@ patch_method_invocation (patch, primary,
          alternate class is specified. */
       else
 	{
-	  class_to_search = (where ? where : current_class);
+	  if (where != NULL_TREE)
+	    class_to_search = where;
+	  else
+	    {
+	      class_to_search = current_class;
+
+	      for (;;)
+		{
+		  if (has_method (class_to_search, name))
+		    break;
+		  if (! INNER_CLASS_TYPE_P (class_to_search))
+		    {
+		      parse_error_context (wfl,
+					   "No method named `%s' in scope",
+					   IDENTIFIER_POINTER (name));
+		      PATCH_METHOD_RETURN_ERROR ();
+		    }
+		  class_to_search
+		    = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_to_search)));
+		}
+	    }
 	  lc = 0;
 	}
 
@@ -10512,8 +10532,6 @@ find_applicable_accessible_methods_list 
   /* Search classes */
   else
     {
-      tree sc = class;
-      int seen_inner_class = 0;
       search_applicable_methods_list (lc, TYPE_METHODS (class), 
 				      name, arglist, &list, &all_list);
 
@@ -10530,7 +10548,7 @@ find_applicable_accessible_methods_list 
       /* We must search all interfaces of this class */
       if (!lc)
       {
-	tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
+	tree basetype_vec = TYPE_BINFO_BASETYPES (class);
 	int n = TREE_VEC_LENGTH (basetype_vec), i;
 	for (i = 1; i < n; i++)
 	  {
@@ -10544,24 +10562,6 @@ find_applicable_accessible_methods_list 
 	      }
 	  }
       }
-
-      /* Search enclosing context of inner classes before looking
-         ancestors up. */
-      while (!lc && INNER_CLASS_TYPE_P (class))
-	{
-	  tree rlist;
-	  seen_inner_class = 1;
-	  class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
-	  rlist = find_applicable_accessible_methods_list (lc, class, 
-							   name, arglist);
-	  list = chainon (rlist, list);
-	}
-
-      if (!lc && seen_inner_class 
-	  && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
-	class = CLASSTYPE_SUPER (sc);
-      else
-	class = sc;
 
       /* Search superclass */
       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/typeck.c,v
retrieving revision 1.37.2.2
diff -u -p -r1.37.2.2 typeck.c
--- typeck.c	2001/02/19 20:43:33	1.37.2.2
+++ typeck.c	2001/04/22 00:15:41
@@ -579,6 +579,13 @@ get_type_from_signature (tree signature)
   return type;
 }
 
+tree
+build_null_signature (type)
+     tree type;
+{
+  return NULL_TREE;
+}
+
 /* Return the signature string for the arguments of method type TYPE. */
 
 tree
@@ -761,9 +768,20 @@ lookup_java_method (searched_class, meth
 		    method_signature, build_java_signature);
 }
 
-/* Search in class SEARCHED_CLASS (an its superclasses) for a method
+/* Return true iff CLASS (or its ancestors) has a method METHOD_NAME. */
+
+int
+has_method (class, method_name)
+     tree class;
+     tree method_name;
+{
+  return lookup_do (class, NULL_TREE,  method_name,
+		    NULL_TREE, build_null_signature) != NULL_TREE;
+}
+
+/* Search in class SEARCHED_CLASS (and its superclasses) for a method
    matching METHOD_NAME and signature SIGNATURE.  Also search in
-   SEARCHED_INTERFACE (an its superinterfaces) for a similar match.
+   SEARCHED_INTERFACE (and its superinterfaces) for a similar match.
    Return the matched method DECL or NULL_TREE.  SIGNATURE_BUILDER is
    used on method candidates to build their (sometimes partial)
    signature.  */

-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/



More information about the Java mailing list