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

AltStyle によって変換されたページ (->オリジナル) /