From e8dc9ede31a0588c3620d8dd2c9808f44511a149 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 28 Aug 2015 20:18:32 +0300 Subject: [PATCH] Implemented HiddenDeclaration annotation (doc-comment to be added!) --- .../kotlin/resolve/calls/CallResolver.java | 2 + compiler/testData/builtin-classes.txt | 4 + .../tests/resolve/HiddenDeclarations.kt | 74 +++++++++++++++++++ .../tests/resolve/HiddenDeclarations.txt | 62 ++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 6 ++ core/builtins/src/kotlin/Annotations.kt | 7 ++ .../kotlin/resolve/DescriptorUtils.kt | 5 ++ .../codeInsight/ReferenceVariantsHelper.kt | 3 +- .../HiddenDeclarations.dependency.kt | 14 ++++ .../HiddenDeclarations/HiddenDeclarations.kt | 16 ++++ ...tiFileJvmBasicCompletionTestGenerated.java | 6 ++ .../kotlin/idea/core/KotlinIndicesHelper.kt | 12 +-- 12 files changed, 205 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.txt create mode 100644 idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.dependency.kt create mode 100644 idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index 569ef8ecb5d..cf130bd7674 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -610,6 +610,8 @@ public class CallResolver { ) { final List> candidateResolutionContexts = ContainerUtil.newArrayList(); for (final ResolutionCandidate resolutionCandidate : task.getCandidates()) { + if (DescriptorUtilPackage.isAnnotatedAsHidden(resolutionCandidate.getDescriptor())) continue; + candidatePerfCounter.time(new Function0() { @Override public Unit invoke() { diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index e1670481887..2d90edf8445 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -575,6 +575,10 @@ public interface FloatingPointConstants { public interface Function { } +kotlin.annotation.target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.CONSTRUCTOR}) kotlin.annotation.annotation(mustBeDocumented = true, retention = AnnotationRetention.BINARY) public final class HiddenDeclaration : kotlin.Annotation { + /*primary*/ public constructor HiddenDeclaration() +} + public final enum class InlineOption : kotlin.Enum { enum entry LOCAL_CONTINUE_AND_BREAK diff --git a/compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt b/compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt new file mode 100644 index 00000000000..397e847bab9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt @@ -0,0 +1,74 @@ +package test + +// imports should be resolved +import test.topLevelFun +import test.topLevelProperty + +@HiddenDeclaration +fun topLevelFun(){} + +@HiddenDeclaration +var topLevelProperty = 1 + +@HiddenDeclaration +fun String.topLevelExtensionFun(){} + +@HiddenDeclaration +val String.topLevelExtensionProperty: Int get() = 1 + +open class A { + constructor(p: Int) : this("") {} + + @HiddenDeclaration + constructor(s: String){} + + @HiddenDeclaration + open fun memberFun(){} + + @HiddenDeclaration + val memberProperty = 1 + + @HiddenDeclaration + fun String.memberExtensionFun(){} + + @HiddenDeclaration + val String.memberExtensionProperty: Int get() = 1 + + fun foo() { + topLevelFun() + topLevelProperty++ + "".topLevelExtensionFun() + "".topLevelExtensionProperty + + memberFun() + memberProperty + "".memberExtensionFun() + "".memberExtensionProperty + + A("") + } +} + +interface I { + @HiddenDeclaration + fun foo1() + + @HiddenDeclaration + fun foo2() +} + +class X : I { + override fun foo1() { + } +} + +class B : A("") { + // still can override it + override fun memberFun() { + super.memberFun() // but cannot call super :) + } +} + +class C : A { + constructor() : super("") +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.txt b/compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.txt new file mode 100644 index 00000000000..f1cc78e91a1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.txt @@ -0,0 +1,62 @@ +package + +package test { + kotlin.HiddenDeclaration() internal var topLevelProperty: kotlin.Int + kotlin.HiddenDeclaration() internal val kotlin.String.topLevelExtensionProperty: kotlin.Int + kotlin.HiddenDeclaration() internal fun topLevelFun(): kotlin.Unit + kotlin.HiddenDeclaration() internal fun kotlin.String.topLevelExtensionFun(): kotlin.Unit + + internal open class A { + public constructor A(/*0*/ p: kotlin.Int) + kotlin.HiddenDeclaration() public constructor A(/*0*/ s: kotlin.String) + kotlin.HiddenDeclaration() internal final val memberProperty: kotlin.Int = 1 + kotlin.HiddenDeclaration() internal final val kotlin.String.memberExtensionProperty: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.HiddenDeclaration() internal open fun memberFun(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + kotlin.HiddenDeclaration() internal final fun kotlin.String.memberExtensionFun(): kotlin.Unit + } + + internal final class B : test.A { + public constructor B() + kotlin.HiddenDeclaration() internal final override /*1*/ /*fake_override*/ val memberProperty: kotlin.Int + kotlin.HiddenDeclaration() internal final override /*1*/ /*fake_override*/ val kotlin.String.memberExtensionProperty: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal open override /*1*/ fun memberFun(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + kotlin.HiddenDeclaration() internal final override /*1*/ /*fake_override*/ fun kotlin.String.memberExtensionFun(): kotlin.Unit + } + + internal final class C : test.A { + public constructor C() + kotlin.HiddenDeclaration() internal final override /*1*/ /*fake_override*/ val memberProperty: kotlin.Int + kotlin.HiddenDeclaration() internal final override /*1*/ /*fake_override*/ val kotlin.String.memberExtensionProperty: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.HiddenDeclaration() internal open override /*1*/ /*fake_override*/ fun memberFun(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + kotlin.HiddenDeclaration() internal final override /*1*/ /*fake_override*/ fun kotlin.String.memberExtensionFun(): kotlin.Unit + } + + internal interface I { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + kotlin.HiddenDeclaration() internal abstract fun foo1(): kotlin.Unit + kotlin.HiddenDeclaration() internal abstract fun foo2(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal final class X : test.I { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal open override /*1*/ fun foo1(): kotlin.Unit + kotlin.HiddenDeclaration() internal abstract override /*1*/ /*fake_override*/ fun foo2(): kotlin.Unit + 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 eaff984e570..c9c2137ca6b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -11676,6 +11676,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("HiddenDeclarations.kt") + public void testHiddenDeclarations() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt"); + doTest(fileName); + } + @TestMetadata("incompleteConstructorInvocation.kt") public void testIncompleteConstructorInvocation() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/incompleteConstructorInvocation.kt"); diff --git a/core/builtins/src/kotlin/Annotations.kt b/core/builtins/src/kotlin/Annotations.kt index 789b8aeeb71..184fe717247 100644 --- a/core/builtins/src/kotlin/Annotations.kt +++ b/core/builtins/src/kotlin/Annotations.kt @@ -77,3 +77,10 @@ public annotation(retention = SOURCE) class suppress(vararg val names: String) */ target(FUNCTION) public annotation(retention = SOURCE) class tailRecursive + +/** + * TODO + */ +target(FUNCTION, PROPERTY, CONSTRUCTOR) +annotation(retention = BINARY, mustBeDocumented = true) +public class HiddenDeclaration diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt index a2f43cf7bb5..5c4aa92094f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt @@ -198,3 +198,8 @@ public val DeclarationDescriptor.parentsWithSelf: Sequence get() = parentsWithSelf.drop(1) + +private val HIDDEN_ANNOTATION_FQ_NAME = FqName("kotlin.HiddenDeclaration") /*TODO*/ + +public fun DeclarationDescriptor.isAnnotatedAsHidden(): Boolean = annotations.findAnnotation(HIDDEN_ANNOTATION_FQ_NAME) != null + 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 38448fe55e6..fc75f3b6491 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 @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager +import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotatedAsHidden import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver @@ -75,7 +76,7 @@ public class ReferenceVariantsHelper( ): Collection { var variants: Collection = getReferenceVariantsNoVisibilityFilter(expression, kindFilter, nameFilter, explicitReceiverData, useRuntimeReceiverType) - .filter(visibilityFilter) + .filter { !it.isAnnotatedAsHidden() && visibilityFilter(it) } variants = ShadowedDeclarationsFilter(context, resolutionFacade, expression, explicitReceiverData).filter(variants) diff --git a/idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.dependency.kt b/idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.dependency.kt new file mode 100644 index 00000000000..a24eb5c8577 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.dependency.kt @@ -0,0 +1,14 @@ +package test + +@HiddenDeclaration +fun hiddenFun(){} + +fun notHiddenFun(){} + +@HiddenDeclaration +var hiddenProperty: Int = 1 + +var notHiddenProperty: Int = 1 + +@HiddenDeclaration +val String.hiddenExtension: Int get() = 1 diff --git a/idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.kt b/idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.kt new file mode 100644 index 00000000000..02c5d2a983e --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/HiddenDeclarations/HiddenDeclarations.kt @@ -0,0 +1,16 @@ +package test + +@HiddenDeclaration +fun hiddenFunFromSameFile(){} + +fun String.foo() { + hid +} + +// INVOCATION_COUNT: 2 +// ABSENT: hiddenFun +// ABSENT: hiddenProperty +// ABSENT: hiddenFunFromSameFile +// ABSENT: hiddenExtension +// EXIST: notHiddenFun +// EXIST: notHiddenProperty diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java index dc47865b47f..abf17bb8a8b 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java @@ -125,6 +125,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("HiddenDeclarations") + public void testHiddenDeclarations() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/HiddenDeclarations/"); + doTest(fileName); + } + @TestMetadata("InImportedFunctionLiteralParameter") public void testInImportedFunctionLiteralParameter() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/InImportedFunctionLiteralParameter/"); diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt index 199f9c2a141..9746e4f4083 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager +import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotatedAsHidden import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue @@ -57,11 +58,12 @@ public class KotlinIndicesHelper( private val moduleDescriptor = resolutionFacade.moduleDescriptor private val project = resolutionFacade.project - private val descriptorFilter = - if (applyExcludeSettings) - { d -> visibilityFilter(d) && !isExcludedFromAutoImport(d) } - else - visibilityFilter + private val descriptorFilter: (DeclarationDescriptor) -> Boolean = filter@ { + if (it.isAnnotatedAsHidden()) return@filter false + if (!visibilityFilter(it)) return@filter false + if (applyExcludeSettings && isExcludedFromAutoImport(it)) return@filter false + true + } public fun getTopLevelCallablesByName(name: String): Collection { val declarations = HashSet()