FIR IDE: Make KtReference class descriptors frontend independent
* The new idea-frontend-independent module created * Moved KtReference and it inheritors to that module & implement them in idea-analysis module by using descriptors frontend
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
object ArrayFqNames {
|
||||
val PRIMITIVE_TYPE_TO_ARRAY: Map<PrimitiveType, Name> = hashMapOf(
|
||||
PrimitiveType.BOOLEAN to Name.identifier("booleanArrayOf"),
|
||||
PrimitiveType.CHAR to Name.identifier("charArrayOf"),
|
||||
PrimitiveType.INT to Name.identifier("intArrayOf"),
|
||||
PrimitiveType.BYTE to Name.identifier("byteArrayOf"),
|
||||
PrimitiveType.SHORT to Name.identifier("shortArrayOf"),
|
||||
PrimitiveType.FLOAT to Name.identifier("floatArrayOf"),
|
||||
PrimitiveType.LONG to Name.identifier("longArrayOf"),
|
||||
PrimitiveType.DOUBLE to Name.identifier("doubleArrayOf")
|
||||
)
|
||||
|
||||
val ARRAY_OF_FUNCTION = Name.identifier("arrayOf")
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
@@ -44,21 +33,6 @@ class CollectionLiteralResolver(
|
||||
val callResolver: CallResolver,
|
||||
val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
companion object {
|
||||
val PRIMITIVE_TYPE_TO_ARRAY: Map<PrimitiveType, Name> = hashMapOf(
|
||||
PrimitiveType.BOOLEAN to Name.identifier("booleanArrayOf"),
|
||||
PrimitiveType.CHAR to Name.identifier("charArrayOf"),
|
||||
PrimitiveType.INT to Name.identifier("intArrayOf"),
|
||||
PrimitiveType.BYTE to Name.identifier("byteArrayOf"),
|
||||
PrimitiveType.SHORT to Name.identifier("shortArrayOf"),
|
||||
PrimitiveType.FLOAT to Name.identifier("floatArrayOf"),
|
||||
PrimitiveType.LONG to Name.identifier("longArrayOf"),
|
||||
PrimitiveType.DOUBLE to Name.identifier("doubleArrayOf")
|
||||
)
|
||||
|
||||
val ARRAY_OF_FUNCTION = Name.identifier("arrayOf")
|
||||
}
|
||||
|
||||
fun resolveCollectionLiteral(
|
||||
collectionLiteralExpression: KtCollectionLiteralExpression,
|
||||
context: ExpressionTypingContext
|
||||
@@ -120,11 +94,11 @@ class CollectionLiteralResolver(
|
||||
|
||||
private fun getArrayFunctionCallName(expectedType: KotlinType): Name {
|
||||
if (NO_EXPECTED_TYPE === expectedType || !KotlinBuiltIns.isPrimitiveArray(expectedType)) {
|
||||
return ARRAY_OF_FUNCTION
|
||||
return ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
}
|
||||
|
||||
val descriptor = expectedType.constructor.declarationDescriptor ?: return ARRAY_OF_FUNCTION
|
||||
val descriptor = expectedType.constructor.declarationDescriptor ?: return ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
|
||||
return PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)] ?: ARRAY_OF_FUNCTION
|
||||
return ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)] ?: ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.utils.addToStdlib
|
||||
@@ -50,6 +39,17 @@ inline fun <reified T> Array<*>.firstIsInstance(): T {
|
||||
throw NoSuchElementException("No element of given type found")
|
||||
}
|
||||
|
||||
inline fun <reified T> Iterable<*>.filterIsInstanceWithChecker(additionalChecker: (T) -> Boolean): List<T> {
|
||||
val result = arrayListOf<T>()
|
||||
for (element in this) {
|
||||
if (element is T && additionalChecker(element)) {
|
||||
result += element
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
inline fun <reified T : Any> Iterable<*>.lastIsInstanceOrNull(): T? {
|
||||
when (this) {
|
||||
is List<*> -> {
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.kdoc
|
||||
@@ -20,6 +9,7 @@ import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.references.KtDescriptorsBasedReference
|
||||
import org.jetbrains.kotlin.idea.references.KtMultiReference
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
||||
@@ -28,7 +18,11 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class KDocReference(element: KDocName) : KtMultiReference<KDocName>(element) {
|
||||
//TODO move to frontend-independent module
|
||||
class KDocReference(element: KDocName) : KtMultiReference<KDocName>(element), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val declaration = element.getContainingDoc().getOwner() ?: return arrayListOf()
|
||||
val resolutionFacade = element.getResolutionFacade()
|
||||
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.idea.fir.firResolveState
|
||||
import org.jetbrains.kotlin.idea.fir.getOrBuildFir
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtPackageDirective
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
|
||||
object FirReferenceResolveHelper {
|
||||
fun FirResolvedTypeRef.toTargetPsi(session: FirSession): PsiElement? {
|
||||
val type = type as? ConeLookupTagBasedType ?: return null
|
||||
return (type.lookupTag.toSymbol(session) as? AbstractFirBasedSymbol<*>)?.fir?.psi
|
||||
}
|
||||
|
||||
fun ClassId.toTargetPsi(session: FirSession, calleeReference: FirReference? = null): PsiElement? {
|
||||
val classLikeDeclaration = ConeClassLikeLookupTagImpl(this).toSymbol(session)?.fir
|
||||
if (classLikeDeclaration is FirRegularClass) {
|
||||
if (calleeReference is FirResolvedNamedReference) {
|
||||
val callee = calleeReference.resolvedSymbol.fir as? FirCallableMemberDeclaration
|
||||
// TODO: check callee owner directly?
|
||||
if (callee !is FirConstructor && callee?.isStatic != true) {
|
||||
classLikeDeclaration.companionObject?.let { return it.psi }
|
||||
}
|
||||
}
|
||||
}
|
||||
return classLikeDeclaration?.psi
|
||||
}
|
||||
|
||||
fun FirReference.toTargetPsi(session: FirSession): PsiElement? {
|
||||
return when (this) {
|
||||
is FirResolvedNamedReference -> {
|
||||
resolvedSymbol.fir.psi
|
||||
}
|
||||
is FirResolvedCallableReference -> {
|
||||
resolvedSymbol.fir.psi
|
||||
}
|
||||
is FirThisReference -> {
|
||||
boundSymbol?.fir?.psi
|
||||
}
|
||||
is FirSuperReference -> {
|
||||
(superTypeRef as? FirResolvedTypeRef)?.toTargetPsi(session)
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveToPsiElements(ref: AbstractKtReference<KtElement>): Collection<PsiElement> {
|
||||
val expression = ref.expression
|
||||
val state = expression.firResolveState()
|
||||
val session = state.getSession(expression)
|
||||
when (val fir = expression.getOrBuildFir(state)) {
|
||||
is FirResolvable -> {
|
||||
return listOfNotNull(fir.calleeReference.toTargetPsi(session))
|
||||
}
|
||||
is FirResolvedTypeRef -> {
|
||||
return listOfNotNull(fir.toTargetPsi(session))
|
||||
}
|
||||
is FirResolvedQualifier -> {
|
||||
val classId = fir.classId ?: return emptyList()
|
||||
// Distinguish A.foo() from A(.Companion).foo()
|
||||
// Make expression.parent as? KtDotQualifiedExpression local function
|
||||
var parent = expression.parent as? KtDotQualifiedExpression
|
||||
while (parent != null) {
|
||||
val selectorExpression = parent.selectorExpression ?: break
|
||||
if (selectorExpression === expression) {
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
continue
|
||||
}
|
||||
val parentFir = selectorExpression.getOrBuildFir(state)
|
||||
if (parentFir is FirQualifiedAccess) {
|
||||
return listOfNotNull(classId.toTargetPsi(session, parentFir.calleeReference))
|
||||
}
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
}
|
||||
return listOfNotNull(classId.toTargetPsi(session))
|
||||
}
|
||||
is FirAnnotationCall -> {
|
||||
val type = fir.typeRef as? FirResolvedTypeRef ?: return emptyList()
|
||||
return listOfNotNull(type.toTargetPsi(session))
|
||||
}
|
||||
is FirResolvedImport -> {
|
||||
var parent = expression.parent
|
||||
while (parent is KtDotQualifiedExpression) {
|
||||
if (parent.selectorExpression !== expression) {
|
||||
// Special: package reference in the middle of import directive
|
||||
// import a.<caret>b.c.SomeClass
|
||||
// TODO: return reference to PsiPackage
|
||||
return listOf(expression)
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
val classId = fir.resolvedClassId
|
||||
if (classId != null) {
|
||||
return listOfNotNull(classId.toTargetPsi(session))
|
||||
}
|
||||
val name = fir.importedName ?: return emptyList()
|
||||
val symbolProvider = session.firSymbolProvider
|
||||
return symbolProvider.getTopLevelCallableSymbols(fir.packageFqName, name).mapNotNull { it.fir.psi } +
|
||||
listOfNotNull(symbolProvider.getClassLikeSymbolByFqName(ClassId(fir.packageFqName, name))?.fir?.psi)
|
||||
}
|
||||
is FirFile -> {
|
||||
if (expression.getNonStrictParentOfType<KtPackageDirective>() != null) {
|
||||
// Special: package reference in the middle of package directive
|
||||
return listOf(expression)
|
||||
}
|
||||
return listOfNotNull(fir.psi)
|
||||
}
|
||||
is FirArrayOfCall -> {
|
||||
// We can't yet find PsiElement for arrayOf, intArrayOf, etc.
|
||||
return emptyList()
|
||||
}
|
||||
is FirErrorNamedReference -> {
|
||||
return emptyList()
|
||||
}
|
||||
else -> {
|
||||
// Handle situation when we're in the middle/beginning of qualifier
|
||||
// <caret>A.B.C.foo() or A.<caret>B.C.foo()
|
||||
// NB: in this case we get some parent FIR, like FirBlock, FirProperty, FirFunction or the like
|
||||
var parent = expression.parent as? KtDotQualifiedExpression
|
||||
var unresolvedCounter = 1
|
||||
while (parent != null) {
|
||||
val selectorExpression = parent.selectorExpression ?: break
|
||||
if (selectorExpression === expression) {
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
continue
|
||||
}
|
||||
val parentFir = selectorExpression.getOrBuildFir(state)
|
||||
if (parentFir is FirResolvedQualifier) {
|
||||
var classId = parentFir.classId
|
||||
while (unresolvedCounter > 0) {
|
||||
unresolvedCounter--
|
||||
classId = classId?.outerClassId
|
||||
}
|
||||
return listOfNotNull(classId?.toTargetPsi(session))
|
||||
}
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
unresolvedCounter++
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -66,14 +66,10 @@ class ReferenceImpl(private val argument: KtValueArgument) : PsiReference {
|
||||
override fun isSoft() = false
|
||||
}
|
||||
|
||||
internal class KotlinDefaultAnnotationMethodImplicitReferenceContributor : KotlinReferenceProviderContributor {
|
||||
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
|
||||
registrar.registerProvider<KtValueArgument> {
|
||||
if (it.isNamed()) return@registerProvider null
|
||||
val annotationEntry = it.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } ?: return@registerProvider null
|
||||
if (annotationEntry.valueArguments.size != 1) return@registerProvider null
|
||||
internal val KotlinDefaultAnnotationMethodImplicitReferenceProvider = provider@{ element: KtValueArgument ->
|
||||
if (element.isNamed()) return@provider null
|
||||
val annotationEntry = element.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } ?: return@provider null
|
||||
if (annotationEntry.valueArguments.size != 1) return@provider null
|
||||
|
||||
ReferenceImpl(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
ReferenceImpl(element)
|
||||
}
|
||||
+17
-26
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
@@ -24,10 +13,10 @@ import org.jetbrains.kotlin.psi.KtPackageDirective
|
||||
import org.jetbrains.kotlin.psi.KtUserType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
|
||||
internal class KotlinReferenceContributor : KotlinReferenceProviderContributor {
|
||||
class KotlinReferenceContributor : KotlinReferenceProviderContributor {
|
||||
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
|
||||
with(registrar) {
|
||||
registerProvider(factory = ::KtSimpleNameReference)
|
||||
registerProvider(factory = ::KtSimpleNameReferenceDescriptorsImpl)
|
||||
|
||||
registerMultiProvider<KtNameReferenceExpression> { nameReferenceExpression ->
|
||||
if (nameReferenceExpression.getReferencedNameElementType() != KtTokens.IDENTIFIER) return@registerMultiProvider emptyArray()
|
||||
@@ -37,32 +26,34 @@ internal class KotlinReferenceContributor : KotlinReferenceProviderContributor {
|
||||
|
||||
when (nameReferenceExpression.readWriteAccess(useResolveForReadWrite = false)) {
|
||||
ReferenceAccess.READ ->
|
||||
arrayOf(SyntheticPropertyAccessorReference.Getter(nameReferenceExpression))
|
||||
arrayOf(SyntheticPropertyAccessorReferenceDescriptorImpl(nameReferenceExpression, getter = true))
|
||||
ReferenceAccess.WRITE ->
|
||||
arrayOf(SyntheticPropertyAccessorReference.Setter(nameReferenceExpression))
|
||||
arrayOf(SyntheticPropertyAccessorReferenceDescriptorImpl(nameReferenceExpression, getter = false))
|
||||
ReferenceAccess.READ_WRITE ->
|
||||
arrayOf(
|
||||
SyntheticPropertyAccessorReference.Getter(nameReferenceExpression),
|
||||
SyntheticPropertyAccessorReference.Setter(nameReferenceExpression)
|
||||
SyntheticPropertyAccessorReferenceDescriptorImpl(nameReferenceExpression, getter = true),
|
||||
SyntheticPropertyAccessorReferenceDescriptorImpl(nameReferenceExpression, getter = false)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
registerProvider(factory = ::KtConstructorDelegationReference)
|
||||
registerProvider(factory = ::KtConstructorDelegationReferenceDescriptorsImpl)
|
||||
|
||||
registerProvider(factory = ::KtInvokeFunctionReference)
|
||||
registerProvider(factory = ::KtInvokeFunctionReferenceDescriptorsImpl)
|
||||
|
||||
registerProvider(factory = ::KtArrayAccessReference)
|
||||
registerProvider(factory = ::KtArrayAccessReferenceDescriptorsImpl)
|
||||
|
||||
registerProvider(factory = ::KtCollectionLiteralReference)
|
||||
registerProvider(factory = ::KtCollectionLiteralReferenceDescriptorsImpl)
|
||||
|
||||
registerProvider(factory = ::KtForLoopInReference)
|
||||
registerProvider(factory = ::KtForLoopInReferenceDescriptorsImpl)
|
||||
|
||||
registerProvider(factory = ::KtPropertyDelegationMethodsReference)
|
||||
registerProvider(factory = ::KtPropertyDelegationMethodsReferenceDescriptorsImpl)
|
||||
|
||||
registerProvider(factory = ::KtDestructuringDeclarationReference)
|
||||
registerProvider(factory = ::KtDestructuringDeclarationReferenceDescriptorsImpl)
|
||||
|
||||
registerProvider(factory = ::KDocReference)
|
||||
|
||||
registerProvider(KotlinDefaultAnnotationMethodImplicitReferenceProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.MultiRangeReference
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_SET
|
||||
|
||||
internal class KtArrayAccessReferenceDescriptorsImpl(
|
||||
expression: KtArrayAccessExpression
|
||||
) : KtArrayAccessReference(expression), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
override fun moveFunctionLiteralOutsideParentheses(callExpression: KtCallExpression) {
|
||||
callExpression.moveFunctionLiteralOutsideParentheses()
|
||||
}
|
||||
|
||||
override fun canMoveLambdaOutsideParentheses(callExpression: KtCallExpression): Boolean =
|
||||
callExpression.canMoveLambdaOutsideParentheses()
|
||||
|
||||
override fun doRenameImplicitConventionalCall(newName: String?): KtExpression =
|
||||
renameImplicitConventionalCall(newName)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val getFunctionDescriptor = context[INDEXED_LVALUE_GET, expression]?.candidateDescriptor
|
||||
val setFunctionDescriptor = context[INDEXED_LVALUE_SET, expression]?.candidateDescriptor
|
||||
return listOfNotNull(getFunctionDescriptor, setFunctionDescriptor)
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class KtCollectionLiteralReferenceDescriptorsImpl(
|
||||
expression: KtCollectionLiteralExpression
|
||||
) : KtCollectionLiteralReference(expression), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val resolvedCall = context[BindingContext.COLLECTION_LITERAL_CALL, element]
|
||||
return listOfNotNull(resolvedCall?.resultingDescriptor)
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +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.references;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class KtConstructorDelegationReference extends KtSimpleReference<KtConstructorDelegationReferenceExpression> {
|
||||
public KtConstructorDelegationReference(KtConstructorDelegationReferenceExpression expression) {
|
||||
super(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
return new TextRange(0, getElement().getTextLength());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<Name> getResolvesByNames() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement handleElementRename(@Nullable String newElementName) {
|
||||
// Class rename never affects this reference, so there is no need to fail with exception
|
||||
return getExpression();
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||
|
||||
class KtConstructorDelegationReferenceDescriptorsImpl(
|
||||
expression: KtConstructorDelegationReferenceExpression
|
||||
) : KtConstructorDelegationReference(expression), KtDescriptorsBasedReference {
|
||||
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext) = expression.getReferenceTargets(context)
|
||||
}
|
||||
+7
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -16,8 +16,12 @@ import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEntry) :
|
||||
AbstractKtReference<KtDestructuringDeclarationEntry>(element) {
|
||||
class KtDestructuringDeclarationReferenceDescriptorsImpl(
|
||||
element: KtDestructuringDeclarationEntry
|
||||
) : KtDestructuringDeclarationReference(element), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
return listOfNotNull(context[BindingContext.COMPONENT_RESOLVED_CALL, element]?.candidateDescriptor)
|
||||
}
|
||||
@@ -30,16 +34,4 @@ class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEnt
|
||||
it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleElementRename(newElementName: String): PsiElement? {
|
||||
if (canRename()) return expression
|
||||
throw IncorrectOperationException()
|
||||
}
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() {
|
||||
val destructuringParent = element.parent as? KtDestructuringDeclaration ?: return emptyList()
|
||||
val componentIndex = destructuringParent.entries.indexOf(element) + 1
|
||||
return listOf(Name.identifier("component$componentIndex"))
|
||||
}
|
||||
}
|
||||
+7
-18
@@ -1,45 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class KtForLoopInReference(element: KtForExpression) : KtMultiReference<KtForExpression>(element) {
|
||||
|
||||
override fun getRangeInElement(): TextRange {
|
||||
val inKeyword = expression.inKeyword ?: return TextRange.EMPTY_RANGE
|
||||
|
||||
val offset = inKeyword.startOffsetInParent
|
||||
return TextRange(offset, offset + inKeyword.textLength)
|
||||
}
|
||||
class KtForLoopInReferenceDescriptorsImpl(
|
||||
element: KtForExpression
|
||||
) : KtForLoopInReference(element), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val loopRange = expression.loopRange ?: return emptyList()
|
||||
return LOOP_RANGE_KEYS.mapNotNull { key -> context.get(key, loopRange)?.candidateDescriptor }
|
||||
}
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() = NAMES
|
||||
|
||||
companion object {
|
||||
private val LOOP_RANGE_KEYS = arrayOf(
|
||||
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
|
||||
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL,
|
||||
BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL
|
||||
)
|
||||
|
||||
private val NAMES = listOf(
|
||||
OperatorNameConventions.ITERATOR,
|
||||
OperatorNameConventions.NEXT,
|
||||
OperatorNameConventions.HAS_NEXT
|
||||
)
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
|
||||
class KtInvokeFunctionReferenceDescriptorsImpl(expression: KtCallExpression) : KtInvokeFunctionReference(expression), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val call = element.getCall(context)
|
||||
val resolvedCall = call.getResolvedCall(context)
|
||||
return when {
|
||||
resolvedCall is VariableAsFunctionResolvedCall ->
|
||||
setOf<DeclarationDescriptor>((resolvedCall as VariableAsFunctionResolvedCall).functionCall.candidateDescriptor)
|
||||
call != null && resolvedCall != null && call.callType == Call.CallType.INVOKE ->
|
||||
setOf<DeclarationDescriptor>(resolvedCall.candidateDescriptor)
|
||||
else ->
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun doRenameImplicitConventionalCall(newName: String?): KtExpression =
|
||||
renameImplicitConventionalCall(newName)
|
||||
}
|
||||
-56
@@ -1,56 +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.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.descriptors.accessors
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class KtPropertyDelegationMethodsReference(element: KtPropertyDelegate) : KtMultiReference<KtPropertyDelegate>(element) {
|
||||
|
||||
override fun getRangeInElement(): TextRange {
|
||||
val byKeywordNode = expression.byKeywordNode
|
||||
val offset = byKeywordNode.psi!!.startOffsetInParent
|
||||
return TextRange(offset, offset + byKeywordNode.textLength)
|
||||
}
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val property = expression.getStrictParentOfType<KtProperty>() ?: return emptyList()
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] as? VariableDescriptorWithAccessors
|
||||
?: return emptyList()
|
||||
return (descriptor.accessors.mapNotNull { accessor ->
|
||||
context.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor)?.candidateDescriptor
|
||||
} + listOfNotNull(context.get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, descriptor)?.candidateDescriptor))
|
||||
}
|
||||
|
||||
override val resolvesByNames: Collection<Name> get() = NAMES
|
||||
|
||||
companion object {
|
||||
private val NAMES = listOf(
|
||||
OperatorNameConventions.GET_VALUE,
|
||||
OperatorNameConventions.SET_VALUE,
|
||||
OperatorNameConventions.PROVIDE_DELEGATE
|
||||
)
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.descriptors.accessors
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class KtPropertyDelegationMethodsReferenceDescriptorsImpl(
|
||||
element: KtPropertyDelegate
|
||||
) : KtPropertyDelegationMethodsReference(element), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val property = expression.getStrictParentOfType<KtProperty>() ?: return emptyList()
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] as? VariableDescriptorWithAccessors
|
||||
?: return emptyList()
|
||||
return descriptor.accessors.mapNotNull { accessor ->
|
||||
context.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor)?.candidateDescriptor
|
||||
} + listOfNotNull(context.get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, descriptor)?.candidateDescriptor)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
@@ -51,251 +40,83 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import java.util.*
|
||||
|
||||
interface KtReference : PsiPolyVariantReference {
|
||||
fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor>
|
||||
interface KtDescriptorsBasedReference : KtReference {
|
||||
override val resolver get() = KotlinDescriptorsBasedReferenceResolver
|
||||
|
||||
override fun getElement(): KtElement
|
||||
|
||||
val resolvesByNames: Collection<Name>
|
||||
}
|
||||
|
||||
abstract class AbstractKtReference<T : KtElement>(element: T) : PsiPolyVariantReferenceBase<T>(element), KtReference {
|
||||
val expression: T
|
||||
get() = element
|
||||
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val kotlinResolver = KOTLIN_RESOLVER as ResolveCache.PolyVariantResolver<AbstractKtReference<T>>
|
||||
return ResolveCache.getInstance(expression.project).resolveWithCaching(this, kotlinResolver, false, incompleteCode)
|
||||
fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
|
||||
return getTargetDescriptors(bindingContext)
|
||||
}
|
||||
|
||||
fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor>
|
||||
|
||||
override fun isReferenceTo(element: PsiElement): Boolean {
|
||||
return matchesTarget(element)
|
||||
}
|
||||
|
||||
override fun getCanonicalText(): String = "<TBD>"
|
||||
|
||||
open fun canRename(): Boolean = false
|
||||
override fun handleElementRename(newElementName: String): PsiElement? = throw IncorrectOperationException()
|
||||
|
||||
override fun bindToElement(element: PsiElement): PsiElement = throw IncorrectOperationException()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun getVariants(): Array<Any> = PsiReference.EMPTY_ARRAY as Array<Any>
|
||||
|
||||
override fun isSoft(): Boolean = false
|
||||
|
||||
override fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
|
||||
return getTargetDescriptors(bindingContext)
|
||||
}
|
||||
|
||||
protected abstract fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor>
|
||||
|
||||
override fun toString() = this::class.java.simpleName + ": " + expression.text
|
||||
|
||||
companion object {
|
||||
private object FirReferenceResolveHelper {
|
||||
fun FirResolvedTypeRef.toTargetPsi(session: FirSession): PsiElement? {
|
||||
val type = type as? ConeLookupTagBasedType ?: return null
|
||||
return (type.lookupTag.toSymbol(session) as? AbstractFirBasedSymbol<*>)?.fir?.psi
|
||||
}
|
||||
|
||||
fun ClassId.toTargetPsi(session: FirSession, calleeReference: FirReference? = null): PsiElement? {
|
||||
val classLikeDeclaration = ConeClassLikeLookupTagImpl(this).toSymbol(session)?.fir
|
||||
if (classLikeDeclaration is FirRegularClass) {
|
||||
if (calleeReference is FirResolvedNamedReference) {
|
||||
val callee = calleeReference.resolvedSymbol.fir as? FirCallableMemberDeclaration
|
||||
// TODO: check callee owner directly?
|
||||
if (callee !is FirConstructor && callee?.isStatic != true) {
|
||||
classLikeDeclaration.companionObject?.let { return it.psi }
|
||||
}
|
||||
}
|
||||
}
|
||||
return classLikeDeclaration?.psi
|
||||
}
|
||||
|
||||
fun FirReference.toTargetPsi(session: FirSession): PsiElement? {
|
||||
return when (this) {
|
||||
is FirResolvedNamedReference -> {
|
||||
resolvedSymbol.fir.psi
|
||||
}
|
||||
is FirResolvedCallableReference -> {
|
||||
resolvedSymbol.fir.psi
|
||||
}
|
||||
is FirThisReference -> {
|
||||
boundSymbol?.fir?.psi
|
||||
}
|
||||
is FirSuperReference -> {
|
||||
(superTypeRef as? FirResolvedTypeRef)?.toTargetPsi(session)
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveToPsiElements(ref: AbstractKtReference<KtElement>): Collection<PsiElement> {
|
||||
val expression = ref.expression
|
||||
val state = expression.firResolveState()
|
||||
val session = state.getSession(expression)
|
||||
when (val fir = expression.getOrBuildFir(state)) {
|
||||
is FirResolvable -> {
|
||||
return listOfNotNull(fir.calleeReference.toTargetPsi(session))
|
||||
}
|
||||
is FirResolvedTypeRef -> {
|
||||
return listOfNotNull(fir.toTargetPsi(session))
|
||||
}
|
||||
is FirResolvedQualifier -> {
|
||||
val classId = fir.classId ?: return emptyList()
|
||||
// Distinguish A.foo() from A(.Companion).foo()
|
||||
// Make expression.parent as? KtDotQualifiedExpression local function
|
||||
var parent = expression.parent as? KtDotQualifiedExpression
|
||||
while (parent != null) {
|
||||
val selectorExpression = parent.selectorExpression ?: break
|
||||
if (selectorExpression === expression) {
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
continue
|
||||
}
|
||||
val parentFir = selectorExpression.getOrBuildFir(state)
|
||||
if (parentFir is FirQualifiedAccess) {
|
||||
return listOfNotNull(classId.toTargetPsi(session, parentFir.calleeReference))
|
||||
}
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
}
|
||||
return listOfNotNull(classId.toTargetPsi(session))
|
||||
}
|
||||
is FirAnnotationCall -> {
|
||||
val type = fir.typeRef as? FirResolvedTypeRef ?: return emptyList()
|
||||
return listOfNotNull(type.toTargetPsi(session))
|
||||
}
|
||||
is FirResolvedImport -> {
|
||||
var parent = expression.parent
|
||||
while (parent is KtDotQualifiedExpression) {
|
||||
if (parent.selectorExpression !== expression) {
|
||||
// Special: package reference in the middle of import directive
|
||||
// import a.<caret>b.c.SomeClass
|
||||
// TODO: return reference to PsiPackage
|
||||
return listOf(expression)
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
val classId = fir.resolvedClassId
|
||||
if (classId != null) {
|
||||
return listOfNotNull(classId.toTargetPsi(session))
|
||||
}
|
||||
val name = fir.importedName ?: return emptyList()
|
||||
val symbolProvider = session.firSymbolProvider
|
||||
return symbolProvider.getTopLevelCallableSymbols(fir.packageFqName, name).mapNotNull { it.fir.psi } +
|
||||
listOfNotNull(symbolProvider.getClassLikeSymbolByFqName(ClassId(fir.packageFqName, name))?.fir?.psi)
|
||||
}
|
||||
is FirFile -> {
|
||||
if (expression.getNonStrictParentOfType<KtPackageDirective>() != null) {
|
||||
// Special: package reference in the middle of package directive
|
||||
return listOf(expression)
|
||||
}
|
||||
return listOfNotNull(fir.psi)
|
||||
}
|
||||
is FirArrayOfCall -> {
|
||||
// We can't yet find PsiElement for arrayOf, intArrayOf, etc.
|
||||
return emptyList()
|
||||
}
|
||||
is FirErrorNamedReference -> {
|
||||
return emptyList()
|
||||
}
|
||||
else -> {
|
||||
// Handle situation when we're in the middle/beginning of qualifier
|
||||
// <caret>A.B.C.foo() or A.<caret>B.C.foo()
|
||||
// NB: in this case we get some parent FIR, like FirBlock, FirProperty, FirFunction or the like
|
||||
var parent = expression.parent as? KtDotQualifiedExpression
|
||||
var unresolvedCounter = 1
|
||||
while (parent != null) {
|
||||
val selectorExpression = parent.selectorExpression ?: break
|
||||
if (selectorExpression === expression) {
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
continue
|
||||
}
|
||||
val parentFir = selectorExpression.getOrBuildFir(state)
|
||||
if (parentFir is FirResolvedQualifier) {
|
||||
var classId = parentFir.classId
|
||||
while (unresolvedCounter > 0) {
|
||||
unresolvedCounter--
|
||||
classId = classId?.outerClassId
|
||||
}
|
||||
return listOfNotNull(classId?.toTargetPsi(session))
|
||||
}
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
unresolvedCounter++
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinReferenceResolver : ResolveCache.PolyVariantResolver<AbstractKtReference<KtElement>> {
|
||||
class KotlinResolveResult(element: PsiElement) : PsiElementResolveResult(element)
|
||||
|
||||
private fun resolveToPsiElements(ref: AbstractKtReference<KtElement>): Collection<PsiElement> {
|
||||
if (FirResolution.enabled) {
|
||||
return FirReferenceResolveHelper.resolveToPsiElements(ref)
|
||||
}
|
||||
val bindingContext = ref.expression.analyze(BodyResolveMode.PARTIAL)
|
||||
return resolveToPsiElements(ref, bindingContext, ref.getTargetDescriptors(bindingContext))
|
||||
}
|
||||
|
||||
private fun resolveToPsiElements(
|
||||
ref: AbstractKtReference<KtElement>,
|
||||
context: BindingContext,
|
||||
targetDescriptors: Collection<DeclarationDescriptor>
|
||||
): Collection<PsiElement> {
|
||||
if (targetDescriptors.isNotEmpty()) {
|
||||
return targetDescriptors.flatMap { target -> resolveToPsiElements(ref, target) }.toSet()
|
||||
}
|
||||
|
||||
val labelTargets = getLabelTargets(ref, context)
|
||||
if (labelTargets != null) {
|
||||
return labelTargets
|
||||
}
|
||||
|
||||
return Collections.emptySet()
|
||||
}
|
||||
|
||||
private fun resolveToPsiElements(
|
||||
ref: AbstractKtReference<KtElement>,
|
||||
targetDescriptor: DeclarationDescriptor
|
||||
): Collection<PsiElement> {
|
||||
return if (targetDescriptor is PackageViewDescriptor) {
|
||||
val psiFacade = JavaPsiFacade.getInstance(ref.expression.project)
|
||||
val fqName = targetDescriptor.fqName.asString()
|
||||
listOfNotNull(psiFacade.findPackage(fqName))
|
||||
} else {
|
||||
DescriptorToSourceUtilsIde.getAllDeclarations(ref.expression.project, targetDescriptor, ref.expression.resolveScope)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLabelTargets(ref: AbstractKtReference<KtElement>, context: BindingContext): Collection<PsiElement>? {
|
||||
val reference = ref.expression as? KtReferenceExpression ?: return null
|
||||
val labelTarget = context[BindingContext.LABEL_TARGET, reference]
|
||||
if (labelTarget != null) {
|
||||
return listOf(labelTarget)
|
||||
}
|
||||
return context[BindingContext.AMBIGUOUS_LABEL_TARGET, reference]
|
||||
}
|
||||
|
||||
override fun resolve(ref: AbstractKtReference<KtElement>, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
return runWithCancellationCheck {
|
||||
val resolveToPsiElements = resolveToPsiElements(ref)
|
||||
resolveToPsiElements.map { KotlinResolveResult(it) }.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val KOTLIN_RESOLVER = KotlinReferenceResolver()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class KtSimpleReference<T : KtReferenceExpression>(expression: T) : AbstractKtReference<T>(expression) {
|
||||
override fun getTargetDescriptors(context: BindingContext) = expression.getReferenceTargets(context)
|
||||
fun KtReference.resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
|
||||
if (this !is KtDescriptorsBasedReference) {
|
||||
error("Reference $this should be KtDescriptorsBasedReference but was ${this::class}")
|
||||
}
|
||||
return resolveToDescriptors(bindingContext)
|
||||
}
|
||||
|
||||
abstract class KtMultiReference<T : KtElement>(expression: T) : AbstractKtReference<T>(expression)
|
||||
|
||||
object KotlinDescriptorsBasedReferenceResolver : ResolveCache.PolyVariantResolver<KtReference> {
|
||||
class KotlinResolveResult(element: PsiElement) : PsiElementResolveResult(element)
|
||||
|
||||
private fun resolveToPsiElements(ref: KtDescriptorsBasedReference): Collection<PsiElement> {
|
||||
if (FirResolution.enabled) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return FirReferenceResolveHelper.resolveToPsiElements(ref as AbstractKtReference<KtElement>)
|
||||
}
|
||||
val bindingContext = ref.element.analyze(BodyResolveMode.PARTIAL)
|
||||
return resolveToPsiElements(ref, bindingContext, ref.getTargetDescriptors(bindingContext))
|
||||
}
|
||||
|
||||
private fun resolveToPsiElements(
|
||||
ref: KtDescriptorsBasedReference,
|
||||
context: BindingContext,
|
||||
targetDescriptors: Collection<DeclarationDescriptor>
|
||||
): Collection<PsiElement> {
|
||||
if (targetDescriptors.isNotEmpty()) {
|
||||
return targetDescriptors.flatMap { target -> resolveToPsiElements(ref, target) }.toSet()
|
||||
}
|
||||
|
||||
val labelTargets = getLabelTargets(ref, context)
|
||||
if (labelTargets != null) {
|
||||
return labelTargets
|
||||
}
|
||||
|
||||
return Collections.emptySet()
|
||||
}
|
||||
|
||||
private fun resolveToPsiElements(
|
||||
ref: KtDescriptorsBasedReference,
|
||||
targetDescriptor: DeclarationDescriptor
|
||||
): Collection<PsiElement> {
|
||||
return if (targetDescriptor is PackageViewDescriptor) {
|
||||
val psiFacade = JavaPsiFacade.getInstance(ref.element.project)
|
||||
val fqName = targetDescriptor.fqName.asString()
|
||||
listOfNotNull(psiFacade.findPackage(fqName))
|
||||
} else {
|
||||
DescriptorToSourceUtilsIde.getAllDeclarations(ref.element.project, targetDescriptor, ref.element.resolveScope)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLabelTargets(ref: KtDescriptorsBasedReference, context: BindingContext): Collection<PsiElement>? {
|
||||
val reference = ref.element as? KtReferenceExpression ?: return null
|
||||
val labelTarget = context[BindingContext.LABEL_TARGET, reference]
|
||||
if (labelTarget != null) {
|
||||
return listOf(labelTarget)
|
||||
}
|
||||
return context[BindingContext.AMBIGUOUS_LABEL_TARGET, reference]
|
||||
}
|
||||
|
||||
override fun resolve(ref: KtReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
return runWithCancellationCheck {
|
||||
val resolveToPsiElements = resolveToPsiElements(ref as KtDescriptorsBasedReference)
|
||||
resolveToPsiElements.map { KotlinResolveResult(it) }.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.references
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import com.intellij.util.SmartList
|
||||
@@ -33,15 +34,21 @@ import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
||||
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleReference<KtSimpleNameExpression>(expression) {
|
||||
class KtSimpleNameReferenceDescriptorsImpl(
|
||||
expression: KtSimpleNameExpression
|
||||
) : KtSimpleNameReference(expression), KtDescriptorsBasedReference {
|
||||
override fun doCanBeReferenceTo(candidateTarget: PsiElement): Boolean =
|
||||
canBeReferenceTo(candidateTarget)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
return SmartList<DeclarationDescriptor>().apply {
|
||||
// Replace Java property with its accessor(s)
|
||||
for (descriptor in super.getTargetDescriptors(context)) {
|
||||
for (descriptor in expression.getReferenceTargets(context)) {
|
||||
val sizeBefore = size
|
||||
|
||||
if (descriptor !is JavaPropertyDescriptor) {
|
||||
@@ -71,7 +78,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
||||
if (extension.isReferenceTo(this, element)) return true
|
||||
}
|
||||
|
||||
return super.isReferenceTo(element)
|
||||
return super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||
}
|
||||
|
||||
override fun getRangeInElement(): TextRange {
|
||||
@@ -141,23 +148,18 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
||||
return expression
|
||||
}
|
||||
|
||||
enum class ShorteningMode {
|
||||
NO_SHORTENING,
|
||||
DELAYED_SHORTENING,
|
||||
FORCED_SHORTENING
|
||||
}
|
||||
|
||||
// By default reference binding is delayed
|
||||
override fun bindToElement(element: PsiElement): PsiElement =
|
||||
bindToElement(element, ShorteningMode.DELAYED_SHORTENING)
|
||||
|
||||
fun bindToElement(element: PsiElement, shorteningMode: ShorteningMode): PsiElement =
|
||||
override fun bindToElement(element: PsiElement, shorteningMode: ShorteningMode): PsiElement =
|
||||
element.getKotlinFqName()?.let { fqName -> bindToFqName(fqName, shorteningMode, element) } ?: expression
|
||||
|
||||
fun bindToFqName(
|
||||
override fun bindToFqName(
|
||||
fqName: FqName,
|
||||
shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING,
|
||||
targetElement: PsiElement? = null
|
||||
shorteningMode: ShorteningMode,
|
||||
targetElement: PsiElement?
|
||||
): PsiElement {
|
||||
val expression = expression
|
||||
if (fqName.isRoot) return expression
|
||||
@@ -289,7 +291,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
||||
return listOf(element.getReferencedNameAsName())
|
||||
}
|
||||
|
||||
fun getImportAlias(): KtImportAlias? {
|
||||
override fun getImportAlias(): KtImportAlias? {
|
||||
fun DeclarationDescriptor.unwrap() = if (this is ImportedFromObjectCallableDescriptor<*>) callableFromObject else this
|
||||
|
||||
val element = element
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
class ReadWriteAccessCheckerDescriptorsImpl : ReadWriteAccessChecker {
|
||||
override fun readWriteAccessWithFullExpressionByResolve(assignment: KtBinaryExpression): Pair<ReferenceAccess, KtExpression> {
|
||||
val resolvedCall = assignment.resolveToCall() ?: return ReferenceAccess.READ_WRITE to assignment
|
||||
if (!resolvedCall.isReallySuccess()) return ReferenceAccess.READ_WRITE to assignment
|
||||
return if (resolvedCall.resultingDescriptor.name in OperatorConventions.ASSIGNMENT_OPERATIONS.values)
|
||||
ReferenceAccess.READ to assignment
|
||||
else
|
||||
ReferenceAccess.READ_WRITE to assignment
|
||||
}
|
||||
}
|
||||
+12
-26
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
@@ -22,14 +20,22 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpression, private val getter: Boolean) :
|
||||
KtSimpleReference<KtNameReferenceExpression>(expression) {
|
||||
class SyntheticPropertyAccessorReferenceDescriptorImpl(
|
||||
expression: KtNameReferenceExpression,
|
||||
getter: Boolean
|
||||
) : SyntheticPropertyAccessorReference(expression, getter), KtDescriptorsBasedReference {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||
super<SyntheticPropertyAccessorReference>.isReferenceTo(element)
|
||||
|
||||
override fun additionalIsReferenceToChecker(element: PsiElement): Boolean = matchesTarget(element)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val descriptors = super.getTargetDescriptors(context)
|
||||
val descriptors = expression.getReferenceTargets(context)
|
||||
if (descriptors.none { it is SyntheticJavaPropertyDescriptor }) return emptyList()
|
||||
|
||||
val result = SmartList<FunctionDescriptor>()
|
||||
@@ -45,23 +51,6 @@ sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpre
|
||||
return result
|
||||
}
|
||||
|
||||
override fun isReferenceTo(element: PsiElement): Boolean {
|
||||
if (element !is PsiMethod || !isAccessorName(element.name)) return false
|
||||
if (!getter && expression.readWriteAccess(true) == ReferenceAccess.READ) return false
|
||||
return super.isReferenceTo(element)
|
||||
}
|
||||
|
||||
private fun isAccessorName(name: String): Boolean {
|
||||
if (getter) {
|
||||
return name.startsWith("get") || name.startsWith("is")
|
||||
}
|
||||
return name.startsWith("set")
|
||||
}
|
||||
|
||||
override fun getRangeInElement() = TextRange(0, expression.textLength)
|
||||
|
||||
override fun canRename() = true
|
||||
|
||||
private fun renameByPropertyName(newName: String): PsiElement? {
|
||||
val nameIdentifier = KtPsiFactory(expression).createNameIdentifier(newName)
|
||||
expression.getReferencedNameElement().replace(nameIdentifier)
|
||||
@@ -183,7 +172,4 @@ sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpre
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() = listOf(element.getReferencedNameAsName())
|
||||
|
||||
class Getter(expression: KtNameReferenceExpression) : SyntheticPropertyAccessorReference(expression, true)
|
||||
class Setter(expression: KtNameReferenceExpression) : SyntheticPropertyAccessorReference(expression, false)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -221,20 +221,20 @@ fun AbstractKtReference<out KtExpression>.renameImplicitConventionalCall(newName
|
||||
return newExpression
|
||||
}
|
||||
|
||||
val KtSimpleNameExpression.mainReference: KtSimpleNameReference
|
||||
val KtSimpleNameExpression.mainReference: KtSimpleNameReferenceDescriptorsImpl
|
||||
get() = references.firstIsInstance()
|
||||
|
||||
val KtReferenceExpression.mainReference: KtReference
|
||||
get() = if (this is KtSimpleNameExpression) mainReference else references.firstIsInstance<KtReference>()
|
||||
val KtReferenceExpression.mainReference: KtDescriptorsBasedReference
|
||||
get() = if (this is KtSimpleNameExpression) mainReference else references.firstIsInstance<KtDescriptorsBasedReference>()
|
||||
|
||||
val KDocName.mainReference: KDocReference
|
||||
get() = references.firstIsInstance()
|
||||
|
||||
val KtElement.mainReference: KtReference?
|
||||
val KtElement.mainReference: KtDescriptorsBasedReference?
|
||||
get() = when (this) {
|
||||
is KtReferenceExpression -> mainReference
|
||||
is KDocName -> mainReference
|
||||
else -> references.firstIsInstanceOrNull<KtReference>()
|
||||
else -> references.firstIsInstanceOrNull<KtDescriptorsBasedReference>()
|
||||
}
|
||||
|
||||
fun KtElement.resolveMainReferenceToDescriptors(): Collection<DeclarationDescriptor> {
|
||||
@@ -248,46 +248,6 @@ fun PsiReference.getImportAlias(): KtImportAlias? {
|
||||
|
||||
// ----------- Read/write access -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) {
|
||||
READ(true, false), WRITE(false, true), READ_WRITE(true, true)
|
||||
}
|
||||
|
||||
fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean) = readWriteAccessWithFullExpression(useResolveForReadWrite).first
|
||||
|
||||
fun KtExpression.readWriteAccessWithFullExpression(useResolveForReadWrite: Boolean): Pair<ReferenceAccess, KtExpression> {
|
||||
var expression = getQualifiedExpressionForSelectorOrThis()
|
||||
loop@ while (true) {
|
||||
when (val parent = expression.parent) {
|
||||
is KtParenthesizedExpression, is KtAnnotatedExpression, is KtLabeledExpression -> expression = parent as KtExpression
|
||||
else -> break@loop
|
||||
}
|
||||
}
|
||||
|
||||
val assignment = expression.getAssignmentByLHS()
|
||||
if (assignment != null) {
|
||||
when (assignment.operationToken) {
|
||||
KtTokens.EQ -> return ReferenceAccess.WRITE to assignment
|
||||
|
||||
else -> {
|
||||
if (!useResolveForReadWrite) return ReferenceAccess.READ_WRITE to assignment
|
||||
|
||||
val resolvedCall = assignment.resolveToCall() ?: return ReferenceAccess.READ_WRITE to assignment
|
||||
if (!resolvedCall.isReallySuccess()) return ReferenceAccess.READ_WRITE to assignment
|
||||
return if (resolvedCall.resultingDescriptor.name in OperatorConventions.ASSIGNMENT_OPERATIONS.values)
|
||||
ReferenceAccess.READ to assignment
|
||||
else
|
||||
ReferenceAccess.READ_WRITE to assignment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unaryExpression = expression.parent as? KtUnaryExpression
|
||||
return if (unaryExpression != null && unaryExpression.operationToken in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) })
|
||||
ReferenceAccess.READ_WRITE to unaryExpression
|
||||
else
|
||||
ReferenceAccess.READ to expression
|
||||
}
|
||||
|
||||
fun KtReference.canBeResolvedViaImport(target: DeclarationDescriptor, bindingContext: BindingContext): Boolean {
|
||||
if (this is KDocReference) {
|
||||
val qualifier = element.getQualifier() ?: return true
|
||||
|
||||
@@ -16,6 +16,7 @@ dependencies {
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":idea:ide-common"))
|
||||
compile(project(":idea:idea-jps-common"))
|
||||
compile(project(":idea:idea-frontend-independent"))
|
||||
compile(project(":kotlin-util-klib-metadata"))
|
||||
compile(project(":plugins:android-extensions-compiler"))
|
||||
compile(project(":kotlin-scripting-compiler-impl"))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -158,8 +158,6 @@ fun KtCallableDeclaration.canOmitDeclaredType(initializerOrBodyExpression: KtExp
|
||||
return canChangeTypeToSubtype && expressionType.isSubtypeOf(declaredType)
|
||||
}
|
||||
|
||||
fun String.unquote(): String = KtPsiUtil.unquoteIdentifier(this)
|
||||
|
||||
fun FqName.quoteSegmentsIfNeeded(): String {
|
||||
return pathSegments().joinToString(".") { it.asString().quoteIfNeeded() }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -45,14 +45,6 @@ import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
inline fun <reified T : PsiElement> PsiElement.replaced(newElement: T): T {
|
||||
val result = replace(newElement)
|
||||
return result as? T ?: (result as KtParenthesizedExpression).expression as T
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : PsiElement> T.copied(): T = copy() as T
|
||||
|
||||
fun KtLambdaArgument.moveInsideParentheses(bindingContext: BindingContext): KtCallExpression {
|
||||
val ktExpression = this.getArgumentExpression()
|
||||
?: throw KotlinExceptionWithAttachments("no argument expression for $this")
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/*
|
||||
This module should not depend on compiler scpecific functionality
|
||||
No dependencies on descriptors (for now we still have transitive one by psi module), fir and similar modules,
|
||||
but may be dependencies on frontend independent one like psi & type-system
|
||||
This module is needed for smooth migration from descriptor frontend based IJ plugin to interlayer based one
|
||||
*/
|
||||
compileOnly(project(":compiler:psi"))
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
compileOnly(intellijCoreDep())
|
||||
compileOnly(intellijDep())
|
||||
|
||||
Platform[191].orLower {
|
||||
compileOnly(intellijDep()) { includeJars("java-api", "java-impl") }
|
||||
}
|
||||
|
||||
Platform[192].orHigher {
|
||||
compileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.KtParenthesizedExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
|
||||
inline fun <reified T : PsiElement> PsiElement.replaced(newElement: T): T {
|
||||
val result = replace(newElement)
|
||||
return result as? T ?: (result as KtParenthesizedExpression).expression as T
|
||||
}
|
||||
|
||||
//todo make inline
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : PsiElement> T.copied(): T = copy() as T
|
||||
|
||||
fun String.unquote(): String = KtPsiUtil.unquoteIdentifier(this)
|
||||
|
||||
|
||||
|
||||
+10
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -8,24 +8,15 @@ package org.jetbrains.kotlin.idea.references
|
||||
import com.google.common.collect.Lists
|
||||
import com.intellij.psi.MultiRangeReference
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.lexer.KtToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.buildExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_SET
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class KtArrayAccessReference(
|
||||
abstract class KtArrayAccessReference(
|
||||
expression: KtArrayAccessExpression
|
||||
) : KtSimpleReference<KtArrayAccessExpression>(expression), MultiRangeReference {
|
||||
override val resolvesByNames: Collection<Name>
|
||||
@@ -33,12 +24,6 @@ class KtArrayAccessReference(
|
||||
|
||||
override fun getRangeInElement() = element.textRange.shiftRight(-element.textOffset)
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val getFunctionDescriptor = context[INDEXED_LVALUE_GET, expression]?.candidateDescriptor
|
||||
val setFunctionDescriptor = context[INDEXED_LVALUE_SET, expression]?.candidateDescriptor
|
||||
return listOfNotNull(getFunctionDescriptor, setFunctionDescriptor)
|
||||
}
|
||||
|
||||
private fun getBracketRange(bracketToken: KtToken) =
|
||||
expression.indicesNode.node.findChildByType(bracketToken)?.textRange?.shiftRight(-expression.textOffset)
|
||||
|
||||
@@ -65,15 +50,19 @@ class KtArrayAccessReference(
|
||||
}
|
||||
val fullCallExpression = arrayAccessExpression.replaced(replacement)
|
||||
val callExpression = fullCallExpression.getPossiblyQualifiedCallExpression()
|
||||
if (callExpression != null && callExpression.canMoveLambdaOutsideParentheses()) {
|
||||
callExpression.moveFunctionLiteralOutsideParentheses()
|
||||
if (callExpression != null && canMoveLambdaOutsideParentheses(callExpression)) {
|
||||
moveFunctionLiteralOutsideParentheses(callExpression)
|
||||
}
|
||||
return fullCallExpression
|
||||
}
|
||||
|
||||
return this.renameImplicitConventionalCall(newElementName)
|
||||
return doRenameImplicitConventionalCall(newElementName)
|
||||
}
|
||||
|
||||
protected abstract fun moveFunctionLiteralOutsideParentheses(callExpression: KtCallExpression)
|
||||
protected abstract fun canMoveLambdaOutsideParentheses(callExpression: KtCallExpression): Boolean
|
||||
protected abstract fun doRenameImplicitConventionalCall(newName: String?): KtExpression
|
||||
|
||||
companion object {
|
||||
private val NAMES = Lists.newArrayList(OperatorNameConventions.GET, OperatorNameConventions.SET)
|
||||
}
|
||||
+4
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -8,26 +8,18 @@ package org.jetbrains.kotlin.idea.references
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.MultiRangeReference
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
|
||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||
|
||||
class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) :
|
||||
abstract class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) :
|
||||
KtSimpleReference<KtCollectionLiteralExpression>(expression), MultiRangeReference {
|
||||
companion object {
|
||||
private val COLLECTION_LITERAL_CALL_NAMES =
|
||||
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values + CollectionLiteralResolver.ARRAY_OF_FUNCTION
|
||||
private val COLLECTION_LITERAL_CALL_NAMES = ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY.values + ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
}
|
||||
|
||||
override fun getRangeInElement(): TextRange = element.normalizeRange()
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val resolvedCall = context[BindingContext.COLLECTION_LITERAL_CALL, element]
|
||||
return listOfNotNull(resolvedCall?.resultingDescriptor)
|
||||
}
|
||||
|
||||
override fun getRanges(): List<TextRange> {
|
||||
return listOfNotNull(element.leftBracket?.normalizeRange(), element.rightBracket?.normalizeRange())
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression
|
||||
|
||||
abstract class KtConstructorDelegationReference(
|
||||
expression: KtConstructorDelegationReferenceExpression
|
||||
) : KtSimpleReference<KtConstructorDelegationReferenceExpression>(expression) {
|
||||
override fun getRangeInElement(): TextRange {
|
||||
return TextRange(0, element.textLength)
|
||||
}
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() = emptyList()
|
||||
|
||||
override fun handleElementRename(newElementName: String): PsiElement? {
|
||||
// Class rename never affects this reference, so there is no need to fail with exception
|
||||
return expression
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
|
||||
abstract class KtDestructuringDeclarationReference(
|
||||
element: KtDestructuringDeclarationEntry
|
||||
) : AbstractKtReference<KtDestructuringDeclarationEntry>(element) {
|
||||
|
||||
override fun getRangeInElement() = TextRange(0, element.textLength)
|
||||
|
||||
abstract override fun canRename(): Boolean
|
||||
|
||||
override fun handleElementRename(newElementName: String): PsiElement? {
|
||||
if (canRename()) return expression
|
||||
throw IncorrectOperationException()
|
||||
}
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() {
|
||||
val destructuringParent = element.parent as? KtDestructuringDeclaration ?: return emptyList()
|
||||
val componentIndex = destructuringParent.entries.indexOf(element) + 1
|
||||
return listOf(Name.identifier("component$componentIndex"))
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
abstract class KtForLoopInReference(element: KtForExpression) : KtMultiReference<KtForExpression>(element) {
|
||||
override fun getRangeInElement(): TextRange {
|
||||
val inKeyword = expression.inKeyword ?: return TextRange.EMPTY_RANGE
|
||||
|
||||
val offset = inKeyword.startOffsetInParent
|
||||
return TextRange(offset, offset + inKeyword.textLength)
|
||||
}
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() = NAMES
|
||||
|
||||
companion object {
|
||||
private val NAMES = listOf(
|
||||
OperatorNameConventions.ITERATOR,
|
||||
OperatorNameConventions.NEXT,
|
||||
OperatorNameConventions.HAS_NEXT
|
||||
)
|
||||
}
|
||||
}
|
||||
+14
-11
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.IndexNotReadyException
|
||||
import com.intellij.psi.ContributedReferenceHost
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -21,15 +22,20 @@ import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
internal interface KotlinPsiReferenceProvider {
|
||||
interface KotlinPsiReferenceProvider {
|
||||
fun getReferencesByElement(element: PsiElement): Array<PsiReference>
|
||||
}
|
||||
|
||||
internal interface KotlinReferenceProviderContributor {
|
||||
interface KotlinReferenceProviderContributor {
|
||||
fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar)
|
||||
|
||||
companion object {
|
||||
fun getInstance(): KotlinReferenceProviderContributor = service()
|
||||
}
|
||||
}
|
||||
|
||||
internal class KotlinPsiReferenceRegistrar {
|
||||
|
||||
class KotlinPsiReferenceRegistrar {
|
||||
val providers: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider> = MultiMap.create()
|
||||
|
||||
inline fun <reified E : KtElement> registerProvider(crossinline factory: (E) -> PsiReference?) {
|
||||
@@ -38,10 +44,9 @@ internal class KotlinPsiReferenceRegistrar {
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified E : KtElement> registerMultiProvider(crossinline factory: (E) -> Array<PsiReference>) {
|
||||
inline fun <reified E : KtElement> registerMultiProvider(crossinline factory: (E) -> Array<PsiReference>) {
|
||||
val provider: KotlinPsiReferenceProvider = object : KotlinPsiReferenceProvider {
|
||||
override fun getReferencesByElement(element: PsiElement): Array<PsiReference> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return factory(element as E)
|
||||
}
|
||||
}
|
||||
@@ -58,15 +63,13 @@ class KtIdeReferenceProviderService : KotlinReferenceProvidersService() {
|
||||
private val originalProvidersBinding: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider>
|
||||
private val providersBindingCache: Map<Class<out PsiElement>, List<KotlinPsiReferenceProvider>>
|
||||
|
||||
private val referenceContributors = listOf(KotlinReferenceContributor(), KotlinDefaultAnnotationMethodImplicitReferenceContributor())
|
||||
|
||||
init {
|
||||
val registrar = KotlinPsiReferenceRegistrar()
|
||||
referenceContributors.forEach { it.registerReferenceProviders(registrar) }
|
||||
KotlinReferenceProviderContributor.getInstance().registerReferenceProviders(registrar)
|
||||
originalProvidersBinding = registrar.providers
|
||||
|
||||
providersBindingCache = ConcurrentFactoryMap.createMap<Class<out PsiElement>, List<KotlinPsiReferenceProvider>> { klass ->
|
||||
val result = ContainerUtil.newSmartList<KotlinPsiReferenceProvider>()
|
||||
val result = SmartList<KotlinPsiReferenceProvider>()
|
||||
for (bindingClass in originalProvidersBinding.keySet()) {
|
||||
if (bindingClass.isAssignableFrom(klass)) {
|
||||
result.addAll(originalProvidersBinding.get(bindingClass))
|
||||
+7
-37
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
@@ -20,40 +9,20 @@ import com.intellij.lang.ASTNode
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.MultiRangeReference
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
|
||||
class KtInvokeFunctionReference(expression: KtCallExpression) : KtSimpleReference<KtCallExpression>(expression), MultiRangeReference {
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() = NAMES
|
||||
abstract class KtInvokeFunctionReference(expression: KtCallExpression) : KtSimpleReference<KtCallExpression>(expression), MultiRangeReference {
|
||||
override val resolvesByNames: Collection<Name> get() = NAMES
|
||||
|
||||
override fun getRangeInElement(): TextRange {
|
||||
return element.textRange.shiftRight(-element.textOffset)
|
||||
}
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val call = element.getCall(context)
|
||||
val resolvedCall = call.getResolvedCall(context)
|
||||
return when {
|
||||
resolvedCall is VariableAsFunctionResolvedCall ->
|
||||
setOf<DeclarationDescriptor>((resolvedCall as VariableAsFunctionResolvedCall).functionCall.candidateDescriptor)
|
||||
call != null && resolvedCall != null && call.callType == Call.CallType.INVOKE ->
|
||||
setOf<DeclarationDescriptor>(resolvedCall.candidateDescriptor)
|
||||
else ->
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRanges(): List<TextRange> {
|
||||
val list = ArrayList<TextRange>()
|
||||
val valueArgumentList = expression.valueArgumentList
|
||||
@@ -111,11 +80,12 @@ class KtInvokeFunctionReference(expression: KtCallExpression) : KtSimpleReferenc
|
||||
return fullCallExpression.replace(arrayAccessExpression)
|
||||
}
|
||||
|
||||
return renameImplicitConventionalCall(newElementName)
|
||||
return doRenameImplicitConventionalCall(newElementName)
|
||||
}
|
||||
|
||||
companion object {
|
||||
protected abstract fun doRenameImplicitConventionalCall(newName: String?): KtExpression
|
||||
|
||||
companion object {
|
||||
private val NAMES = listOf(OperatorNameConventions.INVOKE)
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
abstract class KtPropertyDelegationMethodsReference(element: KtPropertyDelegate) : KtMultiReference<KtPropertyDelegate>(element) {
|
||||
override fun getRangeInElement(): TextRange {
|
||||
val byKeywordNode = expression.byKeywordNode
|
||||
val offset = byKeywordNode.psi!!.startOffsetInParent
|
||||
return TextRange(offset, offset + byKeywordNode.textLength)
|
||||
}
|
||||
|
||||
override val resolvesByNames: Collection<Name> get() = NAMES
|
||||
|
||||
companion object {
|
||||
private val NAMES = listOf(
|
||||
OperatorNameConventions.GET_VALUE,
|
||||
OperatorNameConventions.SET_VALUE,
|
||||
OperatorNameConventions.PROVIDE_DELEGATE
|
||||
)
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||
|
||||
interface KtReference : PsiPolyVariantReference {
|
||||
val resolver: ResolveCache.PolyVariantResolver<KtReference>
|
||||
|
||||
override fun getElement(): KtElement
|
||||
|
||||
val resolvesByNames: Collection<Name>
|
||||
}
|
||||
|
||||
abstract class AbstractKtReference<T : KtElement>(element: T) : PsiPolyVariantReferenceBase<T>(element), KtReference {
|
||||
val expression: T
|
||||
get() = element
|
||||
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> =
|
||||
ResolveCache.getInstance(expression.project).resolveWithCaching(this, resolver, false, incompleteCode)
|
||||
|
||||
override fun getCanonicalText(): String = "<TBD>"
|
||||
|
||||
open fun canRename(): Boolean = false
|
||||
override fun handleElementRename(newElementName: String): PsiElement? = throw IncorrectOperationException()
|
||||
|
||||
override fun bindToElement(element: PsiElement): PsiElement = throw IncorrectOperationException()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun getVariants(): Array<Any> = PsiReference.EMPTY_ARRAY as Array<Any>
|
||||
|
||||
override fun isSoft(): Boolean = false
|
||||
|
||||
override fun toString() = this::class.java.simpleName + ": " + expression.text
|
||||
}
|
||||
|
||||
abstract class KtSimpleReference<T : KtReferenceExpression>(expression: T) : AbstractKtReference<T>(expression)
|
||||
|
||||
abstract class KtMultiReference<T : KtElement>(expression: T) : AbstractKtReference<T>(expression)
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
abstract class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleReference<KtSimpleNameExpression>(expression) {
|
||||
override fun isReferenceTo(element: PsiElement): Boolean {
|
||||
if (!doCanBeReferenceTo(element)) return false
|
||||
|
||||
|
||||
@Suppress("DEPRECATION") // compatibility with 191
|
||||
for (extension in Extensions.getArea(element.project).getExtensionPoint(SimpleNameReferenceExtension.EP_NAME).extensions) {
|
||||
if (extension.isReferenceTo(this, element)) return true
|
||||
}
|
||||
|
||||
return super.isReferenceTo(element)
|
||||
}
|
||||
|
||||
protected abstract fun doCanBeReferenceTo(candidateTarget: PsiElement): Boolean
|
||||
|
||||
override fun getRangeInElement(): TextRange {
|
||||
val element = element.getReferencedNameElement()
|
||||
val startOffset = getElement().startOffset
|
||||
return element.textRange.shiftRight(-startOffset)
|
||||
}
|
||||
|
||||
override fun canRename(): Boolean {
|
||||
if (expression.getParentOfTypeAndBranch<KtWhenConditionInRange>(strict = true) { operationReference } != null) return false
|
||||
|
||||
val elementType = expression.getReferencedNameElementType()
|
||||
if (elementType == KtTokens.PLUSPLUS || elementType == KtTokens.MINUSMINUS) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
abstract override fun handleElementRename(newElementName: String): PsiElement?
|
||||
|
||||
enum class ShorteningMode {
|
||||
NO_SHORTENING,
|
||||
DELAYED_SHORTENING,
|
||||
FORCED_SHORTENING
|
||||
}
|
||||
|
||||
// By default reference binding is delayed
|
||||
override fun bindToElement(element: PsiElement): PsiElement =
|
||||
bindToElement(element, ShorteningMode.DELAYED_SHORTENING)
|
||||
|
||||
abstract fun bindToElement(element: PsiElement, shorteningMode: ShorteningMode): PsiElement
|
||||
|
||||
abstract fun bindToFqName(
|
||||
fqName: FqName,
|
||||
shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING,
|
||||
targetElement: PsiElement? = null
|
||||
): PsiElement
|
||||
|
||||
override fun getCanonicalText(): String = expression.text
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() {
|
||||
val element = element
|
||||
|
||||
if (element is KtOperationReferenceExpression) {
|
||||
val tokenType = element.operationSignTokenType
|
||||
if (tokenType != null) {
|
||||
val name = OperatorConventions.getNameForOperationSymbol(
|
||||
tokenType, element.parent is KtUnaryExpression, element.parent is KtBinaryExpression
|
||||
) ?: return emptyList()
|
||||
val counterpart = OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS[tokenType]
|
||||
return if (counterpart != null) {
|
||||
val counterpartName = OperatorConventions.getNameForOperationSymbol(counterpart, false, true)!!
|
||||
listOf(name, counterpartName)
|
||||
} else {
|
||||
listOf(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return listOf(element.getReferencedNameAsName())
|
||||
}
|
||||
|
||||
abstract fun getImportAlias(): KtImportAlias?
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.constant
|
||||
|
||||
interface ReadWriteAccessChecker {
|
||||
fun readWriteAccessWithFullExpressionByResolve(assignment: KtBinaryExpression): Pair<ReferenceAccess, KtExpression>? = null
|
||||
|
||||
fun readWriteAccessWithFullExpression(
|
||||
targetExpression: KtExpression,
|
||||
useResolveForReadWrite: Boolean
|
||||
): Pair<ReferenceAccess, KtExpression> {
|
||||
var expression = targetExpression.getQualifiedExpressionForSelectorOrThis()
|
||||
loop@ while (true) {
|
||||
when (val parent = expression.parent) {
|
||||
is KtParenthesizedExpression, is KtAnnotatedExpression, is KtLabeledExpression -> expression = parent as KtExpression
|
||||
else -> break@loop
|
||||
}
|
||||
}
|
||||
|
||||
val assignment = expression.getAssignmentByLHS()
|
||||
if (assignment != null) {
|
||||
when (assignment.operationToken) {
|
||||
KtTokens.EQ -> return ReferenceAccess.WRITE to assignment
|
||||
|
||||
else -> {
|
||||
return (
|
||||
if (useResolveForReadWrite) readWriteAccessWithFullExpressionByResolve(assignment)
|
||||
else null
|
||||
) ?: ReferenceAccess.READ_WRITE to assignment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unaryExpression = expression.parent as? KtUnaryExpression
|
||||
return if (unaryExpression != null && unaryExpression.operationToken in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) })
|
||||
ReferenceAccess.READ_WRITE to unaryExpression
|
||||
else
|
||||
ReferenceAccess.READ to expression
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getInstance(): ReadWriteAccessChecker = service()
|
||||
}
|
||||
}
|
||||
|
||||
enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) {
|
||||
READ(true, false), WRITE(false, true), READ_WRITE(true, true)
|
||||
}
|
||||
|
||||
fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean) =
|
||||
readWriteAccessWithFullExpression(useResolveForReadWrite).first
|
||||
|
||||
fun KtExpression.readWriteAccessWithFullExpression(useResolveForReadWrite: Boolean): Pair<ReferenceAccess, KtExpression> =
|
||||
ReadWriteAccessChecker.getInstance().readWriteAccessWithFullExpression(this, useResolveForReadWrite)
|
||||
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
|
||||
abstract class SyntheticPropertyAccessorReference(
|
||||
expression: KtNameReferenceExpression,
|
||||
val getter: Boolean
|
||||
) : KtSimpleReference<KtNameReferenceExpression>(expression) {
|
||||
|
||||
override fun isReferenceTo(element: PsiElement): Boolean {
|
||||
if (element !is PsiMethod || !isAccessorName(element.name)) return false
|
||||
if (!getter && expression.readWriteAccess(true) == ReferenceAccess.READ) return false
|
||||
return additionalIsReferenceToChecker(element)
|
||||
}
|
||||
|
||||
protected abstract fun additionalIsReferenceToChecker(element: PsiElement): Boolean
|
||||
|
||||
private fun isAccessorName(name: String): Boolean {
|
||||
if (getter) {
|
||||
return name.startsWith("get") || name.startsWith("is")
|
||||
}
|
||||
return name.startsWith("set")
|
||||
}
|
||||
|
||||
override fun getRangeInElement() = TextRange(0, expression.textLength)
|
||||
|
||||
override fun canRename() = true
|
||||
|
||||
abstract override fun handleElementRename(newElementName: String): PsiElement?
|
||||
|
||||
override val resolvesByNames: Collection<Name>
|
||||
get() = listOf(element.getReferencedNameAsName())
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.core.util.runInReadActionWithWriteActionPriorit
|
||||
import org.jetbrains.kotlin.idea.patterns.KotlinFunctionPattern
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
|
||||
@@ -171,6 +171,12 @@
|
||||
<applicationService serviceInterface="org.jetbrains.kotlin.idea.caches.FileAttributeService"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.caches.FileAttributeServiceImpl"/>
|
||||
|
||||
<applicationService serviceInterface="org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.references.ReadWriteAccessCheckerDescriptorsImpl"/>
|
||||
|
||||
<applicationService serviceInterface="org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.references.KotlinReferenceContributor"/>
|
||||
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.KotlinPluginUpdater"/>
|
||||
|
||||
<applicationService serviceInterface="org.jetbrains.kotlin.psi.KotlinDeclarationNavigationPolicy"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.canBeResolvedViaImport
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.references.*
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
@@ -35,8 +24,8 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
@@ -294,8 +283,8 @@ fun KtDotQualifiedExpression.deleteFirstReceiver(): KtExpression {
|
||||
return this
|
||||
}
|
||||
|
||||
private val ARRAY_OF_METHODS = setOf(CollectionLiteralResolver.ARRAY_OF_FUNCTION) +
|
||||
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values.toSet() +
|
||||
private val ARRAY_OF_METHODS = setOf(ArrayFqNames.ARRAY_OF_FUNCTION) +
|
||||
ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY.values.toSet() +
|
||||
Name.identifier("emptyArray")
|
||||
|
||||
fun KtCallExpression.isArrayOfMethod(): Boolean {
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -14,8 +14,7 @@ import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver.Companion.ARRAY_OF_FUNCTION
|
||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver.Companion.PRIMITIVE_TYPE_TO_ARRAY
|
||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||
|
||||
class SurroundWithArrayOfWithSpreadOperatorInFunctionFix(
|
||||
val wrapper: Name,
|
||||
@@ -52,7 +51,7 @@ class SurroundWithArrayOfWithSpreadOperatorInFunctionFix(
|
||||
|
||||
val parameterType = actualDiagnostic.a
|
||||
|
||||
val wrapper = PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayElementType(parameterType)] ?: ARRAY_OF_FUNCTION
|
||||
val wrapper = ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayElementType(parameterType)] ?: ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
return SurroundWithArrayOfWithSpreadOperatorInFunctionFix(wrapper, actualDiagnostic.psiElement)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.core.setDefaultValue
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinCallableDefinitionUsage
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.addRemoveModifier.setModifierList
|
||||
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.pullUp
|
||||
@@ -33,6 +22,7 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.getChildrenToAnalyze
|
||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.resolveToDescriptorWrapperAware
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper
|
||||
import org.jetbrains.kotlin.idea.refactoring.pullUp.renderForConflicts
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -13,9 +13,11 @@ import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.refactoring.rename.RenameJavaMethodProcessor
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
|
||||
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReferenceDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.filterIsInstanceWithChecker
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
|
||||
class KotlinAwareJavaGetterRenameProcessor : RenameJavaMethodProcessor() {
|
||||
@@ -38,12 +40,12 @@ class KotlinAwareJavaGetterRenameProcessor : RenameJavaMethodProcessor() {
|
||||
.filter { it.parameters.size == 1 && it.returnType == PsiType.VOID }
|
||||
.flatMap {
|
||||
super.findReferences(it, searchScope, searchInCommentsAndStrings)
|
||||
.filterIsInstance<SyntheticPropertyAccessorReference.Setter>()
|
||||
.filterIsInstanceWithChecker<SyntheticPropertyAccessorReference> { !it.getter }
|
||||
}
|
||||
.ifEmpty { return getterReferences }
|
||||
return ArrayList<PsiReference>(getterReferences.size + setterReferences.size).apply {
|
||||
addAll(getterReferences)
|
||||
setterReferences.mapTo(this) { SyntheticPropertyAccessorReference.Getter(it.expression) }
|
||||
setterReferences.mapTo(this) { SyntheticPropertyAccessorReferenceDescriptorImpl(it.expression, getter = true) }
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-14
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.search.ideaExtensions
|
||||
@@ -94,7 +83,7 @@ class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() {
|
||||
return readWriteAccess.isRead != isGetter && readWriteAccess.isWrite == isGetter
|
||||
}
|
||||
if (ref is SyntheticPropertyAccessorReference) {
|
||||
return (ref is SyntheticPropertyAccessorReference.Getter) != isGetter
|
||||
return ref.getter != isGetter
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -12,9 +12,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.toArgumentList
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.types.*
|
||||
|
||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
|
||||
|
||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||
|
||||
class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
@@ -23,9 +21,9 @@ class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApp
|
||||
val primitiveArrayType = element.type.type as? JKJavaPrimitiveType
|
||||
val arrayConstructorName =
|
||||
if (primitiveArrayType != null)
|
||||
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY[PrimitiveType.valueOf(primitiveArrayType.jvmPrimitiveType.name)]!!.asString()
|
||||
ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[PrimitiveType.valueOf(primitiveArrayType.jvmPrimitiveType.name)]!!.asString()
|
||||
else
|
||||
CollectionLiteralResolver.ARRAY_OF_FUNCTION.asString()
|
||||
ArrayFqNames.ARRAY_OF_FUNCTION.asString()
|
||||
val typeArguments =
|
||||
if (primitiveArrayType == null) JKTypeArgumentList(listOf(element::type.detached()))
|
||||
else JKTypeArgumentList()
|
||||
|
||||
@@ -93,6 +93,7 @@ val projectsToShadow by extra(listOf(
|
||||
":idea:idea-jvm",
|
||||
":idea:idea-git",
|
||||
":idea:idea-jps-common",
|
||||
":idea:idea-frontend-independent",
|
||||
*if (Ide.IJ())
|
||||
arrayOf(
|
||||
":idea:idea-maven",
|
||||
|
||||
@@ -183,6 +183,7 @@ include ":kotlin-build-common",
|
||||
":idea:jvm-debugger:jvm-debugger-coroutine",
|
||||
":idea:jvm-debugger:jvm-debugger-test",
|
||||
":idea:scripting-support",
|
||||
":idea:idea-frontend-independent",
|
||||
":libraries:tools:new-project-wizard",
|
||||
":idea:idea-new-project-wizard",
|
||||
":libraries:tools:new-project-wizard:new-project-wizard-cli",
|
||||
|
||||
Reference in New Issue
Block a user