Report special diagnostic on inlineUsage with LOCAL_CONTINUE_AND_BREAK

Such usages should be removed by quckfixes
This commit is contained in:
Denis Zharkov
2015-09-09 17:28:46 +03:00
parent 04483eb826
commit 7b3303c152
5 changed files with 26 additions and 3 deletions
@@ -143,7 +143,7 @@ public interface Errors {
DiagnosticFactory0<JetAnnotationEntry> DEPRECATED_UNESCAPED_ANNOTATION = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> DEPRECATED_ESCAPED_MODIFIER = DiagnosticFactory0.create(WARNING);
DiagnosticFactory1<JetAnnotationEntry, String> DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER = DiagnosticFactory1.create(WARNING);
DiagnosticFactory0<JetAnnotationEntry> DEPRECATED_ANNOTATION_USE = DiagnosticFactory0.create(WARNING);
// Classes and traits
@@ -134,7 +134,8 @@ public class DefaultErrorMessages {
MAP.put(DEPRECATED_UNESCAPED_ANNOTATION, "Annotations without '@' are deprecated now");
MAP.put(DEPRECATED_ESCAPED_MODIFIER, "Modifiers with '@' are deprecated now");
MAP.put(DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER, "Annotation ''{0}'' will become a modifier soon. Do not use ''@'' before it", STRING);
MAP.put(DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER, "This annotation will become a modifier soon. Use ''{0}'' modifier instead", STRING);
MAP.put(DEPRECATED_ANNOTATION_USE, "This annotation use is deprecated");
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
MAP.put(ABSTRACT_MODIFIER_IN_TRAIT, "Modifier ''abstract'' is redundant in interface");
@@ -71,7 +71,12 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: continue
if (classDescriptor.fqNameSafe in ANNOTATIONS_SHOULD_BE_REPLACED_WITH_MODIFIERS_FQ_NAMES) {
trace.report(Errors.DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER.on(entry, ANNOTATION_MODIFIERS_MAP[classDescriptor.fqNameSafe]!!))
if (descriptor.isInlineOptionsWithLocalBreaks()) {
trace.report(Errors.DEPRECATED_ANNOTATION_USE.on(entry))
}
else {
trace.report(Errors.DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER.on(entry, ANNOTATION_MODIFIERS_MAP[classDescriptor.fqNameSafe]!!))
}
}
else {
if (!entry.hasAtSymbolOrInList()) {
@@ -93,6 +98,21 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
additionalCheckers.forEach { it.checkEntries(entries, actualTargets.defaultTargets, trace) }
}
private fun AnnotationDescriptor.isInlineOptionsWithLocalBreaks(): Boolean {
val descriptor = type.constructor.declarationDescriptor
if (descriptor !is ClassDescriptor) return false
if (descriptor.fqNameSafe == KotlinBuiltIns.FQ_NAMES.inlineOptions) {
val vararg = (allValueArguments.values().firstOrNull() as? ArrayValue)?.value ?: return false
return vararg.all {
arg ->
val enumValue = (arg as? EnumValue) ?: return false
return enumValue.value.name.asString() == InlineOption.LOCAL_CONTINUE_AND_BREAK.name()
}
}
return false
}
private fun checkAnnotationEntry(entry: JetAnnotationEntry, actualTargets: TargetList, trace: BindingTrace) {
val applicableTargets = applicableTargetSet(entry, trace)
val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget()
@@ -29,3 +29,4 @@ fun bar2(): Array<Q> = null!!
<!DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER!>@tailRecursive<!> fun tailFun(): Int = tailFun()
inline fun inlineFun(<!DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER!>@inlineOptions(InlineOption.ONLY_LOCAL_RETURN)<!> block: () -> Int) {}
inline fun inlineFun2(<!DEPRECATED_ANNOTATION_USE!>@inlineOptions(InlineOption.LOCAL_CONTINUE_AND_BREAK)<!> block: () -> Int) {}
@@ -4,6 +4,7 @@ kotlin.inline() private fun bar(/*0*/ block: () -> kotlin.Int): kotlin.Int
public fun bar2(): kotlin.Array<Q>
kotlin.inline() public fun baz(): kotlin.Unit
kotlin.inline() public fun inlineFun(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) block: () -> kotlin.Int): kotlin.Unit
kotlin.inline() public fun inlineFun2(/*0*/ kotlin.inlineOptions(value = {InlineOption.LOCAL_CONTINUE_AND_BREAK}) block: () -> kotlin.Int): kotlin.Unit
kotlin.external() public fun nativeFun(): kotlin.Int
kotlin.tailRecursive() public fun tailFun(): kotlin.Int