Review changes: revert compiler behaviour, add test, remove inner classes
This commit is contained in:
committed by
Nikolay Krasko
parent
6ba134b1be
commit
213b98fefe
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.java
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart
|
||||||
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties.getPropertyNameCandidatesBySpecialGetterName
|
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties.getPropertyNameCandidatesBySpecialGetterName
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmartForCompiler
|
||||||
|
|
||||||
|
|
||||||
fun propertyNameByGetMethodName(methodName: Name): Name?
|
fun propertyNameByGetMethodName(methodName: Name): Name?
|
||||||
@@ -43,7 +44,7 @@ private fun propertyNameFromAccessorMethodName(methodName: Name, prefix: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!removePrefix) return methodName
|
if (!removePrefix) return methodName
|
||||||
val name = identifier.removePrefix(prefix).decapitalizeSmart(asciiOnly = true)
|
val name = identifier.removePrefix(prefix).decapitalizeSmartForCompiler(asciiOnly = true)
|
||||||
if (!Name.isValidIdentifier(name)) return null
|
if (!Name.isValidIdentifier(name)) return null
|
||||||
return Name.identifier(name)
|
return Name.identifier(name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,28 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("PackageDirectoryMismatch")
|
||||||
|
|
||||||
package org.jetbrains.kotlin.util.capitalizeDecapitalize
|
package org.jetbrains.kotlin.util.capitalizeDecapitalize
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "FooBar" -> "fooBar"
|
||||||
|
* "FOOBar" -> "fooBar"
|
||||||
|
* "FOO" -> "foo"
|
||||||
|
* "FOO_BAR" -> "foO_BAR"
|
||||||
|
*/
|
||||||
|
fun String.decapitalizeSmartForCompiler(asciiOnly: Boolean = false): String {
|
||||||
|
if (isEmpty() || !isUpperCaseCharAt(0, asciiOnly)) return this
|
||||||
|
|
||||||
|
if (length == 1 || !isUpperCaseCharAt(1, asciiOnly)) {
|
||||||
|
return if (asciiOnly) decapitalizeAsciiOnly() else decapitalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
val secondWordStart = (indices.firstOrNull { !isUpperCaseCharAt(it, asciiOnly) } ?: return toLowerCase(this, asciiOnly)) - 1
|
||||||
|
|
||||||
|
return toLowerCase(substring(0, secondWordStart), asciiOnly) + substring(secondWordStart)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "FooBar" -> "fooBar"
|
* "FooBar" -> "fooBar"
|
||||||
* "FOOBar" -> "fooBar"
|
* "FOOBar" -> "fooBar"
|
||||||
@@ -24,52 +44,8 @@ package org.jetbrains.kotlin.util.capitalizeDecapitalize
|
|||||||
* "__F_BAR" -> "fBar"
|
* "__F_BAR" -> "fBar"
|
||||||
*/
|
*/
|
||||||
fun String.decapitalizeSmart(asciiOnly: Boolean = false): String {
|
fun String.decapitalizeSmart(asciiOnly: Boolean = false): String {
|
||||||
fun isUpperCaseCharAt(index: Int): Boolean {
|
return decapitalizeWithUnderscores(this, asciiOnly)
|
||||||
val c = this[index]
|
?: decapitalizeSmartForCompiler(asciiOnly)
|
||||||
return if (asciiOnly) c in 'A'..'Z' else c.isUpperCase()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FOOBAR -> null
|
|
||||||
* FOO_BAR -> "fooBar"
|
|
||||||
* FOO_BAR_BAZ -> "fooBarBaz"
|
|
||||||
* "__F_BAR" -> "fBar"
|
|
||||||
* "F_BAR" -> "fBar"
|
|
||||||
*/
|
|
||||||
fun decapitalizeConst(str: String): String? {
|
|
||||||
val words = str.split("_").filter { it.isNotEmpty() }
|
|
||||||
|
|
||||||
if (words.size <= 1) return null
|
|
||||||
|
|
||||||
val builder = StringBuilder()
|
|
||||||
|
|
||||||
words.forEachIndexed { index, word ->
|
|
||||||
if (index == 0) {
|
|
||||||
builder.append(word.toLowerCase())
|
|
||||||
} else {
|
|
||||||
builder.append(word.first().toUpperCase())
|
|
||||||
builder.append(word.drop(1).toLowerCase())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
val constant = decapitalizeConst(this)
|
|
||||||
|
|
||||||
if (constant != null) return constant
|
|
||||||
|
|
||||||
if (isEmpty() || !isUpperCaseCharAt(0)) return this
|
|
||||||
|
|
||||||
if (length == 1 || !isUpperCaseCharAt(1)) {
|
|
||||||
return if (asciiOnly) decapitalizeAsciiOnly() else decapitalize()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toLowerCase(string: String) = if (asciiOnly) string.toLowerCaseAsciiOnly() else string.toLowerCase()
|
|
||||||
|
|
||||||
val secondWordStart = (indices.firstOrNull { !isUpperCaseCharAt(it) }
|
|
||||||
?: return toLowerCase(this)) - 1
|
|
||||||
return toLowerCase(substring(0, secondWordStart)) + substring(secondWordStart)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,16 +54,55 @@ fun String.decapitalizeSmart(asciiOnly: Boolean = false): String {
|
|||||||
* "foo" -> "FOO"
|
* "foo" -> "FOO"
|
||||||
*/
|
*/
|
||||||
fun String.capitalizeFirstWord(asciiOnly: Boolean = false): String {
|
fun String.capitalizeFirstWord(asciiOnly: Boolean = false): String {
|
||||||
fun toUpperCase(string: String) = if (asciiOnly) string.toUpperCaseAsciiOnly() else string.toUpperCase()
|
val secondWordStart = indices.drop(1).firstOrNull { !isLowerCaseCharAt(it, asciiOnly) }
|
||||||
|
?: return toUpperCase(this, asciiOnly)
|
||||||
|
|
||||||
fun isLowerCaseCharAt(index: Int): Boolean {
|
return toUpperCase(substring(0, secondWordStart), asciiOnly) + substring(secondWordStart)
|
||||||
val c = this[index]
|
}
|
||||||
return if (asciiOnly) c in 'a'..'z' else c.isLowerCase()
|
|
||||||
|
/**
|
||||||
|
* FOOBAR -> null
|
||||||
|
* FOO_BAR -> "fooBar"
|
||||||
|
* FOO_BAR_BAZ -> "fooBarBaz"
|
||||||
|
* "__F_BAR" -> "fBar"
|
||||||
|
* "_F_BAR" -> "fBar"
|
||||||
|
* "F_BAR" -> "fBar"
|
||||||
|
*/
|
||||||
|
private fun decapitalizeWithUnderscores(str: String, asciiOnly: Boolean): String? {
|
||||||
|
val words = str.split("_").filter { it.isNotEmpty() }
|
||||||
|
|
||||||
|
if (words.size <= 1) return null
|
||||||
|
|
||||||
|
val builder = StringBuilder()
|
||||||
|
|
||||||
|
words.forEachIndexed { index, word ->
|
||||||
|
if (index == 0) {
|
||||||
|
builder.append(toLowerCase(word, asciiOnly))
|
||||||
|
} else {
|
||||||
|
builder.append(toUpperCase(word.first().toString(), asciiOnly))
|
||||||
|
builder.append(toLowerCase(word.drop(1), asciiOnly))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val secondWordStart = indices.drop(1).firstOrNull { !isLowerCaseCharAt(it) }
|
return builder.toString()
|
||||||
?: return toUpperCase(this)
|
}
|
||||||
return toUpperCase(substring(0, secondWordStart)) + substring(secondWordStart)
|
|
||||||
|
private fun String.isUpperCaseCharAt(index: Int, asciiOnly: Boolean): Boolean {
|
||||||
|
val c = this[index]
|
||||||
|
return if (asciiOnly) c in 'A'..'Z' else c.isUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.isLowerCaseCharAt(index: Int, asciiOnly: Boolean): Boolean {
|
||||||
|
val c = this[index]
|
||||||
|
return if (asciiOnly) c in 'a'..'z' else c.isLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toLowerCase(string: String, asciiOnly: Boolean): String {
|
||||||
|
return if (asciiOnly) string.toLowerCaseAsciiOnly() else string.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toUpperCase(string: String, asciiOnly: Boolean): String {
|
||||||
|
return if (asciiOnly) string.toUpperCaseAsciiOnly() else string.toUpperCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.capitalizeAsciiOnly(): String {
|
fun String.capitalizeAsciiOnly(): String {
|
||||||
|
|||||||
+2
-1
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmartForCompiler
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
data class ReferenceVariants(val imported: Collection<DeclarationDescriptor>, val notImportedExtensions: Collection<CallableDescriptor>)
|
data class ReferenceVariants(val imported: Collection<DeclarationDescriptor>, val notImportedExtensions: Collection<CallableDescriptor>)
|
||||||
@@ -121,7 +122,7 @@ class ReferenceVariantsCollector(
|
|||||||
|
|
||||||
val getOrSetPrefix = GET_SET_PREFIXES.firstOrNull { prefix.startsWith(it) }
|
val getOrSetPrefix = GET_SET_PREFIXES.firstOrNull { prefix.startsWith(it) }
|
||||||
val additionalPropertyNameFilter: ((String) -> Boolean)? = getOrSetPrefix
|
val additionalPropertyNameFilter: ((String) -> Boolean)? = getOrSetPrefix
|
||||||
?.let { prefixMatcher.cloneWithPrefix(prefix.removePrefix(getOrSetPrefix).decapitalizeSmart()).asStringNameFilter() }
|
?.let { prefixMatcher.cloneWithPrefix(prefix.removePrefix(getOrSetPrefix).decapitalizeSmartForCompiler()).asStringNameFilter() }
|
||||||
|
|
||||||
val shadowedDeclarationsFilter = if (runtimeReceiver != null)
|
val shadowedDeclarationsFilter = if (runtimeReceiver != null)
|
||||||
ShadowedDeclarationsFilter(bindingContext, resolutionFacade, nameExpression, runtimeReceiver)
|
ShadowedDeclarationsFilter(bindingContext, resolutionFacade, nameExpression, runtimeReceiver)
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun a() {
|
||||||
|
val SOME_CONSTANT = 1
|
||||||
|
<selection>SOME_CONSTANT</selection>
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
constant
|
||||||
|
i
|
||||||
|
someConstant
|
||||||
|
*/
|
||||||
+2
@@ -38,6 +38,8 @@ class KotlinNameSuggesterTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
|
|
||||||
fun testNameReferenceExpression() = doTest()
|
fun testNameReferenceExpression() = doTest()
|
||||||
|
|
||||||
|
fun testNameReferenceExpressionForConstants() = doTest()
|
||||||
|
|
||||||
fun testNameString() = doTest()
|
fun testNameString() = doTest()
|
||||||
|
|
||||||
fun testAnonymousObject() = doTest()
|
fun testAnonymousObject() = doTest()
|
||||||
|
|||||||
Reference in New Issue
Block a user