diff --git a/.idea/runConfigurations/Smart_Completion_Tests.xml b/.idea/runConfigurations/Smart_Completion_Tests.xml
index 421247549ac..3f27f24afea 100644
--- a/.idea/runConfigurations/Smart_Completion_Tests.xml
+++ b/.idea/runConfigurations/Smart_Completion_Tests.xml
@@ -28,6 +28,8 @@
+
+
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java
index cd1c66315d5..5504530a8f5 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/SubstitutionUtils.java
@@ -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:
diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt
index 35c15ad6aab..62271643f95 100644
--- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt
+++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheService.kt
@@ -68,6 +68,10 @@ public class KotlinCacheService(val project: Project) {
override fun analyzeFullyAndGetResult(elements: Collection): AnalysisResult {
return cache.getAnalysisResultsForElements(elements)
}
+
+ override fun get(extension: CacheExtension): T {
+ return cache[extension]
+ }
}
}
diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/ResolutionFacade.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/ResolutionFacade.kt
index 1352c63c51f..4e6df6847f1 100644
--- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/ResolutionFacade.kt
+++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/ResolutionFacade.kt
@@ -34,4 +34,6 @@ public trait ResolutionFacade {
public fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor
public fun findModuleDescriptor(element: JetElement): ModuleDescriptor
+
+ public fun get(extension: CacheExtension): T
}
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.kt b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.kt
index baa12d51479..8cf13536f10 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.kt
@@ -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()) {
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt
index 21734624160..b7525ed8768 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt
@@ -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)?,
- val additionalItems: Collection)
+ public class Result(
+ val declarationFilter: ((DeclarationDescriptor) -> Collection)?,
+ val additionalItems: Collection,
+ 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()
+ val inheritanceSearchers = ArrayList()
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? {
@@ -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? {
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt
index 8d528743593..d284010e2cc 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt
@@ -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, expectedInfos: Collection) {
+class TypeInstantiationItems(
+ val resolutionFacade: ResolutionFacade,
+ val moduleDescriptor: ModuleDescriptor,
+ val bindingContext: BindingContext,
+ val visibilityFilter: (DeclarationDescriptor) -> Boolean,
+ val searchScope: GlobalSearchScope
+) {
+ public fun add(
+ items: MutableCollection,
+ inheritanceSearchers: MutableCollection,
+ expectedInfos: Collection
+ ) {
val expectedInfosGrouped: Map> = 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, jetType: JetType, tail: Tail?) {
- if (KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(jetType)) return // do not show "object: ..." for function types
+ private fun addToCollection(
+ items: MutableCollection,
+ inheritanceSearchers: MutableCollection,
+ 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.addInheritorSearcher(
+ descriptor: ClassDescriptor, kotlinClassDescriptor: ClassDescriptor, typeArgs: List, 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,
+ 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, `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,
+ 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))
+ }
+ }
+ }
}
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt
index 3160312d965..ecd1e1f0e94 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt
@@ -225,6 +225,7 @@ enum class SmartCompletionItemPriority {
LAMBDA
FUNCTION_REFERENCE
NULL
+ INHERITOR_INSTANTIATION
}
val SMART_COMPLETION_ITEM_PRIORITY_KEY = Key("SMART_COMPLETION_ITEM_PRIORITY_KEY")
diff --git a/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt b/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt
index c5a3621dfa7..a6b4b03013c 100644
--- a/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt
+++ b/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt
@@ -1,3 +1,3 @@
val c: java.io.Closeable =
-//ELEMENT: object
+//ELEMENT_TEXT: "object: Closeable{...}"
diff --git a/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt.after b/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt.after
index dd45d717dbb..94e8d5e60da 100644
--- a/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt.after
+++ b/idea/testData/completion/handlers/smart/AnonymousObjectInsertsImport.kt.after
@@ -6,4 +6,4 @@ val c: java.io.Closeable = object: Closeable {
}
}
-//ELEMENT: object
+//ELEMENT_TEXT: "object: Closeable{...}"
diff --git a/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt b/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt
index 89f096e66de..fc846187885 100644
--- a/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt
+++ b/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt
@@ -1,3 +1,6 @@
import java.util.Date
var a : Date =
+
+// ELEMENT: Date
+// TAIL_TEXT: "(...) (java.util)"
diff --git a/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt.after b/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt.after
index 930016dcc56..1521502b9d4 100644
--- a/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt.after
+++ b/idea/testData/completion/handlers/smart/ConstructorForJavaClass.kt.after
@@ -1,3 +1,6 @@
import java.util.Date
var a : Date = Date()
+
+// ELEMENT: Date
+// TAIL_TEXT: "(...) (java.util)"
diff --git a/idea/testData/completion/handlers/smart/SAMExpected1.kt b/idea/testData/completion/handlers/smart/SAMExpected1.kt
index 2165af6730a..fdd76379b31 100644
--- a/idea/testData/completion/handlers/smart/SAMExpected1.kt
+++ b/idea/testData/completion/handlers/smart/SAMExpected1.kt
@@ -1,3 +1,4 @@
var a : Runnable =
-// ELEMENT: Runnable
+// ELEMENT_TEXT: Runnable
+// TAIL_TEXT: "()"
diff --git a/idea/testData/completion/handlers/smart/SAMExpected1.kt.after b/idea/testData/completion/handlers/smart/SAMExpected1.kt.after
index 60e6188a3fe..599e5d9546b 100644
--- a/idea/testData/completion/handlers/smart/SAMExpected1.kt.after
+++ b/idea/testData/completion/handlers/smart/SAMExpected1.kt.after
@@ -1,3 +1,4 @@
var a : Runnable = Runnable { }
-// ELEMENT: Runnable
+// ELEMENT_TEXT: Runnable
+// TAIL_TEXT: "()"
diff --git a/idea/testData/completion/smart/ConstructorForGenericJavaClass.kt b/idea/testData/completion/smart/ConstructorForGenericJavaClass.kt
new file mode 100644
index 00000000000..800440d0b37
--- /dev/null
+++ b/idea/testData/completion/smart/ConstructorForGenericJavaClass.kt
@@ -0,0 +1,5 @@
+import java.util.ArrayList
+
+var a : ArrayList =
+
+// EXIST: { lookupString: "ArrayList", itemText: "ArrayList", tailText: "(...) (java.util)" }
diff --git a/idea/testData/completion/smart/ConstructorForGenericJavaClass.kt.todo b/idea/testData/completion/smart/ConstructorForGenericJavaClass.kt.todo
deleted file mode 100644
index 71eb5f66616..00000000000
--- a/idea/testData/completion/smart/ConstructorForGenericJavaClass.kt.todo
+++ /dev/null
@@ -1,5 +0,0 @@
-import java.util.ArrayList
-
-var a : ArrayList =
-
-// EXIST: ArrayList@ArrayList()
diff --git a/idea/testData/completion/smart/Inheritors1.kt b/idea/testData/completion/smart/Inheritors1.kt
new file mode 100644
index 00000000000..081a40088c2
--- /dev/null
+++ b/idea/testData/completion/smart/Inheritors1.kt
@@ -0,0 +1,8 @@
+import java.io.InputStream
+
+fun foo(): InputStream {
+ return
+}
+
+// EXIST: ByteArrayInputStream
+// EXIST: FileInputStream
diff --git a/idea/testData/completion/smart/Inheritors2.kt b/idea/testData/completion/smart/Inheritors2.kt
new file mode 100644
index 00000000000..c6dfb12bcdb
--- /dev/null
+++ b/idea/testData/completion/smart/Inheritors2.kt
@@ -0,0 +1,5 @@
+fun foo(): List {
+ return
+}
+
+// EXIST: { lookupString: "ArrayList", itemText: "ArrayList", tailText: "(...) (java.util)" }
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors1/GenericInheritors1.kt b/idea/testData/completion/smartMultiFile/GenericInheritors1/GenericInheritors1.kt
new file mode 100644
index 00000000000..80a4dd91276
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors1/GenericInheritors1.kt
@@ -0,0 +1,15 @@
+import p.*
+
+fun foo(): KotlinTrait {
+ return
+}
+
+// EXIST: { lookupString: "object", itemText: "object: KotlinTrait{...}" }
+// EXIST: { lookupString: "KotlinInheritor1", itemText: "KotlinInheritor1", tailText: "() (p)" }
+// EXIST: { lookupString: "KotlinInheritor2", itemText: "KotlinInheritor2", tailText: "() (p)" }
+// ABSENT: KotlinInheritor3
+// EXIST: { lookupString: "object", itemText: "object: KotlinInheritor4(){...}" }
+// ABSENT: KotlinInheritor5
+// EXIST: { lookupString: "KotlinInheritor6", itemText: "KotlinInheritor6", tailText: "() (p)" }
+// EXIST: { lookupString: "JavaInheritor1", itemText: "JavaInheritor1", tailText: "() ()" }
+// ABSENT: JavaInheritor2
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors1/JavaInheritors.java b/idea/testData/completion/smartMultiFile/GenericInheritors1/JavaInheritors.java
new file mode 100644
index 00000000000..045668d12f8
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors1/JavaInheritors.java
@@ -0,0 +1,6 @@
+import p.*
+
+class JavaInheritor1 implements KotlinTrait{}
+
+// is not suitable because type arguments do not match
+class JavaInheritor2 implements KotlinTrait{}
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors1/KotlinInheritors.kt b/idea/testData/completion/smartMultiFile/GenericInheritors1/KotlinInheritors.kt
new file mode 100644
index 00000000000..12efb662ecb
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors1/KotlinInheritors.kt
@@ -0,0 +1,23 @@
+package p
+
+trait I1
+trait I2
+trait I3
+
+trait KotlinTrait
+
+open class KotlinInheritor1 : KotlinTrait
+
+class KotlinInheritor2 : KotlinInheritor1()
+
+// is not suitable because type arguments do not match
+class KotlinInheritor3 : KotlinInheritor1()
+
+abstract class KotlinInheritor4 : KotlinTrait
+
+// is not suitable because type arguments do not match
+class KotlinInheritor5 : KotlinTrait
+
+class KotlinInheritor6 : KotlinTrait
+
+// ALLOW_AST_ACCESS
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors2/GenericInheritors2.kt b/idea/testData/completion/smartMultiFile/GenericInheritors2/GenericInheritors2.kt
new file mode 100644
index 00000000000..219f665fddc
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors2/GenericInheritors2.kt
@@ -0,0 +1,8 @@
+import p.*
+
+fun foo(): KotlinTrait {
+ return
+}
+
+// EXIST: { lookupString: "object", itemText: "object: KotlinTrait{...}" }
+// EXIST: { lookupString: "KotlinInheritor", itemText: "KotlinInheritor", tailText: "() (p)" }
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors2/KotlinInheritors.kt b/idea/testData/completion/smartMultiFile/GenericInheritors2/KotlinInheritors.kt
new file mode 100644
index 00000000000..7eeddf70d97
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors2/KotlinInheritors.kt
@@ -0,0 +1,11 @@
+package p
+
+trait I1
+trait I2
+trait I3
+
+trait KotlinTrait
+
+class KotlinInheritor : KotlinTrait
+
+// ALLOW_AST_ACCESS
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors3/GenericInheritors3.kt b/idea/testData/completion/smartMultiFile/GenericInheritors3/GenericInheritors3.kt
new file mode 100644
index 00000000000..f0712e996b0
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors3/GenericInheritors3.kt
@@ -0,0 +1,8 @@
+import p.*
+
+fun foo(): KotlinTrait {
+ return
+}
+
+// EXIST: { lookupString: "object", itemText: "object: KotlinTrait{...}" }
+// ABSENT: KotlinInheritor
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors3/KotlinInheritors.kt b/idea/testData/completion/smartMultiFile/GenericInheritors3/KotlinInheritors.kt
new file mode 100644
index 00000000000..7eeddf70d97
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors3/KotlinInheritors.kt
@@ -0,0 +1,11 @@
+package p
+
+trait I1
+trait I2
+trait I3
+
+trait KotlinTrait
+
+class KotlinInheritor : KotlinTrait
+
+// ALLOW_AST_ACCESS
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors4/GenericInheritors4.kt b/idea/testData/completion/smartMultiFile/GenericInheritors4/GenericInheritors4.kt
new file mode 100644
index 00000000000..dc3f5e7e3e9
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors4/GenericInheritors4.kt
@@ -0,0 +1,8 @@
+import p.*
+
+fun foo(): KotlinTrait> {
+ return
+}
+
+// EXIST: { lookupString: "object", itemText: "object: KotlinTrait>{...}" }
+// EXIST: { lookupString: "KotlinInheritor", itemText: "KotlinInheritor", tailText: "() (p)" }
diff --git a/idea/testData/completion/smartMultiFile/GenericInheritors4/KotlinInheritors.kt b/idea/testData/completion/smartMultiFile/GenericInheritors4/KotlinInheritors.kt
new file mode 100644
index 00000000000..bf3ef9ee514
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/GenericInheritors4/KotlinInheritors.kt
@@ -0,0 +1,10 @@
+package p
+
+trait I1
+trait I2
+
+trait KotlinTrait
+
+class KotlinInheritor : KotlinTrait>
+
+// ALLOW_AST_ACCESS
diff --git a/idea/testData/completion/smartMultiFile/Inheritors/Inheritors.kt b/idea/testData/completion/smartMultiFile/Inheritors/Inheritors.kt
new file mode 100644
index 00000000000..fa6053029e7
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/Inheritors/Inheritors.kt
@@ -0,0 +1,15 @@
+package p1
+
+fun foo(): p2.KotlinTrait {
+ return
+}
+
+// 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: "(...) ()" }
+// ABSENT: JavaInheritor3
+// EXIST: { lookupString: "ObjectInheritor", itemText: "ObjectInheritor", tailText: " (p2)" }
diff --git a/idea/testData/completion/smartMultiFile/Inheritors/JavaInheritors.java b/idea/testData/completion/smartMultiFile/Inheritors/JavaInheritors.java
new file mode 100644
index 00000000000..038038f0fcb
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/Inheritors/JavaInheritors.java
@@ -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 {}
+
diff --git a/idea/testData/completion/smartMultiFile/Inheritors/KotlinInheritors.kt b/idea/testData/completion/smartMultiFile/Inheritors/KotlinInheritors.kt
new file mode 100644
index 00000000000..80b28599d6e
--- /dev/null
+++ b/idea/testData/completion/smartMultiFile/Inheritors/KotlinInheritors.kt
@@ -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
diff --git a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java
index 4881c0800bb..2e8732d5052 100644
--- a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java
+++ b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java
@@ -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");
diff --git a/idea/tests/org/jetbrains/jet/completion/MultiFileSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/MultiFileSmartCompletionTestGenerated.java
index 7e6aa4277e6..ddb3b5ea691 100644
--- a/idea/tests/org/jetbrains/jet/completion/MultiFileSmartCompletionTestGenerated.java
+++ b/idea/tests/org/jetbrains/jet/completion/MultiFileSmartCompletionTestGenerated.java
@@ -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/");
diff --git a/idea/tests/org/jetbrains/jet/plugin/KotlinCompletionTestCase.java b/idea/tests/org/jetbrains/jet/plugin/KotlinCompletionTestCase.java
index 6a8f36617a2..ad966d21496 100644
--- a/idea/tests/org/jetbrains/jet/plugin/KotlinCompletionTestCase.java
+++ b/idea/tests/org/jetbrains/jet/plugin/KotlinCompletionTestCase.java
@@ -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 {