Annotation / modifier checking for setter parameters / for variables / multi declarations, tests, relevant test changes #KT-9145 Fixed
This commit is contained in:
@@ -40,7 +40,8 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
annotated.typeReference?.let { check(it, trace) }
|
||||
annotated.receiverTypeReference?.let { check(it, trace) }
|
||||
}
|
||||
if (annotated is JetFunction) {
|
||||
if (annotated is JetDeclarationWithBody) {
|
||||
// JetFunction or JetPropertyAccessor
|
||||
for (parameter in annotated.valueParameters) {
|
||||
if (!parameter.hasValOrVar()) {
|
||||
check(parameter, trace)
|
||||
@@ -168,6 +169,7 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
private fun getActualTargetList(annotated: JetElement, descriptor: ClassDescriptor?): TargetList {
|
||||
return when (annotated) {
|
||||
is JetClassOrObject -> descriptor?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: TargetLists.T_CLASSIFIER
|
||||
is JetMultiDeclarationEntry -> TargetLists.T_LOCAL_VARIABLE
|
||||
is JetProperty -> {
|
||||
if (annotated.isLocal)
|
||||
TargetLists.T_LOCAL_VARIABLE
|
||||
|
||||
@@ -194,6 +194,15 @@ public class ModifiersChecker {
|
||||
ModifierCheckerCore.INSTANCE$.check(modifierListOwner, trace, descriptor);
|
||||
}
|
||||
|
||||
public void checkModifiersForMultiDeclaration(@NotNull JetMultiDeclaration multiDeclaration) {
|
||||
annotationChecker.check(multiDeclaration, trace, null);
|
||||
ModifierCheckerCore.INSTANCE$.check(multiDeclaration, trace, null);
|
||||
for (JetMultiDeclarationEntry multiEntry: multiDeclaration.getEntries()) {
|
||||
annotationChecker.check(multiEntry, trace, null);
|
||||
ModifierCheckerCore.INSTANCE$.check(multiEntry, trace, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNestedClassAllowed(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
||||
if (modifierListOwner.hasModifier(INNER_KEYWORD)) return;
|
||||
if (modifierListOwner instanceof JetClass && !(modifierListOwner instanceof JetEnumEntry)) {
|
||||
|
||||
@@ -212,7 +212,8 @@ public object ModifierCheckerCore {
|
||||
}
|
||||
|
||||
public fun check(listOwner: JetModifierListOwner, trace: BindingTrace, descriptor: DeclarationDescriptor?) {
|
||||
if (listOwner is JetFunction) {
|
||||
if (listOwner is JetDeclarationWithBody) {
|
||||
// JetFunction or JetPropertyAccessor
|
||||
for (parameter in listOwner.valueParameters) {
|
||||
if (!parameter.hasValOrVar()) {
|
||||
check(parameter, trace, null)
|
||||
|
||||
+2
@@ -392,6 +392,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetParameter loopParameter = expression.getLoopParameter();
|
||||
if (loopParameter != null) {
|
||||
VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(loopParameter, variableDescriptor);
|
||||
|
||||
loopScope.addVariableDescriptor(variableDescriptor);
|
||||
}
|
||||
@@ -404,6 +405,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
components.multiDeclarationResolver.defineLocalVariablesFromMultiDeclaration(
|
||||
loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
|
||||
);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForMultiDeclaration(multiParameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -185,6 +185,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
return TypeInfoFactoryPackage.noTypeInfo(context);
|
||||
}
|
||||
components.multiDeclarationResolver.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForMultiDeclaration(multiDeclaration);
|
||||
return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(multiDeclaration, context));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
annotation class My
|
||||
|
||||
fun foo() {
|
||||
|
||||
@@ -2,7 +2,7 @@ package
|
||||
|
||||
public fun foo(): kotlin.Unit
|
||||
|
||||
kotlin.annotation.annotation() public final class My : kotlin.Annotation {
|
||||
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) kotlin.annotation.annotation() public 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
|
||||
|
||||
+4
-4
@@ -5,10 +5,10 @@ data class A(val x: Int, val y: Int)
|
||||
fun bar(): Array<A> = null!!
|
||||
|
||||
fun foo() {
|
||||
for (Ann(1) i in 1..100) {}
|
||||
for (Ann(2) i in 1..100) {}
|
||||
for (@Ann(1) i in 1..100) {}
|
||||
for (@Ann(2) i in 1..100) {}
|
||||
|
||||
for (Ann(3) (x, @Ann(4) y) in bar()) {}
|
||||
for (<!WRONG_ANNOTATION_TARGET!>@Ann(3)<!> (x, @Ann(4) y) in bar()) {}
|
||||
|
||||
for (<!UNRESOLVED_REFERENCE!>Err<!> (x,y) in bar()) {}
|
||||
for (<!UNRESOLVED_REFERENCE, WRONG_ANNOTATION_TARGET, DEPRECATED_UNESCAPED_ANNOTATION!>Err<!> (x,y) in bar()) {}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fun foo(<!UNRESOLVED_REFERENCE, DEPRECATED_UNESCAPED_ANNOTATION!>varargs<!> <!UNUSED_PARAMETER!>f<!> : Int) {}
|
||||
|
||||
var bar : Int = 1
|
||||
set(<!UNRESOLVED_REFERENCE!>varargs<!> v) {}
|
||||
set(<!UNRESOLVED_REFERENCE, DEPRECATED_UNESCAPED_ANNOTATION!>varargs<!> v) {}
|
||||
|
||||
val x : (Int) -> Int = {<!UNRESOLVED_REFERENCE!>@varargs<!> <!TYPE_MISMATCH!>x<!> <!DEPRECATED_STATIC_ASSERT!>: Int<!> <!SYNTAX!>-> x<!>}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ annotation class test
|
||||
fun foo(@test <!UNUSED_PARAMETER!>f<!> : Int) {}
|
||||
|
||||
var bar : Int = 1
|
||||
set(test v) {}
|
||||
set(@test v) {}
|
||||
|
||||
val x : (Int) -> Int = {@test <!TYPE_MISMATCH!>x<!> <!DEPRECATED_STATIC_ASSERT!>: Int<!> <!SYNTAX!>-> x<!>} // todo fix parser annotation on lambda parameter
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun test(): Any? {
|
||||
@ann val (a, b) = P(1, 1)
|
||||
<!WRONG_ANNOTATION_TARGET!>@ann<!> val (a, b) = P(1, 1)
|
||||
return a + b
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// See KT-9145
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class Ann
|
||||
|
||||
fun foo() {
|
||||
for (<!WRONG_ANNOTATION_TARGET!>@Ann<!> <!WRONG_MODIFIER_TARGET!>private<!> x in 1..100) {
|
||||
if (x == 1) return
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
public fun foo(): kotlin.Unit
|
||||
|
||||
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS}) kotlin.annotation.annotation() public final class Ann : kotlin.Annotation {
|
||||
public constructor Ann()
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class My
|
||||
data class Pair(val a: Int, val b: Int)
|
||||
fun foo(): Int {
|
||||
val (<!WRONG_ANNOTATION_TARGET!>@My<!> <!WRONG_MODIFIER_TARGET!>private<!> a, <!WRONG_ANNOTATION_TARGET!>@My<!> <!WRONG_MODIFIER_TARGET!>public<!> b) = Pair(12, 34)
|
||||
return a + b
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package
|
||||
|
||||
public fun foo(): kotlin.Int
|
||||
|
||||
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS}) kotlin.annotation.annotation() public 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
|
||||
}
|
||||
|
||||
kotlin.data() public final class Pair {
|
||||
public constructor Pair(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int)
|
||||
public final val a: kotlin.Int
|
||||
public final val b: kotlin.Int
|
||||
public final /*synthesized*/ fun component1(): kotlin.Int
|
||||
public final /*synthesized*/ fun component2(): kotlin.Int
|
||||
public final /*synthesized*/ fun copy(/*0*/ a: kotlin.Int = ..., /*1*/ b: kotlin.Int = ...): Pair
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// KT-9145
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class Ann
|
||||
|
||||
var x: Int
|
||||
get() = 1
|
||||
set(<!WRONG_ANNOTATION_TARGET!>@Ann<!> <!WRONG_MODIFIER_TARGET!>private<!> x) { }
|
||||
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
public var x: kotlin.Int
|
||||
|
||||
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS}) kotlin.annotation.annotation() public final class Ann : kotlin.Annotation {
|
||||
public constructor Ann()
|
||||
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
|
||||
}
|
||||
@@ -1043,6 +1043,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forParam.kt")
|
||||
public void testForParam() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/forParam.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("javaDocumented.kt")
|
||||
public void testJavaDocumented() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/javaDocumented.kt");
|
||||
@@ -1061,6 +1067,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multiDeclaration.kt")
|
||||
public void testMultiDeclaration() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/multiDeclaration.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("repeatable.kt")
|
||||
public void testRepeatable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/repeatable.kt");
|
||||
@@ -1073,6 +1085,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("setterParam.kt")
|
||||
public void testSetterParam() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/setterParam.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("target.kt")
|
||||
public void testTarget() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/target.kt");
|
||||
|
||||
+1
-2
@@ -215,8 +215,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
if (completionKind != CompletionKind.NAMED_ARGUMENTS_ONLY) {
|
||||
if (smartCompletion != null) {
|
||||
@suppress("UNUSED_VARIABLE") // we don't use InheritanceSearcher
|
||||
val (additionalItems, inheritanceSearcher) = smartCompletion.additionalItems()
|
||||
val (additionalItems, @Suppress("UNUSED_VARIABLE") inheritanceSearcher) = smartCompletion.additionalItems()
|
||||
|
||||
// all additional items should have SMART_COMPLETION_ITEM_PRIORITY_KEY to be recognized by SmartCompletionInBasicWeigher
|
||||
for (item in additionalItems) {
|
||||
|
||||
Reference in New Issue
Block a user