Merge remote-tracking branch 'origin/master'

This commit is contained in:
Nadya Zabrodina
2015-11-13 16:52:04 +03:00
17 changed files with 292 additions and 2 deletions
@@ -98,6 +98,8 @@ public abstract class QuickFixFactory {
@NotNull public abstract IntentionAction createAddExceptionToThrowsFix(@NotNull PsiElement element);
@NotNull public abstract IntentionAction createAddExceptionFromFieldInitializerToConstructorThrowsFix(@NotNull PsiElement element);
@NotNull public abstract IntentionAction createSurroundWithTryCatchFix(@NotNull PsiElement element);
@NotNull public abstract IntentionAction createGeneralizeCatchFix(@NotNull PsiElement element, @NotNull PsiClassType type);
@@ -799,6 +799,7 @@ public class HighlightUtil extends HighlightUtilBase {
private static void registerUnhandledExceptionFixes(PsiElement element, HighlightInfo errorResult, List<PsiClassType> unhandled) {
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createAddExceptionToCatchFix());
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createAddExceptionToThrowsFix(element));
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createAddExceptionFromFieldInitializerToConstructorThrowsFix(element));
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createSurroundWithTryCatchFix(element));
if (unhandled.size() == 1) {
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createGeneralizeCatchFix(element, unhandled.get(0)));
@@ -167,6 +167,12 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
return QuickFixes.EMPTY_FIX;
}
@NotNull
@Override
public IntentionAction createAddExceptionFromFieldInitializerToConstructorThrowsFix(@NotNull PsiElement element) {
return QuickFixes.EMPTY_FIX;
}
@NotNull
@Override
public IntentionAction createSurroundWithTryCatchFix(@NotNull PsiElement psiElement) {
@@ -0,0 +1,114 @@
/*
* Copyright 2000-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 com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import gnu.trove.THashSet;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
/**
* @author Dmitry Batkovich
*/
public class AddExceptionFromFieldInitializerToConstructorThrowsFix extends BaseIntentionAction {
private final static Logger LOG = Logger.getInstance(AddExceptionFromFieldInitializerToConstructorThrowsFix.class);
private final PsiElement myWrongElement;
public AddExceptionFromFieldInitializerToConstructorThrowsFix(PsiElement element) {
myWrongElement = element;
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (!myWrongElement.isValid()) return false;
final NavigatablePsiElement maybeField =
PsiTreeUtil.getParentOfType(myWrongElement, PsiMethod.class, PsiFunctionalExpression.class, PsiField.class);
if (!(maybeField instanceof PsiField)) return false;
final PsiField field = (PsiField)maybeField;
if (field.hasModifierProperty(PsiModifier.STATIC)) return false;
final PsiClass containingClass = field.getContainingClass();
if ((containingClass == null ||
containingClass instanceof PsiAnonymousClass ||
containingClass.isInterface() ||
!containingClass.isWritable())) {
return false;
}
final List<PsiClassType> exceptions = ExceptionUtil.getUnhandledExceptions(field);
if (exceptions.isEmpty()) {
return false;
}
final PsiMethod[] existedConstructors = containingClass.getConstructors();
setText(QuickFixBundle.message("add.exception.from.field.initializer.to.constructor.throws.text", existedConstructors.length));
return true;
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
PsiDocumentManager.getInstance(project).commitAllDocuments();
final NavigatablePsiElement field =
PsiTreeUtil.getParentOfType(myWrongElement, PsiMethod.class, PsiFunctionalExpression.class, PsiField.class);
if (field instanceof PsiField) {
final PsiClass aClass = ((PsiField)field).getContainingClass();
if (aClass != null) {
PsiMethod[] constructors = aClass.getConstructors();
if (constructors.length == 0) {
final AddDefaultConstructorFix defaultConstructorFix = new AddDefaultConstructorFix(aClass);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
defaultConstructorFix.invoke(project, null, file);
}
});
constructors = aClass.getConstructors();
LOG.assertTrue(constructors.length != 0);
}
Set<PsiClassType> unhandledExceptions = new THashSet<PsiClassType>(ExceptionUtil.getUnhandledExceptions(field));
for (PsiMethod constructor : constructors) {
AddExceptionToThrowsFix.addExceptionsToThrowsList(project, constructor, unhandledExceptions);
}
}
}
}
@Nls
@NotNull
@Override
public String getFamilyName() {
return QuickFixBundle.message("add.exception.from.field.initializer.to.constructor.throws.family.text");
}
@Override
public boolean startInWriteAction() {
return false;
}
}
@@ -168,7 +168,7 @@ public class AddExceptionToThrowsFix extends BaseIntentionAction {
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (!(file instanceof PsiJavaFile)) return false;
if (myWrongElement == null || !myWrongElement.isValid()) return false;
if (!myWrongElement.isValid()) return false;
final List<PsiClassType> unhandled = new ArrayList<PsiClassType>();
if (collectExceptions(unhandled) == null) return false;
@@ -220,6 +220,12 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
return new AddExceptionToThrowsFix(element);
}
@NotNull
@Override
public IntentionAction createAddExceptionFromFieldInitializerToConstructorThrowsFix(@NotNull PsiElement element) {
return new AddExceptionFromFieldInitializerToConstructorThrowsFix(element);
}
@NotNull
@Override
public IntentionAction createSurroundWithTryCatchFix(@NotNull PsiElement element) {
@@ -0,0 +1,23 @@
// "Add exception to class constructors signature" "true"
import java.io.FileWriter;
import java.io.IOException;
class C {
final FileWriter fw = new FileWriter("asd");
C(int i) throws RuntimeException, IOException {
}
C(int i, int j) throws IOException {
}
C(int i, int j, int k) throws Exception {
}
C(int i, int j, int k, int l) throws IOException {
}
}
@@ -0,0 +1,10 @@
// "Add exception to class default constructor signature" "true"
import java.io.FileWriter;
import java.io.IOException;
class C {
final FileWriter fw = new FileWriter("asd");
C() throws IOException {
}
}
@@ -0,0 +1,11 @@
// "Add exception to class constructor signature" "true"
import java.io.FileWriter;
import java.io.IOException;
class C {
final FileWriter fw = new FileWriter("asd");
C(int i) throws RuntimeException, IOException {
}
}
@@ -0,0 +1,23 @@
// "Add exception to class constructors signature" "true"
import java.io.FileWriter;
import java.io.IOException;
class C {
final FileWriter fw = new FileWri<caret>ter("asd");
C(int i) throws RuntimeException {
}
C(int i, int j) throws IOException {
}
C(int i, int j, int k) throws Exception {
}
C(int i, int j, int k, int l) {
}
}
@@ -0,0 +1,7 @@
// "Add exception to class default constructor signature" "true"
import java.io.FileWriter;
class C {
final FileWriter fw = new FileWrit<caret>er("asd");
}
@@ -0,0 +1,15 @@
// "Add exception to class default constructor signature" "false"
import java.io.FileWriter;
class C {
final FileWriter fw = new MyCal<caret>lable() {
@Override
public FileWriter get() {
return new FileWriter("");
}
}.get();
interface MyCallable {
FileWriter get();
}
}
@@ -0,0 +1,10 @@
// "Add exception to class default constructor signature" "false"
import java.io.FileWriter;
class C {
final FileWriter fw = ((MyCall<caret>able) () -> new FileWriter("")).get();
interface MyCallable {
FileWriter get();
}
}
@@ -0,0 +1,11 @@
// "Add exception to class constructor signature" "false"
import java.io.FileWriter;
import java.io.IOException;
class C {
final FileWriter fw = new F<caret>ileWriter("asd");
C() throws IOException {
}
}
@@ -0,0 +1,10 @@
// "Add exception to class constructor signature" "true"
import java.io.FileWriter;
class C {
final FileWriter fw = new F<caret>ileWriter("asd");
C(int i) throws RuntimeException {
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2000-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 com.intellij.codeInsight.daemon.quickFix;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.testFramework.IdeaTestUtil;
/**
* @author Dmitry Batkovich
*/
public class AddExceptionFromFieldInitializerToConstructorThrowsTest extends LightQuickFixParameterizedTestCase {
public void test() throws Exception {
doAllTests();
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/addToConstructorThrows";
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk18();
}
}
@@ -274,4 +274,7 @@ collection.addall.can.be.replaced.with.constructor.fix.title=Replace 'addAll()'
wrap.long.with.math.to.int.text=Wrap using 'Math.toIntExact()'
wrap.long.with.math.to.int.parameter.single.text=Wrap parameter using 'Math.toIntExact()'
wrap.long.with.math.to.int.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''Math.toIntExact()''
wrap.long.with.math.to.int.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''Math.toIntExact()''
add.exception.from.field.initializer.to.constructor.throws.text=Add exception to class {0, choice, 0#default constructor|1#constructor|2#constructors} signature
add.exception.from.field.initializer.to.constructor.throws.family.text=Add exception to class constructors signature