diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 6cf4070150cb..55c63425e2a6 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -1398,9 +1398,11 @@ public class HighlightUtil extends HighlightUtilBase { if (PsiUtil.isLanguageLevel8OrHigher(expr)) { final PsiMethod method = PsiTreeUtil.getParentOfType(expr, PsiMethod.class); if (method != null && method.hasModifierProperty(PsiModifier.DEFAULT) && qualifier == null) { - //todo[r.sh] "Add qualifier" quick fix - String description = JavaErrorMessages.message("unqualified.super.disallowed"); - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(parent).descriptionAndTooltip(description).create(); + final String description = JavaErrorMessages.message("unqualified.super.disallowed"); + final HighlightInfo highlightInfo = + HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(parent).descriptionAndTooltip(description).create(); + QualifySuperArgumentFix.registerQuickFixAction((PsiSuperExpression)expr, highlightInfo); + return highlightInfo; } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifySuperArgumentFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifySuperArgumentFix.java new file mode 100644 index 000000000000..0a3048f23273 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifySuperArgumentFix.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2013 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. + */ + +/** + * Created by IntelliJ IDEA. + * User: cdr + * Date: Nov 13, 2002 + * Time: 3:26:50 PM + * To change this template use Options | File Templates. + */ +package com.intellij.codeInsight.daemon.impl.quickfix; + +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.refactoring.util.RefactoringChangeUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +public class QualifySuperArgumentFix extends QualifyThisOrSuperArgumentFix { + public QualifySuperArgumentFix(@NotNull PsiExpression expression, @NotNull PsiClass psiClass) { + super(expression, psiClass); + } + + @Override + protected String getQualifierText() { + return "super"; + } + + @Override + protected PsiExpression getQualifier(PsiManager manager) { + return RefactoringChangeUtil.createSuperExpression(manager, myPsiClass); + } + + public static void registerQuickFixAction(@NotNull PsiSuperExpression expr, HighlightInfo highlightInfo) { + LOG.assertTrue(expr.getQualifier() == null); + final PsiClass containingClass = PsiTreeUtil.getParentOfType(expr, PsiClass.class); + if (containingClass != null && containingClass.isInterface()) { + final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(expr, PsiMethodCallExpression.class); + if (callExpression != null) { + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(callExpression.getProject()); + for (PsiClass superClass : containingClass.getSupers()) { + if (superClass.isInterface()) { + final PsiMethodCallExpression copy = (PsiMethodCallExpression)callExpression.copy(); + final PsiExpression superQualifierCopy = copy.getMethodExpression().getQualifierExpression(); + LOG.assertTrue(superQualifierCopy != null); + superQualifierCopy.delete(); + if (((PsiMethodCallExpression)elementFactory.createExpressionFromText(copy.getText(), superClass)).resolveMethod() != null) { + QuickFixAction.registerQuickFixAction(highlightInfo, new QualifySuperArgumentFix(expr, superClass)); + } + } + } + } + } + } +} diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java index 4eeb1d7ee730..3b427e829771 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifyThisArgumentFix.java @@ -25,6 +25,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -40,45 +41,19 @@ import org.jetbrains.annotations.NotNull; import java.util.HashSet; import java.util.Set; -public class QualifyThisArgumentFix implements IntentionAction { - private final PsiThisExpression myExpression; - private final PsiClass myPsiClass; - private String myText; - - - public QualifyThisArgumentFix(@NotNull PsiThisExpression expression, @NotNull PsiClass psiClass) { - myExpression = expression; - myPsiClass = psiClass; +public class QualifyThisArgumentFix extends QualifyThisOrSuperArgumentFix{ + public QualifyThisArgumentFix(@NotNull PsiExpression expression, @NotNull PsiClass psiClass) { + super(expression, psiClass); } @Override - public boolean startInWriteAction() { - return true; - } - - @NotNull - @Override - public String getText() { - return myText; + protected String getQualifierText() { + return "this"; } @Override - public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - if (!myExpression.isValid()) return false; - if (!myPsiClass.isValid()) return false; - myText = "Qualify this expression with \'" + myPsiClass.getQualifiedName() + "\'"; - return true; - } - - @NotNull - @Override - public String getFamilyName() { - return "Qualify this"; - } - - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - myExpression.replace(RefactoringChangeUtil.createThisExpression(PsiManager.getInstance(project), myPsiClass)); + protected PsiExpression getQualifier(PsiManager manager) { + return RefactoringChangeUtil.createThisExpression(manager, myPsiClass); } public static void registerQuickFixAction(CandidateInfo[] candidates, PsiCall call, HighlightInfo highlightInfo, final TextRange fixRange) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifyThisOrSuperArgumentFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifyThisOrSuperArgumentFix.java new file mode 100644 index 000000000000..2ea59ccadb91 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QualifyThisOrSuperArgumentFix.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2013 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. + */ + +/** + * Created by IntelliJ IDEA. + * User: cdr + * Date: Nov 13, 2002 + * Time: 3:26:50 PM + * To change this template use Options | File Templates. + */ +package com.intellij.codeInsight.daemon.impl.quickfix; + +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.refactoring.util.RefactoringChangeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +public abstract class QualifyThisOrSuperArgumentFix implements IntentionAction { + protected static final Logger LOG = Logger.getInstance("#" + QualifyThisOrSuperArgumentFix.class.getName()); + protected final PsiExpression myExpression; + protected final PsiClass myPsiClass; + private String myText; + + + public QualifyThisOrSuperArgumentFix(@NotNull PsiExpression expression, @NotNull PsiClass psiClass) { + myExpression = expression; + myPsiClass = psiClass; + } + + @Override + public boolean startInWriteAction() { + return true; + } + + @NotNull + @Override + public String getText() { + return myText; + } + + protected abstract String getQualifierText(); + protected abstract PsiExpression getQualifier(PsiManager manager); + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + if (!myExpression.isValid()) return false; + if (!myPsiClass.isValid()) return false; + myText = "Qualify " + getQualifierText() + " expression with \'" + myPsiClass.getQualifiedName() + "\'"; + return true; + } + + @NotNull + @Override + public String getFamilyName() { + return "Qualify " + getQualifierText(); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + myExpression.replace(getQualifier(PsiManager.getInstance(project))); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/qualifyThis/afterDefaultInInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/qualifyThis/afterDefaultInInterface.java new file mode 100644 index 000000000000..7c4c1c064588 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/qualifyThis/afterDefaultInInterface.java @@ -0,0 +1,14 @@ +// "Qualify super expression with 'Super'" "true" +interface Super +{ + default void method() + { + System.out.println("Super.method()"); + } +} + +interface Sub extends Super { + default void foo() { + Super.super.method(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/qualifyThis/beforeDefaultInInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/qualifyThis/beforeDefaultInInterface.java new file mode 100644 index 000000000000..c4ea300498ca --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/qualifyThis/beforeDefaultInInterface.java @@ -0,0 +1,14 @@ +// "Qualify super expression with 'Super'" "true" +interface Super +{ + default void method() + { + System.out.println("Super.method()"); + } +} + +interface Sub extends Super { + default void foo() { + super.method(); + } +} \ No newline at end of file