From 608ce59f153d50235fb28c6149bbaa95ab550d48 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 4 Jun 2015 16:26:47 +0300 Subject: [PATCH] Resolution: Resolve primary constructor references to primary constructor itself if it's explicitly present in PSI --- .../org/jetbrains/kotlin/resolve/DescriptorResolver.java | 3 ++- .../kotlin/resolve/FunctionDescriptorResolver.kt | 2 +- .../kotlin/resolve/lazy/LazyDeclarationResolver.java | 5 ++--- compiler/testData/resolve/Basic.resolve | 6 +++--- .../ImportingRootScopeWhenProcessingImports.resolve | 8 ++++---- compiler/testData/resolve/ResolveToJava.resolve | 4 ++-- compiler/testData/resolve/ScopeInteraction.resolve | 4 ++-- .../jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt | 7 +++++++ .../src/org/jetbrains/kotlin/idea/kdoc/KDocFinder.kt | 8 +++++++- .../basic/localClassExtraction.kt.conflicts | 2 +- idea/testData/resolve/references/AnnotationOnFile.kt | 2 +- .../resolve/references/AnnotationOnFileWithImport.kt | 2 +- idea/testData/resolve/references/CtrlClickResolve.kt | 2 +- idea/testData/resolve/references/FakeJavaLang1.kt | 2 +- idea/testData/resolve/references/FakeJavaLang3.kt | 2 +- 15 files changed, 36 insertions(+), 23 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 1bf6ac534a9..5e23f7bef6c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -440,7 +440,8 @@ public class DescriptorResolver { ConstructorDescriptorImpl constructorDescriptor = DescriptorFactory.createPrimaryConstructorForObject(classDescriptor, toSourceElement(object)); if (object != null) { - trace.record(CONSTRUCTOR, object, constructorDescriptor); + JetPrimaryConstructor primaryConstructor = object.getPrimaryConstructor(); + trace.record(CONSTRUCTOR, primaryConstructor != null ? primaryConstructor : object, constructorDescriptor); } return constructorDescriptor; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 9d62018e9e7..8370114b027 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -224,7 +224,7 @@ class FunctionDescriptorResolver( classDescriptor, true, classElement.getPrimaryConstructorModifierList(), - classElement, + classElement.getPrimaryConstructor() ?: classElement, classDescriptor.getTypeConstructor().getParameters(), classElement.getPrimaryConstructorParameters(), trace diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java index b101a091c69..02ed9232825 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java @@ -184,9 +184,8 @@ public class LazyDeclarationResolver { @Override public DeclarationDescriptor visitPrimaryConstructor(@NotNull JetPrimaryConstructor constructor, Void data) { - JetClassOrObject klass = constructor.getContainingClassOrObject(); - getClassDescriptor(klass).getConstructors(); - return getBindingContext().get(BindingContext.CONSTRUCTOR, klass); + getClassDescriptor(constructor.getContainingClassOrObject()).getConstructors(); + return getBindingContext().get(BindingContext.CONSTRUCTOR, constructor); } @Override diff --git a/compiler/testData/resolve/Basic.resolve b/compiler/testData/resolve/Basic.resolve index 633eea2061f..ae8260b58b6 100644 --- a/compiler/testData/resolve/Basic.resolve +++ b/compiler/testData/resolve/Basic.resolve @@ -1,12 +1,12 @@ ~A~class A { - ~B~class B() { - ~B()~constructor(i: Int) {} + ~B~class B~B()~() { + ~B(int)~constructor(i: Int) {} } ~foo~fun foo(~foo.a~a : `kotlin::Char`Char) = `foo.a`a`:kotlin::Char` ~fooB~fun fooB() = `foo`foo('1')`:kotlin::Char` ~foo.1~fun foo() : Int = (1.`kotlin::Int.plus(Int)`plus(1))`:kotlin::Int` - ~foo91~fun foo1() : `B`B = `B`B()`:B` + ~foo91~fun foo1() : `B`B = `B()`B()`:B` ~A.a~val a : `kotlin::Int`Int } diff --git a/compiler/testData/resolve/ImportingRootScopeWhenProcessingImports.resolve b/compiler/testData/resolve/ImportingRootScopeWhenProcessingImports.resolve index 70c281936f0..5505cd8b64e 100644 --- a/compiler/testData/resolve/ImportingRootScopeWhenProcessingImports.resolve +++ b/compiler/testData/resolve/ImportingRootScopeWhenProcessingImports.resolve @@ -1,7 +1,7 @@ // FILE: base.kt class java { class lang { - class ~Fake~Fake() + class ~Fake~Fake~Fake()~() } } @@ -9,13 +9,13 @@ class java { import java.lang.* // will import Fake fun foo() { - `Fake`Fake() + `Fake()`Fake() } // FILE: root2.kt fun foo() { `!`Fake() // not imported within "java.lang.*" default import - java.lang.`Fake`Fake() // we all are in same (root) package, so it works + java.lang.`Fake()`Fake() // we all are in same (root) package, so it works } @@ -24,6 +24,6 @@ package nonRoot import java.lang.* // will import Fake fun foo() { - `Fake`Fake() + `Fake()`Fake() java.lang.`!`Fake() // qualified access to root package's class does not work } diff --git a/compiler/testData/resolve/ResolveToJava.resolve b/compiler/testData/resolve/ResolveToJava.resolve index 675db2bb291..3425af5d16d 100644 --- a/compiler/testData/resolve/ResolveToJava.resolve +++ b/compiler/testData/resolve/ResolveToJava.resolve @@ -9,7 +9,7 @@ fun foo(~a~a : `kotlin::Array`Array<`kotlin::Int`Int>) : `java::java.util.ArrayL fun foo(o : `java::java.lang.Object`Object, l : `java::java.util`util.`java::java.util.ArrayList`ArrayList) : `java::java.util.ArrayList`ArrayList {} -~A~class A() { +~A~class A~A()~() { fun f(a : `java::java.util`util.`java::java.util.ArrayList`ArrayList) {} fun f(a : `java::java.util.ArrayList`ArrayList) {} @@ -29,7 +29,7 @@ class B : `java::java.lang.Object`Object { } fun barrr() : `kotlin::Int`Int { - `foo`foo(`A`A()) + `foo`foo(`A()`A()) } } diff --git a/compiler/testData/resolve/ScopeInteraction.resolve b/compiler/testData/resolve/ScopeInteraction.resolve index ca04b89b8e8..01536613647 100644 --- a/compiler/testData/resolve/ScopeInteraction.resolve +++ b/compiler/testData/resolve/ScopeInteraction.resolve @@ -1,9 +1,9 @@ var xxxx = 1 -~SimpleClass~class SimpleClass(x : Int) { +~SimpleClass~class SimpleClass~SimpleClass()~(x : Int) { fun foo() = x } fun foo() { - `SimpleClass`SimpleClass(1).`!`xxxx + `SimpleClass()`SimpleClass(1).`!`xxxx } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt index 80759daaedb..7b326885d03 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt @@ -21,11 +21,13 @@ import com.intellij.psi.FileViewProvider import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText import org.jetbrains.kotlin.idea.decompiler.textBuilder.descriptorToKey import org.jetbrains.kotlin.psi.JetCallableDeclaration +import org.jetbrains.kotlin.psi.JetClassOrObject import org.jetbrains.kotlin.psi.JetDeclaration import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue @@ -42,6 +44,11 @@ public abstract class KotlinClsFileBase(provider: FileViewProvider) : JetFile(pr return callableDeclaration.getValueParameters()[original.getIndex()] } + if (original is ConstructorDescriptor && original.isPrimary()) { + val classOrObject = getDeclarationForDescriptor(original.getContainingDeclaration()) as? JetClassOrObject + return classOrObject?.getPrimaryConstructor() ?: classOrObject + } + val key = descriptorToKey(original) val range = decompiledText.get().renderedDescriptorsToRange[key] diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocFinder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocFinder.kt index 323a024dd8d..6b9020dc6b7 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocFinder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocFinder.kt @@ -21,13 +21,19 @@ import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.psi.JetDeclaration +import org.jetbrains.kotlin.psi.JetPrimaryConstructor import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.resolve.source.PsiSourceElement object KDocFinder { fun findKDoc(declaration: DeclarationDescriptor): KDocTag? { if (declaration is DeclarationDescriptorWithSource) { - val psiDeclaration = (declaration.getSource() as? PsiSourceElement)?.psi?.getNavigationElement() + var psiDeclaration = (declaration.getSource() as? PsiSourceElement)?.psi?.getNavigationElement() + // KDoc for primary constructor is located inside of its class KDoc + if (psiDeclaration is JetPrimaryConstructor) { + psiDeclaration = psiDeclaration.getClassOrObject() + } + if (psiDeclaration is JetDeclaration) { val kdoc = psiDeclaration.getDocComment() if (kdoc != null) { diff --git a/idea/testData/refactoring/extractFunction/basic/localClassExtraction.kt.conflicts b/idea/testData/refactoring/extractFunction/basic/localClassExtraction.kt.conflicts index fe39aecde93..9e21861865b 100644 --- a/idea/testData/refactoring/extractFunction/basic/localClassExtraction.kt.conflicts +++ b/idea/testData/refactoring/extractFunction/basic/localClassExtraction.kt.conflicts @@ -1 +1 @@ -Following declarations are used outside of selected code fragment: local final class A value-parameter val n: Int = ... \ No newline at end of file +Following declarations are used outside of selected code fragment: public constructor A(n: Int = ...) value-parameter val n: Int = ... \ No newline at end of file diff --git a/idea/testData/resolve/references/AnnotationOnFile.kt b/idea/testData/resolve/references/AnnotationOnFile.kt index 2240e810c71..8fa50cb62fe 100644 --- a/idea/testData/resolve/references/AnnotationOnFile.kt +++ b/idea/testData/resolve/references/AnnotationOnFile.kt @@ -2,4 +2,4 @@ package foo -// REF: (kotlin).deprecated +// REF: (in kotlin.deprecated).deprecated(kotlin.String,kotlin.ReplaceWith) diff --git a/idea/testData/resolve/references/AnnotationOnFileWithImport.kt b/idea/testData/resolve/references/AnnotationOnFileWithImport.kt index ede65b752fd..baa50f587f0 100644 --- a/idea/testData/resolve/references/AnnotationOnFileWithImport.kt +++ b/idea/testData/resolve/references/AnnotationOnFileWithImport.kt @@ -4,4 +4,4 @@ package foo import kotlin.deprecated as D -// REF: (kotlin).deprecated +// REF: (in kotlin.deprecated).deprecated(kotlin.String,kotlin.ReplaceWith) diff --git a/idea/testData/resolve/references/CtrlClickResolve.kt b/idea/testData/resolve/references/CtrlClickResolve.kt index 3b1c40e2f43..4ab934eb009 100644 --- a/idea/testData/resolve/references/CtrlClickResolve.kt +++ b/idea/testData/resolve/references/CtrlClickResolve.kt @@ -7,4 +7,4 @@ fun main(args : Array) { var a = IntArray(array(1, 2, 3)) } -// REF: (kotlin).IntArray \ No newline at end of file +// REF: (in kotlin.IntArray).IntArray(Int) \ No newline at end of file diff --git a/idea/testData/resolve/references/FakeJavaLang1.kt b/idea/testData/resolve/references/FakeJavaLang1.kt index 233d4462a0d..6cae25b222e 100644 --- a/idea/testData/resolve/references/FakeJavaLang1.kt +++ b/idea/testData/resolve/references/FakeJavaLang1.kt @@ -4,4 +4,4 @@ fun foo() { Fake() } -//REF: (java.lang).Fake \ No newline at end of file +//REF: (in java.lang.Fake).Fake() \ No newline at end of file diff --git a/idea/testData/resolve/references/FakeJavaLang3.kt b/idea/testData/resolve/references/FakeJavaLang3.kt index 31fb60de84a..989d6d10f55 100644 --- a/idea/testData/resolve/references/FakeJavaLang3.kt +++ b/idea/testData/resolve/references/FakeJavaLang3.kt @@ -5,4 +5,4 @@ fun foo() { Fake() } -//REF: (java.lang).Fake \ No newline at end of file +//REF: (in java.lang.Fake).Fake() \ No newline at end of file