Fix method search wrt scope of inner classes to match JLS2.
authorPer Bothner <per@bothner.com>
Thu, 26 Apr 2001 19:40:34 +0000 (12:40 -0700)
committerPer Bothner <bothner@gcc.gnu.org>
Thu, 26 Apr 2001 19:40:34 +0000 (12:40 -0700)
From-SVN: r41604

gcc/java/ChangeLog
gcc/java/java-tree.h
gcc/java/parse.y
gcc/java/typeck.c

index b9bef8a..d0f04ce 100644 (file)
@@ -1,5 +1,16 @@
 2001-04-26  Per Bothner  <per@bothner.com>
 
+       Fix method search wrt scope of inner classes to match JLS2.
+       * typeck.c (build_null_signature):  New static function.
+       (has_method):  New function.  Uses build_null_signature and lookup_do.
+       * java-tree.h (has_method):  New declaration.
+       * parse.y (find_applicable_accessible_methods_list):  Do not search
+       context of inner classes here.
+       (patch_method_invocation):  Search scope, ie. current and outer clases,
+       for method matching simple name, to find class.
+
+2001-04-26  Per Bothner  <per@bothner.com>
+
        * jcf-write.c (generate_bytecode_insns case SWITCH_EXPR):
        Fix thinko:  If a single case, use if_icmpeq, not ifeq.
 
index 9d62ef3..914ba81 100644 (file)
@@ -960,6 +960,7 @@ extern tree lookup_java_constructor PARAMS ((tree, tree));
 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 fb22d81..a8084ee 100644 (file)
@@ -9882,7 +9882,29 @@ patch_method_invocation (patch, primary, where, from_super,
          alternate class is specified. */
       else
        {
-         class_to_search = (where ? where : current_class);
+         if (where != NULL_TREE)
+           class_to_search = where;
+         else if (QUALIFIED_P (name))
+           class_to_search = current_class;
+         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;
        }
 
@@ -10488,8 +10510,6 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
   /* Search classes */
   else
     {
-      tree sc = class;
-      int seen_inner_class = 0;
       search_applicable_methods_list (lc, TYPE_METHODS (class), 
                                      name, arglist, &list, &all_list);
 
@@ -10506,7 +10526,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
       /* 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++)
          {
@@ -10521,24 +10541,6 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
          }
       }
 
-      /* 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 c6bbd7a..cc514d6 100644 (file)
@@ -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, method_name, method_signature)
                    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, class,  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.  */