move KDoc-related logic shared between IDEA and Dokka to ide-common module
This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.kdoc
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
||||||
|
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
||||||
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
|
|
||||||
|
fun DeclarationDescriptor.findKDoc(): KDocTag? {
|
||||||
|
if (this is DeclarationDescriptorWithSource) {
|
||||||
|
var psiDeclaration = (this.source as? PsiSourceElement)?.psi?.navigationElement
|
||||||
|
// KDoc for primary constructor is located inside of its class KDoc
|
||||||
|
if (psiDeclaration is KtPrimaryConstructor) {
|
||||||
|
psiDeclaration = psiDeclaration.getContainingClassOrObject()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psiDeclaration is KtDeclaration) {
|
||||||
|
val kdoc = psiDeclaration.docComment
|
||||||
|
if (kdoc != null) {
|
||||||
|
if (this is ConstructorDescriptor) {
|
||||||
|
// ConstructorDescriptor resolves to the same JetDeclaration
|
||||||
|
val constructorSection = kdoc.findSectionByTag(KDocKnownTag.CONSTRUCTOR)
|
||||||
|
if (constructorSection != null) {
|
||||||
|
return constructorSection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kdoc.getDefaultSection()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this is PropertyDescriptor) {
|
||||||
|
val containingClassDescriptor = this.containingDeclaration as? ClassDescriptor
|
||||||
|
if (containingClassDescriptor != null) {
|
||||||
|
val classKDoc = containingClassDescriptor.findKDoc()?.getParentOfType<KDoc>(false)
|
||||||
|
if (classKDoc != null) {
|
||||||
|
val propertySection = classKDoc.findSectionByTag(KDocKnownTag.PROPERTY,
|
||||||
|
getName().asString())
|
||||||
|
if (propertySection != null) {
|
||||||
|
return propertySection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this is CallableDescriptor) {
|
||||||
|
for (baseDescriptor in this.overriddenDescriptors) {
|
||||||
|
val baseKDoc = baseDescriptor.original.findKDoc()
|
||||||
|
if (baseKDoc != null) {
|
||||||
|
return baseKDoc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.kdoc
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.util.getFileResolutionScope
|
||||||
|
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
||||||
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.*
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.utils.collectDescriptorsFiltered
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
||||||
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
|
|
||||||
|
fun resolveKDocLink(resolutionFacade: ResolutionFacade,
|
||||||
|
fromDescriptor: DeclarationDescriptor,
|
||||||
|
fromSubjectOfTag: KDocTag?,
|
||||||
|
qualifiedName: List<String>): Collection<DeclarationDescriptor> {
|
||||||
|
if (fromSubjectOfTag?.knownTag == KDocKnownTag.PARAM) {
|
||||||
|
return resolveParamLink(fromDescriptor, qualifiedName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find a matching local descriptor (parameter or type parameter) first.
|
||||||
|
if (qualifiedName.size == 1) {
|
||||||
|
val localResult = resolveInLocalScope(fromDescriptor, qualifiedName.single(), resolutionFacade)
|
||||||
|
if (!localResult.isEmpty()) {
|
||||||
|
return localResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result: Collection<DeclarationDescriptor> = listOf(fromDescriptor)
|
||||||
|
qualifiedName.forEach { nameComponent ->
|
||||||
|
val scope = getKDocLinkResolutionScope(resolutionFacade, result.singleOrNull() ?: return emptyList())
|
||||||
|
result = scope.collectDescriptorsFiltered(nameFilter = { it.asString() == nameComponent})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveInLocalScope(fromDescriptor: DeclarationDescriptor,
|
||||||
|
name: String,
|
||||||
|
resolutionFacade: ResolutionFacade): List<DeclarationDescriptor> {
|
||||||
|
val scope = getKDocLinkResolutionScope(resolutionFacade, fromDescriptor)
|
||||||
|
return scope.collectDescriptorsFiltered(nameFilter = { it.asString() == name }).filter {
|
||||||
|
it.containingDeclaration == fromDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getParamDescriptors(fromDescriptor: DeclarationDescriptor): List<DeclarationDescriptor> {
|
||||||
|
// TODO resolve parameters of functions passed as parameters
|
||||||
|
when (fromDescriptor) {
|
||||||
|
is CallableDescriptor ->
|
||||||
|
return fromDescriptor.valueParameters + fromDescriptor.typeParameters
|
||||||
|
is ClassifierDescriptor -> {
|
||||||
|
val typeParams = fromDescriptor.typeConstructor.parameters
|
||||||
|
if (fromDescriptor is ClassDescriptor) {
|
||||||
|
val constructorDescriptor = fromDescriptor.unsubstitutedPrimaryConstructor
|
||||||
|
if (constructorDescriptor != null) {
|
||||||
|
return typeParams + constructorDescriptor.valueParameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeParams
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveParamLink(fromDescriptor: DeclarationDescriptor, qualifiedName: List<String>): List<DeclarationDescriptor> {
|
||||||
|
val name = qualifiedName.singleOrNull() ?: return listOf()
|
||||||
|
return getParamDescriptors(fromDescriptor).filter { it.name.asString() == name }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): MemberScope {
|
||||||
|
return descriptor.containingDeclaration.getPackage(descriptor.fqName).memberScope
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope {
|
||||||
|
|
||||||
|
val headerScope = LexicalScopeImpl(outerScope, descriptor, false, descriptor.thisAsReceiverParameter,
|
||||||
|
LexicalScopeKind.SYNTHETIC) {
|
||||||
|
for (typeParameter in descriptor.declaredTypeParameters) {
|
||||||
|
addClassifierDescriptor(typeParameter)
|
||||||
|
}
|
||||||
|
for (constructor in descriptor.constructors) {
|
||||||
|
addFunctionDescriptor(constructor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val scopeChain = arrayListOf(descriptor.defaultType.memberScope,
|
||||||
|
descriptor.staticScope)
|
||||||
|
|
||||||
|
descriptor.companionObjectDescriptor?.let {
|
||||||
|
scopeChain.add(it.defaultType.memberScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
return LexicalChainedScope(headerScope, descriptor, false, null,
|
||||||
|
LexicalScopeKind.SYNTHETIC,
|
||||||
|
scopeChain)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getKDocLinkResolutionScope(resolutionFacade: ResolutionFacade, descriptor: DeclarationDescriptor): LexicalScope {
|
||||||
|
return when (descriptor) {
|
||||||
|
is PackageFragmentDescriptor ->
|
||||||
|
LexicalScope.empty(getPackageInnerScope(descriptor).memberScopeAsImportingScope(), descriptor)
|
||||||
|
|
||||||
|
is PackageViewDescriptor ->
|
||||||
|
LexicalScope.empty(descriptor.memberScope.memberScopeAsImportingScope(), descriptor)
|
||||||
|
|
||||||
|
is ClassDescriptor ->
|
||||||
|
getClassInnerScope(getOuterScope(descriptor, resolutionFacade), descriptor)
|
||||||
|
|
||||||
|
is FunctionDescriptor ->
|
||||||
|
FunctionDescriptorUtil.getFunctionInnerScope(getOuterScope(descriptor, resolutionFacade),
|
||||||
|
descriptor, LocalRedeclarationChecker.DO_NOTHING)
|
||||||
|
|
||||||
|
is PropertyDescriptor ->
|
||||||
|
ScopeUtils.makeScopeForPropertyHeader(getOuterScope(descriptor, resolutionFacade), descriptor)
|
||||||
|
|
||||||
|
is DeclarationDescriptorNonRoot ->
|
||||||
|
getOuterScope(descriptor, resolutionFacade)
|
||||||
|
|
||||||
|
else -> throw IllegalArgumentException("Cannot find resolution scope for root $descriptor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope {
|
||||||
|
val parent = descriptor.containingDeclaration
|
||||||
|
if (parent is PackageFragmentDescriptor) {
|
||||||
|
val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile
|
||||||
|
if (containingFile != null) {
|
||||||
|
return resolutionFacade.getFileResolutionScope(containingFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getKDocLinkResolutionScope(resolutionFacade, parent!!)
|
||||||
|
}
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.kdoc
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
|
||||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
|
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
|
||||||
|
|
||||||
object KDocFinder {
|
|
||||||
fun findKDoc(declaration: DeclarationDescriptor): KDocTag? {
|
|
||||||
if (declaration is DeclarationDescriptorWithSource) {
|
|
||||||
var psiDeclaration = (declaration.source as? PsiSourceElement)?.psi?.navigationElement
|
|
||||||
// KDoc for primary constructor is located inside of its class KDoc
|
|
||||||
if (psiDeclaration is KtPrimaryConstructor) {
|
|
||||||
psiDeclaration = psiDeclaration.getContainingClassOrObject()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (psiDeclaration is KtDeclaration) {
|
|
||||||
val kdoc = psiDeclaration.docComment
|
|
||||||
if (kdoc != null) {
|
|
||||||
if (declaration is ConstructorDescriptor) {
|
|
||||||
// ConstructorDescriptor resolves to the same JetDeclaration
|
|
||||||
val constructorSection = kdoc.findSectionByTag(KDocKnownTag.CONSTRUCTOR)
|
|
||||||
if (constructorSection != null) {
|
|
||||||
return constructorSection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return kdoc.getDefaultSection()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declaration is PropertyDescriptor) {
|
|
||||||
val containingClassDescriptor = declaration.containingDeclaration as? ClassDescriptor
|
|
||||||
if (containingClassDescriptor != null) {
|
|
||||||
val classKDoc = findKDoc(containingClassDescriptor)?.getParentOfType<KDoc>(false)
|
|
||||||
if (classKDoc != null) {
|
|
||||||
val propertySection = classKDoc.findSectionByTag(KDocKnownTag.PROPERTY,
|
|
||||||
declaration.getName().asString())
|
|
||||||
if (propertySection != null) {
|
|
||||||
return propertySection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declaration is CallableDescriptor) {
|
|
||||||
for (baseDescriptor in declaration.overriddenDescriptors) {
|
|
||||||
val baseKDoc = findKDoc(baseDescriptor.original)
|
|
||||||
if (baseKDoc != null) {
|
|
||||||
return baseKDoc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,23 +18,13 @@ package org.jetbrains.kotlin.idea.kdoc
|
|||||||
|
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.references.KtMultiReference
|
import org.jetbrains.kotlin.idea.references.KtMultiReference
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
|
||||||
import org.jetbrains.kotlin.idea.util.getFileResolutionScope
|
|
||||||
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.*
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectDescriptorsFiltered
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
|
||||||
|
|
||||||
class KDocReference(element: KDocName): KtMultiReference<KDocName>(element) {
|
class KDocReference(element: KDocName): KtMultiReference<KDocName>(element) {
|
||||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
@@ -63,126 +53,3 @@ class KDocReference(element: KDocName): KtMultiReference<KDocName>(element) {
|
|||||||
|
|
||||||
override fun getCanonicalText(): String = element.getNameText()
|
override fun getCanonicalText(): String = element.getNameText()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resolveKDocLink(resolutionFacade: ResolutionFacade,
|
|
||||||
fromDescriptor: DeclarationDescriptor,
|
|
||||||
fromSubjectOfTag: KDocTag?,
|
|
||||||
qualifiedName: List<String>): Collection<DeclarationDescriptor> {
|
|
||||||
if (fromSubjectOfTag?.knownTag == KDocKnownTag.PARAM) {
|
|
||||||
return resolveParamLink(fromDescriptor, qualifiedName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find a matching local descriptor (parameter or type parameter) first.
|
|
||||||
if (qualifiedName.size == 1) {
|
|
||||||
val localResult = resolveInLocalScope(fromDescriptor, qualifiedName.single(), resolutionFacade)
|
|
||||||
if (!localResult.isEmpty()) {
|
|
||||||
return localResult
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result: Collection<DeclarationDescriptor> = listOf(fromDescriptor)
|
|
||||||
qualifiedName.forEach { nameComponent ->
|
|
||||||
val scope = getResolutionScope(resolutionFacade, result.singleOrNull() ?: return emptyList())
|
|
||||||
result = scope.collectDescriptorsFiltered(nameFilter = { it.asString() == nameComponent})
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resolveInLocalScope(fromDescriptor: DeclarationDescriptor,
|
|
||||||
name: String,
|
|
||||||
resolutionFacade: ResolutionFacade): List<DeclarationDescriptor> {
|
|
||||||
val scope = getResolutionScope(resolutionFacade, fromDescriptor)
|
|
||||||
return scope.collectDescriptorsFiltered(nameFilter = { it.asString() == name }).filter {
|
|
||||||
it.containingDeclaration == fromDescriptor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getParamDescriptors(fromDescriptor: DeclarationDescriptor): List<DeclarationDescriptor> {
|
|
||||||
// TODO resolve parameters of functions passed as parameters
|
|
||||||
when (fromDescriptor) {
|
|
||||||
is CallableDescriptor ->
|
|
||||||
return fromDescriptor.valueParameters + fromDescriptor.typeParameters
|
|
||||||
is ClassifierDescriptor -> {
|
|
||||||
val typeParams = fromDescriptor.typeConstructor.parameters
|
|
||||||
if (fromDescriptor is ClassDescriptor) {
|
|
||||||
val constructorDescriptor = fromDescriptor.unsubstitutedPrimaryConstructor
|
|
||||||
if (constructorDescriptor != null) {
|
|
||||||
return typeParams + constructorDescriptor.valueParameters
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typeParams
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resolveParamLink(fromDescriptor: DeclarationDescriptor, qualifiedName: List<String>): List<DeclarationDescriptor> {
|
|
||||||
val name = qualifiedName.singleOrNull() ?: return listOf()
|
|
||||||
return getParamDescriptors(fromDescriptor).filter { it.name.asString() == name }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): MemberScope {
|
|
||||||
return descriptor.containingDeclaration.getPackage(descriptor.fqName).memberScope
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope {
|
|
||||||
|
|
||||||
val headerScope = LexicalScopeImpl(outerScope, descriptor, false, descriptor.thisAsReceiverParameter,
|
|
||||||
LexicalScopeKind.SYNTHETIC) {
|
|
||||||
for (typeParameter in descriptor.declaredTypeParameters) {
|
|
||||||
addClassifierDescriptor(typeParameter)
|
|
||||||
}
|
|
||||||
for (constructor in descriptor.constructors) {
|
|
||||||
addFunctionDescriptor(constructor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val scopeChain = arrayListOf(descriptor.defaultType.memberScope,
|
|
||||||
descriptor.staticScope)
|
|
||||||
|
|
||||||
descriptor.companionObjectDescriptor?.let {
|
|
||||||
scopeChain.add(it.defaultType.memberScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
return LexicalChainedScope(headerScope, descriptor, false, null,
|
|
||||||
LexicalScopeKind.SYNTHETIC,
|
|
||||||
scopeChain)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getResolutionScope(resolutionFacade: ResolutionFacade, descriptor: DeclarationDescriptor): LexicalScope {
|
|
||||||
return when (descriptor) {
|
|
||||||
is PackageFragmentDescriptor ->
|
|
||||||
LexicalScope.empty(getPackageInnerScope(descriptor).memberScopeAsImportingScope(), descriptor)
|
|
||||||
|
|
||||||
is PackageViewDescriptor ->
|
|
||||||
LexicalScope.empty(descriptor.memberScope.memberScopeAsImportingScope(), descriptor)
|
|
||||||
|
|
||||||
is ClassDescriptor ->
|
|
||||||
getClassInnerScope(getOuterScope(descriptor, resolutionFacade), descriptor)
|
|
||||||
|
|
||||||
is FunctionDescriptor ->
|
|
||||||
FunctionDescriptorUtil.getFunctionInnerScope(getOuterScope(descriptor, resolutionFacade),
|
|
||||||
descriptor, LocalRedeclarationChecker.DO_NOTHING)
|
|
||||||
|
|
||||||
is PropertyDescriptor ->
|
|
||||||
ScopeUtils.makeScopeForPropertyHeader(getOuterScope(descriptor, resolutionFacade), descriptor)
|
|
||||||
|
|
||||||
is DeclarationDescriptorNonRoot ->
|
|
||||||
getOuterScope(descriptor, resolutionFacade)
|
|
||||||
|
|
||||||
else -> throw IllegalArgumentException("Cannot find resolution scope for root $descriptor")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope {
|
|
||||||
val parent = descriptor.containingDeclaration
|
|
||||||
if (parent is PackageFragmentDescriptor) {
|
|
||||||
val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile
|
|
||||||
if (containingFile != null) {
|
|
||||||
return resolutionFacade.getFileResolutionScope(containingFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getResolutionScope(resolutionFacade, parent!!)
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-2
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.core.ExpectedInfo
|
import org.jetbrains.kotlin.idea.core.ExpectedInfo
|
||||||
import org.jetbrains.kotlin.idea.kdoc.getParamDescriptors
|
import org.jetbrains.kotlin.idea.kdoc.getParamDescriptors
|
||||||
import org.jetbrains.kotlin.idea.kdoc.getResolutionScope
|
import org.jetbrains.kotlin.idea.kdoc.getKDocLinkResolutionScope
|
||||||
import org.jetbrains.kotlin.idea.util.CallType
|
import org.jetbrains.kotlin.idea.util.CallType
|
||||||
import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable
|
import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable
|
||||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
||||||
@@ -101,7 +101,7 @@ class KDocNameCompletionSession(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addLinkCompletions(declarationDescriptor: DeclarationDescriptor) {
|
private fun addLinkCompletions(declarationDescriptor: DeclarationDescriptor) {
|
||||||
val scope = getResolutionScope(resolutionFacade, declarationDescriptor)
|
val scope = getKDocLinkResolutionScope(resolutionFacade, declarationDescriptor)
|
||||||
val implicitReceivers = scope.getImplicitReceiversHierarchy().map { it.value }
|
val implicitReceivers = scope.getImplicitReceiversHierarchy().map { it.value }
|
||||||
|
|
||||||
fun isApplicable(descriptor: DeclarationDescriptor): Boolean {
|
fun isApplicable(descriptor: DeclarationDescriptor): Boolean {
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
||||||
import org.jetbrains.kotlin.idea.kdoc.KDocFinder
|
|
||||||
import org.jetbrains.kotlin.idea.kdoc.KDocRenderer
|
import org.jetbrains.kotlin.idea.kdoc.KDocRenderer
|
||||||
|
import org.jetbrains.kotlin.idea.kdoc.findKDoc
|
||||||
import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
|
import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
|
||||||
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
|
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
|
||||||
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
@@ -134,7 +134,7 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() {
|
|||||||
if (!quickNavigation) {
|
if (!quickNavigation) {
|
||||||
renderedDecl = "<pre>" + renderedDecl + "</pre>"
|
renderedDecl = "<pre>" + renderedDecl + "</pre>"
|
||||||
}
|
}
|
||||||
val comment = KDocFinder.findKDoc(declarationDescriptor)
|
val comment = declarationDescriptor.findKDoc()
|
||||||
if (comment != null) {
|
if (comment != null) {
|
||||||
val renderedComment = KDocRenderer.renderKDoc(comment)
|
val renderedComment = KDocRenderer.renderKDoc(comment)
|
||||||
if (renderedComment.startsWith("<p>")) {
|
if (renderedComment.startsWith("<p>")) {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class KDocFinderTest() : LightPlatformCodeInsightFixtureTestCase() {
|
|||||||
val declaration = (myFixture.file as KtFile).declarations[0]
|
val declaration = (myFixture.file as KtFile).declarations[0]
|
||||||
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
||||||
val constructorDescriptor = descriptor.unsubstitutedPrimaryConstructor!!
|
val constructorDescriptor = descriptor.unsubstitutedPrimaryConstructor!!
|
||||||
val doc = KDocFinder.findKDoc(constructorDescriptor)
|
val doc = constructorDescriptor.findKDoc()
|
||||||
Assert.assertEquals("Doc for constructor of class C.", doc!!.getContent())
|
Assert.assertEquals("Doc for constructor of class C.", doc!!.getContent())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ class KDocFinderTest() : LightPlatformCodeInsightFixtureTestCase() {
|
|||||||
val declaration = (myFixture.file as KtFile).declarations.single { it.name == "Bar" }
|
val declaration = (myFixture.file as KtFile).declarations.single { it.name == "Bar" }
|
||||||
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
||||||
val overriddenFunctionDescriptor = descriptor.defaultType.memberScope.getContributedFunctions(Name.identifier("xyzzy"), NoLookupLocation.FROM_TEST).single()
|
val overriddenFunctionDescriptor = descriptor.defaultType.memberScope.getContributedFunctions(Name.identifier("xyzzy"), NoLookupLocation.FROM_TEST).single()
|
||||||
val doc = KDocFinder.findKDoc(overriddenFunctionDescriptor)
|
val doc = overriddenFunctionDescriptor.findKDoc()
|
||||||
Assert.assertEquals("Doc for method xyzzy", doc!!.getContent())
|
Assert.assertEquals("Doc for method xyzzy", doc!!.getContent())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ class KDocFinderTest() : LightPlatformCodeInsightFixtureTestCase() {
|
|||||||
val declaration = (myFixture.file as KtFile).declarations.single { it.name == "Bar" }
|
val declaration = (myFixture.file as KtFile).declarations.single { it.name == "Bar" }
|
||||||
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
||||||
val overriddenFunctionDescriptor = descriptor.defaultType.memberScope.getContributedFunctions(Name.identifier("xyzzy"), NoLookupLocation.FROM_TEST).single()
|
val overriddenFunctionDescriptor = descriptor.defaultType.memberScope.getContributedFunctions(Name.identifier("xyzzy"), NoLookupLocation.FROM_TEST).single()
|
||||||
val doc = KDocFinder.findKDoc(overriddenFunctionDescriptor)
|
val doc = overriddenFunctionDescriptor.findKDoc()
|
||||||
Assert.assertEquals("Doc for method xyzzy", doc!!.getContent())
|
Assert.assertEquals("Doc for method xyzzy", doc!!.getContent())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ class KDocFinderTest() : LightPlatformCodeInsightFixtureTestCase() {
|
|||||||
val declaration = (myFixture.file as KtFile).declarations.single { it.name == "Foo" }
|
val declaration = (myFixture.file as KtFile).declarations.single { it.name == "Foo" }
|
||||||
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
||||||
val propertyDescriptor = descriptor.defaultType.memberScope.getContributedVariables(Name.identifier("xyzzy"), NoLookupLocation.FROM_TEST).single()
|
val propertyDescriptor = descriptor.defaultType.memberScope.getContributedVariables(Name.identifier("xyzzy"), NoLookupLocation.FROM_TEST).single()
|
||||||
val doc = KDocFinder.findKDoc(propertyDescriptor)
|
val doc = propertyDescriptor.findKDoc()
|
||||||
Assert.assertEquals("Doc for property xyzzy", doc!!.getContent())
|
Assert.assertEquals("Doc for property xyzzy", doc!!.getContent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user