blob: 2fe672fb481c3f9790cdb5099dcc91fa76a0c258 [file] [log] [blame]
/*
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* 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.siyeh.ipp.exceptions;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.NonNls;
import java.util.*;
public class DetailExceptionsIntention extends Intention {
@Override
@NotNull
public PsiElementPredicate getElementPredicate() {
return new DetailExceptionsPredicate();
}
@Override
public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException {
final PsiJavaToken token = (PsiJavaToken)element;
PsiElement parent = token.getParent();
if (parent instanceof PsiCatchSection) {
parent = parent.getParent();
}
if (!(parent instanceof PsiTryStatement)) {
return;
}
final PsiTryStatement tryStatement = (PsiTryStatement)parent;
@NonNls final StringBuilder newTryStatement = new StringBuilder("try");
final Set<PsiType> exceptionsThrown = new HashSet<PsiType>();
final PsiResourceList resourceList = tryStatement.getResourceList();
if (resourceList != null) {
newTryStatement.append(resourceList.getText());
ExceptionUtils.calculateExceptionsThrownForResourceList(resourceList, exceptionsThrown);
}
final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
if (tryBlock == null) {
return;
}
final String tryBlockText = tryBlock.getText();
newTryStatement.append(tryBlockText);
ExceptionUtils.calculateExceptionsThrownForCodeBlock(tryBlock, exceptionsThrown);
final Comparator<PsiType> comparator = new HierarchicalTypeComparator();
final List<PsiType> exceptionsAlreadyEmitted = new ArrayList<PsiType>();
final PsiCatchSection[] catchSections = tryStatement.getCatchSections();
for (PsiCatchSection catchSection : catchSections) {
final PsiParameter parameter = catchSection.getParameter();
final PsiCodeBlock block = catchSection.getCatchBlock();
if (parameter != null && block != null) {
final PsiType caughtType = parameter.getType();
final List<PsiType> exceptionsToExpand = new ArrayList<PsiType>(10);
for (Object aExceptionsThrown : exceptionsThrown) {
final PsiType thrownType = (PsiType)aExceptionsThrown;
if (caughtType.isAssignableFrom(thrownType)) {
exceptionsToExpand.add(thrownType);
}
}
exceptionsToExpand.removeAll(exceptionsAlreadyEmitted);
Collections.sort(exceptionsToExpand, comparator);
for (PsiType thrownType : exceptionsToExpand) {
newTryStatement.append("catch(").append(thrownType.getCanonicalText()).append(' ').append(parameter.getName()).append(')');
newTryStatement.append(block.getText());
exceptionsAlreadyEmitted.add(thrownType);
}
}
}
final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
if (finallyBlock != null) {
newTryStatement.append("finally").append(finallyBlock.getText());
}
final String newStatement = newTryStatement.toString();
PsiReplacementUtil.replaceStatementAndShortenClassNames(tryStatement, newStatement);
}
}