FIR accessor symbols: check all possible getter name variants
This commit is contained in:
+17
-9
@@ -23,7 +23,10 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirSuperTypeScope
|
|||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||||
|
import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeFirstWord
|
||||||
|
|
||||||
class JavaClassUseSiteMemberScope(
|
class JavaClassUseSiteMemberScope(
|
||||||
klass: FirRegularClass,
|
klass: FirRegularClass,
|
||||||
@@ -86,7 +89,7 @@ class JavaClassUseSiteMemberScope(
|
|||||||
|
|
||||||
private fun processAccessorFunctionsAndPropertiesByName(
|
private fun processAccessorFunctionsAndPropertiesByName(
|
||||||
propertyName: Name,
|
propertyName: Name,
|
||||||
getterName: Name,
|
getterNames: List<Name>,
|
||||||
setterName: Name,
|
setterName: Name,
|
||||||
processor: (FirCallableSymbol<*>) -> ProcessorAction
|
processor: (FirCallableSymbol<*>) -> ProcessorAction
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
@@ -98,12 +101,8 @@ class JavaClassUseSiteMemberScope(
|
|||||||
}
|
}
|
||||||
) return STOP
|
) return STOP
|
||||||
if (klass is FirJavaClass) {
|
if (klass is FirJavaClass) {
|
||||||
if (!declaredMemberScope.processFunctionsByName(getterName) { functionSymbol ->
|
for (getterName in getterNames) {
|
||||||
processAccessorFunction(functionSymbol, propertyName, overrideCandidates, processor, isGetter = true)
|
if (!declaredMemberScope.processFunctionsByName(getterName) { functionSymbol ->
|
||||||
}
|
|
||||||
) return STOP
|
|
||||||
if (propertyName.asString().startsWith(IS_PREFIX)) {
|
|
||||||
if (!declaredMemberScope.processFunctionsByName(propertyName) { functionSymbol ->
|
|
||||||
processAccessorFunction(functionSymbol, propertyName, overrideCandidates, processor, isGetter = true)
|
processAccessorFunction(functionSymbol, propertyName, overrideCandidates, processor, isGetter = true)
|
||||||
}
|
}
|
||||||
) return STOP
|
) return STOP
|
||||||
@@ -151,9 +150,18 @@ class JavaClassUseSiteMemberScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
|
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||||
val getterName = Name.identifier(GETTER_PREFIX + name.asString().capitalize())
|
val identifier = name.identifier
|
||||||
|
val capitalizedAsciiName = identifier.capitalizeAsciiOnly()
|
||||||
|
val capitalizedFirstWordName = identifier.capitalizeFirstWord(asciiOnly = true)
|
||||||
|
val getterNames = listOfNotNull(
|
||||||
|
Name.identifier(GETTER_PREFIX + capitalizedAsciiName),
|
||||||
|
if (capitalizedFirstWordName == capitalizedAsciiName) null else Name.identifier(GETTER_PREFIX + capitalizedFirstWordName),
|
||||||
|
name.takeIf { identifier.startsWith(IS_PREFIX) }
|
||||||
|
).filter {
|
||||||
|
propertyNameByGetMethodName(it) == name
|
||||||
|
}
|
||||||
val setterName = Name.identifier(SETTER_PREFIX + name.asString().capitalize())
|
val setterName = Name.identifier(SETTER_PREFIX + name.asString().capitalize())
|
||||||
return processAccessorFunctionsAndPropertiesByName(name, getterName, setterName, processor)
|
return processAccessorFunctionsAndPropertiesByName(name, getterNames, setterName, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ public class D {
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|
||||||
fun test_1(x: A) {
|
fun test_1(x: A) {
|
||||||
val str1 = x.<!UNRESOLVED_REFERENCE!>vmParameters<!> // OK
|
val str1 = x.vmParameters // OK
|
||||||
val str2 = x.vMParameters // should be error
|
val str2 = x.<!UNRESOLVED_REFERENCE!>vMParameters<!> // should be error
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_2(x: B) {
|
fun test_2(x: B) {
|
||||||
@@ -65,8 +65,8 @@ fun test_2(x: B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test_3(x: C) {
|
fun test_3(x: C) {
|
||||||
val error = x.vmParameters // should be error
|
val error = x.<!AMBIGUITY!>vmParameters<!> // should be error
|
||||||
val int = x.vMParameters // should be error
|
val int = x.<!UNRESOLVED_REFERENCE!>vMParameters<!> // should be error
|
||||||
}
|
}
|
||||||
|
|
||||||
class Foo {
|
class Foo {
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
FILE: main.kt
|
FILE: main.kt
|
||||||
public final fun test_1(x: R|A|): R|kotlin/Unit| {
|
public final fun test_1(x: R|A|): R|kotlin/Unit| {
|
||||||
lval str1: <ERROR TYPE REF: Unresolved name: vmParameters> = R|<local>/x|.<Unresolved name: vmParameters>#
|
lval str1: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/x|.R|/A.vmParameters|
|
||||||
lval str2: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/x|.R|/A.vMParameters|
|
lval str2: <ERROR TYPE REF: Unresolved name: vMParameters> = R|<local>/x|.<Unresolved name: vMParameters>#
|
||||||
}
|
}
|
||||||
public final fun test_2(x: R|B|): R|kotlin/Unit| {
|
public final fun test_2(x: R|B|): R|kotlin/Unit| {
|
||||||
lval int: R|ft<kotlin/Int, kotlin/Int?>!| = R|<local>/x|.R|/B.vmParameters|
|
lval int: R|ft<kotlin/Int, kotlin/Int?>!| = R|<local>/x|.R|/B.vmParameters|
|
||||||
lval error: <ERROR TYPE REF: Unresolved name: vMParameters> = R|<local>/x|.<Unresolved name: vMParameters>#
|
lval error: <ERROR TYPE REF: Unresolved name: vMParameters> = R|<local>/x|.<Unresolved name: vMParameters>#
|
||||||
}
|
}
|
||||||
public final fun test_3(x: R|C|): R|kotlin/Unit| {
|
public final fun test_3(x: R|C|): R|kotlin/Unit| {
|
||||||
lval error: R|ft<kotlin/Int, kotlin/Int?>!| = R|<local>/x|.R|/C.vmParameters|
|
lval error: <ERROR TYPE REF: Ambiguity: vmParameters, [/C.vmParameters, /C.vmParameters]> = R|<local>/x|.<Ambiguity: vmParameters, [/C.vmParameters, /C.vmParameters]>#
|
||||||
lval int: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/x|.R|/C.vMParameters|
|
lval int: <ERROR TYPE REF: Unresolved name: vMParameters> = R|<local>/x|.<Unresolved name: vMParameters>#
|
||||||
}
|
}
|
||||||
public final class Foo : R|kotlin/Any| {
|
public final class Foo : R|kotlin/Any| {
|
||||||
public constructor(): R|Foo| {
|
public constructor(): R|Foo| {
|
||||||
|
|||||||
Reference in New Issue
Block a user