Add explicit type to methods in "Convert to @CompileStatic" action (IDEA-95853)

This commit is contained in:
alexey.afanasiev
2017-09-12 13:43:19 +03:00
parent d4ab377370
commit eb94a196bc
4 changed files with 73 additions and 19 deletions
@@ -99,15 +99,18 @@ public class AddReturnTypeFix implements IntentionAction {
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final GrMethod method = findMethod(file, editor.getCaretModel().getOffset());
if (method == null) return;
PsiType type = method.getInferredReturnType();
if (type == null) type = PsiType.getJavaLangObject(PsiManager.getInstance(project), file.getResolveScope());
type = TypesUtil.unboxPrimitiveTypeWrapper(type);
GrReferenceAdjuster.shortenAllReferencesIn(method.setReturnType(type));
applyFix(project, method);
}
@Override
public boolean startInWriteAction() {
return true;
}
public static void applyFix(@NotNull Project project, @NotNull GrMethod method) {
PsiType type = method.getInferredReturnType();
if (type == null) type = PsiType.getJavaLangObject(PsiManager.getInstance(project), method.getResolveScope());
type = TypesUtil.unboxPrimitiveTypeWrapper(type);
GrReferenceAdjuster.shortenAllReferencesIn(method.setReturnType(type));
}
}
@@ -39,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.convertToStatic.fixes.BaseFix;
import org.jetbrains.plugins.groovy.refactoring.convertToStatic.fixes.EmptyFieldTypeFix;
import org.jetbrains.plugins.groovy.refactoring.convertToStatic.fixes.EmptyReturnTypeFix;
import java.util.*;
@@ -51,7 +52,7 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
private final GroovyFile[] myFiles;
private BaseFix[] myFixes = {new EmptyFieldTypeFix()};
private BaseFix[] myFixes = {new EmptyFieldTypeFix(), new EmptyReturnTypeFix()};
protected ConvertToStaticProcessor(Project project, GroovyFile... files) {
super(project);
@@ -94,9 +95,13 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
LOG.assertTrue(file.isValid());
if (file.isScript()) continue;
applyFixes(file);
putCompileAnnotations(file);
checkErrors(file);
try {
applyFixes(file);
putCompileAnnotations(file);
checkErrors(file);
} catch (Exception e) {
LOG.error("Error in converting file: " + file.getName(), e);
}
PsiDocumentManager.getInstance(myProject).commitDocument(document);
@@ -115,6 +120,12 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
}
private void putCompileAnnotations(@NotNull GroovyFile file) {
GrTypeDefinition[] classes = file.getTypeDefinitions();
for (GrTypeDefinition typeDef : classes) { //put annotations
addAnnotation(typeDef, true);
}
Set<GrTypeDefinition> classesWithUnresolvedRef = new HashSet<>();
Set<GrMethod> methodsWithUnresolvedRef = new HashSet<>();
@@ -130,13 +141,11 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
file.accept(new ResolveHighlightingVisitor(file, myProject, callback));
file.accept(new InaccessibleElementVisitor(file, myProject, callback));
GrTypeDefinition[] classes = file.getTypeDefinitions();
for (GrTypeDefinition typeDef : classes) {
boolean isStaticClass = false;
if (!classesWithUnresolvedRef.contains(typeDef)) {
isStaticClass = true;
addAnnotation(typeDef, true);
for (GrTypeDefinition typeDef : classes) { //remove if found not compilable code in class def
boolean isStaticClass = true;
if (classesWithUnresolvedRef.contains(typeDef)) {
isStaticClass = false;
removeAnnotation(typeDef);
}
for (GrMethod method : typeDef.getCodeMethods()) {
@@ -172,9 +181,18 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
}
void addAnnotation(@NotNull PsiModifierListOwner owner, boolean isStatic) {
PsiModifierList modifierList = owner.getModifierList();
String annotation = isStatic ? GROOVY_TRANSFORM_COMPILE_STATIC : GROOVY_TRANSFORM_COMPILE_DYNAMIC;
if (modifierList != null && modifierList.findAnnotation(annotation) == null) {
modifierList.addAnnotation(annotation);
}
}
void removeAnnotation(@NotNull PsiModifierListOwner owner) {
PsiModifierList modifierList = owner.getModifierList();
if (modifierList != null) {
modifierList.addAnnotation(isStatic ? GROOVY_TRANSFORM_COMPILE_STATIC : GROOVY_TRANSFORM_COMPILE_DYNAMIC);
PsiAnnotation psiAnnotation = modifierList.findAnnotation(GROOVY_TRANSFORM_COMPILE_STATIC);
if (psiAnnotation != null) psiAnnotation.delete();
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2017 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.plugins.groovy.refactoring.convertToStatic.fixes
import com.intellij.psi.impl.light.LightElement
import org.jetbrains.plugins.groovy.intentions.style.AddReturnTypeFix
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
class EmptyReturnTypeFix : BaseFix() {
override fun visitReferenceExpression(referenceExpression: GrReferenceExpression) {
val resolveResult = referenceExpression.advancedResolve()
if (!resolveResult.isAccessible || !resolveResult.isApplicable) return
val method = resolveResult.element as? GrMethod ?: return
if (method is LightElement) return
method.returnTypeElementGroovy?.let { return }
AddReturnTypeFix.applyFix(referenceExpression.project, method)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -309,7 +309,7 @@ class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase {
private final List<ThrownExceptionInfo> myInfos
SimpleExceptionsGen(List<? extends ThrownExceptionInfo> infos = []) {
myInfos = infos
myInfos = infos as List<ThrownExceptionInfo>
}
@Override