FIR IDE: add Java synthetic properties support for completion
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
// FIR_COMPARISON
|
||||||
|
|
||||||
|
fun foo(a: java.lang.Thread) {
|
||||||
|
a.na<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// EXIST: {"lookupString":"name","tailText":" (from getName()/setName())","allLookupStrings":"getName, name, setName","itemText":"name"}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// FIR_COMPARISON
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
fun foo(file: File) {
|
fun foo(file: File) {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// FIR_COMPARISON
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
fun foo(file: File) {
|
fun foo(file: File) {
|
||||||
|
|||||||
+5
@@ -2950,6 +2950,11 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
|||||||
runTest("idea/idea-completion/testData/basic/java/JavaPackage.kt");
|
runTest("idea/idea-completion/testData/basic/java/JavaPackage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("JavaSyntheticProperty.kt")
|
||||||
|
public void testJavaSyntheticProperty() throws Exception {
|
||||||
|
runTest("idea/idea-completion/testData/basic/java/JavaSyntheticProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("KProperty.kt")
|
@TestMetadata("KProperty.kt")
|
||||||
public void testKProperty() throws Exception {
|
public void testKProperty() throws Exception {
|
||||||
runTest("idea/idea-completion/testData/basic/java/KProperty.kt");
|
runTest("idea/idea-completion/testData/basic/java/KProperty.kt");
|
||||||
|
|||||||
+15
-1
@@ -34,7 +34,7 @@ internal class KotlinFirLookupElementFactory {
|
|||||||
fun KtAnalysisSession.createLookupElement(symbol: KtNamedSymbol): LookupElement? {
|
fun KtAnalysisSession.createLookupElement(symbol: KtNamedSymbol): LookupElement? {
|
||||||
val elementBuilder = when (symbol) {
|
val elementBuilder = when (symbol) {
|
||||||
is KtFunctionSymbol -> with(functionLookupElementFactory) { createLookup(symbol) }
|
is KtFunctionSymbol -> with(functionLookupElementFactory) { createLookup(symbol) }
|
||||||
is KtVariableLikeSymbol -> with(variableLookupElementFactory) { createLookup(symbol) }
|
is KtVariableLikeSymbol -> with(variableLookupElementFactory) { createLookup(symbol) }
|
||||||
is KtClassLikeSymbol -> classLookupElementFactory.createLookup(symbol)
|
is KtClassLikeSymbol -> classLookupElementFactory.createLookup(symbol)
|
||||||
is KtTypeParameterSymbol -> typeParameterLookupElementFactory.createLookup(symbol)
|
is KtTypeParameterSymbol -> typeParameterLookupElementFactory.createLookup(symbol)
|
||||||
else -> throw IllegalArgumentException("Cannot create a lookup element for $symbol")
|
else -> throw IllegalArgumentException("Cannot create a lookup element for $symbol")
|
||||||
@@ -67,9 +67,23 @@ private class VariableLookupElementFactory {
|
|||||||
fun KtAnalysisSession.createLookup(symbol: KtVariableLikeSymbol): LookupElementBuilder {
|
fun KtAnalysisSession.createLookup(symbol: KtVariableLikeSymbol): LookupElementBuilder {
|
||||||
return LookupElementBuilder.create(UniqueLookupObject(), symbol.name.asString())
|
return LookupElementBuilder.create(UniqueLookupObject(), symbol.name.asString())
|
||||||
.withTypeText(symbol.type.render())
|
.withTypeText(symbol.type.render())
|
||||||
|
.markIfSyntheticJavaProperty(symbol)
|
||||||
.withInsertHandler(createInsertHandler(symbol))
|
.withInsertHandler(createInsertHandler(symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun LookupElementBuilder.markIfSyntheticJavaProperty(symbol: KtVariableLikeSymbol): LookupElementBuilder = when (symbol) {
|
||||||
|
is KtSyntheticJavaPropertySymbol -> {
|
||||||
|
val getterName = symbol.javaGetterName.asString()
|
||||||
|
val setterName = symbol.javaSetterName?.asString()
|
||||||
|
this.withTailText((" (from ${buildSyntheticPropertyTailText(getterName, setterName)})"))
|
||||||
|
.withLookupStrings(listOfNotNull(getterName, setterName))
|
||||||
|
}
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildSyntheticPropertyTailText(getterName: String, setterName: String?): String =
|
||||||
|
if (setterName != null) "$getterName()/$setterName()" else "$getterName()"
|
||||||
|
|
||||||
private fun createInsertHandler(symbol: KtVariableLikeSymbol): InsertHandler<LookupElement> {
|
private fun createInsertHandler(symbol: KtVariableLikeSymbol): InsertHandler<LookupElement> {
|
||||||
return QuotedNamesAwareInsertionHandler(symbol.name)
|
return QuotedNamesAwareInsertionHandler(symbol.name)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -2950,6 +2950,11 @@ public class HighLevelJvmBasicCompletionTestGenerated extends AbstractHighLevelJ
|
|||||||
runTest("idea/idea-completion/testData/basic/java/JavaPackage.kt");
|
runTest("idea/idea-completion/testData/basic/java/JavaPackage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("JavaSyntheticProperty.kt")
|
||||||
|
public void testJavaSyntheticProperty() throws Exception {
|
||||||
|
runTest("idea/idea-completion/testData/basic/java/JavaSyntheticProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("KProperty.kt")
|
@TestMetadata("KProperty.kt")
|
||||||
public void testKProperty() throws Exception {
|
public void testKProperty() throws Exception {
|
||||||
runTest("idea/idea-completion/testData/basic/java/KProperty.kt");
|
runTest("idea/idea-completion/testData/basic/java/KProperty.kt");
|
||||||
|
|||||||
+12
-5
@@ -6,15 +6,14 @@
|
|||||||
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope
|
||||||
import org.jetbrains.kotlin.fir.resolve.scope
|
import org.jetbrains.kotlin.fir.resolve.scope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
import org.jetbrains.kotlin.fir.scopes.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.LowLevelFirApiFacadeForCompletion
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.LowLevelFirApiFacadeForCompletion
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getFirFile
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getFirFile
|
||||||
@@ -122,9 +121,17 @@ internal class KtFirScopeProvider(
|
|||||||
firResolveState.firTransformerProvider.getScopeSession(firSession),
|
firResolveState.firTransformerProvider.getScopeSession(firSession),
|
||||||
FakeOverrideTypeCalculator.Forced
|
FakeOverrideTypeCalculator.Forced
|
||||||
) ?: return null
|
) ?: return null
|
||||||
return convertToKtScope(firTypeScope)
|
return getCompositeScope(
|
||||||
|
listOf(
|
||||||
|
convertToKtScope(firTypeScope),
|
||||||
|
firTypeScope.getSyntheticPropertiesScope(firSession)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirTypeScope.getSyntheticPropertiesScope(firSession: FirSession): KtScope =
|
||||||
|
convertToKtScope(FirSyntheticPropertiesScope(firSession, this))
|
||||||
|
|
||||||
override fun getScopeContextForPosition(
|
override fun getScopeContextForPosition(
|
||||||
originalFile: KtFile,
|
originalFile: KtFile,
|
||||||
positionInFakeFile: KtElement
|
positionInFakeFile: KtElement
|
||||||
|
|||||||
Reference in New Issue
Block a user