diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ModuleDependencyMapper.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ModuleDependencyMapper.kt index 64b53ac1e2a..936a10420e4 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ModuleDependencyMapper.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ModuleDependencyMapper.kt @@ -114,7 +114,7 @@ fun createModuleResolverProvider( ) } -private fun collectAllModuleInfosFromIdeaModel(project: Project): List { +fun collectAllModuleInfosFromIdeaModel(project: Project): List { val ideaModules = ModuleManager.getInstance(project).modules.toList() val modulesSourcesInfos = ideaModules.flatMap { listOf(it.productionSourceInfo(), it.testSourceInfo()) } diff --git a/idea/src/org/jetbrains/kotlin/idea/kdoc/IdeSampleResolutionService.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/IdeSampleResolutionService.kt similarity index 70% rename from idea/src/org/jetbrains/kotlin/idea/kdoc/IdeSampleResolutionService.kt rename to idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/IdeSampleResolutionService.kt index 583340504a4..fa3828dfbfd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/kdoc/IdeSampleResolutionService.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/IdeSampleResolutionService.kt @@ -19,8 +19,11 @@ package org.jetbrains.kotlin.idea.kdoc import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.collectAllModuleInfosFromIdeaModel +import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.idea.stubindex.KotlinClassShortNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinFunctionShortNameIndex import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.BindingContext @@ -29,16 +32,29 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class IdeSampleResolutionService(val project: Project) : SampleResolutionService { override fun resolveSample(context: BindingContext, fromDescriptor: DeclarationDescriptor, resolutionFacade: ResolutionFacade, qualifiedName: List): Collection { + val allScope = GlobalSearchScope.projectScope(project) + val shortName = qualifiedName.lastOrNull() ?: return emptyList() - val functions = KotlinFunctionShortNameIndex.getInstance().get(shortName, project, allScope) + val targetFqName = FqName.fromSegments(qualifiedName) + val functions = KotlinFunctionShortNameIndex.getInstance().get(shortName, project, allScope).asSequence() + val classes = KotlinClassShortNameIndex.getInstance().get(shortName, project, allScope).asSequence() - val descriptors = functions.asSequence() + val descriptors = (functions + classes) .filter { it.fqName == targetFqName } .map { it.resolveToDescriptor(BodyResolveMode.PARTIAL) } // TODO Filter out not visible due dependencies config descriptors .toList() - return descriptors + if(descriptors.isNotEmpty()) + return descriptors + + val packageDescriptors = collectAllModuleInfosFromIdeaModel(project) + .asSequence() + .map { resolutionFacade.findModuleDescriptor(it)?.getPackage(targetFqName) } + .filterNotNull() + .filterNot { it.isEmpty() } + + return packageDescriptors.toList() } } \ No newline at end of file diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt index 6057a3f80e7..1b1d1fee8d6 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt @@ -148,7 +148,7 @@ class KDocNameCompletionSession( val qualifiedLink = kDocLink.getLinkText().split('.').dropLast(1) val nameFilter = descriptorNameFilter.toNameFilter() if (qualifiedLink.isNotEmpty()) { - val parentDescriptors = resolveKDocLink(bindingContext, resolutionFacade, declarationDescriptor, null, qualifiedLink) + val parentDescriptors = resolveKDocLink(bindingContext, resolutionFacade, declarationDescriptor, kDocLink.getTagIfSubject(), qualifiedLink) val childDescriptorsOfPartialLink = parentDescriptors.asSequence().flatMap { val scope = getKDocLinkResolutionScope(resolutionFacade, it) collectDescriptorsFromScope(scope, nameFilter, false) diff --git a/idea/testData/kdoc/multiModuleSamples/fqName/code/usage.kt b/idea/testData/kdoc/multiModuleSamples/fqName/code/usage.kt new file mode 100644 index 00000000000..59d5ed9a854 --- /dev/null +++ b/idea/testData/kdoc/multiModuleSamples/fqName/code/usage.kt @@ -0,0 +1,19 @@ +/** + * @sample samples.SampleGroup.mySample + * @sample samples.megasamples.MegaSamplesGroup.megaSample + * @sample samples.notindir.NotInDirSamples.sssample + * @sample smaplez.a.b.c.Samplez.sssample + */ +fun some() { + +} + + +//INFO:
public fun some(): Unit defined in root package

+//INFO:
Samples:
samples.SampleGroup.mySample

+//INFO: println("Hello, world")
+//INFO: 
samples.megasamples.MegaSamplesGroup.megaSample

+//INFO: println("...---...")
+//INFO: 
samples.notindir.NotInDirSamples.sssample

+//INFO: println("location is samplesTest/")
+//INFO: 
smaplez.a.b.c.Samplez.sssample
// Unresolved
diff --git a/idea/testData/kdoc/multiModuleSamples/fqName/samples/EMPTY b/idea/testData/kdoc/multiModuleSamples/fqName/samples/EMPTY new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/notInDirectorySamples.kt b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/notInDirectorySamples.kt new file mode 100644 index 00000000000..01a6f46ec7b --- /dev/null +++ b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/notInDirectorySamples.kt @@ -0,0 +1,7 @@ +package samples.notindir + +object NotInDirSamples { + fun sssample() { + println("location is samplesTest/") + } +} \ No newline at end of file diff --git a/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samples/megasamples/cool.kt b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samples/megasamples/cool.kt new file mode 100644 index 00000000000..96da6634a91 --- /dev/null +++ b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samples/megasamples/cool.kt @@ -0,0 +1,7 @@ +package samples.megasamples + +object MegaSamplesGroup { + fun megaSample() { + println("...---...") + } +} \ No newline at end of file diff --git a/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samples/sample.kt b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samples/sample.kt new file mode 100644 index 00000000000..545d53614d6 --- /dev/null +++ b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samples/sample.kt @@ -0,0 +1,7 @@ +package samples + +object SampleGroup { + fun mySample() { + println("Hello, world") + } +} \ No newline at end of file diff --git a/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samplez.kt b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samplez.kt new file mode 100644 index 00000000000..fc26990d24b --- /dev/null +++ b/idea/testData/kdoc/multiModuleSamples/fqName/samplesTest/samplez.kt @@ -0,0 +1,7 @@ +package samplez.a.b.c + +object Samplez { + fun sssample() { + println("samplez") + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/kdoc/KDocSampleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/kdoc/KDocSampleTest.kt index 3739675f755..fd35eb02366 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/kdoc/KDocSampleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/kdoc/KDocSampleTest.kt @@ -21,8 +21,13 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess import com.intellij.rt.execution.junit.FileComparisonFailure +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest.wrapToFileComparisonFailure import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest +import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File @@ -44,10 +49,47 @@ class KDocSampleTest : AbstractMultiModuleTest() { samples.addDependency(code) - doTest("simple/code/usage.kt") + doInfoTest("simple/code/usage.kt") } - fun doTest(path: String) { + fun testFqName() { + + val code = module("code") + val samples = module("samples", hasTestRoot = true) + + samples.addDependency(code) + + doInfoTest("fqName/code/usage.kt") + doResolveTest("fqName/code/usage.kt", "samples") + doResolveTest("fqName/code/usage.kt", "samples.SampleGroup") + doResolveTest("fqName/code/usage.kt", "samples.megasamples") + doResolveTest("fqName/code/usage.kt", "samples.megasamples.MegaSamplesGroup") + doResolveTest("fqName/code/usage.kt", "samples.notindir") + doResolveTest("fqName/code/usage.kt", "samples.notindir.NotInDirSamples") + doResolveTest("fqName/code/usage.kt", "samplez") + doResolveTest("fqName/code/usage.kt", "samplez.a") + doResolveTest("fqName/code/usage.kt", "samplez.a.b") + doResolveTest("fqName/code/usage.kt", "samplez.a.b.c") + doResolveTest("fqName/code/usage.kt", "samplez.a.b.c.Samplez") + } + + fun doResolveTest(path: String, link: String) { + + configureByFile(path) + val documentationManager = DocumentationManager.getInstance(myProject) + val targetElement = documentationManager.findTargetElement(myEditor, file) + + targetElement as KtElement + + val bindingContext = targetElement.analyze() + val descriptor = bindingContext[DECLARATION_TO_DESCRIPTOR, targetElement]!! + val kdoc = descriptor.findKDoc()!! as KDocSection + val resolutionFacade = targetElement.getResolutionFacade() + assertNotEmpty(resolveKDocLink(bindingContext, resolutionFacade, descriptor, kdoc.findTagByName("sample")!!, link.split("."))) + + } + + fun doInfoTest(path: String) { val testDataFile = File(testPath, path) configureByFile(path) val documentationManager = DocumentationManager.getInstance(myProject) @@ -77,11 +119,11 @@ class KDocSampleTest : AbstractMultiModuleTest() { if (expectedInfo.endsWith("...\n")) { if (!info!!.startsWith(expectedInfo.removeSuffix("...\n"))) { - wrapToFileComparisonFailure(info, testDataPath, textData) + wrapToFileComparisonFailure(info, testDataFile.absolutePath, textData) } } else if (expectedInfo != info) { - wrapToFileComparisonFailure(info, path, textData) + wrapToFileComparisonFailure(info!!, testDataFile.absolutePath, textData) } } }