On Wed, 3 Apr 2024 18:14:39 GMT, Pavel Rappo <pra...@openjdk.org> wrote:

>> Creating a link to a constructor or a method or comparing constructors or 
>> methods __does not__ factor in type parameters. When constructors or methods 
>> are overloaded and differ only in type parameters -- a situation which is 
>> absent in JDK API, but present elsewhere -- that causes significant defects, 
>> such as:
>> 
>>   - missing entries in summary tables, lists and indexes,
>>   - duplicating links in the table of contents.
>> 
>> This PR fixes those defects, and the fix is two-fold. Firstly, we update 
>> comparators to consider type parameters. That takes care of missing 
>> constructors and methods. Secondly, we update id (anchor) and link 
>> generation to always use the "erased" notation. That takes care of 
>> duplicating links.
>> 
>> What's the "erased" notation? Suppose we have the following method:
>> 
>>     <T extends String> T m(T arg)
>> 
>> The current notation refers to it as `m(T)`. That works fine until there's 
>> no other method, such as
>> 
>>     <T> T m(T arg)
>> 
>> In which case, the current notation will produce a collision: `m(T)`. By 
>> contrast, the erased notation for those two methods is `m(java.lang.String)` 
>> and `m(java.lang.Object)` respectively. No collision.
>> 
>> While longer, I believe that the erased notation is collision-proof. Why? 
>> Because [JLS 8.4.2][] says that "it is a compile-time error to declare two 
>> methods with override-equivalent signatures in a class". Which means that 
>> for any two constructors or methods the erasure of their signatures must 
>> differ, or else it won't compile.
>> 
>> The change is pretty straightforward, except for some test fallout that 
>> required attention.
>> 
>> [JLS 8.4.2]: 
>> https://docs.oracle.com/javase/specs/jls/se22/html/jls-8.html#jls-8.4.2
>
> Pavel Rappo has updated the pull request with a new target base due to a 
> merge or a rebase. The incremental webrev excludes the unrelated changes 
> brought in by the merge/rebase. The pull request contains 11 additional 
> commits since the last revision:
> 
>  - Merge branch 'master' into 8325088
>  - Remove registration phase
>    
>    Makes the code more robust and simple.
>  - Merge branch 'master' into 8325088
>  - Update copyright years
>    
>    Note: any commit hashes below might be outdated due to subsequent
>    history rewriting (e.g. git rebase).
>    
>     - revert 
> src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIndexBuilder.java
>  as spurious
>     - revert 
> test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java
>  as spurious
>     - revert 
> test/langtools/jdk/javadoc/doclet/testMemberSummary/TestMemberSummary.java as 
> spurious
>     - revert 
> test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java
>  as spurious
>     - revert test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering.java 
> as spurious
>     - revert 
> test/langtools/jdk/javadoc/doclet/testOverriddenMethods/TestOverrideMethods.java
>  as spurious
>     - revert 
> test/langtools/jdk/javadoc/doclet/testPrivateClasses/TestPrivateClasses.java 
> as spurious
>     - revert test/langtools/jdk/javadoc/doclet/testSeeTag/TestSeeTag.java as 
> spurious
>     - revert 
> test/langtools/jdk/javadoc/doclet/testVisibleMembers/TestVisibleMembers.java 
> as spurious
>  - Use erased notation only when necessary
>    
>    Partially reverts 4f028269, which is the bulk of the previous solution,
>    then adds a centralised ID registry for executable elements.
>    
>    The centralised registry is an alternative solution, which is more
>    gentle and less disruptive to tests and composability (-link and
>    -linkoffline).
>  - Update copyright years
>    
>    Note: any commit hashes below might be outdated due to subsequent
>    history rewriting (e.g. git rebase).
>    
>     + update 
> src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIndexBuilder.java
>  due to 4f0282694fd
>     + update 
> test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java
>  due to 4f0282694fd
>     + update 
> test/langtools/jdk/javadoc/doclet/testMemberSummary/TestMemberSummary.java 
> due to 4f0282694fd
>     + update 
> test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java
>  due to 4f0282694fd
>     + update test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering....

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriter.java
 line 195:

> 193:         HtmlId erasureAnchor = htmlIds.forErasure(constructor);
> 194:         if (erasureAnchor != null
> 195:                 && !erasureAnchor.name().equals(memberAnchor.name())) {

Is this redundant now that the erasure handling is encapsulated within 
forMember?

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java
 line 562:

> 560:                 && e.getKind() != ElementKind.METHOD)
> 561:             throw new 
> IllegalArgumentException(String.valueOf(e.getKind()));
> 562:         var vmt = configuration.getVisibleMemberTable((TypeElement) 
> e.getEnclosingElement());

Will the vmt differ if we specify `-private`? And say if we have 2 methods like:

private <T extends Runnable> void method(T arg) {}
public <T extends Number> void method(T arg) {}

Will the Number public method be consistently erased whether or not `-private` 
is set?

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java
 line 571:

> 569:         var list = Stream.concat(Stream.concat(ctors.stream(), 
> methods.stream()), otherMethods.stream())
> 570:                 .map(e1 -> (ExecutableElement) e1)
> 571:                 .toList();

We can maybe do something like:

record ErasureCheck(ExecutableElement element, HtmlId erasure) {}

// ...
    .map(e1 -> new ErasureCheck(e1, forErasure(e1)))
    .collect(Collectors.groupingBy(check -> check.erasure == null));

// 1. Map all elements that can _only_ be addressed by the simple id
for (var m : groups.get(true)) {...}

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/18519#discussion_r1550637811
PR Review Comment: https://git.openjdk.org/jdk/pull/18519#discussion_r1550635930
PR Review Comment: https://git.openjdk.org/jdk/pull/18519#discussion_r1550643002

Reply via email to