Fixed visibility checks for annotation usage on top-level declarations
#KT-12429 Fixed
This commit is contained in:
+30
-7
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,15 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.lazy.descriptors
|
package org.jetbrains.kotlin.resolve.lazy.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationUseSiteTarget
|
|
||||||
import org.jetbrains.kotlin.resolve.AnnotationResolver
|
import org.jetbrains.kotlin.resolve.AnnotationResolver
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
@@ -35,6 +33,7 @@ import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
|
||||||
abstract class LazyAnnotationsContext(
|
abstract class LazyAnnotationsContext(
|
||||||
val annotationResolver: AnnotationResolver,
|
val annotationResolver: AnnotationResolver,
|
||||||
@@ -120,7 +119,7 @@ class LazyAnnotationDescriptor(
|
|||||||
|
|
||||||
private val type = c.storageManager.createLazyValue {
|
private val type = c.storageManager.createLazyValue {
|
||||||
c.annotationResolver.resolveAnnotationType(
|
c.annotationResolver.resolveAnnotationType(
|
||||||
c.scope,
|
scope,
|
||||||
annotationEntry,
|
annotationEntry,
|
||||||
c.trace
|
c.trace
|
||||||
)
|
)
|
||||||
@@ -132,12 +131,18 @@ class LazyAnnotationDescriptor(
|
|||||||
|
|
||||||
private val source = annotationEntry.toSourceElement()
|
private val source = annotationEntry.toSourceElement()
|
||||||
|
|
||||||
|
val scope = if (c.scope.ownerDescriptor is PackageFragmentDescriptor) {
|
||||||
|
LexicalScope.Companion.empty(c.scope, FileDescriptorForVisibilityChecks(source, c.scope.ownerDescriptor))
|
||||||
|
} else {
|
||||||
|
c.scope
|
||||||
|
}
|
||||||
|
|
||||||
override fun getType() = type()
|
override fun getType() = type()
|
||||||
|
|
||||||
override fun getAllValueArguments() = valueArguments()
|
override fun getAllValueArguments() = valueArguments()
|
||||||
|
|
||||||
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
|
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
|
||||||
val resolutionResults = c.annotationResolver.resolveAnnotationCall(annotationEntry, c.scope, c.trace)
|
val resolutionResults = c.annotationResolver.resolveAnnotationCall(annotationEntry, scope, c.trace)
|
||||||
AnnotationResolver.checkAnnotationType(annotationEntry, c.trace, resolutionResults)
|
AnnotationResolver.checkAnnotationType(annotationEntry, c.trace, resolutionResults)
|
||||||
|
|
||||||
if (!resolutionResults.isSingleResult) return mapOf()
|
if (!resolutionResults.isSingleResult) return mapOf()
|
||||||
@@ -157,4 +162,22 @@ class LazyAnnotationDescriptor(
|
|||||||
ForceResolveUtil.forceResolveAllContents(getType())
|
ForceResolveUtil.forceResolveAllContents(getType())
|
||||||
allValueArguments
|
allValueArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class FileDescriptorForVisibilityChecks(
|
||||||
|
private val source: SourceElement,
|
||||||
|
private val containingDeclaration: DeclarationDescriptor
|
||||||
|
) : DeclarationDescriptorWithSource {
|
||||||
|
override val annotations: Annotations get() = Annotations.EMPTY
|
||||||
|
override fun getContainingDeclaration() = containingDeclaration
|
||||||
|
override fun getSource() = source
|
||||||
|
override fun getOriginal() = this
|
||||||
|
override fun getName() = Name.special("< file descriptor for annotation resolution >")
|
||||||
|
|
||||||
|
private fun error(): Nothing = error("This method should not be called")
|
||||||
|
override fun substitute(substitutor: TypeSubstitutor): DeclarationDescriptor? = error()
|
||||||
|
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R = error()
|
||||||
|
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) = error()
|
||||||
|
|
||||||
|
override fun toString(): String = "${name.asString()} declared in LazyAnnotations.kt"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
private const val a = ""
|
||||||
|
|
||||||
|
@Deprecated("$a")
|
||||||
|
fun test() {}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
private const val a: kotlin.String = ""
|
||||||
|
@kotlin.Deprecated(message = "") public fun test(): kotlin.Unit
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// FILE: 1.kt
|
||||||
|
package pp
|
||||||
|
|
||||||
|
private annotation class A(val s: String)
|
||||||
|
private const val foo = "O"
|
||||||
|
|
||||||
|
@A(foo)
|
||||||
|
fun f1() {}
|
||||||
|
|
||||||
|
@A(foo)
|
||||||
|
val p1 = ""
|
||||||
|
|
||||||
|
@A(foo)
|
||||||
|
class C1
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: 2.kt
|
||||||
|
package pp
|
||||||
|
|
||||||
|
@<!INVISIBLE_REFERENCE, INVISIBLE_MEMBER!>A<!>(<!INVISIBLE_MEMBER!>foo<!>)
|
||||||
|
fun f2() {}
|
||||||
|
|
||||||
|
@<!INVISIBLE_REFERENCE, INVISIBLE_MEMBER!>A<!>(<!INVISIBLE_MEMBER!>foo<!>)
|
||||||
|
val p2 = ""
|
||||||
|
|
||||||
|
@<!INVISIBLE_REFERENCE, INVISIBLE_MEMBER!>A<!>(<!INVISIBLE_MEMBER!>foo<!>)
|
||||||
|
class C2
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
package pp {
|
||||||
|
private const val foo: kotlin.String = "O"
|
||||||
|
@pp.A(s = "O") public val p1: kotlin.String = ""
|
||||||
|
@pp.A(s = "O") public val p2: kotlin.String = ""
|
||||||
|
@pp.A(s = "O") public fun f1(): kotlin.Unit
|
||||||
|
@pp.A(s = "O") public fun f2(): kotlin.Unit
|
||||||
|
|
||||||
|
private final annotation class A : kotlin.Annotation {
|
||||||
|
public constructor A(/*0*/ s: kotlin.String)
|
||||||
|
public final val s: kotlin.String
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
@pp.A(s = "O") public final class C1 {
|
||||||
|
public constructor C1()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
@pp.A(s = "O") public final class C2 {
|
||||||
|
public constructor C2()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13257,6 +13257,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/privateInFile"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/privateInFile"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt12429.kt")
|
||||||
|
public void testKt12429() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/privateInFile/kt12429.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelAnnotationCall.kt")
|
||||||
|
public void testTopLevelAnnotationCall() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/privateInFile/topLevelAnnotationCall.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("visibility.kt")
|
@TestMetadata("visibility.kt")
|
||||||
public void testVisibility() throws Exception {
|
public void testVisibility() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/privateInFile/visibility.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/privateInFile/visibility.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user