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.
|
* 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.
|
||||||
* 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.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
@@ -44,21 +33,6 @@ class CollectionLiteralResolver(
|
|||||||
val callResolver: CallResolver,
|
val callResolver: CallResolver,
|
||||||
val languageVersionSettings: LanguageVersionSettings
|
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(
|
fun resolveCollectionLiteral(
|
||||||
collectionLiteralExpression: KtCollectionLiteralExpression,
|
collectionLiteralExpression: KtCollectionLiteralExpression,
|
||||||
context: ExpressionTypingContext
|
context: ExpressionTypingContext
|
||||||
@@ -120,11 +94,11 @@ class CollectionLiteralResolver(
|
|||||||
|
|
||||||
private fun getArrayFunctionCallName(expectedType: KotlinType): Name {
|
private fun getArrayFunctionCallName(expectedType: KotlinType): Name {
|
||||||
if (NO_EXPECTED_TYPE === expectedType || !KotlinBuiltIns.isPrimitiveArray(expectedType)) {
|
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.
|
* 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.
|
||||||
* 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.utils.addToStdlib
|
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")
|
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? {
|
inline fun <reified T : Any> Iterable<*>.lastIsInstanceOrNull(): T? {
|
||||||
when (this) {
|
when (this) {
|
||||||
is List<*> -> {
|
is List<*> -> {
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* 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.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.kdoc
|
package org.jetbrains.kotlin.idea.kdoc
|
||||||
@@ -20,6 +9,7 @@ import com.intellij.openapi.util.TextRange
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.references.KtDescriptorsBasedReference
|
||||||
import org.jetbrains.kotlin.idea.references.KtMultiReference
|
import org.jetbrains.kotlin.idea.references.KtMultiReference
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
||||||
@@ -28,7 +18,11 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
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> {
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
val declaration = element.getContainingDoc().getOwner() ?: return arrayListOf()
|
val declaration = element.getContainingDoc().getOwner() ?: return arrayListOf()
|
||||||
val resolutionFacade = element.getResolutionFacade()
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-10
@@ -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.
|
* 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
|
override fun isSoft() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class KotlinDefaultAnnotationMethodImplicitReferenceContributor : KotlinReferenceProviderContributor {
|
internal val KotlinDefaultAnnotationMethodImplicitReferenceProvider = provider@{ element: KtValueArgument ->
|
||||||
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
|
if (element.isNamed()) return@provider null
|
||||||
registrar.registerProvider<KtValueArgument> {
|
val annotationEntry = element.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } ?: return@provider null
|
||||||
if (it.isNamed()) return@registerProvider null
|
if (annotationEntry.valueArguments.size != 1) return@provider null
|
||||||
val annotationEntry = it.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } ?: return@registerProvider null
|
|
||||||
if (annotationEntry.valueArguments.size != 1) return@registerProvider null
|
|
||||||
|
|
||||||
ReferenceImpl(it)
|
ReferenceImpl(element)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+17
-26
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* 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.
|
||||||
* 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
|
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.KtUserType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
|
|
||||||
internal class KotlinReferenceContributor : KotlinReferenceProviderContributor {
|
class KotlinReferenceContributor : KotlinReferenceProviderContributor {
|
||||||
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
|
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
|
||||||
with(registrar) {
|
with(registrar) {
|
||||||
registerProvider(factory = ::KtSimpleNameReference)
|
registerProvider(factory = ::KtSimpleNameReferenceDescriptorsImpl)
|
||||||
|
|
||||||
registerMultiProvider<KtNameReferenceExpression> { nameReferenceExpression ->
|
registerMultiProvider<KtNameReferenceExpression> { nameReferenceExpression ->
|
||||||
if (nameReferenceExpression.getReferencedNameElementType() != KtTokens.IDENTIFIER) return@registerMultiProvider emptyArray()
|
if (nameReferenceExpression.getReferencedNameElementType() != KtTokens.IDENTIFIER) return@registerMultiProvider emptyArray()
|
||||||
@@ -37,32 +26,34 @@ internal class KotlinReferenceContributor : KotlinReferenceProviderContributor {
|
|||||||
|
|
||||||
when (nameReferenceExpression.readWriteAccess(useResolveForReadWrite = false)) {
|
when (nameReferenceExpression.readWriteAccess(useResolveForReadWrite = false)) {
|
||||||
ReferenceAccess.READ ->
|
ReferenceAccess.READ ->
|
||||||
arrayOf(SyntheticPropertyAccessorReference.Getter(nameReferenceExpression))
|
arrayOf(SyntheticPropertyAccessorReferenceDescriptorImpl(nameReferenceExpression, getter = true))
|
||||||
ReferenceAccess.WRITE ->
|
ReferenceAccess.WRITE ->
|
||||||
arrayOf(SyntheticPropertyAccessorReference.Setter(nameReferenceExpression))
|
arrayOf(SyntheticPropertyAccessorReferenceDescriptorImpl(nameReferenceExpression, getter = false))
|
||||||
ReferenceAccess.READ_WRITE ->
|
ReferenceAccess.READ_WRITE ->
|
||||||
arrayOf(
|
arrayOf(
|
||||||
SyntheticPropertyAccessorReference.Getter(nameReferenceExpression),
|
SyntheticPropertyAccessorReferenceDescriptorImpl(nameReferenceExpression, getter = true),
|
||||||
SyntheticPropertyAccessorReference.Setter(nameReferenceExpression)
|
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(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.
|
* 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.psi.KtDestructuringDeclarationEntry
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEntry) :
|
class KtDestructuringDeclarationReferenceDescriptorsImpl(
|
||||||
AbstractKtReference<KtDestructuringDeclarationEntry>(element) {
|
element: KtDestructuringDeclarationEntry
|
||||||
|
) : KtDestructuringDeclarationReference(element), KtDescriptorsBasedReference {
|
||||||
|
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||||
|
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||||
|
|
||||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
return listOfNotNull(context[BindingContext.COMPONENT_RESOLVED_CALL, element]?.candidateDescriptor)
|
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
|
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.
|
* 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
|
package org.jetbrains.kotlin.idea.references
|
||||||
|
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
class KtForLoopInReference(element: KtForExpression) : KtMultiReference<KtForExpression>(element) {
|
class KtForLoopInReferenceDescriptorsImpl(
|
||||||
|
element: KtForExpression
|
||||||
override fun getRangeInElement(): TextRange {
|
) : KtForLoopInReference(element), KtDescriptorsBasedReference {
|
||||||
val inKeyword = expression.inKeyword ?: return TextRange.EMPTY_RANGE
|
override fun isReferenceTo(element: PsiElement): Boolean =
|
||||||
|
super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||||
val offset = inKeyword.startOffsetInParent
|
|
||||||
return TextRange(offset, offset + inKeyword.textLength)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
val loopRange = expression.loopRange ?: return emptyList()
|
val loopRange = expression.loopRange ?: return emptyList()
|
||||||
return LOOP_RANGE_KEYS.mapNotNull { key -> context.get(key, loopRange)?.candidateDescriptor }
|
return LOOP_RANGE_KEYS.mapNotNull { key -> context.get(key, loopRange)?.candidateDescriptor }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val resolvesByNames: Collection<Name>
|
|
||||||
get() = NAMES
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LOOP_RANGE_KEYS = arrayOf(
|
private val LOOP_RANGE_KEYS = arrayOf(
|
||||||
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
|
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
|
||||||
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL,
|
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL,
|
||||||
BindingContext.LOOP_RANGE_HAS_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.
|
* 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.
|
||||||
* 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
|
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 org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
interface KtReference : PsiPolyVariantReference {
|
interface KtDescriptorsBasedReference : KtReference {
|
||||||
fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor>
|
override val resolver get() = KotlinDescriptorsBasedReferenceResolver
|
||||||
|
|
||||||
override fun getElement(): KtElement
|
fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
|
return getTargetDescriptors(bindingContext)
|
||||||
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 getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor>
|
||||||
|
|
||||||
override fun isReferenceTo(element: PsiElement): Boolean {
|
override fun isReferenceTo(element: PsiElement): Boolean {
|
||||||
return matchesTarget(element)
|
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) {
|
fun KtReference.resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
override fun getTargetDescriptors(context: BindingContext) = expression.getReferenceTargets(context)
|
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.
|
* 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.extensions.Extensions
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiReference
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
import com.intellij.util.SmartList
|
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.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
||||||
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
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.descriptorUtil.getImportableDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
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> {
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
return SmartList<DeclarationDescriptor>().apply {
|
return SmartList<DeclarationDescriptor>().apply {
|
||||||
// Replace Java property with its accessor(s)
|
// Replace Java property with its accessor(s)
|
||||||
for (descriptor in super.getTargetDescriptors(context)) {
|
for (descriptor in expression.getReferenceTargets(context)) {
|
||||||
val sizeBefore = size
|
val sizeBefore = size
|
||||||
|
|
||||||
if (descriptor !is JavaPropertyDescriptor) {
|
if (descriptor !is JavaPropertyDescriptor) {
|
||||||
@@ -71,7 +78,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
if (extension.isReferenceTo(this, element)) return true
|
if (extension.isReferenceTo(this, element)) return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.isReferenceTo(element)
|
return super<KtDescriptorsBasedReference>.isReferenceTo(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRangeInElement(): TextRange {
|
override fun getRangeInElement(): TextRange {
|
||||||
@@ -141,23 +148,18 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
return expression
|
return expression
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ShorteningMode {
|
|
||||||
NO_SHORTENING,
|
|
||||||
DELAYED_SHORTENING,
|
|
||||||
FORCED_SHORTENING
|
|
||||||
}
|
|
||||||
|
|
||||||
// By default reference binding is delayed
|
// By default reference binding is delayed
|
||||||
override fun bindToElement(element: PsiElement): PsiElement =
|
override fun bindToElement(element: PsiElement): PsiElement =
|
||||||
bindToElement(element, ShorteningMode.DELAYED_SHORTENING)
|
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
|
element.getKotlinFqName()?.let { fqName -> bindToFqName(fqName, shorteningMode, element) } ?: expression
|
||||||
|
|
||||||
fun bindToFqName(
|
override fun bindToFqName(
|
||||||
fqName: FqName,
|
fqName: FqName,
|
||||||
shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING,
|
shorteningMode: ShorteningMode,
|
||||||
targetElement: PsiElement? = null
|
targetElement: PsiElement?
|
||||||
): PsiElement {
|
): PsiElement {
|
||||||
val expression = expression
|
val expression = expression
|
||||||
if (fqName.isRoot) return expression
|
if (fqName.isRoot) return expression
|
||||||
@@ -289,7 +291,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
|
|||||||
return listOf(element.getReferencedNameAsName())
|
return listOf(element.getReferencedNameAsName())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getImportAlias(): KtImportAlias? {
|
override fun getImportAlias(): KtImportAlias? {
|
||||||
fun DeclarationDescriptor.unwrap() = if (this is ImportedFromObjectCallableDescriptor<*>) callableFromObject else this
|
fun DeclarationDescriptor.unwrap() = if (this is ImportedFromObjectCallableDescriptor<*>) callableFromObject else this
|
||||||
|
|
||||||
val element = element
|
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.
|
* 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
|
package org.jetbrains.kotlin.idea.references
|
||||||
|
|
||||||
import com.intellij.openapi.util.TextRange
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiMethod
|
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpression, private val getter: Boolean) :
|
class SyntheticPropertyAccessorReferenceDescriptorImpl(
|
||||||
KtSimpleReference<KtNameReferenceExpression>(expression) {
|
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> {
|
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()
|
if (descriptors.none { it is SyntheticJavaPropertyDescriptor }) return emptyList()
|
||||||
|
|
||||||
val result = SmartList<FunctionDescriptor>()
|
val result = SmartList<FunctionDescriptor>()
|
||||||
@@ -45,23 +51,6 @@ sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpre
|
|||||||
return result
|
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? {
|
private fun renameByPropertyName(newName: String): PsiElement? {
|
||||||
val nameIdentifier = KtPsiFactory(expression).createNameIdentifier(newName)
|
val nameIdentifier = KtPsiFactory(expression).createNameIdentifier(newName)
|
||||||
expression.getReferencedNameElement().replace(nameIdentifier)
|
expression.getReferencedNameElement().replace(nameIdentifier)
|
||||||
@@ -183,7 +172,4 @@ sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpre
|
|||||||
|
|
||||||
override val resolvesByNames: Collection<Name>
|
override val resolvesByNames: Collection<Name>
|
||||||
get() = listOf(element.getReferencedNameAsName())
|
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.
|
* 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
|
return newExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
val KtSimpleNameExpression.mainReference: KtSimpleNameReference
|
val KtSimpleNameExpression.mainReference: KtSimpleNameReferenceDescriptorsImpl
|
||||||
get() = references.firstIsInstance()
|
get() = references.firstIsInstance()
|
||||||
|
|
||||||
val KtReferenceExpression.mainReference: KtReference
|
val KtReferenceExpression.mainReference: KtDescriptorsBasedReference
|
||||||
get() = if (this is KtSimpleNameExpression) mainReference else references.firstIsInstance<KtReference>()
|
get() = if (this is KtSimpleNameExpression) mainReference else references.firstIsInstance<KtDescriptorsBasedReference>()
|
||||||
|
|
||||||
val KDocName.mainReference: KDocReference
|
val KDocName.mainReference: KDocReference
|
||||||
get() = references.firstIsInstance()
|
get() = references.firstIsInstance()
|
||||||
|
|
||||||
val KtElement.mainReference: KtReference?
|
val KtElement.mainReference: KtDescriptorsBasedReference?
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
is KtReferenceExpression -> mainReference
|
is KtReferenceExpression -> mainReference
|
||||||
is KDocName -> mainReference
|
is KDocName -> mainReference
|
||||||
else -> references.firstIsInstanceOrNull<KtReference>()
|
else -> references.firstIsInstanceOrNull<KtDescriptorsBasedReference>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KtElement.resolveMainReferenceToDescriptors(): Collection<DeclarationDescriptor> {
|
fun KtElement.resolveMainReferenceToDescriptors(): Collection<DeclarationDescriptor> {
|
||||||
@@ -248,46 +248,6 @@ fun PsiReference.getImportAlias(): KtImportAlias? {
|
|||||||
|
|
||||||
// ----------- Read/write access -----------------------------------------------------------------------------------------------------------------------
|
// ----------- 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 {
|
fun KtReference.canBeResolvedViaImport(target: DeclarationDescriptor, bindingContext: BindingContext): Boolean {
|
||||||
if (this is KDocReference) {
|
if (this is KDocReference) {
|
||||||
val qualifier = element.getQualifier() ?: return true
|
val qualifier = element.getQualifier() ?: return true
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ dependencies {
|
|||||||
compile(project(":compiler:util"))
|
compile(project(":compiler:util"))
|
||||||
compile(project(":idea:ide-common"))
|
compile(project(":idea:ide-common"))
|
||||||
compile(project(":idea:idea-jps-common"))
|
compile(project(":idea:idea-jps-common"))
|
||||||
|
compile(project(":idea:idea-frontend-independent"))
|
||||||
compile(project(":kotlin-util-klib-metadata"))
|
compile(project(":kotlin-util-klib-metadata"))
|
||||||
compile(project(":plugins:android-extensions-compiler"))
|
compile(project(":plugins:android-extensions-compiler"))
|
||||||
compile(project(":kotlin-scripting-compiler-impl"))
|
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.
|
* 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)
|
return canChangeTypeToSubtype && expressionType.isSubtypeOf(declaredType)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.unquote(): String = KtPsiUtil.unquoteIdentifier(this)
|
|
||||||
|
|
||||||
fun FqName.quoteSegmentsIfNeeded(): String {
|
fun FqName.quoteSegmentsIfNeeded(): String {
|
||||||
return pathSegments().joinToString(".") { it.asString().quoteIfNeeded() }
|
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.
|
* 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.KotlinExceptionWithAttachments
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
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 {
|
fun KtLambdaArgument.moveInsideParentheses(bindingContext: BindingContext): KtCallExpression {
|
||||||
val ktExpression = this.getArgumentExpression()
|
val ktExpression = this.getArgumentExpression()
|
||||||
?: throw KotlinExceptionWithAttachments("no argument expression for $this")
|
?: 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.
|
* 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.google.common.collect.Lists
|
||||||
import com.intellij.psi.MultiRangeReference
|
import com.intellij.psi.MultiRangeReference
|
||||||
import com.intellij.psi.PsiElement
|
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.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.lexer.KtToken
|
import org.jetbrains.kotlin.lexer.KtToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
|
||||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
|
||||||
import org.jetbrains.kotlin.psi.buildExpression
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression
|
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
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
class KtArrayAccessReference(
|
abstract class KtArrayAccessReference(
|
||||||
expression: KtArrayAccessExpression
|
expression: KtArrayAccessExpression
|
||||||
) : KtSimpleReference<KtArrayAccessExpression>(expression), MultiRangeReference {
|
) : KtSimpleReference<KtArrayAccessExpression>(expression), MultiRangeReference {
|
||||||
override val resolvesByNames: Collection<Name>
|
override val resolvesByNames: Collection<Name>
|
||||||
@@ -33,12 +24,6 @@ class KtArrayAccessReference(
|
|||||||
|
|
||||||
override fun getRangeInElement() = element.textRange.shiftRight(-element.textOffset)
|
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) =
|
private fun getBracketRange(bracketToken: KtToken) =
|
||||||
expression.indicesNode.node.findChildByType(bracketToken)?.textRange?.shiftRight(-expression.textOffset)
|
expression.indicesNode.node.findChildByType(bracketToken)?.textRange?.shiftRight(-expression.textOffset)
|
||||||
|
|
||||||
@@ -65,15 +50,19 @@ class KtArrayAccessReference(
|
|||||||
}
|
}
|
||||||
val fullCallExpression = arrayAccessExpression.replaced(replacement)
|
val fullCallExpression = arrayAccessExpression.replaced(replacement)
|
||||||
val callExpression = fullCallExpression.getPossiblyQualifiedCallExpression()
|
val callExpression = fullCallExpression.getPossiblyQualifiedCallExpression()
|
||||||
if (callExpression != null && callExpression.canMoveLambdaOutsideParentheses()) {
|
if (callExpression != null && canMoveLambdaOutsideParentheses(callExpression)) {
|
||||||
callExpression.moveFunctionLiteralOutsideParentheses()
|
moveFunctionLiteralOutsideParentheses(callExpression)
|
||||||
}
|
}
|
||||||
return fullCallExpression
|
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 {
|
companion object {
|
||||||
private val NAMES = Lists.newArrayList(OperatorNameConventions.GET, OperatorNameConventions.SET)
|
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.
|
* 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.openapi.util.TextRange
|
||||||
import com.intellij.psi.MultiRangeReference
|
import com.intellij.psi.MultiRangeReference
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
|
|
||||||
|
|
||||||
class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) :
|
abstract class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) :
|
||||||
KtSimpleReference<KtCollectionLiteralExpression>(expression), MultiRangeReference {
|
KtSimpleReference<KtCollectionLiteralExpression>(expression), MultiRangeReference {
|
||||||
companion object {
|
companion object {
|
||||||
private val COLLECTION_LITERAL_CALL_NAMES =
|
private val COLLECTION_LITERAL_CALL_NAMES = ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY.values + ArrayFqNames.ARRAY_OF_FUNCTION
|
||||||
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values + CollectionLiteralResolver.ARRAY_OF_FUNCTION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRangeInElement(): TextRange = element.normalizeRange()
|
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> {
|
override fun getRanges(): List<TextRange> {
|
||||||
return listOfNotNull(element.leftBracket?.normalizeRange(), element.rightBracket?.normalizeRange())
|
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
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* that can be found in the license/LICENSE.txt file.
|
* 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
|
package org.jetbrains.kotlin.idea.references
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.openapi.project.IndexNotReadyException
|
import com.intellij.openapi.project.IndexNotReadyException
|
||||||
import com.intellij.psi.ContributedReferenceHost
|
import com.intellij.psi.ContributedReferenceHost
|
||||||
import com.intellij.psi.PsiElement
|
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.psi.KtElement
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
internal interface KotlinPsiReferenceProvider {
|
interface KotlinPsiReferenceProvider {
|
||||||
fun getReferencesByElement(element: PsiElement): Array<PsiReference>
|
fun getReferencesByElement(element: PsiElement): Array<PsiReference>
|
||||||
}
|
}
|
||||||
|
|
||||||
internal interface KotlinReferenceProviderContributor {
|
interface KotlinReferenceProviderContributor {
|
||||||
fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar)
|
fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getInstance(): KotlinReferenceProviderContributor = service()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class KotlinPsiReferenceRegistrar {
|
|
||||||
|
class KotlinPsiReferenceRegistrar {
|
||||||
val providers: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider> = MultiMap.create()
|
val providers: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider> = MultiMap.create()
|
||||||
|
|
||||||
inline fun <reified E : KtElement> registerProvider(crossinline factory: (E) -> PsiReference?) {
|
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 {
|
val provider: KotlinPsiReferenceProvider = object : KotlinPsiReferenceProvider {
|
||||||
override fun getReferencesByElement(element: PsiElement): Array<PsiReference> {
|
override fun getReferencesByElement(element: PsiElement): Array<PsiReference> {
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return factory(element as E)
|
return factory(element as E)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,15 +63,13 @@ class KtIdeReferenceProviderService : KotlinReferenceProvidersService() {
|
|||||||
private val originalProvidersBinding: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider>
|
private val originalProvidersBinding: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider>
|
||||||
private val providersBindingCache: Map<Class<out PsiElement>, List<KotlinPsiReferenceProvider>>
|
private val providersBindingCache: Map<Class<out PsiElement>, List<KotlinPsiReferenceProvider>>
|
||||||
|
|
||||||
private val referenceContributors = listOf(KotlinReferenceContributor(), KotlinDefaultAnnotationMethodImplicitReferenceContributor())
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val registrar = KotlinPsiReferenceRegistrar()
|
val registrar = KotlinPsiReferenceRegistrar()
|
||||||
referenceContributors.forEach { it.registerReferenceProviders(registrar) }
|
KotlinReferenceProviderContributor.getInstance().registerReferenceProviders(registrar)
|
||||||
originalProvidersBinding = registrar.providers
|
originalProvidersBinding = registrar.providers
|
||||||
|
|
||||||
providersBindingCache = ConcurrentFactoryMap.createMap<Class<out PsiElement>, List<KotlinPsiReferenceProvider>> { klass ->
|
providersBindingCache = ConcurrentFactoryMap.createMap<Class<out PsiElement>, List<KotlinPsiReferenceProvider>> { klass ->
|
||||||
val result = ContainerUtil.newSmartList<KotlinPsiReferenceProvider>()
|
val result = SmartList<KotlinPsiReferenceProvider>()
|
||||||
for (bindingClass in originalProvidersBinding.keySet()) {
|
for (bindingClass in originalProvidersBinding.keySet()) {
|
||||||
if (bindingClass.isAssignableFrom(klass)) {
|
if (bindingClass.isAssignableFrom(klass)) {
|
||||||
result.addAll(originalProvidersBinding.get(bindingClass))
|
result.addAll(originalProvidersBinding.get(bindingClass))
|
||||||
+7
-37
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* 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.
|
||||||
* 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
|
package org.jetbrains.kotlin.idea.references
|
||||||
@@ -20,40 +9,20 @@ import com.intellij.lang.ASTNode
|
|||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.MultiRangeReference
|
import com.intellij.psi.MultiRangeReference
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
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 org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KtInvokeFunctionReference(expression: KtCallExpression) : KtSimpleReference<KtCallExpression>(expression), MultiRangeReference {
|
abstract class KtInvokeFunctionReference(expression: KtCallExpression) : KtSimpleReference<KtCallExpression>(expression), MultiRangeReference {
|
||||||
|
override val resolvesByNames: Collection<Name> get() = NAMES
|
||||||
override val resolvesByNames: Collection<Name>
|
|
||||||
get() = NAMES
|
|
||||||
|
|
||||||
override fun getRangeInElement(): TextRange {
|
override fun getRangeInElement(): TextRange {
|
||||||
return element.textRange.shiftRight(-element.textOffset)
|
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> {
|
override fun getRanges(): List<TextRange> {
|
||||||
val list = ArrayList<TextRange>()
|
val list = ArrayList<TextRange>()
|
||||||
val valueArgumentList = expression.valueArgumentList
|
val valueArgumentList = expression.valueArgumentList
|
||||||
@@ -111,11 +80,12 @@ class KtInvokeFunctionReference(expression: KtCallExpression) : KtSimpleReferenc
|
|||||||
return fullCallExpression.replace(arrayAccessExpression)
|
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)
|
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.
|
* 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.
|
* 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.patterns.KotlinFunctionPattern
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
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.search.usagesSearch.descriptor
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
|||||||
@@ -171,6 +171,12 @@
|
|||||||
<applicationService serviceInterface="org.jetbrains.kotlin.idea.caches.FileAttributeService"
|
<applicationService serviceInterface="org.jetbrains.kotlin.idea.caches.FileAttributeService"
|
||||||
serviceImplementation="org.jetbrains.kotlin.idea.caches.FileAttributeServiceImpl"/>
|
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 serviceImplementation="org.jetbrains.kotlin.idea.KotlinPluginUpdater"/>
|
||||||
|
|
||||||
<applicationService serviceInterface="org.jetbrains.kotlin.psi.KotlinDeclarationNavigationPolicy"
|
<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.
|
* 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.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
||||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
import org.jetbrains.kotlin.idea.references.*
|
||||||
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.util.getResolutionScope
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.intentions
|
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.containingClass
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
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.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
@@ -294,8 +283,8 @@ fun KtDotQualifiedExpression.deleteFirstReceiver(): KtExpression {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private val ARRAY_OF_METHODS = setOf(CollectionLiteralResolver.ARRAY_OF_FUNCTION) +
|
private val ARRAY_OF_METHODS = setOf(ArrayFqNames.ARRAY_OF_FUNCTION) +
|
||||||
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values.toSet() +
|
ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY.values.toSet() +
|
||||||
Name.identifier("emptyArray")
|
Name.identifier("emptyArray")
|
||||||
|
|
||||||
fun KtCallExpression.isArrayOfMethod(): Boolean {
|
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.
|
* 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.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver.Companion.ARRAY_OF_FUNCTION
|
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver.Companion.PRIMITIVE_TYPE_TO_ARRAY
|
|
||||||
|
|
||||||
class SurroundWithArrayOfWithSpreadOperatorInFunctionFix(
|
class SurroundWithArrayOfWithSpreadOperatorInFunctionFix(
|
||||||
val wrapper: Name,
|
val wrapper: Name,
|
||||||
@@ -52,7 +51,7 @@ class SurroundWithArrayOfWithSpreadOperatorInFunctionFix(
|
|||||||
|
|
||||||
val parameterType = actualDiagnostic.a
|
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)
|
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.
|
* 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.refactoring.changeSignature.usages.KotlinCallableDefinitionUsage
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
|
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.addRemoveModifier.setModifierList
|
import org.jetbrains.kotlin.psi.addRemoveModifier.setModifierList
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
|
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.refactoring.pullUp
|
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.refactoring.memberInfo.resolveToDescriptorWrapperAware
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
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.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
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.
|
* 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.refactoring.pullUp.renderForConflicts
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
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.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
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.
|
* 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 com.intellij.refactoring.rename.RenameJavaMethodProcessor
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
|
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.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.filterIsInstanceWithChecker
|
||||||
import org.jetbrains.kotlin.utils.ifEmpty
|
import org.jetbrains.kotlin.utils.ifEmpty
|
||||||
|
|
||||||
class KotlinAwareJavaGetterRenameProcessor : RenameJavaMethodProcessor() {
|
class KotlinAwareJavaGetterRenameProcessor : RenameJavaMethodProcessor() {
|
||||||
@@ -38,12 +40,12 @@ class KotlinAwareJavaGetterRenameProcessor : RenameJavaMethodProcessor() {
|
|||||||
.filter { it.parameters.size == 1 && it.returnType == PsiType.VOID }
|
.filter { it.parameters.size == 1 && it.returnType == PsiType.VOID }
|
||||||
.flatMap {
|
.flatMap {
|
||||||
super.findReferences(it, searchScope, searchInCommentsAndStrings)
|
super.findReferences(it, searchScope, searchInCommentsAndStrings)
|
||||||
.filterIsInstance<SyntheticPropertyAccessorReference.Setter>()
|
.filterIsInstanceWithChecker<SyntheticPropertyAccessorReference> { !it.getter }
|
||||||
}
|
}
|
||||||
.ifEmpty { return getterReferences }
|
.ifEmpty { return getterReferences }
|
||||||
return ArrayList<PsiReference>(getterReferences.size + setterReferences.size).apply {
|
return ArrayList<PsiReference>(getterReferences.size + setterReferences.size).apply {
|
||||||
addAll(getterReferences)
|
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.
|
* 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.
|
||||||
* 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.search.ideaExtensions
|
package org.jetbrains.kotlin.idea.search.ideaExtensions
|
||||||
@@ -94,7 +83,7 @@ class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() {
|
|||||||
return readWriteAccess.isRead != isGetter && readWriteAccess.isWrite == isGetter
|
return readWriteAccess.isRead != isGetter && readWriteAccess.isWrite == isGetter
|
||||||
}
|
}
|
||||||
if (ref is SyntheticPropertyAccessorReference) {
|
if (ref is SyntheticPropertyAccessorReference) {
|
||||||
return (ref is SyntheticPropertyAccessorReference.Getter) != isGetter
|
return ref.getter != isGetter
|
||||||
}
|
}
|
||||||
return false
|
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.
|
* 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.toArgumentList
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
import org.jetbrains.kotlin.nj2k.types.*
|
import org.jetbrains.kotlin.nj2k.types.*
|
||||||
|
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
|
|
||||||
|
|
||||||
|
|
||||||
class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
@@ -23,9 +21,9 @@ class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApp
|
|||||||
val primitiveArrayType = element.type.type as? JKJavaPrimitiveType
|
val primitiveArrayType = element.type.type as? JKJavaPrimitiveType
|
||||||
val arrayConstructorName =
|
val arrayConstructorName =
|
||||||
if (primitiveArrayType != null)
|
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
|
else
|
||||||
CollectionLiteralResolver.ARRAY_OF_FUNCTION.asString()
|
ArrayFqNames.ARRAY_OF_FUNCTION.asString()
|
||||||
val typeArguments =
|
val typeArguments =
|
||||||
if (primitiveArrayType == null) JKTypeArgumentList(listOf(element::type.detached()))
|
if (primitiveArrayType == null) JKTypeArgumentList(listOf(element::type.detached()))
|
||||||
else JKTypeArgumentList()
|
else JKTypeArgumentList()
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ val projectsToShadow by extra(listOf(
|
|||||||
":idea:idea-jvm",
|
":idea:idea-jvm",
|
||||||
":idea:idea-git",
|
":idea:idea-git",
|
||||||
":idea:idea-jps-common",
|
":idea:idea-jps-common",
|
||||||
|
":idea:idea-frontend-independent",
|
||||||
*if (Ide.IJ())
|
*if (Ide.IJ())
|
||||||
arrayOf(
|
arrayOf(
|
||||||
":idea:idea-maven",
|
":idea:idea-maven",
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ include ":kotlin-build-common",
|
|||||||
":idea:jvm-debugger:jvm-debugger-coroutine",
|
":idea:jvm-debugger:jvm-debugger-coroutine",
|
||||||
":idea:jvm-debugger:jvm-debugger-test",
|
":idea:jvm-debugger:jvm-debugger-test",
|
||||||
":idea:scripting-support",
|
":idea:scripting-support",
|
||||||
|
":idea:idea-frontend-independent",
|
||||||
":libraries:tools:new-project-wizard",
|
":libraries:tools:new-project-wizard",
|
||||||
":idea:idea-new-project-wizard",
|
":idea:idea-new-project-wizard",
|
||||||
":libraries:tools:new-project-wizard:new-project-wizard-cli",
|
":libraries:tools:new-project-wizard:new-project-wizard-cli",
|
||||||
|
|||||||
Reference in New Issue
Block a user