Class is an annotation iff it is annotated by kotlin.annotation.annotation, or is kotlin.annotation.annotation itself.
JetClassOrObject.isAnnotation() is no more in use during resolve. Additional test.
This commit is contained in:
@@ -656,9 +656,14 @@ public class JetFlowInformationProvider {
|
||||
else if (element instanceof JetParameter) {
|
||||
PsiElement owner = element.getParent().getParent();
|
||||
if (owner instanceof JetPrimaryConstructor) {
|
||||
if (!((JetParameter) element).hasValOrVar() &&
|
||||
!((JetPrimaryConstructor) owner).getContainingClassOrObject().isAnnotation()) {
|
||||
report(Errors.UNUSED_PARAMETER.on((JetParameter) element, variableDescriptor), ctxt);
|
||||
if (!((JetParameter) element).hasValOrVar()) {
|
||||
JetClassOrObject containingClass = ((JetPrimaryConstructor) owner).getContainingClassOrObject();
|
||||
DeclarationDescriptor containingClassDescriptor = trace.get(
|
||||
BindingContext.DECLARATION_TO_DESCRIPTOR, containingClass
|
||||
);
|
||||
if (!DescriptorUtils.isAnnotationClass(containingClassDescriptor)) {
|
||||
report(Errors.UNUSED_PARAMETER.on((JetParameter) element, variableDescriptor), ctxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (owner instanceof JetFunction) {
|
||||
|
||||
@@ -108,7 +108,7 @@ abstract public class JetClassOrObject : JetTypeParameterListOwnerStub<KotlinCla
|
||||
|
||||
public fun getSecondaryConstructors(): List<JetSecondaryConstructor> = getBody()?.getSecondaryConstructors().orEmpty()
|
||||
|
||||
deprecated(value = "It's no more possible to determine it exactly using AST. Use ClassDescriptor methods instead, e.g. getKind()")
|
||||
deprecated(value = "It's no more possible to determine it exactly using AST. Use ClassDescriptor.getKind() instead")
|
||||
public fun isAnnotation(): Boolean = getBuiltInAnnotationEntry() != null
|
||||
|
||||
public fun getBuiltInAnnotationEntry(): JetAnnotationEntry? = getAnnotation(KotlinBuiltIns.FQ_NAMES.annotation.shortName().asString())
|
||||
|
||||
@@ -170,16 +170,6 @@ public class ModifiersChecker {
|
||||
return modifierList != null && modifierList.hasModifier(INNER_KEYWORD);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Visibility getDefaultClassVisibility(@NotNull ClassDescriptor descriptor) {
|
||||
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) {
|
||||
// should be be accessible where containing class is accessible by default
|
||||
return Visibilities.PUBLIC;
|
||||
}
|
||||
return Visibilities.INTERNAL;
|
||||
}
|
||||
|
||||
|
||||
public class ModifiersCheckingProcedure {
|
||||
|
||||
@NotNull
|
||||
|
||||
+5
-3
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
||||
@@ -226,7 +227,7 @@ public class CallExpressionResolver {
|
||||
if (functionDescriptor instanceof ConstructorDescriptor) {
|
||||
DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
|
||||
if (DescriptorUtils.isAnnotationClass(containingDescriptor)
|
||||
&& !canInstantiateAnnotationClass(callExpression)) {
|
||||
&& !canInstantiateAnnotationClass(callExpression, context.trace)) {
|
||||
context.trace.report(ANNOTATION_CLASS_CONSTRUCTOR_CALL.on(callExpression));
|
||||
}
|
||||
if (DescriptorUtils.isEnumClass(containingDescriptor)) {
|
||||
@@ -273,7 +274,7 @@ public class CallExpressionResolver {
|
||||
return TypeInfoFactoryPackage.noTypeInfo(context);
|
||||
}
|
||||
|
||||
private static boolean canInstantiateAnnotationClass(@NotNull JetCallExpression expression) {
|
||||
private static boolean canInstantiateAnnotationClass(@NotNull JetCallExpression expression, @NotNull BindingTrace trace) {
|
||||
//noinspection unchecked
|
||||
PsiElement parent = PsiTreeUtil.getParentOfType(expression, JetValueArgument.class, JetParameter.class);
|
||||
if (parent instanceof JetValueArgument) {
|
||||
@@ -282,7 +283,8 @@ public class CallExpressionResolver {
|
||||
else if (parent instanceof JetParameter) {
|
||||
JetClass jetClass = PsiTreeUtil.getParentOfType(parent, JetClass.class);
|
||||
if (jetClass != null) {
|
||||
return jetClass.isAnnotation();
|
||||
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, jetClass);
|
||||
return DescriptorUtils.isAnnotationClass(descriptor);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -37,9 +37,6 @@ public class JetClassInfo extends JetClassOrObjectInfo<JetClass> {
|
||||
else if (element.isEnum()) {
|
||||
this.kind = ClassKind.ENUM_CLASS;
|
||||
}
|
||||
else if (element.isAnnotation()) {
|
||||
this.kind = ClassKind.ANNOTATION_CLASS;
|
||||
}
|
||||
else {
|
||||
this.kind = ClassKind.CLASS;
|
||||
}
|
||||
|
||||
+30
-10
@@ -78,8 +78,8 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
private final LazyClassTypeConstructor typeConstructor;
|
||||
private final Modality modality;
|
||||
private final Visibility visibility;
|
||||
private final ClassKind kind;
|
||||
private final boolean isInner;
|
||||
private final NotNullLazyValue<ClassKind> kind;
|
||||
private final NotNullLazyValue<Boolean> isInner;
|
||||
|
||||
private final Annotations annotations;
|
||||
private final Annotations danglingAnnotations;
|
||||
@@ -119,24 +119,44 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
|
||||
this.typeConstructor = new LazyClassTypeConstructor();
|
||||
|
||||
this.kind = classLikeInfo.getClassKind();
|
||||
final ClassKind syntaxKind = classLikeInfo.getClassKind();
|
||||
this.isCompanionObject = classLikeInfo instanceof JetObjectInfo && ((JetObjectInfo) classLikeInfo).isCompanionObject();
|
||||
|
||||
JetModifierList modifierList = classLikeInfo.getModifierList();
|
||||
if (kind.isSingleton()) {
|
||||
final JetModifierList modifierList = classLikeInfo.getModifierList();
|
||||
if (syntaxKind.isSingleton()) {
|
||||
this.modality = Modality.FINAL;
|
||||
}
|
||||
else {
|
||||
Modality defaultModality = kind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL;
|
||||
Modality defaultModality = syntaxKind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL;
|
||||
this.modality = resolveModalityFromModifiers(modifierList, defaultModality);
|
||||
}
|
||||
|
||||
boolean isLocal = classOrObject != null && JetPsiUtil.isLocal(classOrObject);
|
||||
this.visibility = isLocal ? Visibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this));
|
||||
this.isInner = isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(this);
|
||||
Visibility defaultVisibility;
|
||||
if (syntaxKind == ClassKind.ENUM_ENTRY || (syntaxKind == ClassKind.OBJECT && isCompanionObject)) {
|
||||
defaultVisibility = Visibilities.PUBLIC;
|
||||
}
|
||||
else {
|
||||
defaultVisibility = Visibilities.INTERNAL;
|
||||
}
|
||||
this.visibility = isLocal ? Visibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, defaultVisibility);
|
||||
|
||||
StorageManager storageManager = c.getStorageManager();
|
||||
final ClassDescriptor descriptor = this;
|
||||
|
||||
this.isInner = storageManager.createLazyValue(new Function0<Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke() {
|
||||
return isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(descriptor);
|
||||
}
|
||||
});
|
||||
|
||||
this.kind = storageManager.createLazyValue(new Function0<ClassKind>() {
|
||||
@Override
|
||||
public ClassKind invoke() {
|
||||
return (syntaxKind == ClassKind.CLASS && KotlinBuiltIns.isAnnotation(descriptor)) ? ClassKind.ANNOTATION_CLASS : syntaxKind;
|
||||
}
|
||||
});
|
||||
|
||||
if (modifierList != null) {
|
||||
this.annotations = new LazyAnnotations(
|
||||
@@ -386,7 +406,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassKind getKind() {
|
||||
return kind;
|
||||
return kind.invoke();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -403,7 +423,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
|
||||
@Override
|
||||
public boolean isInner() {
|
||||
return isInner;
|
||||
return isInner.invoke();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: a.kt
|
||||
|
||||
<!NOT_AN_ANNOTATION_CLASS!>annotation<!> class annotation
|
||||
|
||||
// FILE: test/b.kt
|
||||
|
||||
package test
|
||||
|
||||
<!NOT_AN_ANNOTATION_CLASS!>test.annotation<!> class annotation
|
||||
|
||||
kotlin.annotation.annotation class realAnnotation
|
||||
|
||||
realAnnotation class My
|
||||
|
||||
// FILE: other/c.kt
|
||||
|
||||
package other
|
||||
|
||||
annotation class My
|
||||
|
||||
<!NOT_AN_ANNOTATION_CLASS!>test.annotation<!> class Your
|
||||
|
||||
kotlin.annotation.annotation class His
|
||||
|
||||
My class Our
|
||||
@@ -0,0 +1,63 @@
|
||||
package
|
||||
|
||||
annotation() internal final class annotation {
|
||||
public constructor annotation()
|
||||
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
|
||||
}
|
||||
|
||||
package other {
|
||||
|
||||
kotlin.annotation.annotation() internal final class His : kotlin.Annotation {
|
||||
public constructor His()
|
||||
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
|
||||
}
|
||||
|
||||
kotlin.annotation.annotation() internal final class My : kotlin.Annotation {
|
||||
public constructor My()
|
||||
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
|
||||
}
|
||||
|
||||
other.My() internal final class Our {
|
||||
public constructor Our()
|
||||
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
|
||||
}
|
||||
|
||||
test.annotation() internal final class Your {
|
||||
public constructor Your()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
package test {
|
||||
|
||||
test.realAnnotation() internal final class My {
|
||||
public constructor My()
|
||||
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
|
||||
}
|
||||
|
||||
test.annotation() internal final class annotation {
|
||||
public constructor annotation()
|
||||
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
|
||||
}
|
||||
|
||||
kotlin.annotation.annotation() internal final class realAnnotation : kotlin.Annotation {
|
||||
public constructor realAnnotation()
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,13 @@ enum class Target {
|
||||
FUNCTION
|
||||
}
|
||||
|
||||
target(Target.CLASSIFIER)
|
||||
public annotation class target(vararg val allowedTargets: Target)
|
||||
<!NOT_AN_ANNOTATION_CLASS!>target(Target.CLASSIFIER)<!>
|
||||
public <!NOT_AN_ANNOTATION_CLASS!>annotation<!> class target(vararg val allowedTargets: Target)
|
||||
|
||||
target(Target.CLASSIFIER)
|
||||
public annotation(AnnotationRetention.SOURCE) class annotation(
|
||||
<!NOT_AN_ANNOTATION_CLASS!>target(Target.CLASSIFIER)<!>
|
||||
public <!NOT_AN_ANNOTATION_CLASS!>annotation(AnnotationRetention.SOURCE)<!> class annotation(
|
||||
val retention: AnnotationRetention = AnnotationRetention.RUNTIME,
|
||||
val repeatable: Boolean = false
|
||||
)
|
||||
|
||||
annotation class some
|
||||
|
||||
<!NOT_AN_ANNOTATION_CLASS!>annotation<!> class some
|
||||
@@ -34,7 +34,7 @@ internal final enum class Target : kotlin.Enum<Target> {
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Target>
|
||||
}
|
||||
|
||||
target(allowedTargets = {Target.CLASSIFIER}) annotation(retention = AnnotationRetention.SOURCE) public final class annotation : kotlin.Annotation {
|
||||
target(allowedTargets = {Target.CLASSIFIER}) annotation(retention = AnnotationRetention.SOURCE) public final class annotation {
|
||||
public constructor annotation(/*0*/ retention: kotlin.annotation.AnnotationRetention = ..., /*1*/ repeatable: kotlin.Boolean = ...)
|
||||
internal final val repeatable: kotlin.Boolean
|
||||
internal final val retention: kotlin.annotation.AnnotationRetention
|
||||
@@ -43,14 +43,14 @@ target(allowedTargets = {Target.CLASSIFIER}) annotation(retention = AnnotationRe
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
annotation() internal final class some : kotlin.Annotation {
|
||||
annotation() internal final class some {
|
||||
public constructor some()
|
||||
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
|
||||
}
|
||||
|
||||
target(allowedTargets = {Target.CLASSIFIER}) annotation() public final class target : kotlin.Annotation {
|
||||
target(allowedTargets = {Target.CLASSIFIER}) annotation() public final class target {
|
||||
public constructor target(/*0*/ vararg allowedTargets: Target /*kotlin.Array<out Target>*/)
|
||||
internal final val allowedTargets: kotlin.Array<out Target>
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
|
||||
@@ -669,6 +669,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationIdentifier.kt")
|
||||
public void testAnnotationIdentifier() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationInheritance.kt")
|
||||
public void testAnnotationInheritance() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/annotationInheritance.kt");
|
||||
|
||||
@@ -997,6 +997,11 @@ public class KotlinBuiltIns {
|
||||
return FQ_NAMES.array.equals(getFqName(descriptor));
|
||||
}
|
||||
|
||||
public static boolean isAnnotation(@NotNull ClassDescriptor descriptor) {
|
||||
return DescriptorUtils.getFqName(descriptor) == FQ_NAMES.annotation.toUnsafe()
|
||||
|| containsAnnotation(descriptor, FQ_NAMES.annotation);
|
||||
}
|
||||
|
||||
public static boolean isCloneable(@NotNull ClassDescriptor descriptor) {
|
||||
return FQ_NAMES.cloneable.equals(getFqName(descriptor));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user