Smart completion: inheritors instantiation suggested + fixed a bug with incorrect presentation of generic java class instantiation
This commit is contained in:
@@ -28,6 +28,8 @@
|
||||
<pattern testClass="org.jetbrains.jet.completion.JvmSmartCompletionTestGenerated" />
|
||||
<pattern testClass="org.jetbrains.jet.completion.handlers.SmartCompletionHandlerTestGenerated" />
|
||||
<pattern testClass="org.jetbrains.jet.completion.handlers.SmartCompletionMultifileHandlerTest" />
|
||||
<pattern testClass="org.jetbrains.jet.completion.weighers.SmartCompletionWeigherTestGenerated" />
|
||||
<pattern testClass="org.jetbrains.jet.completion.MultiFileSmartCompletionTestGenerated" />
|
||||
</patterns>
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
|
||||
@@ -43,7 +43,7 @@ public class SubstitutionUtils {
|
||||
return typeSubstitutor;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
For each supertype of a given type, we map type parameters to type arguments.
|
||||
|
||||
For instance, we have the following class hierarchy:
|
||||
|
||||
@@ -68,6 +68,10 @@ public class KotlinCacheService(val project: Project) {
|
||||
override fun analyzeFullyAndGetResult(elements: Collection<JetElement>): AnalysisResult {
|
||||
return cache.getAnalysisResultsForElements(elements)
|
||||
}
|
||||
|
||||
override fun <T> get(extension: CacheExtension<T>): T {
|
||||
return cache[extension]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,4 +34,6 @@ public trait ResolutionFacade {
|
||||
public fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor
|
||||
|
||||
public fun findModuleDescriptor(element: JetElement): ModuleDescriptor
|
||||
|
||||
public fun <T> get(extension: CacheExtension<T>): T
|
||||
}
|
||||
|
||||
@@ -229,7 +229,9 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
|
||||
override fun doComplete() {
|
||||
if (jetReference != null) {
|
||||
val completion = SmartCompletion(jetReference.expression, resolutionFacade, bindingContext!!, { isVisibleDescriptor(it) }, parameters.getOriginalFile() as JetFile, boldImmediateLookupElementFactory)
|
||||
val completion = SmartCompletion(jetReference.expression, resolutionFacade, moduleDescriptor,
|
||||
bindingContext!!, { isVisibleDescriptor(it) }, searchScope,
|
||||
parameters.getOriginalFile() as JetFile, boldImmediateLookupElementFactory)
|
||||
val result = completion.execute()
|
||||
if (result != null) {
|
||||
collector.addElements(result.additionalItems)
|
||||
@@ -237,10 +239,15 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
val filter = result.declarationFilter
|
||||
if (filter != null) {
|
||||
getReferenceVariants(DESCRIPTOR_KIND_MASK).forEach { collector.addElements(filter(it)) }
|
||||
|
||||
flushToResultSet()
|
||||
|
||||
processNonImported { collector.addElements(filter(it)) }
|
||||
flushToResultSet()
|
||||
}
|
||||
|
||||
result.inheritanceSearcher?.search({ prefixMatcher.prefixMatches(it) }) {
|
||||
collector.addElement(it)
|
||||
flushToResultSet()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +256,6 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
private fun processNonImported(processor: (DeclarationDescriptor) -> Unit) {
|
||||
if (shouldRunTopLevelCompletion()) {
|
||||
getKotlinTopLevelCallables().forEach(processor)
|
||||
getKotlinTopLevelObjects().forEach(processor) //TODO: shouldn't it work via inheritors search?
|
||||
}
|
||||
|
||||
if (shouldRunExtensionsCompletion()) {
|
||||
|
||||
@@ -34,17 +34,26 @@ import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression
|
||||
import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.jet.plugin.caches.resolve.ResolutionFacade
|
||||
import org.jetbrains.jet.plugin.caches.resolve.resolveToDescriptor
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
|
||||
trait InheritanceItemsSearcher {
|
||||
fun search(nameFilter: (String) -> Boolean, consumer: (LookupElement) -> Unit)
|
||||
}
|
||||
|
||||
class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
val resolutionFacade: ResolutionFacade,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val bindingContext: BindingContext,
|
||||
val visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
||||
val searchScope: GlobalSearchScope,
|
||||
val originalFile: JetFile,
|
||||
val boldImmediateLookupElementFactory: LookupElementFactory) {
|
||||
private val project = expression.getProject()
|
||||
|
||||
public data class Result(val declarationFilter: ((DeclarationDescriptor) -> Collection<LookupElement>)?,
|
||||
val additionalItems: Collection<LookupElement>)
|
||||
public class Result(
|
||||
val declarationFilter: ((DeclarationDescriptor) -> Collection<LookupElement>)?,
|
||||
val additionalItems: Collection<LookupElement>,
|
||||
val inheritanceSearcher: InheritanceItemsSearcher?)
|
||||
|
||||
public fun execute(): Result? {
|
||||
fun postProcess(item: LookupElement): LookupElement {
|
||||
@@ -72,9 +81,9 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
val additionalItems = result.additionalItems.map(::postProcess)
|
||||
val filter = result.declarationFilter
|
||||
return if (filter != null)
|
||||
Result({ filter(it).map(::postProcess) }, additionalItems)
|
||||
Result({ filter(it).map(::postProcess) }, additionalItems, result.inheritanceSearcher)
|
||||
else
|
||||
Result(null, additionalItems)
|
||||
Result(null, additionalItems, result.inheritanceSearcher)
|
||||
}
|
||||
|
||||
private fun executeInternal(): Result? {
|
||||
@@ -127,8 +136,10 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
}
|
||||
|
||||
val additionalItems = ArrayList<LookupElement>()
|
||||
val inheritanceSearchers = ArrayList<InheritanceItemsSearcher>()
|
||||
if (receiver == null) {
|
||||
TypeInstantiationItems(resolutionFacade, bindingContext, visibilityFilter).addToCollection(additionalItems, expectedInfos)
|
||||
TypeInstantiationItems(resolutionFacade, moduleDescriptor, bindingContext, visibilityFilter, searchScope)
|
||||
.add(additionalItems, inheritanceSearchers, expectedInfos)
|
||||
|
||||
StaticMembers(bindingContext, resolutionFacade).addToCollection(additionalItems, expectedInfos, expression, itemsToSkip)
|
||||
|
||||
@@ -141,7 +152,15 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
MultipleArgumentsItemProvider(bindingContext, typesWithSmartCasts).addToCollection(additionalItems, expectedInfos, expression)
|
||||
}
|
||||
|
||||
return Result(::filterDeclaration, additionalItems)
|
||||
val inheritanceSearcher = if (inheritanceSearchers.isNotEmpty())
|
||||
object : InheritanceItemsSearcher {
|
||||
override fun search(nameFilter: (String) -> Boolean, consumer: (LookupElement) -> Unit) {
|
||||
inheritanceSearchers.forEach { it.search(nameFilter, consumer) }
|
||||
}
|
||||
}
|
||||
else
|
||||
null
|
||||
return Result(::filterDeclaration, additionalItems, inheritanceSearcher)
|
||||
}
|
||||
|
||||
private fun calcExpectedInfos(expression: JetExpression): Collection<ExpectedInfo>? {
|
||||
@@ -289,7 +308,7 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
val lookupElement = lookupElementForType(jetType) ?: continue
|
||||
items.add(lookupElement.addTailAndNameSimilarity(infos))
|
||||
}
|
||||
return Result(null, items)
|
||||
return Result(null, items, null)
|
||||
}
|
||||
|
||||
private fun lookupElementForType(jetType: JetType): LookupElement? {
|
||||
|
||||
@@ -39,23 +39,95 @@ import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor
|
||||
import org.jetbrains.jet.plugin.caches.resolve.ResolutionFacade
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||
import org.jetbrains.jet.asJava.KotlinLightClass
|
||||
import org.jetbrains.jet.lang.types.TypeProjection
|
||||
import org.jetbrains.jet.utils.addIfNotNull
|
||||
import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaClassImpl
|
||||
import org.jetbrains.jet.asJava.LightClassUtil
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject
|
||||
import org.jetbrains.jet.lang.resolve.PossiblyBareType
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap
|
||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.resolveTopLevelClass
|
||||
|
||||
class TypeInstantiationItems(val resolutionFacade: ResolutionFacade, val bindingContext: BindingContext, val visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, expectedInfos: Collection<ExpectedInfo>) {
|
||||
class TypeInstantiationItems(
|
||||
val resolutionFacade: ResolutionFacade,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val bindingContext: BindingContext,
|
||||
val visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
||||
val searchScope: GlobalSearchScope
|
||||
) {
|
||||
public fun add(
|
||||
items: MutableCollection<LookupElement>,
|
||||
inheritanceSearchers: MutableCollection<InheritanceItemsSearcher>,
|
||||
expectedInfos: Collection<ExpectedInfo>
|
||||
) {
|
||||
val expectedInfosGrouped: Map<JetType, List<ExpectedInfo>> = expectedInfos.groupBy { it.type.makeNotNullable() }
|
||||
for ((jetType, infos) in expectedInfosGrouped) {
|
||||
for ((type, infos) in expectedInfosGrouped) {
|
||||
val tail = mergeTails(infos.map { it.tail })
|
||||
addToCollection(collection, jetType, tail)
|
||||
addToCollection(items, inheritanceSearchers, type, tail)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addToCollection(collection: MutableCollection<LookupElement>, jetType: JetType, tail: Tail?) {
|
||||
if (KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(jetType)) return // do not show "object: ..." for function types
|
||||
private fun addToCollection(
|
||||
items: MutableCollection<LookupElement>,
|
||||
inheritanceSearchers: MutableCollection<InheritanceItemsSearcher>,
|
||||
type: JetType,
|
||||
tail: Tail?
|
||||
) {
|
||||
if (KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(type)) return // do not show "object: ..." for function types
|
||||
|
||||
val classifier = jetType.getConstructor().getDeclarationDescriptor()
|
||||
val classifier = type.getConstructor().getDeclarationDescriptor()
|
||||
if (classifier !is ClassDescriptor) return
|
||||
|
||||
addSamConstructorItem(collection, classifier, tail)
|
||||
addSamConstructorItem(items, classifier, tail)
|
||||
|
||||
val typeArgs = type.getArguments()
|
||||
items.addIfNotNull(createTypeInstantiationItem(classifier, typeArgs, tail))
|
||||
|
||||
inheritanceSearchers.addInheritorSearcher(classifier, classifier, typeArgs, tail)
|
||||
|
||||
val javaAnalogFqName = KotlinToJavaTypesMap.getInstance().getKotlinToJavaFqName(DescriptorUtils.getFqNameSafe(classifier))
|
||||
if (javaAnalogFqName != null) {
|
||||
val javaAnalog = moduleDescriptor.resolveTopLevelClass(javaAnalogFqName)
|
||||
if (javaAnalog != null) {
|
||||
inheritanceSearchers.addInheritorSearcher(javaAnalog, classifier, typeArgs, tail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableCollection<InheritanceItemsSearcher>.addInheritorSearcher(
|
||||
descriptor: ClassDescriptor, kotlinClassDescriptor: ClassDescriptor, typeArgs: List<TypeProjection>, tail: Tail?
|
||||
) {
|
||||
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
|
||||
val psiClass: PsiClass = when (declaration) {
|
||||
is PsiClass -> declaration
|
||||
is JetClassOrObject -> LightClassUtil.getPsiClass(declaration) ?: return
|
||||
else -> return
|
||||
}
|
||||
if (declaration.getContainingFile().getVirtualFile() == null) return //TODO!
|
||||
add(InheritanceSearcher(psiClass, kotlinClassDescriptor, typeArgs, tail))
|
||||
}
|
||||
|
||||
private fun createTypeInstantiationItem(
|
||||
classifier: ClassDescriptor,
|
||||
typeArgs: List<TypeProjection?>,
|
||||
tail: Tail?
|
||||
): LookupElement? {
|
||||
var lookupElement = LookupElementFactory.DEFAULT.createLookupElement(classifier, resolutionFacade, bindingContext)
|
||||
|
||||
if (classifier.getKind() == ClassKind.OBJECT) {
|
||||
return lookupElement.addTail(tail)
|
||||
}
|
||||
|
||||
val isAbstract = classifier.getModality() == Modality.ABSTRACT
|
||||
val allConstructors = classifier.getConstructors()
|
||||
@@ -65,14 +137,11 @@ class TypeInstantiationItems(val resolutionFacade: ResolutionFacade, val binding
|
||||
else
|
||||
visibilityFilter(it)
|
||||
}
|
||||
if (allConstructors.isNotEmpty() && visibleConstructors.isEmpty()) return
|
||||
|
||||
var lookupElement = LookupElementFactory.DEFAULT.createLookupElement(classifier, resolutionFacade, bindingContext)
|
||||
if (allConstructors.isNotEmpty() && visibleConstructors.isEmpty()) return null
|
||||
|
||||
var lookupString = lookupElement.getLookupString()
|
||||
var allLookupStrings = setOf(lookupString)
|
||||
|
||||
val typeArgs = jetType.getArguments()
|
||||
var itemText = lookupString + DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderTypeArguments(typeArgs)
|
||||
var signatureText: String? = null
|
||||
|
||||
@@ -140,9 +209,11 @@ class TypeInstantiationItems(val resolutionFacade: ResolutionFacade, val binding
|
||||
getDelegate().renderElement(presentation)
|
||||
presentation.setItemText(itemText)
|
||||
|
||||
presentation.clearTail()
|
||||
if (signatureText != null) {
|
||||
presentation.prependTailText(signatureText!!, false)
|
||||
presentation.appendTailText(signatureText!!, false)
|
||||
}
|
||||
presentation.appendTailText(" (" + DescriptorUtils.getFqName(classifier.getContainingDeclaration()) + ")", true)
|
||||
}
|
||||
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
@@ -150,7 +221,7 @@ class TypeInstantiationItems(val resolutionFacade: ResolutionFacade, val binding
|
||||
}
|
||||
}
|
||||
|
||||
collection.add(lookupElement.addTail(tail))
|
||||
return lookupElement.addTail(tail)
|
||||
}
|
||||
|
||||
private fun addSamConstructorItem(collection: MutableCollection<LookupElement>, `class`: ClassDescriptor, tail: Tail?) {
|
||||
@@ -170,4 +241,44 @@ class TypeInstantiationItems(val resolutionFacade: ResolutionFacade, val binding
|
||||
collection.add(lookupElement)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class InheritanceSearcher(
|
||||
val psiClass: PsiClass,
|
||||
val classDescriptor: ClassDescriptor,
|
||||
val typeArgs: List<TypeProjection?>,
|
||||
val tail: Tail?) : InheritanceItemsSearcher {
|
||||
|
||||
private val typeConstructor = classDescriptor.getTypeConstructor()
|
||||
private val baseHasTypeArgs = typeConstructor.getParameters().isNotEmpty()
|
||||
private val expectedType = JetTypeImpl(Annotations.EMPTY, typeConstructor, false, typeArgs, classDescriptor.getMemberScope(typeArgs))
|
||||
|
||||
override fun search(nameFilter: (String) -> Boolean, consumer: (LookupElement) -> Unit) {
|
||||
val parameters = ClassInheritorsSearch.SearchParameters(psiClass, searchScope, true, true, false, nameFilter)
|
||||
for (inheritor in ClassInheritorsSearch.search(parameters)) {
|
||||
val descriptor = if (inheritor is KotlinLightClass) {
|
||||
val origin = inheritor.origin ?: continue
|
||||
resolutionFacade.resolveToDescriptor(origin)
|
||||
}
|
||||
else {
|
||||
resolutionFacade.get(JavaResolveExtension)(inheritor).first.resolveClass(JavaClassImpl(inheritor))
|
||||
} as? ClassDescriptor ?: continue
|
||||
if (!visibilityFilter(descriptor)) continue
|
||||
|
||||
val hasTypeArgs = descriptor.getTypeConstructor().getParameters().isNotEmpty()
|
||||
val resultingType = if (hasTypeArgs) {
|
||||
val reconstructionResult = PossiblyBareType.bare(descriptor.getTypeConstructor(), false).reconstruct(expectedType)
|
||||
reconstructionResult.getResultingType() ?: continue
|
||||
}
|
||||
else {
|
||||
val type = descriptor.getDefaultType()
|
||||
// check if derived type matches type arguments for base
|
||||
if (baseHasTypeArgs && !type.isSubtypeOf(expectedType)) continue
|
||||
type
|
||||
}
|
||||
|
||||
val lookupElement = createTypeInstantiationItem(descriptor, resultingType.getArguments(), tail) ?: continue
|
||||
consumer(lookupElement.assignSmartCompletionPriority(SmartCompletionItemPriority.INHERITOR_INSTANTIATION))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,6 +225,7 @@ enum class SmartCompletionItemPriority {
|
||||
LAMBDA
|
||||
FUNCTION_REFERENCE
|
||||
NULL
|
||||
INHERITOR_INSTANTIATION
|
||||
}
|
||||
|
||||
val SMART_COMPLETION_ITEM_PRIORITY_KEY = Key<SmartCompletionItemPriority>("SMART_COMPLETION_ITEM_PRIORITY_KEY")
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
val c: java.io.Closeable = <caret>
|
||||
|
||||
//ELEMENT: object
|
||||
//ELEMENT_TEXT: "object: Closeable{...}"
|
||||
|
||||
@@ -6,4 +6,4 @@ val c: java.io.Closeable = object: Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
//ELEMENT: object
|
||||
//ELEMENT_TEXT: "object: Closeable{...}"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import java.util.Date
|
||||
|
||||
var a : Date = <caret>
|
||||
|
||||
// ELEMENT: Date
|
||||
// TAIL_TEXT: "(...) (java.util)"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import java.util.Date
|
||||
|
||||
var a : Date = Date(<caret>)
|
||||
|
||||
// ELEMENT: Date
|
||||
// TAIL_TEXT: "(...) (java.util)"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var a : Runnable = <caret>
|
||||
|
||||
// ELEMENT: Runnable
|
||||
// ELEMENT_TEXT: Runnable
|
||||
// TAIL_TEXT: "()"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var a : Runnable = Runnable { <caret> }
|
||||
|
||||
// ELEMENT: Runnable
|
||||
// ELEMENT_TEXT: Runnable
|
||||
// TAIL_TEXT: "()"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import java.util.ArrayList
|
||||
|
||||
var a : ArrayList<String> = <caret>
|
||||
|
||||
// EXIST: { lookupString: "ArrayList", itemText: "ArrayList<String>", tailText: "(...) (java.util)" }
|
||||
@@ -1,5 +0,0 @@
|
||||
import java.util.ArrayList
|
||||
|
||||
var a : ArrayList<String> = <caret>
|
||||
|
||||
// EXIST: ArrayList@ArrayList<String>()
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.io.InputStream
|
||||
|
||||
fun foo(): InputStream {
|
||||
return <caret>
|
||||
}
|
||||
|
||||
// EXIST: ByteArrayInputStream
|
||||
// EXIST: FileInputStream
|
||||
@@ -0,0 +1,5 @@
|
||||
fun foo(): List<String> {
|
||||
return <caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "ArrayList", itemText: "ArrayList<String>", tailText: "(...) (java.util)" }
|
||||
@@ -0,0 +1,15 @@
|
||||
import p.*
|
||||
|
||||
fun foo(): KotlinTrait<I1, I2> {
|
||||
return <caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "object", itemText: "object: KotlinTrait<I1, I2>{...}" }
|
||||
// EXIST: { lookupString: "KotlinInheritor1", itemText: "KotlinInheritor1<I1>", tailText: "() (p)" }
|
||||
// EXIST: { lookupString: "KotlinInheritor2", itemText: "KotlinInheritor2", tailText: "() (p)" }
|
||||
// ABSENT: KotlinInheritor3
|
||||
// EXIST: { lookupString: "object", itemText: "object: KotlinInheritor4<I1, I2>(){...}" }
|
||||
// ABSENT: KotlinInheritor5
|
||||
// EXIST: { lookupString: "KotlinInheritor6", itemText: "KotlinInheritor6<I1, out Any?, out I3>", tailText: "() (p)" }
|
||||
// EXIST: { lookupString: "JavaInheritor1", itemText: "JavaInheritor1", tailText: "() (<root>)" }
|
||||
// ABSENT: JavaInheritor2
|
||||
@@ -0,0 +1,6 @@
|
||||
import p.*
|
||||
|
||||
class JavaInheritor1 implements KotlinTrait<I1, I2>{}
|
||||
|
||||
// is not suitable because type arguments do not match
|
||||
class JavaInheritor2 implements KotlinTrait<I1, I3>{}
|
||||
@@ -0,0 +1,23 @@
|
||||
package p
|
||||
|
||||
trait I1
|
||||
trait I2
|
||||
trait I3
|
||||
|
||||
trait KotlinTrait<T1, T2>
|
||||
|
||||
open class KotlinInheritor1<T> : KotlinTrait<T, I2>
|
||||
|
||||
class KotlinInheritor2 : KotlinInheritor1<I1>()
|
||||
|
||||
// is not suitable because type arguments do not match
|
||||
class KotlinInheritor3 : KotlinInheritor1<Any>()
|
||||
|
||||
abstract class KotlinInheritor4<T, V> : KotlinTrait<T, V>
|
||||
|
||||
// is not suitable because type arguments do not match
|
||||
class KotlinInheritor5 : KotlinTrait<Char, I2>
|
||||
|
||||
class KotlinInheritor6<T1, T2, T3 : I3> : KotlinTrait<T1, I2>
|
||||
|
||||
// ALLOW_AST_ACCESS
|
||||
@@ -0,0 +1,8 @@
|
||||
import p.*
|
||||
|
||||
fun foo(): KotlinTrait<I1, I1> {
|
||||
return <caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "object", itemText: "object: KotlinTrait<I1, I1>{...}" }
|
||||
// EXIST: { lookupString: "KotlinInheritor", itemText: "KotlinInheritor<I1>", tailText: "() (p)" }
|
||||
@@ -0,0 +1,11 @@
|
||||
package p
|
||||
|
||||
trait I1
|
||||
trait I2
|
||||
trait I3
|
||||
|
||||
trait KotlinTrait<T1, T2>
|
||||
|
||||
class KotlinInheritor<T> : KotlinTrait<T, T>
|
||||
|
||||
// ALLOW_AST_ACCESS
|
||||
@@ -0,0 +1,8 @@
|
||||
import p.*
|
||||
|
||||
fun foo(): KotlinTrait<I1, I2> {
|
||||
return <caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "object", itemText: "object: KotlinTrait<I1, I2>{...}" }
|
||||
// ABSENT: KotlinInheritor
|
||||
@@ -0,0 +1,11 @@
|
||||
package p
|
||||
|
||||
trait I1
|
||||
trait I2
|
||||
trait I3
|
||||
|
||||
trait KotlinTrait<T1, T2>
|
||||
|
||||
class KotlinInheritor<T> : KotlinTrait<T, T>
|
||||
|
||||
// ALLOW_AST_ACCESS
|
||||
@@ -0,0 +1,8 @@
|
||||
import p.*
|
||||
|
||||
fun foo(): KotlinTrait<I1<I2>> {
|
||||
return <caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "object", itemText: "object: KotlinTrait<I1<I2>>{...}" }
|
||||
// EXIST: { lookupString: "KotlinInheritor", itemText: "KotlinInheritor<I2>", tailText: "() (p)" }
|
||||
@@ -0,0 +1,10 @@
|
||||
package p
|
||||
|
||||
trait I1<T>
|
||||
trait I2
|
||||
|
||||
trait KotlinTrait<T>
|
||||
|
||||
class KotlinInheritor<T> : KotlinTrait<I1<T>>
|
||||
|
||||
// ALLOW_AST_ACCESS
|
||||
@@ -0,0 +1,15 @@
|
||||
package p1
|
||||
|
||||
fun foo(): p2.KotlinTrait {
|
||||
return <caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "object", itemText: "object: KotlinTrait{...}" }
|
||||
// EXIST: { lookupString: "KotlinInheritor1", itemText: "KotlinInheritor1", tailText: "() (p2)" }
|
||||
// EXIST: { lookupString: "KotlinInheritor2", itemText: "KotlinInheritor2", tailText: "(s: String) (p2)" }
|
||||
// EXIST: { lookupString: "object", itemText: "object: KotlinInheritor3(){...}" }
|
||||
// ABSENT: PrivateInheritor
|
||||
// EXIST: { lookupString: "object", itemText: "object: JavaInheritor1(){...}" }
|
||||
// EXIST: { lookupString: "JavaInheritor2", itemText: "JavaInheritor2", tailText: "(...) (<root>)" }
|
||||
// ABSENT: JavaInheritor3
|
||||
// EXIST: { lookupString: "ObjectInheritor", itemText: "ObjectInheritor", tailText: " (p2)" }
|
||||
@@ -0,0 +1,16 @@
|
||||
import p2.KotlinTrait
|
||||
|
||||
public abstract class JavaInheritor1 implements KotlinTrait {
|
||||
}
|
||||
|
||||
public class JavaInheritor2 extends JavaInheritor1 {
|
||||
public JavaInheritor2() {
|
||||
}
|
||||
|
||||
public JavaInheritor2(int p) {
|
||||
}
|
||||
}
|
||||
|
||||
// not visible - it's package local
|
||||
class JavaInheritor3 extends KotlinTrait {}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package p2
|
||||
|
||||
trait KotlinTrait
|
||||
|
||||
open class KotlinInheritor1 : KotlinTrait
|
||||
|
||||
class KotlinInheritor2(s: String) : KotlinInheritor1()
|
||||
|
||||
abstract class KotlinInheritor3 : KotlinTrait
|
||||
|
||||
class C {
|
||||
private class PrivateInheritor : KotlinTrait
|
||||
}
|
||||
|
||||
object ObjectInheritor : KotlinTrait
|
||||
|
||||
// ALLOW_AST_ACCESS
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.completion;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.jet.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.InnerTestClasses;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -168,6 +167,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorForGenericJavaClass.kt")
|
||||
public void testConstructorForGenericJavaClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/ConstructorForGenericJavaClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorForGenericType.kt")
|
||||
public void testConstructorForGenericType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/ConstructorForGenericType.kt");
|
||||
@@ -384,6 +389,18 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Inheritors1.kt")
|
||||
public void testInheritors1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/Inheritors1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Inheritors2.kt")
|
||||
public void testInheritors2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/Inheritors2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InsideIdentifier.kt")
|
||||
public void testInsideIdentifier() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/InsideIdentifier.kt");
|
||||
|
||||
@@ -42,6 +42,36 @@ public class MultiFileSmartCompletionTestGenerated extends AbstractMultiFileSmar
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GenericInheritors1")
|
||||
public void testGenericInheritors1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smartMultiFile/GenericInheritors1/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GenericInheritors2")
|
||||
public void testGenericInheritors2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smartMultiFile/GenericInheritors2/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GenericInheritors3")
|
||||
public void testGenericInheritors3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smartMultiFile/GenericInheritors3/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GenericInheritors4")
|
||||
public void testGenericInheritors4() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smartMultiFile/GenericInheritors4/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Inheritors")
|
||||
public void testInheritors() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smartMultiFile/Inheritors/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("JavaStaticMethodArgument")
|
||||
public void testJavaStaticMethodArgument() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smartMultiFile/JavaStaticMethodArgument/");
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.jet.plugin;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionTestCase;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
|
||||
abstract public class KotlinCompletionTestCase extends CompletionTestCase {
|
||||
|
||||
Reference in New Issue
Block a user