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