Community
Participate
Working Groups
20050118 Wrong / strange bindings for references in javadoc to methods with type variables as parameter types. See my comments in the javadoc. /** * @see #add(T) => fine * @see Sub#add(T) => arguable, but I think it's wrong that T binds to T of A<T> * the method binding looks like an 'erasure' binding * @see Sub#add(E) => warning (E cannot be reolved to a type), no binding * @see Unrelated1#add(E) => warning (E cannot be resolved to a type), no binding * @see Unrelated1#add(Object) => using wrong type yields a warning, which is OK * @see Unrelated1#add(Number) => using the method erasure yield no warning * @see Unrelated1#add(Integer) => no warning * @see Unrelated2#add(T) => T binds to T of A<T>, which is wrong */ class A<T>{ public boolean add(T t) { return true; } } class Sub<E extends Number> extends A<E> { public boolean add(E e) { if (e.doubleValue() > 0) return false; return super.add(e); } } class Unrelated1<E extends Number> { public boolean add(E e) { return false; } } interface Unrelated2<E> { boolean add(E e); } interface Unrelated3<T> { boolean add(T t); }
Fix I intend to apply produce following results: /** * @see #add(T) * - no warning * - method binding = Test.add(Object) * - parameter binding = T of A * @see Sub#add(T) * - warning = "The method add(Object) in the type Test is not applicable * for arguments (T)" * -> It's on type Test as Sub.add wouldn't accept Object as parameter... * - method binding = Test.add(Object) * - parameter binding = T of A * -> Nothing to do here, T is resolved to TypeVariable. * It's now hidden by warning... * @see Sub#add(E) * - warning = "E cannot be resolved to a type" * - method binding = Sub.add(E) * - parameter binding = null (sounds OK for an unresolved type) * @see Unrelated1#add(E) * - warning = "E cannot be resolved to a type" * - method binding = Unrelated1.add(E) * - parameter binding = null (sounds OK for an unresolved type) * @see Unrelated1#add(Object) * - warning = "The method add(Number) in the type Unrelated1 is not * applicable for arguments (Object)" * - method binding = Unrelated1.add(Number) * - parameter binding = java.lang.Object * @see Unrelated1#add(Number) => using the method erasure yield no warning * - no warning * - method binding = Unrelated1.add(Number) * - parameter binding = java.lang.Number * @see Unrelated1#add(Integer) => no warning * - no warning * - method binding = Unrelated1.add(Number) * - parameter binding = java.lang.Integer * @see Unrelated2#add(T) * - warning = "The method add(Number) in the type Unrelated1 is not * applicable for arguments (Object)" * - method binding = Unrelated2.add(Object) * - parameter binding = T of A * -> Nothing to do here, T is resolved to TypeVariable. * It's now hidden by warning... */ Please let me know what's your feeling about them, thanks
Stop, stop, stop! The Javadoc tool does not accept '@see' reference containing type parameters! The reference in a see or link tag seems to have to be a RAW reference. Try it with a 1.5 version of the Javadoc tool. What is accepted is /** * @see #add(Object) * @see Sub#add(Object) Resolves to A#foo(Object) * @see Sub#add(Number) * @see Unrelated1#add(Object) * @see Unrelated2#add(Object) */ So the Javadoc tooling should also only allow these. The bindings should all be RAW reference bindings (also for type references! '@see Test')
I guess that the three "stop" are for the three points I'll described below ;-) The fix was based on Javadoc tool tests which obviously uses raw type for method/constructors receiver type reference... If you read *carefully* my example, you'll see that all references (except one) with type parameter are warned by compiler. The only exception is that compiler accepts #add(T) although Javadoc does not. I thought that in this case we should not follow Javadoc behavior which is definitely poor. Another difference with Javadoc tool is for following example: * @see Unrelated1#add(Integer) * - no warning * - method binding = Unrelated1.add(Number) * - parameter binding = java.lang.Integer Again, I thought that Javadoc tool was wrong here and compiler did not have to copy is behavior. If it obviously uses a raw type for type reference then Unrelated1#add(Integer) is a valid reference to method Unrelated1#add. However, for these two differences, I *finally* agree that, even if Javadoc behavior does not sound really smart, compiler has to comply with this behavior. In these cases, Javadoc will not generate reference as they are considered as invalid and our compiler as to reveal this fact... So, I'll stop current implementation as requested and change this behavior to comply with Javadoc tool one. Last point, unfortunately, there's an error in my example. Following case: * @see Unrelated1#add(E) * - warning = "E cannot be resolved to a type" * - method binding = Unrelated1.add(E) * - parameter binding = null (sounds OK for an unresolved type) should have method binding = Unrelated1.add(Object) which is the closest match regarding to the reference... It's a bug of current implementation and will be fixed...
One 'stop' was also targeted to Markus' bug request. It's all about the Javadoc tool, it's our 'compiler'. I assume it follows the specs (I haven't checked these yet, just played with the javadoc tool). If the specs only allow raw references, then all other references have to be errors (or warnings, if you want to be nice). So either there are no bindings, or (if you want to be nice) a guess of the raw binding that could be what the user meant. But you couldn't return a binding like 'Sub.add(E)', or also not Unrelated1.add(Number). There are no such raw method bindings. What exists is Unrelated1.add(Object) or Sub.add(Number).
Ok, second try: /** * @see Test#add(T) * @see #add(T) * - warning = "The method add(Object) in the type Test is not applicable for * the arguments (T)" * - method binding = Test.add(Object) * - parameter binding = T of A * @see Sub#add(T) * - warning = "The method add(Object) in the type Test is not applicable for * the arguments (T)" * - method binding = Test.add(Object) * - parameter binding = T of A * -> Do we need to change this as T natually resolved to TypeVariable? * As compiler raises a warning, it's perhaps not a problem now... * @see Sub#add(E) * - warning = "E cannot be resolved to a type" * - method binding = null * - parameter binding = null * @see Unrelated1#add(E) * - warning = "E cannot be resolved to a type" * - method binding = null * - parameter binding = null * @see Unrelated1#add(Object) * - warning = "The method add(Object) in the type Test is not applicable for * the arguments (Object)" * - method binding = Unrelated1.add(Number) * - parameter binding = java.lang.Object * @see tests.Unrelated1#add(Number) * - no warning * - method binding = Unrelated1.add(Number) * - parameter binding = java.lang.Number * @see Unrelated1#add(Integer) * - warning = "The method add(Object) in the type Test is not applicable for * the arguments (Integer)" * - method binding = Unrelated1.add(Number) * - parameter binding = java.lang.Integer * @see Unrelated2#add(T) * - warning = "The method add(Object) in the type Test is not applicable for * the arguments (T)" * - method binding = Unrelated2.add(Object) * - parameter binding = T of A * -> Do we need to change this as T natually resolved to TypeVariable? * As compiler raises a warning, it's perhaps not a problem now... */
I've splitted your sample in 8 files ( one for each @see tag , expect for 2 first ones which are in same file tests/p1/Test.java) and run Javadoc tool... I get following result (same as our compiler with proposed fix): Generating tests/p1/\Test.html... tests\p1\Test.java:9: warning - Tag @see: can't find add(T) in tests.p1.Test tests\p1\Test.java:9: warning - Tag @see: can't find add(T) in tests.p1.Test Generating tests/p2/\Test.html... tests\p2\Test.java:10: warning - Tag @see: can't find add(T) in tests.p2.Sub Generating tests/p3/\Test.html... tests\p3\Test.java:8: warning - Tag @see: can't find add(E) in tests.p3.Sub Generating tests/p4/\Test.html... tests\p4\Test.java:9: warning - Tag @see: can't find add(E) in tests.Unrelated1 Generating tests/p5/\Test.html... tests\p5\Test.java:10: warning - Tag @see: can't find add(Object) in tests.Unrelated1 Generating tests/p6/\Test.html... Generating tests/p7/\Test.html... tests\p7\Test.java:10: warning - Tag @see: can't find add(Integer) in tests.Unrelated1 Generating tests/p8/\Test.html... tests\p8\Test.java:11: warning - Tag @see: can't find add(T) in tests.Unrelated2 Generating tests/\Unrelated1.html... Generating tests/\Unrelated2.html... Generating tests/\Unrelated3.html...
Looks good to me!
Fixed. Warnings and bindings are as described in comment 5. [jdt-core-internal] Changes done in method internalResolveType(Scope) of ImplicitDocTypeReference (renamed to JavadocImplicitTypeReference), JavadocMessageSend and JavadocAllocationExpression. Test cases #testBug83217* added in JavadocTest_1_* classes
Verified in I20050214-0927 for 3.1M5