diff --git a/compiler/frontend.java/frontend.java.iml b/compiler/frontend.java/frontend.java.iml
index 6f37b7eda52..57f41bf2a78 100644
--- a/compiler/frontend.java/frontend.java.iml
+++ b/compiler/frontend.java/frontend.java.iml
@@ -13,5 +13,6 @@
+
\ No newline at end of file
diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt
index a0a8791600b..2a630a13a48 100644
--- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt
+++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SyntheticExtensionsScope.kt
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.JetType
+import org.jetbrains.kotlin.utils.addIfNotNull
+import java.util.*
interface SyntheticExtensionPropertyDescriptor : PropertyDescriptor {
val getMethod: FunctionDescriptor
@@ -50,12 +52,12 @@ class SyntheticExtensionsScope(storageManager: StorageManager) : JetScope by Jet
private fun syntheticPropertyInClass(javaClass: JavaClassDescriptor, type: JetType, name: Name): PropertyDescriptor? {
val memberScope = javaClass.getMemberScope(type.getArguments())
- val getMethod = memberScope.getFunctions(name.toGetMethodName()).singleOrNull {
+ val getMethod = memberScope.getFunctions(toGetMethodName(name)).singleOrNull {
it.getValueParameters().isEmpty() && it.getTypeParameters().isEmpty() && it.getVisibility() == Visibilities.PUBLIC //TODO: what about protected and package-local?
} ?: return null
val propertyType = getMethod.getReturnType() ?: return null
- val setMethod = memberScope.getFunctions(name.toSetMethodName()).singleOrNull {
+ val setMethod = memberScope.getFunctions(toSetMethodName(name)).singleOrNull {
it.getValueParameters().singleOrNull()?.getType() == propertyType
&& it.getTypeParameters().isEmpty()
&& it.getReturnType()?.let { KotlinBuiltIns.isUnit(it) } ?: false
@@ -68,10 +70,10 @@ class SyntheticExtensionsScope(storageManager: StorageManager) : JetScope by Jet
override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name): Collection {
if (name.isSpecial()) return emptyList()
if (name.getIdentifier()[0].isUpperCase()) return emptyList()
- return collectSyntheticProperties(null, receiverType, name) ?: emptyList()
+ return collectSyntheticPropertiesByName(null, receiverType, name) ?: emptyList()
}
- private fun collectSyntheticProperties(result: SmartList?, type: JetType, name: Name): SmartList? {
+ private fun collectSyntheticPropertiesByName(result: SmartList?, type: JetType, name: Name): SmartList? {
@suppress("NAME_SHADOWING")
var result = result
@@ -81,11 +83,32 @@ class SyntheticExtensionsScope(storageManager: StorageManager) : JetScope by Jet
result = result.add(syntheticPropertyInClass(Triple(classifier, type, name)))
}
- typeConstructor.getSupertypes().forEach { result = collectSyntheticProperties(result, it, name) }
+ typeConstructor.getSupertypes().forEach { result = collectSyntheticPropertiesByName(result, it, name) }
return result
}
+ override fun getSyntheticExtensionProperties(receiverType: JetType): Collection {
+ val result = ArrayList()
+ result.collectSyntheticProperties(receiverType)
+ return result
+ }
+
+ private fun MutableList.collectSyntheticProperties(type: JetType) {
+ val typeConstructor = type.getConstructor()
+ val classifier = typeConstructor.getDeclarationDescriptor()
+ if (classifier is JavaClassDescriptor) {
+ for (descriptor in classifier.getMemberScope(type.getArguments()).getAllDescriptors()) {
+ if (descriptor is FunctionDescriptor) {
+ val propertyName = fromGetMethodName(descriptor.getName()) ?: continue
+ addIfNotNull(syntheticPropertyInClass(classifier, type, propertyName))
+ }
+ }
+ }
+
+ typeConstructor.getSupertypes().forEach { collectSyntheticProperties(it) }
+ }
+
private fun SmartList?.add(property: PropertyDescriptor?): SmartList? {
if (property == null) return this
val list = if (this != null) this else SmartList()
@@ -96,12 +119,19 @@ class SyntheticExtensionsScope(storageManager: StorageManager) : JetScope by Jet
//TODO: "is"?
//TODO: methods like "getURL"?
//TODO: reuse code with generation?
- private fun Name.toGetMethodName(): Name {
- return Name.identifier("get" + getIdentifier().capitalize())
+ private fun toGetMethodName(propertyName: Name): Name {
+ return Name.identifier("get" + propertyName.getIdentifier().capitalize())
}
- private fun Name.toSetMethodName(): Name {
- return Name.identifier("set" + getIdentifier().capitalize())
+ private fun toSetMethodName(propertyName: Name): Name {
+ return Name.identifier("set" + propertyName.getIdentifier().capitalize())
+ }
+
+ private fun fromGetMethodName(methodName: Name): Name? {
+ if (methodName.isSpecial()) return null
+ val identifier = methodName.getIdentifier()
+ if (!identifier.startsWith("get")) return null
+ return Name.identifier(identifier.removePrefix("get").decapitalize())
}
private class MyPropertyDescriptor(
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt
index 3e653a4432a..94a9868fae2 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt
@@ -57,6 +57,10 @@ class AllUnderImportsScope : JetScope {
return scopes.flatMap { it.getSyntheticExtensionProperties(receiverType, name) }
}
+ override fun getSyntheticExtensionProperties(receiverType: JetType): Collection {
+ return scopes.flatMap { it.getSyntheticExtensionProperties(receiverType) }
+ }
+
override fun getPackage(name: Name): PackageViewDescriptor? = null // packages are not imported by all under imports
override fun getLocalVariable(name: Name): VariableDescriptor? = null
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt
index 0dded31f58a..6b84617d723 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt
@@ -19,11 +19,11 @@ package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
-import org.jetbrains.kotlin.resolve.scopes.JetScope
+import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.utils.Printer
-class SingleImportScope(private val aliasName: Name, private val descriptors: Collection) : JetScope {
+class SingleImportScope(private val aliasName: Name, private val descriptors: Collection) : JetScopeImpl() {
override fun getClassifier(name: Name)
= if (name == aliasName) descriptors.filterIsInstance().singleOrNull() else null
@@ -36,20 +36,10 @@ class SingleImportScope(private val aliasName: Name, private val descriptors: Co
override fun getFunctions(name: Name)
= if (name == aliasName) descriptors.filterIsInstance() else emptyList()
- override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name): Collection = emptyList()
-
- override fun getLocalVariable(name: Name): VariableDescriptor? = null
-
override fun getContainingDeclaration(): DeclarationDescriptor = throw UnsupportedOperationException()
- override fun getDeclarationsByLabel(labelName: Name): Collection = emptyList()
-
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors
- override fun getImplicitReceiversHierarchy(): List = emptyList()
-
- override fun getOwnDeclaredDescriptors(): Collection = emptyList()
-
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getSimpleName(), ": ", aliasName)
}
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt
index d3a9b7fdfa3..903d61c4e9e 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt
@@ -260,6 +260,17 @@ class LazyImportScope(
return importResolver.collectFromImports(name, LookupMode.EVERYTHING) { scope, name -> scope.getSyntheticExtensionProperties(receiverType, name) }
}
+ override fun getSyntheticExtensionProperties(receiverType: JetType): Collection {
+ // we do not perform any filtering by visibility here because all descriptors from both visible/invisible filter scopes are to be added anyway
+ if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf()
+
+ return importResolver.resolveSession.getStorageManager().compute {
+ importResolver.indexedImports.imports.flatMapTo(LinkedHashSet()) { import ->
+ importResolver.getImportScope(import, LookupMode.EVERYTHING).getSyntheticExtensionProperties(receiverType)
+ }
+ }
+ }
+
override fun getDeclarationsByLabel(labelName: Name): Collection = listOf()
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection {
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt
index fd3e126ac8a..d6fe4b51cbf 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProvider
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
+import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl
import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.JetType
@@ -41,7 +42,7 @@ protected constructor(
protected val declarationProvider: DP,
protected val thisDescriptor: D,
protected val trace: BindingTrace
-) : JetScope {
+) : JetScopeImpl() {
protected val storageManager: StorageManager = c.storageManager
private val classDescriptors: MemoizedFunctionToNotNull> = storageManager.createMemoizedFunction { resolveClassDescriptor(it) }
@@ -111,12 +112,6 @@ protected constructor(
protected abstract fun getNonDeclaredProperties(name: Name, result: MutableSet)
- override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name) = listOf()
-
- override fun getLocalVariable(name: Name): VariableDescriptor? = null
-
- override fun getDeclarationsByLabel(labelName: Name) = setOf()
-
protected fun computeDescriptorsFromDeclaredElements(kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean): List {
val declarations = declarationProvider.getDeclarations(kindFilter, nameFilter)
@@ -163,8 +158,6 @@ protected constructor(
return result.toReadOnlyList()
}
- override fun getImplicitReceiversHierarchy() = listOf()
-
// Do not change this, override in concrete subclasses:
// it is very easy to compromise laziness of this class, and fail all the debugging
// a generic implementation can't do this properly
diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt
index e82897671a4..0628b88ac3f 100644
--- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt
+++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
+import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.TypeUtils
@@ -51,7 +52,7 @@ import java.util.LinkedHashSet
public abstract class LazyJavaMemberScope(
protected val c: LazyJavaResolverContext,
private val containingDeclaration: DeclarationDescriptor
-) : JetScope {
+) : JetScopeImpl() {
// this lazy value is not used at all in LazyPackageFragmentScopeForJavaPackage because we do not use caching there
// but is placed in the base class to not duplicate code
private val allDescriptors = c.storageManager.createRecursionTolerantLazyValue>(
@@ -297,11 +298,6 @@ public abstract class LazyJavaMemberScope(
override fun getProperties(name: Name): Collection = properties(name)
- override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name) = listOf()
-
- override fun getLocalVariable(name: Name): VariableDescriptor? = null
- override fun getDeclarationsByLabel(labelName: Name) = listOf()
-
override fun getOwnDeclaredDescriptors() = getDescriptors()
override fun getDescriptors(kindFilter: DescriptorKindFilter,
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt
index 98f4032841d..aee4d5f6423 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt
@@ -51,6 +51,10 @@ public abstract class AbstractScopeAdapter : JetScope {
return workerScope.getSyntheticExtensionProperties(receiverType, name)
}
+ override fun getSyntheticExtensionProperties(receiverType: JetType): Collection {
+ return workerScope.getSyntheticExtensionProperties(receiverType)
+ }
+
override fun getLocalVariable(name: Name): VariableDescriptor? {
return workerScope.getLocalVariable(name)
}
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt
index 0a270366fdb..7d1319fbeb4 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt
@@ -68,6 +68,9 @@ public open class ChainedScope(
override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name): Collection
= getFromAllScopes { it.getSyntheticExtensionProperties(receiverType, name) }
+ override fun getSyntheticExtensionProperties(receiverType: JetType): Collection
+ = getFromAllScopes { it.getSyntheticExtensionProperties(receiverType) }
+
override fun getImplicitReceiversHierarchy(): List {
if (implicitReceiverHierarchy == null) {
val result = ArrayList()
@@ -82,12 +85,8 @@ public open class ChainedScope(
override fun getDeclarationsByLabel(labelName: Name) = scopeChain.flatMap { it.getDeclarationsByLabel(labelName) }
- override fun getDescriptors(kindFilter: DescriptorKindFilter,
- nameFilter: (Name) -> Boolean): Collection {
- val result = LinkedHashSet()
- scopeChain.flatMapTo(result) { it.getDescriptors(kindFilter, nameFilter) }
- return result
- }
+ override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
+ = getFromAllScopes { it.getDescriptors(kindFilter, nameFilter) }
override fun getOwnDeclaredDescriptors(): Collection {
throw UnsupportedOperationException()
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt
index b2e6067b031..55dadbd0179 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt
@@ -22,29 +22,19 @@ import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
-public class ExplicitImportsScope(private val descriptors: Collection) : JetScope {
+public class ExplicitImportsScope(private val descriptors: Collection) : JetScopeImpl() {
override fun getClassifier(name: Name) = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull()
override fun getPackage(name: Name)= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull()
override fun getProperties(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance()
- override fun getLocalVariable(name: Name): VariableDescriptor? = null
-
override fun getFunctions(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance()
- override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name): Collection = listOf()
-
override fun getContainingDeclaration() = throw UnsupportedOperationException()
- override fun getDeclarationsByLabel(labelName: Name) = emptyList()
-
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors
- override fun getImplicitReceiversHierarchy() = emptyList()
-
- override fun getOwnDeclaredDescriptors() = emptyList()
-
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getName())
}
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/FilteringScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/FilteringScope.kt
index 313181b5638..650c8ff0f8c 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/FilteringScope.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/FilteringScope.kt
@@ -38,6 +38,8 @@ public class FilteringScope(private val workerScope: JetScope, private val predi
override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name) = workerScope.getSyntheticExtensionProperties(receiverType, name).filter(predicate)
+ override fun getSyntheticExtensionProperties(receiverType: JetType) = workerScope.getSyntheticExtensionProperties(receiverType).filter(predicate)
+
override fun getLocalVariable(name: Name) = filterDescriptor(workerScope.getLocalVariable(name))
override fun getDescriptors(kindFilter: DescriptorKindFilter,
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt
index a6ba0850059..d2ddc74eca1 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt
@@ -37,6 +37,8 @@ public trait JetScope {
public fun getSyntheticExtensionProperties(receiverType: JetType, name: Name): Collection
+ public fun getSyntheticExtensionProperties(receiverType: JetType): Collection
+
public fun getContainingDeclaration(): DeclarationDescriptor
public fun getDeclarationsByLabel(labelName: Name): Collection
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScopeImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScopeImpl.kt
index 3761435f6f0..011ed035050 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScopeImpl.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScopeImpl.kt
@@ -34,6 +34,8 @@ public abstract class JetScopeImpl : JetScope {
override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name): Collection = listOf()
+ override fun getSyntheticExtensionProperties(receiverType: JetType): Collection = listOf()
+
override fun getDeclarationsByLabel(labelName: Name): Collection = listOf()
override fun getDescriptors(kindFilter: DescriptorKindFilter,
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinClass.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinClass.kt
index d53d46cf158..cfe0ea28415 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinClass.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinClass.kt
@@ -27,7 +27,7 @@ import kotlin.properties.Delegates
public class StaticScopeForKotlinClass(
private val containingClass: ClassDescriptor
-) : JetScope {
+) : JetScopeImpl() {
override fun getClassifier(name: Name) = null // TODO
private val functions: List by Delegates.lazy {
@@ -46,13 +46,7 @@ public class StaticScopeForKotlinClass(
override fun getFunctions(name: Name) = functions.filterTo(ArrayList(2)) { it.getName() == name }
- override fun getPackage(name: Name) = null
- override fun getProperties(name: Name) = listOf()
- override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name) = listOf()
- override fun getLocalVariable(name: Name) = null
override fun getContainingDeclaration() = containingClass
- override fun getDeclarationsByLabel(labelName: Name) = listOf()
- override fun getImplicitReceiversHierarchy() = listOf()
override fun printScopeStructure(p: Printer) {
p.println("Static scope for $containingClass")
diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt
index 19bc67d6cb6..2d53c9f2ad9 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt
@@ -71,6 +71,8 @@ public class SubstitutingScope(private val workerScope: JetScope, private val su
override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name) = substitute(workerScope.getSyntheticExtensionProperties(receiverType, name))
+ override fun getSyntheticExtensionProperties(receiverType: JetType) = substitute(workerScope.getSyntheticExtensionProperties(receiverType))
+
override fun getPackage(name: Name) = workerScope.getPackage(name)
override fun getImplicitReceiversHierarchy(): List {
diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java
index 320058f54b3..6c0716e61dc 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java
+++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java
@@ -99,6 +99,12 @@ public class ErrorUtils {
return ERROR_PROPERTY_GROUP;
}
+ @NotNull
+ @Override
+ public Collection getSyntheticExtensionProperties(@NotNull JetType receiverType) {
+ return ERROR_PROPERTY_GROUP;
+ }
+
@Override
public VariableDescriptor getLocalVariable(@NotNull Name name) {
return ERROR_PROPERTY;
@@ -209,6 +215,12 @@ public class ErrorUtils {
throw new IllegalStateException();
}
+ @NotNull
+ @Override
+ public Collection getSyntheticExtensionProperties(@NotNull JetType receiverType) {
+ throw new IllegalStateException();
+ }
+
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt
index 7ead7345cf7..f2cc98fdb0c 100644
--- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt
+++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
-import org.jetbrains.kotlin.resolve.scopes.JetScope
+import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl
import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.ProtoBuf.Callable.CallableKind
@@ -34,7 +34,7 @@ import java.util.LinkedHashSet
public abstract class DeserializedMemberScope protected constructor(
protected val c: DeserializationContext,
membersList: Collection
-) : JetScope {
+) : JetScopeImpl() {
private data class ProtoKey(val name: Name, val kind: Kind, val isExtension: Boolean)
private enum class Kind { FUNCTION, PROPERTY }
@@ -112,16 +112,8 @@ public abstract class DeserializedMemberScope protected constructor(
protected abstract fun addClassDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean)
- override fun getSyntheticExtensionProperties(receiverType: JetType, name: Name) = listOf()
-
- override fun getPackage(name: Name): PackageViewDescriptor? = null
-
- override fun getLocalVariable(name: Name): VariableDescriptor? = null
-
override fun getContainingDeclaration() = c.containingDeclaration
- override fun getDeclarationsByLabel(labelName: Name): Collection = listOf()
-
protected fun computeDescriptors(kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean): Collection {
//NOTE: descriptors should be in the same order they were serialized in
diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt
index 83fbe3443b2..96032f7e66f 100644
--- a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt
+++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt
@@ -88,6 +88,8 @@ public class ReferenceVariantsHelper(
val descriptors = LinkedHashSet()
+ val dataFlowInfo = context.getDataFlowInfo(expression)
+
val pair = getExplicitReceiverData(expression)
if (pair != null) {
val (receiverExpression, callType) = pair
@@ -104,25 +106,17 @@ public class ReferenceVariantsHelper(
context.getType(receiverExpression)
if (expressionType != null && !expressionType.isError()) {
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
- val dataFlowInfo = context.getDataFlowInfo(expression)
-
- for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, containingDeclaration, dataFlowInfo)) {
- descriptors.addMembersFromReceiver(variant, callType, kindFilter, nameFilter)
- }
+ descriptors.addMembersFromReceiverAndSyntheticExtensions(receiverValue, callType, kindFilter, nameFilter, resolutionScope, dataFlowInfo)
descriptors.addCallableExtensions(resolutionScope, receiverValue, dataFlowInfo, callType, kindFilter, nameFilter)
}
}
else {
- val dataFlowInfo = context.getDataFlowInfo(expression)
-
// process instance members that can be called via implicit receiver's instances
val receivers = resolutionScope.getImplicitReceiversWithInstance()
val receiverValues = receivers.map { it.getValue() }
for (receiverValue in receiverValues) {
- for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, containingDeclaration, dataFlowInfo)) {
- descriptors.addMembersFromReceiver(variant, CallType.NORMAL, kindFilter, nameFilter)
- }
+ descriptors.addMembersFromReceiverAndSyntheticExtensions(receiverValue, CallType.NORMAL, kindFilter, nameFilter, resolutionScope, dataFlowInfo)
}
// process extensions and non-instance members
@@ -143,22 +137,36 @@ public class ReferenceVariantsHelper(
return descriptors
}
- private fun MutableCollection.addMembersFromReceiver(
- receiverType: JetType,
+ private fun MutableSet.addMembersFromReceiverAndSyntheticExtensions(
+ receiverValue: ReceiverValue,
callType: CallType,
kindFilter: DescriptorKindFilter,
- nameFilter: (Name) -> Boolean
+ nameFilter: (Name) -> Boolean,
+ resolutionScope: JetScope,
+ dataFlowInfo: DataFlowInfo
) {
- var memberFilter = kindFilter exclude DescriptorKindExclude.Extensions
- val members = receiverType.getMemberScope().getDescriptorsFiltered(DescriptorKindFilter.ALL, nameFilter) // filter by kind later because of constructors
- for (member in members) {
- if (member is ClassDescriptor) {
- if (member.isInner()) {
- member.getConstructors().filterTo(this) { callType.canCall(it) && memberFilter.accepts(it) }
+ val memberFilter = kindFilter exclude DescriptorKindExclude.Extensions
+ val containingDeclaration = resolutionScope.getContainingDeclaration()
+
+ for (receiverType in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, containingDeclaration, dataFlowInfo)) {
+ val members = receiverType.getMemberScope().getDescriptorsFiltered(DescriptorKindFilter.ALL, nameFilter) // filter by kind later because of constructors
+ for (member in members) {
+ if (member is ClassDescriptor) {
+ if (member.isInner()) {
+ member.getConstructors().filterTo(this) { callType.canCall(it) && memberFilter.accepts(it) }
+ }
+ }
+ else if (callType.canCall(member) && memberFilter.accepts(member)) {
+ this.add(member)
}
}
- else if (callType.canCall(member) && memberFilter.accepts(member)) {
- this.add(member)
+
+ if (!kindFilter.excludes.contains(DescriptorKindExclude.Extensions)) {
+ for (extension in resolutionScope.getSyntheticExtensionProperties(receiverType)) {
+ if (nameFilter(extension.getName()) && kindFilter.accepts(extension)) {
+ addAll(extension.substituteExtensionIfCallable(receiverValue, callType, context, dataFlowInfo, containingDeclaration))
+ }
+ }
}
}
}
diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt
index 62e7260e9dd..7f2178a7dbb 100644
--- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt
+++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt
@@ -217,16 +217,20 @@ public class LookupElementFactory(
if (descriptor is CallableDescriptor) {
if (descriptor.getExtensionReceiverParameter() != null) {
- val container = descriptor.getContainingDeclaration()
- val containerPresentation = if (container is ClassDescriptor) {
- DescriptorUtils.getFqNameFromTopLevelClass(container).toString()
- }
- else {
- DescriptorUtils.getFqName(container).toString()
- }
val originalReceiver = descriptor.getOriginal().getExtensionReceiverParameter()!!
val receiverPresentation = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(originalReceiver.getType())
- element = element.appendTailText(" for $receiverPresentation in $containerPresentation", true)
+ element = element.appendTailText(" for $receiverPresentation", true)
+
+ val container = descriptor.getContainingDeclaration()
+ val containerPresentation = if (container is ClassDescriptor)
+ DescriptorUtils.getFqNameFromTopLevelClass(container).toString()
+ else if (container is PackageFragmentDescriptor)
+ container.fqName.toString()
+ else
+ null
+ if (containerPresentation != null) {
+ element = element.appendTailText(" in $containerPresentation", true)
+ }
}
else {
val container = descriptor.getContainingDeclaration()
diff --git a/idea/idea-completion/testData/basic/common/extensions/Extensions.kt b/idea/idea-completion/testData/basic/common/extensions/Extensions.kt
index 2da87f2994a..bc09d2cd9b9 100644
--- a/idea/idea-completion/testData/basic/common/extensions/Extensions.kt
+++ b/idea/idea-completion/testData/basic/common/extensions/Extensions.kt
@@ -3,6 +3,8 @@ package a.b
class Some {
inner class Inner {
fun foo() {
+ fun String.localExtension() = 1
+
"".
}
@@ -19,3 +21,4 @@ val String.extProp: Int get() = 1
// EXIST: { lookupString: "extProp", itemText: "extProp", tailText: " for String in a.b", typeText: "Int" }
// EXIST: { lookupString: "memberExtFun", itemText: "memberExtFun", tailText: "() for String in Some.Inner", typeText: "Unit" }
// EXIST: { lookupString: "memberExtProp", itemText: "memberExtProp", tailText: " for String in Some", typeText: "Int" }
+// EXIST: { lookupString: "localExtension", itemText: "localExtension", tailText: "() for String", typeText: "Int" }
diff --git a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt
new file mode 100644
index 00000000000..568ab2a2869
--- /dev/null
+++ b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt
@@ -0,0 +1,7 @@
+import java.io.File
+
+fun foo(file: File) {
+ file.
+}
+
+// EXIST_JAVA_ONLY: { lookupString: "absolutePath", itemText: "absolutePath", tailText: " for File", typeText: "String!" }
diff --git a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt
new file mode 100644
index 00000000000..511ecc4b5bd
--- /dev/null
+++ b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt
@@ -0,0 +1,7 @@
+import java.io.File
+
+fun File.foo() {
+
+}
+
+// EXIST_JAVA_ONLY: { lookupString: "absolutePath", itemText: "absolutePath", tailText: " for File", typeText: "String!" }
diff --git a/idea/idea-completion/testData/handlers/basic/SyntheticExtension.kt b/idea/idea-completion/testData/handlers/basic/SyntheticExtension.kt
new file mode 100644
index 00000000000..a4f68a36f93
--- /dev/null
+++ b/idea/idea-completion/testData/handlers/basic/SyntheticExtension.kt
@@ -0,0 +1,7 @@
+import java.io.File
+
+fun foo(file: File) {
+ file.abs
+}
+
+// ELEMENT: absolutePath
diff --git a/idea/idea-completion/testData/handlers/basic/SyntheticExtension.kt.after b/idea/idea-completion/testData/handlers/basic/SyntheticExtension.kt.after
new file mode 100644
index 00000000000..69f9eb2d9b1
--- /dev/null
+++ b/idea/idea-completion/testData/handlers/basic/SyntheticExtension.kt.after
@@ -0,0 +1,7 @@
+import java.io.File
+
+fun foo(file: File) {
+ file.absolutePath
+}
+
+// ELEMENT: absolutePath
diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java
index f4c5eb64996..0b5a1a64a44 100644
--- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java
+++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java
@@ -1209,6 +1209,18 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
doTest(fileName);
}
+ @TestMetadata("SyntheticExtensions1.kt")
+ public void testSyntheticExtensions1() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("SyntheticExtensions2.kt")
+ public void testSyntheticExtensions2() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("WrongExplicitReceiver.kt")
public void testWrongExplicitReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/WrongExplicitReceiver.kt");
diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java
index 3f3935b0f2b..c0771c4c166 100644
--- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java
+++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java
@@ -1209,6 +1209,18 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
doTest(fileName);
}
+ @TestMetadata("SyntheticExtensions1.kt")
+ public void testSyntheticExtensions1() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("SyntheticExtensions2.kt")
+ public void testSyntheticExtensions2() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("WrongExplicitReceiver.kt")
public void testWrongExplicitReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/WrongExplicitReceiver.kt");
diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java
index e29bb1ea289..7f62698685d 100644
--- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java
+++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java
@@ -119,6 +119,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
doTest(fileName);
}
+ @TestMetadata("SyntheticExtension.kt")
+ public void testSyntheticExtension() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/SyntheticExtension.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("idea/idea-completion/testData/handlers/basic/exclChar")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)