• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download

<lambda>null1 package org.jetbrains.dokka
2 
3 import com.google.inject.Inject
4 import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
5 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
6 import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
7 import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
8 
9 class DeclarationLinkResolver
10         @Inject constructor(val resolutionFacade: DokkaResolutionFacade,
11                             val refGraph: NodeReferenceGraph,
12                             val logger: DokkaLogger,
13                             val options: DocumentationOptions,
14                             val externalDocumentationLinkResolver: ExternalDocumentationLinkResolver,
15                             val elementSignatureProvider: ElementSignatureProvider) {
16 
17 
18     fun tryResolveContentLink(fromDescriptor: DeclarationDescriptor, href: String): ContentBlock? {
19         val symbol = try {
20             val symbols = resolveKDocLink(resolutionFacade.resolveSession.bindingContext,
21                     resolutionFacade, fromDescriptor, null, href.split('.').toList())
22             findTargetSymbol(symbols)
23         } catch(e: Exception) {
24             null
25         }
26 
27         // don't include unresolved links in generated doc
28         // assume that if an href doesn't contain '/', it's not an attempt to reference an external file
29         if (symbol != null) {
30             val externalHref = externalDocumentationLinkResolver.buildExternalDocumentationLink(symbol)
31             if (externalHref != null) {
32                 return ContentExternalLink(externalHref)
33             }
34             val signature = elementSignatureProvider.signature(symbol)
35             val referencedAt = fromDescriptor.signatureWithSourceLocation()
36 
37             return ContentNodeLazyLink(href, { ->
38                 val target = refGraph.lookup(signature)
39 
40                 if (target == null) {
41                     logger.warn("Can't find node by signature `$signature`, referenced at $referencedAt")
42                 }
43                 target
44             })
45         }
46         if ("/" in href) {
47             return ContentExternalLink(href)
48         }
49         return null
50     }
51 
52     fun resolveContentLink(fromDescriptor: DeclarationDescriptor, href: String) =
53             tryResolveContentLink(fromDescriptor, href) ?: run {
54                 logger.warn("Unresolved link to $href in doc comment of ${fromDescriptor.signatureWithSourceLocation()}")
55                 ContentExternalLink("#")
56             }
57 
58     fun findTargetSymbol(symbols: Collection<DeclarationDescriptor>): DeclarationDescriptor? {
59         if (symbols.isEmpty()) {
60             return null
61         }
62         val symbol = symbols.first()
63         if (symbol is CallableMemberDescriptor && symbol.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
64             return symbol.overriddenDescriptors.firstOrNull()
65         }
66         if (symbol is TypeAliasDescriptor && !symbol.isDocumented(options)) {
67             return symbol.classDescriptor
68         }
69         return symbol
70     }
71 
72 }
73