FIR: use SyntheticPropertySymbol & synthetic scope instead of FirAccessorSymbol

Before this commit, we used FirAccessorSymbol to emulate synthetic properties.
These symbols were generated in Java use-site scope.
Now, we use synthetic scope instead which is above MemberScopeTowerLevel.
This is more performance-friendly and does not require override matching.
However, accessor symbols should be used in situation when Java accessor
overrides Kotlin property which is broken in this commit
(that's why MapEntry test is corrupted here).
Also, we should not create synthetics for pure Kotlin accessors
(that's why javaAccessorConversion test is corrupted here).
This commit is contained in:
Mikhail Glukhikh
2019-11-29 15:56:23 +03:00
parent ae62ccb76d
commit d15dae6ac6
13 changed files with 76 additions and 84 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter
import org.jetbrains.kotlin.fir.resolve.calls.possibleGetterNamesByPropertyName
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
@@ -23,10 +24,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirSuperTypeScope
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.*
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.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeFirstWord
class JavaClassUseSiteMemberScope(
klass: FirRegularClass,
@@ -150,28 +148,16 @@ class JavaClassUseSiteMemberScope(
}
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
if (name.isSpecial) {
// Do not generate accessors at all?
if (true) {
return processAccessorFunctionsAndPropertiesByName(name, emptyList(), null, processor)
}
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 + identifier.capitalize())
val getterNames = possibleGetterNamesByPropertyName(name)
val setterName = Name.identifier(SETTER_PREFIX + name.identifier.capitalize())
return processAccessorFunctionsAndPropertiesByName(name, getterNames, setterName, processor)
}
companion object {
private const val GETTER_PREFIX = "get"
private const val SETTER_PREFIX = "set"
private const val IS_PREFIX = "is"
}
}