diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt index 9b9dc1ca771..d2d0f9f28b5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt @@ -17,10 +17,7 @@ package org.jetbrains.kotlin.resolve.scopes.utils import com.intellij.util.SmartList -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor -import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name @@ -46,20 +43,43 @@ public fun LexicalScope.getFileScope(): FileScope { /** * Adds receivers to the list in order of locality, so that the closest (the most local) receiver goes first */ -public fun LexicalScope.getImplicitReceiversHierarchy(): List = collectFromMeAndParent { it.implicitReceiver } +public fun LexicalScope.getImplicitReceiversHierarchy(): List { + // todo remove hack + var jetScopeRefactoringHack: JetScope? = null + val receivers = collectFromMeAndParent { + if (it is MemberScopeToFileScopeAdapter) { + jetScopeRefactoringHack = it.memberScope + } + it.implicitReceiver + } -public fun LexicalScope.getDeclarationsByLabel(labelName: Name): Collection = collectFromMeAndParent { - if (it.isOwnerDescriptorAccessibleByLabel && it.ownerDescriptor.name == labelName) { - it.ownerDescriptor - } else { - null + return if (jetScopeRefactoringHack != null) { + receivers + jetScopeRefactoringHack!!.getImplicitReceiversHierarchy() + } + else { + receivers + } +} + +public fun LexicalScope.getDeclarationsByLabel(labelName: Name): Collection = collectAllFromMeAndParent { + if(it is MemberScopeToFileScopeAdapter) { // todo remove this hack + it.memberScope.getDeclarationsByLabel(labelName) + } + else if (it.isOwnerDescriptorAccessibleByLabel && it.ownerDescriptor.name == labelName) { + listOf(it.ownerDescriptor) + } + else { + listOf() } } @deprecated("Use getOwnProperties instead") public fun LexicalScope.getLocalVariable(name: Name, location: LookupLocation = NoLookupLocation.UNSORTED): VariableDescriptor? { processForMeAndParent { - if (it !is FileScope) { // todo check this + if (it is MemberScopeToFileScopeAdapter) { // todo remove hack + return it.memberScope.getLocalVariable(name) + } + else if (it !is FileScope) { // todo check this it.getDeclaredVariables(name, location).singleOrNull()?.let { return it } } } @@ -73,7 +93,13 @@ public fun LexicalScope.getClassifier(name: Name, location: LookupLocation = NoL return null } -public fun LexicalScope.asJetScope(): JetScope = LexicalToJetScopeAdapter(this) +public fun LexicalScope.asJetScope(): JetScope { + if (this is JetScope) return this + return LexicalToJetScopeAdapter(this) +} + +@deprecated("Remove this method after scope refactoring") +public fun JetScope.memberScopeAsFileScope(): FileScope = MemberScopeToFileScopeAdapter(this) private class LexicalToJetScopeAdapter(val lexicalScope: LexicalScope): JetScope { @@ -81,8 +107,14 @@ private class LexicalToJetScopeAdapter(val lexicalScope: LexicalScope): JetScope override fun getPackage(name: Name) = lexicalScope.getFileScope().getPackage(name) - override fun getProperties(name: Name, location: LookupLocation) = lexicalScope.collectAllFromMeAndParent { - it.getDeclaredVariables(name, location) + override fun getProperties(name: Name, location: LookupLocation): Collection { + val fileScope = lexicalScope.getFileScope() + if (fileScope is MemberScopeToFileScopeAdapter) { + return fileScope.memberScope.getProperties(name, location) + } + else { + return fileScope.getDeclaredVariables(name, location) + } } override fun getLocalVariable(name: Name) = lexicalScope.getLocalVariable(name) @@ -91,7 +123,6 @@ private class LexicalToJetScopeAdapter(val lexicalScope: LexicalScope): JetScope it.getDeclaredFunctions(name, location) } - override fun getSyntheticExtensionProperties(receiverTypes: Collection, name: Name, location: LookupLocation) = lexicalScope.getFileScope().getSyntheticExtensionProperties(receiverTypes, name, location) @@ -115,8 +146,59 @@ private class LexicalToJetScopeAdapter(val lexicalScope: LexicalScope): JetScope } override fun getImplicitReceiversHierarchy() = lexicalScope.getImplicitReceiversHierarchy() - override fun printScopeStructure(p: Printer) = lexicalScope.printStructure(p) override fun getOwnDeclaredDescriptors() = lexicalScope.getDeclaredDescriptors() + + override fun printScopeStructure(p: Printer) { + p.println(javaClass.simpleName) + p.pushIndent() + + lexicalScope.printStructure(p) + + p.popIndent() + p.println("}") + } +} + +private class MemberScopeToFileScopeAdapter(val memberScope: JetScope) : FileScope { + override fun getPackage(name: Name): PackageViewDescriptor? = memberScope.getPackage(name) + + override fun getSyntheticExtensionProperties(receiverTypes: Collection, name: Name, location: LookupLocation) + = memberScope.getSyntheticExtensionProperties(receiverTypes, name, location) + + override fun getSyntheticExtensionFunctions(receiverTypes: Collection, name: Name, location: LookupLocation) + = memberScope.getSyntheticExtensionFunctions(receiverTypes, name, location) + + override fun getSyntheticExtensionProperties(receiverTypes: Collection) + = memberScope.getSyntheticExtensionProperties(receiverTypes) + + override fun getSyntheticExtensionFunctions(receiverTypes: Collection) + = memberScope.getSyntheticExtensionFunctions(receiverTypes) + + override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) + = memberScope.getDescriptors(kindFilter, nameFilter) + + override val ownerDescriptor: DeclarationDescriptor + get() = memberScope.getContainingDeclaration() + + override fun getDeclaredDescriptors() = memberScope.getOwnDeclaredDescriptors() + + override fun getDeclaredClassifier(name: Name, location: LookupLocation) = memberScope.getClassifier(name, location) + + override fun getDeclaredVariables(name: Name, location: LookupLocation): Collection { + throw IllegalStateException() + } + + override fun getDeclaredFunctions(name: Name, location: LookupLocation) = memberScope.getFunctions(name, location) + + override fun printStructure(p: Printer) { + p.println(javaClass.simpleName) + p.pushIndent() + + memberScope.printScopeStructure(p.withholdIndentOnce()) + + p.popIndent() + p.println("}") + } } private inline fun LexicalScope.processForMeAndParent(process: (LexicalScope) -> Unit) { diff --git a/compiler/testData/diagnostics/tests/extensions/extensionPropertyVsParameter.kt b/compiler/testData/diagnostics/tests/extensions/extensionPropertyVsParameter.kt new file mode 100644 index 00000000000..4ae6532be52 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/extensionPropertyVsParameter.kt @@ -0,0 +1,8 @@ +val Int.foo: Int + get() = this + + +fun test(foo: Int) { + test(4.foo) + test(foo) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/extensions/extensionPropertyVsParameter.txt b/compiler/testData/diagnostics/tests/extensions/extensionPropertyVsParameter.txt new file mode 100644 index 00000000000..108b4c15489 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/extensionPropertyVsParameter.txt @@ -0,0 +1,4 @@ +package + +internal val kotlin.Int.foo: kotlin.Int +internal fun test(/*0*/ foo: kotlin.Int): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/extensions/variableInvoke.kt b/compiler/testData/diagnostics/tests/extensions/variableInvoke.kt new file mode 100644 index 00000000000..b503b6cb3ea --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/variableInvoke.kt @@ -0,0 +1,9 @@ +class A(foo: Int.() -> Unit) { + init { + 4.foo() + } +} + +fun test(foo: Int.() -> Unit) { + 4.foo() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/extensions/variableInvoke.txt b/compiler/testData/diagnostics/tests/extensions/variableInvoke.txt new file mode 100644 index 00000000000..b3e77bd0fe3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/variableInvoke.txt @@ -0,0 +1,10 @@ +package + +internal fun test(/*0*/ foo: kotlin.Int.() -> kotlin.Unit): kotlin.Unit + +internal final class A { + public constructor A(/*0*/ foo: kotlin.Int.() -> kotlin.Unit) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index c7462ea43f9..c15e9925f1f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -5571,6 +5571,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("extensionPropertyVsParameter.kt") + public void testExtensionPropertyVsParameter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/extensions/extensionPropertyVsParameter.kt"); + doTest(fileName); + } + @TestMetadata("ExtensionsCalledOnSuper.kt") public void testExtensionsCalledOnSuper() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/extensions/ExtensionsCalledOnSuper.kt"); @@ -5642,6 +5648,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver2.kt"); doTest(fileName); } + + @TestMetadata("variableInvoke.kt") + public void testVariableInvoke() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/extensions/variableInvoke.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/diagnostics/tests/functionAsExpression")