diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt index 66afc03d222..6a27f83d2ea 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt @@ -9,10 +9,12 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.registerJvmEffectiveVisibilityResolver import org.jetbrains.kotlin.fir.resolve.calls.jvm.registerJvmCallConflictResolverFactory import org.jetbrains.kotlin.fir.resolve.registerJavaClassMapper +import org.jetbrains.kotlin.fir.resolve.registerJavaSyntheticNamesProvider fun FirSession.registerJavaSpecificComponents() { registerJavaVisibilityChecker() registerJvmCallConflictResolverFactory() registerJvmEffectiveVisibilityResolver() registerJavaClassMapper() + registerJavaSyntheticNamesProvider() } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt index d20582f48f2..b96144c67fc 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack import org.jetbrains.kotlin.fir.java.declarations.* -import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope +import org.jetbrains.kotlin.fir.resolve.FirJavaSyntheticNamesProvider import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.getContainingCallableNamesIfPresent @@ -157,7 +157,7 @@ class JavaClassUseSiteMemberScope( if (name.isSpecial) { return processAccessorFunctionsAndPropertiesByName(name, emptyList(), processor) } - val getterNames = FirSyntheticPropertiesScope.possibleGetterNamesByPropertyName(name) + val getterNames = FirJavaSyntheticNamesProvider.possibleGetterNamesByPropertyName(name) val setterName = Name.identifier(SETTER_PREFIX + name.identifier.capitalize()) return processAccessorFunctionsAndPropertiesByName(name, getterNames, processor) } diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaSyntheticNamesProvider.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaSyntheticNamesProvider.kt new file mode 100644 index 00000000000..19ddd5401f9 --- /dev/null +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaSyntheticNamesProvider.kt @@ -0,0 +1,46 @@ +/* + * 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.fir.resolve + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider +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 + +object FirJavaSyntheticNamesProvider : FirSyntheticNamesProvider() { + private const val GETTER_PREFIX = "get" + private const val IS_PREFIX = "is" + + override fun possibleGetterNamesByPropertyName(name: Name): List { + if (name.isSpecial) return emptyList() + val identifier = name.identifier + val capitalizedAsciiName = identifier.capitalizeAsciiOnly() + val capitalizedFirstWordName = identifier.capitalizeFirstWord(asciiOnly = true) + return 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 + } + } + + override fun setterNameByGetterName(name: Name): Name { + val identifier = name.identifier + val prefix = when { + identifier.startsWith("get") -> "get" + identifier.startsWith("is") -> "is" + else -> throw IllegalArgumentException() + } + return Name.identifier("set" + identifier.removePrefix(prefix)) + } +} + +fun FirSession.registerJavaSyntheticNamesProvider() { + register(FirSyntheticNamesProvider::class, FirJavaSyntheticNamesProvider) +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirSyntheticNamesProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirSyntheticNamesProvider.kt new file mode 100644 index 00000000000..1b1dda43683 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirSyntheticNamesProvider.kt @@ -0,0 +1,17 @@ +/* + * 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.fir.resolve.calls + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent +import org.jetbrains.kotlin.name.Name + +abstract class FirSyntheticNamesProvider : FirSessionComponent { + abstract fun possibleGetterNamesByPropertyName(name: Name): List + abstract fun setterNameByGetterName(name: Name): Name +} + +val FirSession.syntheticNamesProvider: FirSyntheticNamesProvider by FirSession.sessionComponentAccessor() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt index 5f9a6591b90..25664b45177 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt @@ -19,10 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* -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 SyntheticPropertySymbol( callableId: CallableId, @@ -37,38 +34,10 @@ class FirSyntheticPropertiesScope( val session: FirSession, private val baseScope: FirTypeScope ) : FirScope() { - - companion object { - private const val GETTER_PREFIX = "get" - private const val IS_PREFIX = "is" - - fun possibleGetterNamesByPropertyName(name: Name): List { - if (name.isSpecial) return emptyList() - val identifier = name.identifier - val capitalizedAsciiName = identifier.capitalizeAsciiOnly() - val capitalizedFirstWordName = identifier.capitalizeFirstWord(asciiOnly = true) - return 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 - } - } - - fun setterNameByGetterName(name: Name): Name { - val identifier = name.identifier - val prefix = when { - identifier.startsWith("get") -> "get" - identifier.startsWith("is") -> "is" - else -> throw IllegalArgumentException() - } - return Name.identifier("set" + identifier.removePrefix(prefix)) - } - } + private val syntheticNamesProvider = session.syntheticNamesProvider override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { - val getterNames = possibleGetterNamesByPropertyName(name) + val getterNames = syntheticNamesProvider.possibleGetterNamesByPropertyName(name) for (getterName in getterNames) { baseScope.processFunctionsByName(getterName) { checkGetAndCreateSynthetic(name, getterName, it, processor) @@ -94,7 +63,7 @@ class FirSyntheticPropertiesScope( var matchingSetter: FirSimpleFunction? = null if (getterReturnType != null) { - val setterName = setterNameByGetterName(getterName) + val setterName = syntheticNamesProvider.setterNameByGetterName(getterName) baseScope.processFunctionsByName(setterName, fun(setterSymbol: FirFunctionSymbol<*>) { if (matchingSetter != null) return val setter = setterSymbol.fir as? FirSimpleFunction ?: return