Annotation / modifier checking for setter parameters / for variables / multi declarations, tests, relevant test changes #KT-9145 Fixed

This commit is contained in:
Mikhail Glukhikh
2015-09-14 20:06:08 +03:00
parent f1fcb14f44
commit 22229af930
19 changed files with 112 additions and 12 deletions
@@ -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)
@@ -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);
}
}
@@ -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
@@ -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");
@@ -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) {