Parameter name completion allows user prefix part in the name + more strict prefix matcher used
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.patterns.ElementPattern
|
||||
@@ -119,11 +120,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
kotlinIdentifierPartPattern or singleCharPattern('@'),
|
||||
kotlinIdentifierStartPattern)
|
||||
|
||||
protected val resultSet: CompletionResultSet = resultSet
|
||||
.withPrefixMatcher(prefix)
|
||||
.addKotlinSorting(parameters)
|
||||
|
||||
protected val prefixMatcher: PrefixMatcher = this.resultSet.getPrefixMatcher()
|
||||
protected val prefixMatcher: PrefixMatcher = CamelHumpMatcher(prefix)
|
||||
|
||||
protected val isVisibleFilter: (DeclarationDescriptor) -> Boolean = { isVisibleDescriptor(it) }
|
||||
|
||||
@@ -157,7 +154,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
else
|
||||
LookupElementsCollector.Context.NORMAL
|
||||
|
||||
protected val collector: LookupElementsCollector = LookupElementsCollector(prefixMatcher, parameters, resolutionFacade, lookupElementFactory, inDescriptor, collectorContext)
|
||||
protected val collector: LookupElementsCollector = LookupElementsCollector(prefixMatcher, parameters, resultSet, resolutionFacade, lookupElementFactory, inDescriptor, collectorContext)
|
||||
|
||||
protected val originalSearchScope: GlobalSearchScope = ResolutionFacade.getResolveScope(parameters.getOriginalFile() as JetFile)
|
||||
|
||||
@@ -181,7 +178,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
}
|
||||
|
||||
protected fun flushToResultSet() {
|
||||
collector.flushToResultSet(resultSet)
|
||||
collector.flushToResultSet()
|
||||
}
|
||||
|
||||
public fun complete(): Boolean {
|
||||
@@ -399,11 +396,12 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
}
|
||||
|
||||
if (completionKind != CompletionKind.KEYWORDS_ONLY) {
|
||||
flushToResultSet()
|
||||
|
||||
if (!configuration.completeNonImportedDeclarations && isNoQualifierContext()) {
|
||||
JavaCompletionContributor.advertiseSecondCompletion(project, resultSet)
|
||||
collector.advertiseSecondCompletion()
|
||||
}
|
||||
|
||||
flushToResultSet()
|
||||
addNonImported(completionKind)
|
||||
|
||||
if (position.getContainingFile() is JetCodeFragment) {
|
||||
|
||||
+2
-2
@@ -80,7 +80,7 @@ class KDocNameCompletionSession(parameters: CompletionParameters,
|
||||
.filter { it.getName().asString() !in documentedParameters }
|
||||
|
||||
descriptors.forEach {
|
||||
resultSet.addElement(lookupElementFactory.createLookupElement(it, false))
|
||||
collector.addElement(lookupElementFactory.createLookupElement(it, false))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class KDocNameCompletionSession(parameters: CompletionParameters,
|
||||
val scope = getResolutionScope(resolutionFacade, declarationDescriptor)
|
||||
scope.getDescriptors(nameFilter = prefixMatcher.asNameFilter()).forEach {
|
||||
val element = lookupElementFactory.createLookupElement(it, false)
|
||||
resultSet.addElement(object: LookupElementDecorator<LookupElement>(element) {
|
||||
collector.addElement(object: LookupElementDecorator<LookupElement>(element) {
|
||||
override fun handleInsert(context: InsertionContext?) {
|
||||
// insert only plain name here, no qualifier/parentheses/etc.
|
||||
}
|
||||
|
||||
+25
-10
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionParameters
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
@@ -32,10 +29,12 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.*
|
||||
import java.util.ArrayList
|
||||
import java.util.LinkedHashMap
|
||||
|
||||
class LookupElementsCollector(
|
||||
private val prefixMatcher: PrefixMatcher,
|
||||
private val defaultPrefixMatcher: PrefixMatcher,
|
||||
private val completionParameters: CompletionParameters,
|
||||
resultSet: CompletionResultSet,
|
||||
private val resolutionFacade: ResolutionFacade,
|
||||
private val lookupElementFactory: LookupElementFactory,
|
||||
private val inDescriptor: DeclarationDescriptor?,
|
||||
@@ -47,11 +46,21 @@ class LookupElementsCollector(
|
||||
INFIX_CALL
|
||||
}
|
||||
|
||||
private val elements = ArrayList<LookupElement>()
|
||||
private val elements = LinkedHashMap<PrefixMatcher, ArrayList<LookupElement>>()
|
||||
|
||||
public fun flushToResultSet(resultSet: CompletionResultSet) {
|
||||
private val defaultResultSet = resultSet
|
||||
.withPrefixMatcher(defaultPrefixMatcher)
|
||||
.addKotlinSorting(completionParameters)
|
||||
|
||||
public fun flushToResultSet() {
|
||||
if (!elements.isEmpty()) {
|
||||
resultSet.addAllElements(elements)
|
||||
for ((prefixMatcher, elements) in elements) {
|
||||
val resultSet = if (prefixMatcher == defaultPrefixMatcher)
|
||||
defaultResultSet
|
||||
else
|
||||
defaultResultSet.withPrefixMatcher(prefixMatcher)
|
||||
resultSet.addAllElements(elements)
|
||||
}
|
||||
elements.clear()
|
||||
isResultEmpty = false
|
||||
}
|
||||
@@ -137,7 +146,7 @@ class LookupElementsCollector(
|
||||
}
|
||||
}
|
||||
|
||||
public fun addElement(element: LookupElement) {
|
||||
public fun addElement(element: LookupElement, prefixMatcher: PrefixMatcher = defaultPrefixMatcher) {
|
||||
if (prefixMatcher.prefixMatches(element)) {
|
||||
val decorated = object : LookupElementDecorator<LookupElement>(element) {
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
@@ -158,10 +167,12 @@ class LookupElementsCollector(
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (suppressItemSelectionByCharsOnTyping) {
|
||||
decorated.putUserData(KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING, Unit)
|
||||
}
|
||||
elements.add(decorated)
|
||||
|
||||
elements.getOrPut(prefixMatcher) { ArrayList() }.add(decorated)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,4 +195,8 @@ class LookupElementsCollector(
|
||||
public fun addElements(elements: Iterable<LookupElement>) {
|
||||
elements.forEach { addElement(it) }
|
||||
}
|
||||
|
||||
public fun advertiseSecondCompletion() {
|
||||
JavaCompletionContributor.advertiseSecondCompletion(completionParameters.getOriginalFile().getProject(), defaultResultSet)
|
||||
}
|
||||
}
|
||||
|
||||
+85
-49
@@ -20,11 +20,13 @@ import com.intellij.codeInsight.completion.CompletionInitializationContext
|
||||
import com.intellij.codeInsight.completion.CompletionParameters
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher
|
||||
import com.intellij.codeInsight.lookup.*
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import com.intellij.psi.codeStyle.NameUtil
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -49,21 +51,42 @@ import java.util.*
|
||||
class ParameterNameAndTypeCompletion(
|
||||
private val collector: LookupElementsCollector,
|
||||
private val lookupElementFactory: LookupElementFactory,
|
||||
private val prefixMatcher: PrefixMatcher,
|
||||
defaultPrefixMatcher: PrefixMatcher,
|
||||
private val resolutionFacade: ResolutionFacade
|
||||
) {
|
||||
private val modifiedPrefixMatcher = prefixMatcher.cloneWithPrefix(prefixMatcher.getPrefix().capitalize())
|
||||
private val parametersInCurrentFilePrefixMatcher = MyPrefixMatcher(defaultPrefixMatcher.getPrefix())
|
||||
|
||||
private val prefixWords: Array<String>
|
||||
private val allPrefixes: List<String> // prefixes to use to generate parameter names from class names
|
||||
|
||||
init {
|
||||
val prefix = defaultPrefixMatcher.getPrefix()
|
||||
prefixWords = NameUtil.splitNameIntoWords(prefix)
|
||||
|
||||
allPrefixes = if (prefix.isEmpty() || prefix[0].isUpperCase())
|
||||
emptyList()
|
||||
else
|
||||
prefixWords.indices.map { if (it == 0) prefix else prefixWords.drop(it).join("") }
|
||||
}
|
||||
|
||||
private val allPrefixMatchers = allPrefixes.map { MyPrefixMatcher(it) }
|
||||
|
||||
private val userPrefixes = allPrefixes.indices.map { prefixWords.take(it).join("") }
|
||||
|
||||
private val suggestionsByTypesAdded = HashSet<Type>()
|
||||
|
||||
public fun addFromImportedClasses(position: PsiElement, bindingContext: BindingContext, visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
if (prefixMatcher.getPrefix().isEmpty()) return
|
||||
for ((i, prefixMatcher) in allPrefixMatchers.withIndex()) {
|
||||
val resolutionScope = position.getResolutionScope(bindingContext)
|
||||
val classifiers = resolutionScope.getDescriptorsFiltered(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS, prefixMatcher.toClassifierNamePrefixMatcher().asNameFilter())
|
||||
|
||||
val resolutionScope = position.getResolutionScope(bindingContext)
|
||||
val classifiers = resolutionScope.getDescriptorsFiltered(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS, modifiedPrefixMatcher.asNameFilter())
|
||||
|
||||
for (classifier in classifiers) {
|
||||
if (visibilityFilter(classifier)) {
|
||||
addSuggestionsForClassifier(classifier)
|
||||
for (classifier in classifiers) {
|
||||
if (visibilityFilter(classifier)) {
|
||||
addSuggestionsForClassifier(classifier, userPrefixes[i], prefixMatcher)
|
||||
}
|
||||
}
|
||||
|
||||
collector.flushToResultSet()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,24 +112,31 @@ class ParameterNameAndTypeCompletion(
|
||||
}
|
||||
|
||||
public fun addFromAllClasses(parameters: CompletionParameters, indicesHelper: KotlinIndicesHelper) {
|
||||
if (prefixMatcher.getPrefix().isEmpty()) return
|
||||
for ((i, prefixMatcher) in allPrefixMatchers.withIndex()) {
|
||||
AllClassesCompletion(parameters, indicesHelper, prefixMatcher.toClassifierNamePrefixMatcher(), { !it.isSingleton() })
|
||||
.collect(
|
||||
{ addSuggestionsForClassifier(it, userPrefixes[i], prefixMatcher) },
|
||||
{ addSuggestionsForJavaClass(it, userPrefixes[i], prefixMatcher) }
|
||||
)
|
||||
|
||||
AllClassesCompletion(parameters, indicesHelper, modifiedPrefixMatcher, { !it.isSingleton() })
|
||||
.collect({ addSuggestionsForClassifier(it) }, { addSuggestionsForJavaClass(it) })
|
||||
collector.flushToResultSet()
|
||||
}
|
||||
}
|
||||
|
||||
private fun PrefixMatcher.toClassifierNamePrefixMatcher() = cloneWithPrefix(getPrefix().capitalize())
|
||||
|
||||
public fun addFromParametersInFile(position: PsiElement, resolutionFacade: ResolutionFacade, visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
val lookupElementToCount = LinkedHashMap<LookupElement, Int>()
|
||||
position.getContainingFile().forEachDescendantOfType<JetParameter>(
|
||||
canGoInside = { it !is JetExpression || it is JetDeclaration } // we analyze parameters inside bodies to not resolve too much
|
||||
) { declaration ->
|
||||
val name = declaration.getName()
|
||||
if (name != null && prefixMatcher.prefixMatches(name)) {
|
||||
if (name != null && parametersInCurrentFilePrefixMatcher.prefixMatches(name)) {
|
||||
val parameter = resolutionFacade.analyze(declaration)[BindingContext.VALUE_PARAMETER, declaration]
|
||||
if (parameter != null) {
|
||||
val parameterType = parameter.getType()
|
||||
if (parameterType.isVisible(visibilityFilter)) {
|
||||
val lookupElement = MyLookupElement.create(NameAndArbitraryType(name, parameterType), lookupElementFactory)
|
||||
val lookupElement = MyLookupElement.create("", name, ArbitraryType(parameterType), lookupElementFactory)
|
||||
val count = lookupElementToCount[lookupElement] ?: 0
|
||||
lookupElementToCount[lookupElement] = count + 1
|
||||
}
|
||||
@@ -116,25 +146,29 @@ class ParameterNameAndTypeCompletion(
|
||||
|
||||
for ((lookupElement, count) in lookupElementToCount) {
|
||||
lookupElement.putUserData(PRIORITY_KEY, -count)
|
||||
collector.addElement(lookupElement)
|
||||
collector.addElement(lookupElement, parametersInCurrentFilePrefixMatcher)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addSuggestionsForClassifier(classifier: DeclarationDescriptor) {
|
||||
addSuggestions(classifier.getName().asString()) { name -> NameAndDescriptorType(name, classifier as ClassifierDescriptor) }
|
||||
private fun addSuggestionsForClassifier(classifier: DeclarationDescriptor, userPrefix: String, prefixMatcher: PrefixMatcher) {
|
||||
addSuggestions(classifier.getName().asString(), userPrefix, prefixMatcher, DescriptorType(classifier as ClassifierDescriptor))
|
||||
}
|
||||
|
||||
private fun addSuggestionsForJavaClass(psiClass: PsiClass) {
|
||||
addSuggestions(psiClass.getName()) { name -> NameAndJavaType(name, psiClass) }
|
||||
private fun addSuggestionsForJavaClass(psiClass: PsiClass, userPrefix: String, prefixMatcher: PrefixMatcher) {
|
||||
addSuggestions(psiClass.getName(), userPrefix, prefixMatcher, JavaClassType(psiClass))
|
||||
}
|
||||
|
||||
private inline fun addSuggestions(className: String, nameAndTypeFactory: (String) -> NameAndType) {
|
||||
val parameterNames = JetNameSuggester.getCamelNames(className, EmptyValidator)
|
||||
for (parameterName in parameterNames) {
|
||||
if (prefixMatcher.prefixMatches(parameterName)) {
|
||||
val lookupElement = MyLookupElement.create(nameAndTypeFactory(parameterName), lookupElementFactory)
|
||||
private fun addSuggestions(className: String, userPrefix: String, prefixMatcher: PrefixMatcher, type: Type) {
|
||||
if (suggestionsByTypesAdded.contains(type)) return // don't add suggestions for the same with longer user prefix
|
||||
|
||||
val nameSuggestions = JetNameSuggester.getCamelNames(className, EmptyValidator, userPrefix.isEmpty())
|
||||
for (name in nameSuggestions) {
|
||||
if (prefixMatcher.prefixMatches(name)) {
|
||||
val lookupElement = MyLookupElement.create(userPrefix, name, type, lookupElementFactory)
|
||||
if (lookupElement != null) {
|
||||
collector.addElement(lookupElement)
|
||||
lookupElement.putUserData(PRIORITY_KEY, userPrefix.length()) // suggestions with longer user prefix get smaller priority
|
||||
collector.addElement(lookupElement, prefixMatcher)
|
||||
suggestionsByTypesAdded.add(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,55 +180,51 @@ class ParameterNameAndTypeCompletion(
|
||||
return visibilityFilter(classifier) && getArguments().all { it.getType().isVisible(visibilityFilter) }
|
||||
}
|
||||
|
||||
private abstract class NameAndType(val parameterName: String) {
|
||||
private abstract class Type(private val idString: String) {
|
||||
abstract fun createTypeLookupElement(lookupElementFactory: LookupElementFactory): LookupElement?
|
||||
abstract val typeIdString: String // types with equal id-string are considered as equal (used to avoid duplicated items)
|
||||
|
||||
override fun equals(other: Any?) = other is Type && other.idString == idString
|
||||
override fun hashCode() = idString.hashCode()
|
||||
}
|
||||
|
||||
private class NameAndDescriptorType(parameterName: String, private val classifier: ClassifierDescriptor) : NameAndType(parameterName) {
|
||||
private class DescriptorType(private val classifier: ClassifierDescriptor) : Type(DescriptorUtils.getFqName(classifier).render()) {
|
||||
override fun createTypeLookupElement(lookupElementFactory: LookupElementFactory)
|
||||
= lookupElementFactory.createLookupElement(classifier, false)
|
||||
|
||||
override val typeIdString: String
|
||||
get() = DescriptorUtils.getFqName(classifier).render()
|
||||
}
|
||||
|
||||
private class NameAndJavaType(parameterName: String, private val psiClass: PsiClass) : NameAndType(parameterName) {
|
||||
private class JavaClassType(private val psiClass: PsiClass) : Type(psiClass.getQualifiedName()!!) {
|
||||
override fun createTypeLookupElement(lookupElementFactory: LookupElementFactory)
|
||||
= lookupElementFactory.createLookupElementForJavaClass(psiClass)
|
||||
|
||||
override val typeIdString: String
|
||||
get() = psiClass.getQualifiedName()!!
|
||||
}
|
||||
|
||||
private class NameAndArbitraryType(parameterName: String, private val type: JetType) : NameAndType(parameterName) {
|
||||
private class ArbitraryType(private val type: JetType) : Type(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)) {
|
||||
override fun createTypeLookupElement(lookupElementFactory: LookupElementFactory)
|
||||
= lookupElementFactory.createLookupElementForType(type)
|
||||
|
||||
override val typeIdString: String
|
||||
get() = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||
}
|
||||
|
||||
private class MyLookupElement private constructor(
|
||||
private val parameterName: String,
|
||||
private val typeIdString: String,
|
||||
private data class MyLookupElement private constructor(
|
||||
private val userPrefix: String,
|
||||
private val nameSuggestion: String,
|
||||
private val type: Type,
|
||||
typeLookupElement: LookupElement
|
||||
) : LookupElementDecorator<LookupElement>(typeLookupElement) {
|
||||
|
||||
companion object {
|
||||
fun create(nameAndType: NameAndType, factory: LookupElementFactory): LookupElement? {
|
||||
val typeLookupElement = nameAndType.createTypeLookupElement(factory) ?: return null
|
||||
val lookupElement = MyLookupElement(nameAndType.parameterName, nameAndType.typeIdString, typeLookupElement)
|
||||
fun create(userPrefix: String, nameSuggestion: String, type: Type, factory: LookupElementFactory): LookupElement? {
|
||||
val typeLookupElement = type.createTypeLookupElement(factory) ?: return null
|
||||
val lookupElement = MyLookupElement(userPrefix, nameSuggestion, type, typeLookupElement)
|
||||
return lookupElement.suppressAutoInsertion()
|
||||
}
|
||||
}
|
||||
|
||||
private val parameterName = userPrefix + nameSuggestion
|
||||
|
||||
override fun equals(other: Any?)
|
||||
= other is MyLookupElement && parameterName == other.parameterName && typeIdString == other.typeIdString
|
||||
= other is MyLookupElement && nameSuggestion == other.nameSuggestion && userPrefix == other.userPrefix && type == other.type
|
||||
override fun hashCode() = parameterName.hashCode()
|
||||
|
||||
override fun getLookupString() = parameterName
|
||||
override fun getAllLookupStrings() = setOf(parameterName)
|
||||
override fun getLookupString() = nameSuggestion
|
||||
override fun getAllLookupStrings() = setOf(nameSuggestion)
|
||||
|
||||
override fun renderElement(presentation: LookupElementPresentation) {
|
||||
super.renderElement(presentation)
|
||||
@@ -205,7 +235,7 @@ class ParameterNameAndTypeCompletion(
|
||||
val settings = CodeStyleSettingsManager.getInstance(context.getProject()).getCurrentSettings().getCustomSettings(javaClass<JetCodeStyleSettings>())
|
||||
val spaceBefore = if (settings.SPACE_BEFORE_TYPE_COLON) " " else ""
|
||||
val spaceAfter = if (settings.SPACE_AFTER_TYPE_COLON) " " else ""
|
||||
val text = parameterName + spaceBefore + ":" + spaceAfter
|
||||
val text = nameSuggestion + spaceBefore + ":" + spaceAfter
|
||||
val startOffset = context.getStartOffset()
|
||||
context.getDocument().insertString(startOffset, text)
|
||||
|
||||
@@ -223,4 +253,10 @@ class ParameterNameAndTypeCompletion(
|
||||
object Weigher : LookupElementWeigher("kotlin.parameterNameAndTypePriority") {
|
||||
override fun weigh(element: LookupElement, context: WeighingContext): Int = element.getUserData(PRIORITY_KEY) ?: 0
|
||||
}
|
||||
|
||||
private class MyPrefixMatcher(prefix: String) : CamelHumpMatcher(prefix, false) {
|
||||
override fun prefixMatches(element: LookupElement) = isStartMatch(element)
|
||||
|
||||
override fun cloneWithPrefix(prefix: String) = MyPrefixMatcher(prefix)
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package pack
|
||||
|
||||
class DeclarationDescriptor
|
||||
|
||||
fun f(dd<caret>)
|
||||
|
||||
// EXIST: { lookupString: "declarationDescriptor", itemText: "declarationDescriptor: DeclarationDescriptor", tailText: " (pack)" }
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
class FooBar
|
||||
class FooBaaaaar
|
||||
|
||||
fun f(fooBa<caret>)
|
||||
fun f(fooBaaaa<caret>)
|
||||
|
||||
// AUTOCOMPLETE_SETTING: true
|
||||
// EXIST: fooBar
|
||||
// EXIST: fooBaaaaar
|
||||
// NUMBER: 1
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import kotlin.properties.*
|
||||
|
||||
fun f(readOnlyProp<caret>)
|
||||
fun f(keyMissin<caret>)
|
||||
|
||||
// EXIST: { lookupString: "readOnlyProperty", itemText: "readOnlyProperty: ReadOnlyProperty", tailText: "<R, T> (kotlin.properties)" }
|
||||
// EXIST: { lookupString: "keyMissingException", itemText: "keyMissingException: KeyMissingException", tailText: " (kotlin.properties)" }
|
||||
// NUMBER: 1
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import java.io.*
|
||||
import java.sql.*
|
||||
|
||||
fun f(printSt<caret>)
|
||||
fun f(blob<caret>)
|
||||
|
||||
// EXIST_JAVA_ONLY: { lookupString: "printStream", itemText: "printStream: PrintStream", tailText: " (java.io)" }
|
||||
// EXIST_JAVA_ONLY: { lookupString: "blob", itemText: "blob: Blob", tailText: " (java.sql)" }
|
||||
// NUMBER_JAVA: 1
|
||||
|
||||
+9
-10
@@ -1,17 +1,16 @@
|
||||
package ppp
|
||||
|
||||
import java.io.*
|
||||
import java.security.*
|
||||
|
||||
class MyPrintStream
|
||||
class MyAlgorithmException
|
||||
|
||||
fun f1(printStream: PrintStream){}
|
||||
fun f2(printStream: PrintStream?){}
|
||||
fun f3(printStream: MyPrintStream){}
|
||||
fun f1(algorithmException: NoSuchAlgorithmException){}
|
||||
fun f2(algorithmException: NoSuchAlgorithmException?){}
|
||||
fun f3(algorithmException: MyAlgorithmException){}
|
||||
|
||||
fun f(printStr<caret>)
|
||||
fun f(algorith<caret>)
|
||||
|
||||
// EXIST_JAVA_ONLY: { lookupString: "printStream", itemText: "printStream: PrintStream", tailText: " (java.io)" }
|
||||
// EXIST_JAVA_ONLY: { lookupString: "printStream", itemText: "printStream: PrintStream?", tailText: " (java.io)" }
|
||||
// EXIST: { lookupString: "printStream", itemText: "printStream: MyPrintStream", tailText: " (ppp)" }
|
||||
// EXIST: { lookupString: "myPrintStream", itemText: "myPrintStream: MyPrintStream", tailText: " (ppp)" }
|
||||
// EXIST_JAVA_ONLY: { lookupString: "algorithmException", itemText: "algorithmException: NoSuchAlgorithmException", tailText: " (java.security)" }
|
||||
// EXIST_JAVA_ONLY: { lookupString: "algorithmException", itemText: "algorithmException: NoSuchAlgorithmException?", tailText: " (java.security)" }
|
||||
// EXIST: { lookupString: "algorithmException", itemText: "algorithmException: MyAlgorithmException", tailText: " (ppp)" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
@@ -7,5 +7,5 @@ class Boo
|
||||
fun f(b<caret>)
|
||||
|
||||
// EXIST: { lookupString: "bar", itemText: "bar: FooBar", tailText: " (pack)" }
|
||||
// EXIST: { lookupString: "fooBar", itemText: "fooBar: FooBar", tailText: " (pack)" }
|
||||
// ABSENT: fooBar
|
||||
// EXIST: { lookupString: "boo", itemText: "boo: Boo", tailText: " (pack)" }
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package pack
|
||||
|
||||
class FooBar
|
||||
|
||||
class Boo
|
||||
|
||||
fun f(myB<caret>)
|
||||
|
||||
// EXIST: { lookupString: "Bar", itemText: "myBar: FooBar", tailText: " (pack)" }
|
||||
// ABSENT: FooBar
|
||||
// EXIST: { lookupString: "Boo", itemText: "myBoo: Boo", tailText: " (pack)" }
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun f(myF<caret>)
|
||||
|
||||
// EXIST_JAVA_ONLY: { lookupString: "File", itemText: "myFile: File", tailText: " (java.io)" }
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package pack
|
||||
|
||||
class FooFaa
|
||||
|
||||
class Fuu
|
||||
|
||||
fun f(myFooF<caret>)
|
||||
|
||||
// EXIST: { lookupString: "FooFaa", itemText: "myFooFaa: FooFaa", tailText: " (pack)" }
|
||||
// EXIST: { lookupString: "Fuu", itemText: "myFooFuu: Fuu", tailText: " (pack)" }
|
||||
// ABSENT: { itemText: "myFooFooFaa: FooFaa" }
|
||||
+1
-1
@@ -7,5 +7,5 @@ class Boo
|
||||
class C(val b<caret>)
|
||||
|
||||
// EXIST: { lookupString: "bar", itemText: "bar: FooBar", tailText: " (pack)" }
|
||||
// EXIST: { lookupString: "fooBar", itemText: "fooBar: FooBar", tailText: " (pack)" }
|
||||
// ABSENT: fooBar
|
||||
// EXIST: { lookupString: "boo", itemText: "boo: Boo", tailText: " (pack)" }
|
||||
|
||||
+1
-1
@@ -7,5 +7,5 @@ class C(private var b<caret>) {
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "bar", itemText: "bar: FooBar", tailText: " (pack)" }
|
||||
// EXIST: { lookupString: "fooBar", itemText: "fooBar: FooBar", tailText: " (pack)" }
|
||||
// ABSENT: fooBar
|
||||
// EXIST: { lookupString: "boo", itemText: "boo: Boo", tailText: " (pack.C)" }
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class FooBar
|
||||
|
||||
fun f(myFo<caret>)
|
||||
|
||||
// ELEMENT: FooBar
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class FooBar
|
||||
|
||||
fun f(myFooBar: FooBar<caret>)
|
||||
|
||||
// ELEMENT: FooBar
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class ZzzYyyXxx
|
||||
|
||||
class YyyXoo
|
||||
|
||||
class Xaa
|
||||
|
||||
fun foo(zzzYyyX<caret>)
|
||||
|
||||
// ORDER: zzzYyyXxx
|
||||
// ORDER: YyyXoo
|
||||
// ORDER: Xaa
|
||||
+24
@@ -1410,6 +1410,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/parameterNameAndType"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("ByAbbreviation.kt")
|
||||
public void testByAbbreviation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/ByAbbreviation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NoAutoInsertion.kt")
|
||||
public void testNoAutoInsertion() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/NoAutoInsertion.kt");
|
||||
@@ -1482,6 +1488,24 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix1.kt")
|
||||
public void testUserPrefix1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/UserPrefix1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix2.kt")
|
||||
public void testUserPrefix2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/UserPrefix2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix3.kt")
|
||||
public void testUserPrefix3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/UserPrefix3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ValParameter.kt")
|
||||
public void testValParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/ValParameter.kt");
|
||||
|
||||
+24
@@ -1410,6 +1410,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/parameterNameAndType"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("ByAbbreviation.kt")
|
||||
public void testByAbbreviation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/ByAbbreviation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NoAutoInsertion.kt")
|
||||
public void testNoAutoInsertion() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/NoAutoInsertion.kt");
|
||||
@@ -1482,6 +1488,24 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix1.kt")
|
||||
public void testUserPrefix1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/UserPrefix1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix2.kt")
|
||||
public void testUserPrefix2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/UserPrefix2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix3.kt")
|
||||
public void testUserPrefix3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/UserPrefix3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ValParameter.kt")
|
||||
public void testValParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/parameterNameAndType/ValParameter.kt");
|
||||
|
||||
+6
@@ -294,6 +294,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/Simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix.kt")
|
||||
public void testUserPrefix() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/UserPrefix.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/handlers/basic/stringTemplate")
|
||||
|
||||
+6
@@ -174,5 +174,11 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType/StartMatchFirst.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UserPrefix.kt")
|
||||
public void testUserPrefix() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType/UserPrefix.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-5
@@ -199,13 +199,17 @@ public class JetNameSuggester {
|
||||
|
||||
private static final String[] ACCESSOR_PREFIXES = { "get", "is", "set" };
|
||||
|
||||
public static List<String> getCamelNames(String name, JetNameValidator validator) {
|
||||
public static List<String> getCamelNames(String name, JetNameValidator validator, boolean startLowerCase) {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
addCamelNames(result, name, validator);
|
||||
addCamelNames(result, name, validator, startLowerCase);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void addCamelNames(ArrayList<String> result, String name, JetNameValidator validator) {
|
||||
addCamelNames(result, name, validator, true);
|
||||
}
|
||||
|
||||
private static void addCamelNames(ArrayList<String> result, String name, JetNameValidator validator, boolean startLowerCase) {
|
||||
if (name == "") return;
|
||||
String s = deleteNonLetterFromString(name);
|
||||
|
||||
@@ -225,11 +229,12 @@ public class JetNameSuggester {
|
||||
boolean upperCaseLetter = Character.isUpperCase(c);
|
||||
|
||||
if (i == 0) {
|
||||
addName(result, decapitalize(s), validator);
|
||||
addName(result, startLowerCase ? decapitalize(s) : s, validator);
|
||||
}
|
||||
else {
|
||||
if (upperCaseLetter && !upperCaseLetterBefore) {
|
||||
addName(result, decapitalize(s.substring(i)), validator);
|
||||
String substring = s.substring(i);
|
||||
addName(result, startLowerCase ? decapitalize(substring) : substring, validator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +242,7 @@ public class JetNameSuggester {
|
||||
}
|
||||
}
|
||||
|
||||
private static String decapitalize(String s) {
|
||||
public static String decapitalize(String s) {
|
||||
char c = s.charAt(0);
|
||||
if (!Character.isUpperCase(c)) return s;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user