Skip to content

Conversation

BlaBlaHuman
Copy link

No description provided.

@BlaBlaHuman
Copy link
Author

Hi, please pay close attention to all the examples and details in the tag-sections chapter. I tried to gather all the information on them I could from our discussions and from the original KEEP, however, I might have misunderstood something.

And I'm still not quite sure about the details of this multi-resolution. In the KEEP I mentioned that we should return all the symbols the compiler could resolve this reference to (i.e. all symbols from some scope), not just symbols of the same kind. It seems like a valid and requested feature, and there won't be too many symbols with the same name in the same scope anyways. It's probably more important than just handling overloads by returning multiple symbols of the same kind.

/**
 * @see Foo - now it's able to point to the function
 */
interface Foo 

fun Foo(): Foo = object : Foo {}

@nikitabobko
Copy link
Member

BlaBlaHuman wants to merge 1 commit into kdoc/Streamline-KDoc-ambiguity-references from kdoc/omak/Streamline-KDoc-ambiguity-references

The proposal is already merged to the main branch https://github.com/Kotlin/KEEP/blob/main/proposals/KEEP-0389-kdoc-streamline-KDoc-ambiguity-references.md, so please update the proposal in the main branch, avoid merging non-main branches into each other

@BlaBlaHuman BlaBlaHuman changed the base branch from kdoc/Streamline-KDoc-ambiguity-references to main July 15, 2025 10:21
@BlaBlaHuman BlaBlaHuman force-pushed the kdoc/omak/Streamline-KDoc-ambiguity-references branch from d6a1d6f to 9a3f9b8 Compare July 15, 2025 10:25
Copy link

@marcopennekamp marcopennekamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comprehensive update! 🙌

I left a lot of comments in the review, but I think my main points of contention are:

  1. We need clear definitions for the key concepts, such as the "KDoc context", the exact steps of the resolution algorithm, and generally just more precise formulations for a lot of things.
  2. I think the resolution algorithm could be described more clearly by mentioning the exact layers (self-links, scopes, global references, packages), essentially rearranging some sections a bit to arrive at a single, well-described algorithm.
  3. We need to discuss property resolution and whether (1) properties should be resolved as first segments during multi-segment resolution and (2) legally accessing a property (e.g. [name.length]) in KDoc references is desired in the future.

And this definitely needs another round of copyediting, but let's get the specifics right first. 👍

Comment on lines 883 to 886
* Before performing a scope transformation for relative names, the resolver has to make sure that there are no
non-function declarations matching some prefix of the given name in a more local scope.
If such a declaration is found in some scope, then there is no need to process all further scopes,
as the compiler would resolve this prefix to the declaration in this scope.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the wording is quite roundabout here. For example, "prefix" can suggest a lot of incorrect things, like a prefix of the string name, or more than the first segment (a multi-segment prefix of a multi-segment name).

I would specifically concentrate in the definitions in this whole section on "resolving the first segment" and whenever that resolves to a non-function, we have deterministically picked the scope that we want to apply relative resolution to.

And then we don't need any special wording for "if a conflicting declaration is found in a local scope, the resolver should not proceed to further scopes/global retrieval", because the outlined algorithm clearly stops where the first segment is resolved to a non-function.

Copy link
Contributor

@vmishenev vmishenev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the additions and proofreading 👍

I have not properly checked the 'Implementation details' section, as I am not familiar with the implementation, although the described logic seems correct.

I would also like to see the final version of KEEP after editing.

Copy link
Contributor

@whyoleg whyoleg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Great work!
I've left mostly some questions regarding some of the examples, as the other parts already have a lot of good feedback!

val A = 5

fun usage() {
A.B.C() // UNRESOLVED
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you help me to understand, why we don't resolve this link, but resolve the link above, with fun A()? (and the same for example with receiver below)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the compiler does so. Paste these code snippets in your IDE and see how the resolution changes depending on the type of A here. If it encounters something other than a function while trying to resolve some segment (A in this case), i.e. a property or a class, it stops and considers the reference to be unresolved. So the term "non-function" is correct here. I'll try to make it more transparent

Comment on lines 761 to 769
The resolver should iterate through scopes from local to global
and look for a chain of nested classifiers starting in the current scope.
If this chain is found,
the resolver just picks this classifier member scope and looks for symbols with the given short name.
However, if, at some point of this symbols-by-segment search,
the resolver comes across some non-function symbol from which
it's impossible to continue the chain, the resolver should stop and consider this link as unresolved.
Examples of such cases are classes with no nested classifiers matching the next segment and properties.
Again, see [following chapter](#restrictions-of-multi-segment-names-resolution) for more info.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I ask a bit of an unrelated question?
Why did the question about properties (e.g., [name.length]) even appear in the discussion? I mean, this isn't a supported KDoc syntax, and it is not mentioned in the document (as far as I see).
I mean, maybe I'm missing something obvious, or compiler-related knowledge, but for me, this feels like a whole new feature for KDoc, similar to overloads, and so should be discussed totally separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants