+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):
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));
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;
}
/* Search classes */
else
{
- tree sc = class;
- int seen_inner_class = 0;
search_applicable_methods_list (lc, TYPE_METHODS (class),
name, arglist, &list, &all_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++)
{
}
}
- /* 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)
{
return type;
}
+tree
+build_null_signature (type)
+ tree type;
+{
+ return NULL_TREE;
+}
+
/* Return the signature string for the arguments of method type TYPE. */
tree
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. */