diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java index 15f5186a4c0..79750722ffa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java @@ -47,4 +47,13 @@ public class JetAnnotation extends JetElementImplStub 1) { + entry.delete(); + } + else { + delete(); + } + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt index 5938ecde734..383d66f08c1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt @@ -99,7 +99,11 @@ public class KotlinCleanupInspection(): LocalInspectionTool(), CleanupLocalInspe Errors.USELESS_CAST, Errors.USELESS_ELVIS, ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION, - Errors.DEPRECATED_SYMBOL_WITH_MESSAGE + Errors.DEPRECATED_SYMBOL_WITH_MESSAGE, + Errors.DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER, + Errors.DEPRECATED_DECAPITALIZED_ANNOTATION, + Errors.DEPRECATED_ESCAPED_MODIFIER, + Errors.DEPRECATED_UNESCAPED_ANNOTATION ) private fun Diagnostic.isObsoleteLabel(): Boolean { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 233cabcd490..6485ea55b9b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClas import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateLocalVariableActionFactory import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateParameterByNamedArgumentActionFactory import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateParameterByRefActionFactory +import org.jetbrains.kotlin.idea.quickfix.migration.* import org.jetbrains.kotlin.idea.quickfix.replaceWith.DeprecatedSymbolUsageFix import org.jetbrains.kotlin.idea.quickfix.replaceWith.DeprecatedSymbolUsageInWholeProjectFix import org.jetbrains.kotlin.lexer.JetTokens.* @@ -324,5 +325,11 @@ public class QuickFixRegistrar : QuickFixContributor { UPPER_BOUND_VIOLATED.registerFactory(AddGenericUpperBoundFix.Factory) TYPE_INFERENCE_UPPER_BOUND_VIOLATED.registerFactory(AddGenericUpperBoundFix.Factory) + + DEPRECATED_UNESCAPED_ANNOTATION.registerFactory(UnescapedAnnotationFix.Factory) + DEPRECATED_ESCAPED_MODIFIER.registerFactory(EscapedModifierFix.Factory) + DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER.registerFactory(ReplaceAnnotationWithModifierFix.Factory) + DEPRECATED_DECAPITALIZED_ANNOTATION.registerFactory(DecapitalizedAnnotationFix.Factory) + DEPRECATED_ANNOTATION_USE.registerFactory(RemoveAnnotationFix.Factory) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/DecapitalizedAnnotationFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/DecapitalizedAnnotationFix.kt new file mode 100644 index 00000000000..03bd87ea151 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/DecapitalizedAnnotationFix.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix.migration + +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.idea.quickfix.CleanupFix +import org.jetbrains.kotlin.idea.quickfix.JetIntentionAction +import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory +import org.jetbrains.kotlin.idea.quickfix.replaceWith.ClassUsageReplacementStrategy +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe + +public class DecapitalizedAnnotationFix( + element: JetSimpleNameExpression, + private val classDescriptor: ClassDescriptor, + private val replacer: () -> JetElement +) : JetIntentionAction(element), CleanupFix { + override fun getFamilyName() = "Replace deprecated decapitalized annotations" + override fun getText() = "Replace with '${classDescriptor.fqNameSafe.asString()}'" + + override fun invoke(project: Project, editor: Editor?, file: JetFile) { + replacer() + } + + companion object Factory : JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val diagnosticWithParameters = Errors.DEPRECATED_DECAPITALIZED_ANNOTATION.cast(diagnostic) + val classDescriptor = diagnosticWithParameters.a + val element = diagnosticWithParameters.psiElement + + val replacement = JetPsiFactory(element).createType(classDescriptor.fqNameSafe.asString()).typeElement as JetUserType + val replacer = ClassUsageReplacementStrategy(replacement).createReplacer(element) ?: return null + + return DecapitalizedAnnotationFix(element, classDescriptor, replacer) + } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/EscapedModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/EscapedModifierFix.kt new file mode 100644 index 00000000000..fbf2ef02f76 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/EscapedModifierFix.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix.migration + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.idea.quickfix.CleanupFix +import org.jetbrains.kotlin.idea.quickfix.JetIntentionAction +import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory +import org.jetbrains.kotlin.lexer.JetModifierKeywordToken +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.JetPsiFactory + +public class EscapedModifierFix(element: PsiElement) : JetIntentionAction(element), CleanupFix { + override fun getText() = "Remove '@'" + override fun getFamilyName() = text + + override fun invoke(project: Project, editor: Editor?, file: JetFile) { + val modifier = element.node.elementType as JetModifierKeywordToken + element.replace(JetPsiFactory(project).createModifier(modifier)) + } + + companion object Factory : JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic) = EscapedModifierFix(diagnostic.psiElement) + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/RemoveAnnotationFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/RemoveAnnotationFix.kt new file mode 100644 index 00000000000..d31071cea2f --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/RemoveAnnotationFix.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix.migration + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.idea.quickfix.JetIntentionAction +import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory +import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionForFirstParentOfType +import org.jetbrains.kotlin.psi.JetAnnotationEntry +import org.jetbrains.kotlin.psi.JetFile + +public class RemoveAnnotationFix(element: JetAnnotationEntry) : JetIntentionAction(element) { + override fun getFamilyName(): String = getText() + override fun getText(): String = "Remove annotation" + + override fun invoke(project: Project, editor: Editor?, file: JetFile) { + element.delete() + } + + object Factory : JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic) = diagnostic.createIntentionForFirstParentOfType(::RemoveAnnotationFix) + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/ReplaceAnnotationWithModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/ReplaceAnnotationWithModifierFix.kt new file mode 100644 index 00000000000..4179093beda --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/ReplaceAnnotationWithModifierFix.kt @@ -0,0 +1,70 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix.migration + +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.idea.core.CommentSaver +import org.jetbrains.kotlin.idea.quickfix.CleanupFix +import org.jetbrains.kotlin.idea.quickfix.JetIntentionAction +import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory +import org.jetbrains.kotlin.lexer.JetModifierKeywordToken +import org.jetbrains.kotlin.lexer.JetTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType + +public class ReplaceAnnotationWithModifierFix( + element: JetAnnotationEntry, + private val replacement: JetModifierKeywordToken +) : JetIntentionAction(element), CleanupFix { + override fun getFamilyName() = "Replace with modifier" + override fun getText() = "Replace with '${replacement.value}'" + + override fun invoke(project: Project, editor: Editor?, file: JetFile) { + val psiFactory = JetPsiFactory(project) + val modifier = psiFactory.createModifier(replacement) + + val parent = element.parent + if (parent !is JetAnnotation) { + val commentSaver = CommentSaver(element, saveLineBreaks = true) + val result = element.replace(modifier) + commentSaver.restore(result) + } + else { + // within annotation list + val modifierListOwner = (parent.parent?.parent as? JetModifierListOwner) ?: return + // insert modifier + modifierListOwner.addModifier(replacement) + + parent.removeEntry(element) + } + } + + companion object Factory : JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val annotationEntry = diagnostic.psiElement.getNonStrictParentOfType() ?: return null + val modifierValue = Errors.DEPRECATED_ANNOTATION_THAT_BECOMES_MODIFIER.cast(diagnostic).a + + return ReplaceAnnotationWithModifierFix( + annotationEntry, JetTokens.ANNOTATION_MODIFIERS_KEYWORDS_ARRAY.first() { it.value == modifierValue } + ) + } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/UnescapedAnnotationFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/UnescapedAnnotationFix.kt new file mode 100644 index 00000000000..c792c05e1f4 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/UnescapedAnnotationFix.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix.migration + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.idea.quickfix.CleanupFix +import org.jetbrains.kotlin.idea.quickfix.JetIntentionAction +import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory +import org.jetbrains.kotlin.psi.JetAnnotationEntry +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.* + +public class UnescapedAnnotationFix(element: JetAnnotationEntry) : JetIntentionAction(element), CleanupFix { + override fun getText() = "Add '@' before annotation" + override fun getFamilyName() = text + + override fun invoke(project: Project, editor: Editor?, file: JetFile) = element.addAtSymbol() + + companion object Factory : JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic) = diagnostic.createIntentionForFirstParentOfType(::UnescapedAnnotationFix) + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/util.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/util.kt new file mode 100644 index 00000000000..33c1fbc87e4 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/util.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix.migration + +import org.jetbrains.kotlin.psi.JetAnnotationEntry +import org.jetbrains.kotlin.psi.JetPsiFactory + +public fun JetAnnotationEntry.addAtSymbol() { + addBefore(JetPsiFactory(this).createAnnotationEntry("@ann").atSymbol!!, firstChild) +} diff --git a/idea/testData/inspections/cleanup/cleanup.kt b/idea/testData/inspections/cleanup/cleanup.kt index 1c058f4c013..57beeaf9e8a 100644 --- a/idea/testData/inspections/cleanup/cleanup.kt +++ b/idea/testData/inspections/cleanup/cleanup.kt @@ -37,3 +37,22 @@ fun unnecessaryCast(x: String) = x as String fun unnecessaryElvis(x: String) = x ?: "" JavaAnn(1, "abc") class MyClass + +annotation class Ann() + +Ann class A1 + +Ann() class A2 + +kotlin.data class A3 + +@inline @private fun baz() { + @suppress("UNCHECKED_CAST") + (1 as T) + + @data class Local +} + +deprecated("123", ReplaceWith("34")) class Obsolete + +native fun nativeFun(): Int diff --git a/idea/testData/inspections/cleanup/cleanup.kt.after b/idea/testData/inspections/cleanup/cleanup.kt.after index 23d2a72b80d..85d0619e0da 100644 --- a/idea/testData/inspections/cleanup/cleanup.kt.after +++ b/idea/testData/inspections/cleanup/cleanup.kt.after @@ -35,4 +35,23 @@ fun unnecessaryCast(x: String) = x fun unnecessaryElvis(x: String) = x -JavaAnn(1, arg1 = "abc") class MyClass +@JavaAnn(1, arg1 = "abc") class MyClass + +annotation class Ann() + +@Ann class A1 + +@Ann() class A2 + +data class A3 + +inline private fun baz() { + @Suppress("UNCHECKED_CAST") + (1 as T) + + data class Local +} + +@Deprecated("123", ReplaceWith("34")) class Obsolete + +external fun nativeFun(): Int diff --git a/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt b/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt index 3d767053060..f6c7b54042e 100644 --- a/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt +++ b/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt @@ -3,6 +3,6 @@ // ACTION: Make private // ACTION: Make internal -J.foo(1, "2") fun test() { +@J.foo(1, "2") fun test() { } \ No newline at end of file diff --git a/idea/testData/quickfix/migration/annotationModifier.kt b/idea/testData/quickfix/migration/annotationModifier.kt new file mode 100644 index 00000000000..d9bd4cbd2fa --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier.kt @@ -0,0 +1,5 @@ +// "Replace with 'data'" "true" + +@data +/* abc*/(1) +class A diff --git a/idea/testData/quickfix/migration/annotationModifier.kt.after b/idea/testData/quickfix/migration/annotationModifier.kt.after new file mode 100644 index 00000000000..adbc7c3e97c --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier.kt.after @@ -0,0 +1,4 @@ +// "Replace with 'data'" "true" + +data/* abc*/ +class A diff --git a/idea/testData/quickfix/migration/annotationModifier2.kt b/idea/testData/quickfix/migration/annotationModifier2.kt new file mode 100644 index 00000000000..7b045264e6f --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier2.kt @@ -0,0 +1,5 @@ +// "Replace with 'inline'" "true" + +annotation class Ann(val x: Int) + +kotlin.inline fun foo() {} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/annotationModifier2.kt.after b/idea/testData/quickfix/migration/annotationModifier2.kt.after new file mode 100644 index 00000000000..0d23c036724 --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier2.kt.after @@ -0,0 +1,5 @@ +// "Replace with 'inline'" "true" + +annotation class Ann(val x: Int) + +inline fun foo() {} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/annotationModifier3.kt b/idea/testData/quickfix/migration/annotationModifier3.kt new file mode 100644 index 00000000000..04e18fadacc --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier3.kt @@ -0,0 +1,6 @@ +// "Replace with 'data'" "true" + +annotation class Ann +@[data Ann] +/* abc*/ +class A diff --git a/idea/testData/quickfix/migration/annotationModifier3.kt.after b/idea/testData/quickfix/migration/annotationModifier3.kt.after new file mode 100644 index 00000000000..509e5a7b4f1 --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier3.kt.after @@ -0,0 +1,6 @@ +// "Replace with 'data'" "true" + +annotation class Ann +@[Ann] +data /* abc*/ +class A diff --git a/idea/testData/quickfix/migration/annotationModifier4.kt b/idea/testData/quickfix/migration/annotationModifier4.kt new file mode 100644 index 00000000000..e81e6aafde5 --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier4.kt @@ -0,0 +1,5 @@ +// "Replace with 'data'" "true" + +@[data] +/* abc*/ +class A diff --git a/idea/testData/quickfix/migration/annotationModifier4.kt.after b/idea/testData/quickfix/migration/annotationModifier4.kt.after new file mode 100644 index 00000000000..b57b27fdf01 --- /dev/null +++ b/idea/testData/quickfix/migration/annotationModifier4.kt.after @@ -0,0 +1,4 @@ +// "Replace with 'data'" "true" + +data /* abc*/ +class A diff --git a/idea/testData/quickfix/migration/decapitalizedAnnotation/annotationPosition.kt b/idea/testData/quickfix/migration/decapitalizedAnnotation/annotationPosition.kt new file mode 100644 index 00000000000..94ac8fac02d --- /dev/null +++ b/idea/testData/quickfix/migration/decapitalizedAnnotation/annotationPosition.kt @@ -0,0 +1,3 @@ +// "Replace with 'kotlin.Deprecated'" "true" +@deprecated("") +class A diff --git a/idea/testData/quickfix/migration/decapitalizedAnnotation/annotationPosition.kt.after b/idea/testData/quickfix/migration/decapitalizedAnnotation/annotationPosition.kt.after new file mode 100644 index 00000000000..329c26e5f25 --- /dev/null +++ b/idea/testData/quickfix/migration/decapitalizedAnnotation/annotationPosition.kt.after @@ -0,0 +1,3 @@ +// "Replace with 'kotlin.Deprecated'" "true" +@Deprecated("") +class A diff --git a/idea/testData/quickfix/migration/decapitalizedAnnotation/valueParameter.kt b/idea/testData/quickfix/migration/decapitalizedAnnotation/valueParameter.kt new file mode 100644 index 00000000000..32257c2c0fe --- /dev/null +++ b/idea/testData/quickfix/migration/decapitalizedAnnotation/valueParameter.kt @@ -0,0 +1,3 @@ +// "Replace with 'kotlin.Deprecated'" "true" + +fun foo(x: kotlin.deprecated) {} diff --git a/idea/testData/quickfix/migration/decapitalizedAnnotation/valueParameter.kt.after b/idea/testData/quickfix/migration/decapitalizedAnnotation/valueParameter.kt.after new file mode 100644 index 00000000000..996fabe91e8 --- /dev/null +++ b/idea/testData/quickfix/migration/decapitalizedAnnotation/valueParameter.kt.after @@ -0,0 +1,3 @@ +// "Replace with 'kotlin.Deprecated'" "true" + +fun foo(x: Deprecated) {} diff --git a/idea/testData/quickfix/migration/escapedModifier.kt b/idea/testData/quickfix/migration/escapedModifier.kt new file mode 100644 index 00000000000..a70760d2ac2 --- /dev/null +++ b/idea/testData/quickfix/migration/escapedModifier.kt @@ -0,0 +1,5 @@ +// "Remove '@'" "true" + +@private +/* abc*/ +class A diff --git a/idea/testData/quickfix/migration/escapedModifier.kt.after b/idea/testData/quickfix/migration/escapedModifier.kt.after new file mode 100644 index 00000000000..d5aab64a446 --- /dev/null +++ b/idea/testData/quickfix/migration/escapedModifier.kt.after @@ -0,0 +1,5 @@ +// "Remove '@'" "true" + +private +/* abc*/ +class A diff --git a/idea/testData/quickfix/migration/inlineOptions.kt b/idea/testData/quickfix/migration/inlineOptions.kt new file mode 100644 index 00000000000..0860d62eeca --- /dev/null +++ b/idea/testData/quickfix/migration/inlineOptions.kt @@ -0,0 +1,3 @@ +// "Replace with 'crossinline'" "true" + +inline fun inlineFun(@inlineOptions(InlineOption.ONLY_LOCAL_RETURN) block: () -> Int) {} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/inlineOptions.kt.after b/idea/testData/quickfix/migration/inlineOptions.kt.after new file mode 100644 index 00000000000..a7179b65093 --- /dev/null +++ b/idea/testData/quickfix/migration/inlineOptions.kt.after @@ -0,0 +1,3 @@ +// "Replace with 'crossinline'" "true" + +inline fun inlineFun(crossinline block: () -> Int) {} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/inlineOptionsWithBreak.kt b/idea/testData/quickfix/migration/inlineOptionsWithBreak.kt new file mode 100644 index 00000000000..f66072fe530 --- /dev/null +++ b/idea/testData/quickfix/migration/inlineOptionsWithBreak.kt @@ -0,0 +1,3 @@ +// "Remove annotation" "true" + +inline fun inlineFun(@inlineOptions(InlineOption.LOCAL_CONTINUE_AND_BREAK) block: () -> Int) {} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/inlineOptionsWithBreak.kt.after b/idea/testData/quickfix/migration/inlineOptionsWithBreak.kt.after new file mode 100644 index 00000000000..1ee8c0603f3 --- /dev/null +++ b/idea/testData/quickfix/migration/inlineOptionsWithBreak.kt.after @@ -0,0 +1,3 @@ +// "Remove annotation" "true" + +inline fun inlineFun(block: () -> Int) {} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/tailRec.kt b/idea/testData/quickfix/migration/tailRec.kt new file mode 100644 index 00000000000..ef54eb78888 --- /dev/null +++ b/idea/testData/quickfix/migration/tailRec.kt @@ -0,0 +1,8 @@ +// "Replace with 'tailrec'" "true" + +@tailRecursive +fun foo() { + if (1 > 2) { + foo() + } +} diff --git a/idea/testData/quickfix/migration/tailRec.kt.after b/idea/testData/quickfix/migration/tailRec.kt.after new file mode 100644 index 00000000000..c67f0ee7325 --- /dev/null +++ b/idea/testData/quickfix/migration/tailRec.kt.after @@ -0,0 +1,8 @@ +// "Replace with 'tailrec'" "true" + +tailrec +fun foo() { + if (1 > 2) { + foo() + } +} diff --git a/idea/testData/quickfix/migration/unescapedAnnotation.kt b/idea/testData/quickfix/migration/unescapedAnnotation.kt new file mode 100644 index 00000000000..332bf9ed2a5 --- /dev/null +++ b/idea/testData/quickfix/migration/unescapedAnnotation.kt @@ -0,0 +1,7 @@ +// "Add '@' before annotation" "true" + +annotation class Ann(val x: Int) + +Ann +/* abc*/(1) +class A diff --git a/idea/testData/quickfix/migration/unescapedAnnotation.kt.after b/idea/testData/quickfix/migration/unescapedAnnotation.kt.after new file mode 100644 index 00000000000..1c5d85bff6a --- /dev/null +++ b/idea/testData/quickfix/migration/unescapedAnnotation.kt.after @@ -0,0 +1,7 @@ +// "Add '@' before annotation" "true" + +annotation class Ann(val x: Int) + +@Ann +/* abc*/(1) +class A diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index ca40436d516..11230aa127e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -4019,6 +4019,60 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); } + @TestMetadata("annotationModifier.kt") + public void testAnnotationModifier() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/annotationModifier.kt"); + doTest(fileName); + } + + @TestMetadata("annotationModifier2.kt") + public void testAnnotationModifier2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/annotationModifier2.kt"); + doTest(fileName); + } + + @TestMetadata("annotationModifier3.kt") + public void testAnnotationModifier3() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/annotationModifier3.kt"); + doTest(fileName); + } + + @TestMetadata("annotationModifier4.kt") + public void testAnnotationModifier4() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/annotationModifier4.kt"); + doTest(fileName); + } + + @TestMetadata("escapedModifier.kt") + public void testEscapedModifier() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/escapedModifier.kt"); + doTest(fileName); + } + + @TestMetadata("inlineOptions.kt") + public void testInlineOptions() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/inlineOptions.kt"); + doTest(fileName); + } + + @TestMetadata("inlineOptionsWithBreak.kt") + public void testInlineOptionsWithBreak() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/inlineOptionsWithBreak.kt"); + doTest(fileName); + } + + @TestMetadata("tailRec.kt") + public void testTailRec() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/tailRec.kt"); + doTest(fileName); + } + + @TestMetadata("unescapedAnnotation.kt") + public void testUnescapedAnnotation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/unescapedAnnotation.kt"); + doTest(fileName); + } + @TestMetadata("idea/testData/quickfix/migration/conflictingExtension") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -4112,6 +4166,27 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/migration/decapitalizedAnnotation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class DecapitalizedAnnotation extends AbstractQuickFixTest { + public void testAllFilesPresentInDecapitalizedAnnotation() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration/decapitalizedAnnotation"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("annotationPosition.kt") + public void testAnnotationPosition() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/decapitalizedAnnotation/annotationPosition.kt"); + doTest(fileName); + } + + @TestMetadata("valueParameter.kt") + public void testValueParameter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/decapitalizedAnnotation/valueParameter.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/migration/lambdaSyntax") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)