Skip to content

Commit

Permalink
Used CustomExceptionHandler ExtensionPoint to reimplement @SneakyThrows
Browse files Browse the repository at this point in the history
… handler

and fixed Sneaky Throws Not Correctly Detected for Anonymous Inner Class #74
  • Loading branch information
Michail Plushnikov committed Feb 6, 2015
1 parent 24c2b06 commit 92b1b2c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 44 deletions.
Expand Up @@ -2,14 +2,10 @@


import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter; import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import de.plushnikov.intellij.plugin.handler.LazyGetterHandler; import de.plushnikov.intellij.plugin.handler.LazyGetterHandler;
import de.plushnikov.intellij.plugin.handler.SneakyThrowsExceptionHandler;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;


Expand All @@ -18,28 +14,13 @@


public class LombokHighlightErrorFilter implements HighlightInfoFilter { public class LombokHighlightErrorFilter implements HighlightInfoFilter {


private static final String UNHANDLED_EXCEPTION_PREFIX_TEXT = "Unhandled exception:";
private static final String UNHANDLED_EXCEPTIONS_PREFIX_TEXT = "Unhandled exceptions:";
private static final String UNHANDLED_AUTOCLOSABLE_EXCEPTIONS_PREFIX_TEXT = "Unhandled exception from auto-closeable resource:";

private static final Pattern UNINITIALIZED_MESSAGE = Pattern.compile("Variable '.+' might not have been initialized"); private static final Pattern UNINITIALIZED_MESSAGE = Pattern.compile("Variable '.+' might not have been initialized");


@Override @Override
public boolean accept(@NotNull HighlightInfo highlightInfo, @Nullable PsiFile file) { public boolean accept(@NotNull HighlightInfo highlightInfo, @Nullable PsiFile file) {
if (null != file && HighlightSeverity.ERROR.equals(highlightInfo.getSeverity())) { if (null != file && HighlightSeverity.ERROR.equals(highlightInfo.getSeverity())) {
final String description = StringUtil.notNullize(highlightInfo.getDescription()); final String description = StringUtil.notNullize(highlightInfo.getDescription());


// Handling SneakyThrows
if (HighlightInfoType.UNHANDLED_EXCEPTION.equals(highlightInfo.type) && unhandledException(description)) {
final String unhandledExceptions = description.substring(description.indexOf(':') + 1).trim();
final String[] exceptionFQNs = unhandledExceptions.split(",");
if (exceptionFQNs.length > 0) {
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(file.findElementAt(highlightInfo.getStartOffset()), PsiMethod.class);
if (null != psiMethod) {
return !SneakyThrowsExceptionHandler.isExceptionHandled(psiMethod, exceptionFQNs);
}
}
}
// Handling LazyGetter // Handling LazyGetter
if (uninitializedField(description) && LazyGetterHandler.isLazyGetterHandled(highlightInfo, file)) { if (uninitializedField(description) && LazyGetterHandler.isLazyGetterHandled(highlightInfo, file)) {
return false; return false;
Expand All @@ -48,12 +29,6 @@ public boolean accept(@NotNull HighlightInfo highlightInfo, @Nullable PsiFile fi
return true; return true;
} }


private boolean unhandledException(String description) {
return (StringUtil.startsWith(description, UNHANDLED_EXCEPTION_PREFIX_TEXT) ||
StringUtil.startsWith(description, UNHANDLED_EXCEPTIONS_PREFIX_TEXT) ||
StringUtil.startsWith(description, UNHANDLED_AUTOCLOSABLE_EXCEPTIONS_PREFIX_TEXT));
}

private boolean uninitializedField(String description) { private boolean uninitializedField(String description) {
Matcher matcher = UNINITIALIZED_MESSAGE.matcher(description); Matcher matcher = UNINITIALIZED_MESSAGE.matcher(description);
return matcher.matches(); return matcher.matches();
Expand Down
@@ -1,27 +1,34 @@
package de.plushnikov.intellij.plugin.handler; package de.plushnikov.intellij.plugin.handler;


import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.openapi.project.Project; import com.intellij.codeInsight.CustomExceptionHandler;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType; import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifierListOwner; import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiType; import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil;
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil; import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;


import java.util.Collection; import java.util.Collection;


public class SneakyThrowsExceptionHandler { public class SneakyThrowsExceptionHandler extends CustomExceptionHandler {

private static final String ANNOTATION_FQN = SneakyThrows.class.getName(); private static final String ANNOTATION_FQN = SneakyThrows.class.getName();

private static final String JAVA_LANG_THROWABLE = "java.lang.Throwable"; private static final String JAVA_LANG_THROWABLE = "java.lang.Throwable";


public static boolean isExceptionHandled(@NotNull PsiModifierListOwner psiModifierListOwner, String... exceptionFQNs) { @Override
public boolean isHandled(@Nullable PsiElement element, @NotNull PsiClassType exceptionType, PsiElement topElement) {
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
return psiMethod != null && isExceptionHandled(psiMethod, exceptionType);
}

public static boolean isExceptionHandled(@NotNull PsiModifierListOwner psiModifierListOwner, PsiClassType exceptionClassType) {
final PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotation(psiModifierListOwner, ANNOTATION_FQN); final PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotation(psiModifierListOwner, ANNOTATION_FQN);
if (psiAnnotation == null) { if (psiAnnotation == null) {
return false; return false;
Expand All @@ -33,25 +40,17 @@ public static boolean isExceptionHandled(@NotNull PsiModifierListOwner psiModifi
return true; return true;
} }


for (String exceptionFQN : exceptionFQNs) { return isExceptionHandled(exceptionClassType, sneakedExceptionTypes);
if (!isExceptionHandled(exceptionFQN.trim(), psiModifierListOwner, sneakedExceptionTypes)) {
return false;
}
}
return true;
} }


private static boolean isExceptionHandled(@NotNull String exceptionFQN, @NotNull PsiModifierListOwner psiModifierListOwner, @NotNull Collection<PsiType> sneakedExceptionTypes) { private static boolean isExceptionHandled(@NotNull PsiClassType exceptionClassType, @NotNull Collection<PsiType> sneakedExceptionTypes) {
for (PsiType sneakedExceptionType : sneakedExceptionTypes) { for (PsiType sneakedExceptionType : sneakedExceptionTypes) {
if (sneakedExceptionType.equalsToText(JAVA_LANG_THROWABLE) || sneakedExceptionType.equalsToText(exceptionFQN)) { if (sneakedExceptionType.equalsToText(JAVA_LANG_THROWABLE) || sneakedExceptionType.equals(exceptionClassType)) {
return true; return true;
} }
} }


final Project project = psiModifierListOwner.getProject(); final PsiClass unhandledExceptionClass = exceptionClassType.resolve();
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
final PsiClassType unhandledExceptionType = factory.createTypeByFQClassName(exceptionFQN, GlobalSearchScope.allScope(project));
final PsiClass unhandledExceptionClass = unhandledExceptionType.resolve();


if (null != unhandledExceptionClass) { if (null != unhandledExceptionClass) {
for (PsiType sneakedExceptionType : sneakedExceptionTypes) { for (PsiType sneakedExceptionType : sneakedExceptionTypes) {
Expand Down
2 changes: 2 additions & 0 deletions lombok-plugin/src/main/resources/META-INF/plugin.xml
Expand Up @@ -48,6 +48,8 @@
<lang.commenter language="Lombok.Config" implementationClass="de.plushnikov.intellij.plugin.language.LombokConfigCommentor"/> <lang.commenter language="Lombok.Config" implementationClass="de.plushnikov.intellij.plugin.language.LombokConfigCommentor"/>


<fileBasedIndex implementation="de.plushnikov.intellij.plugin.lombokconfig.LombokConfigIndex"/> <fileBasedIndex implementation="de.plushnikov.intellij.plugin.lombokconfig.LombokConfigIndex"/>

<custom.exception.handler implementation="de.plushnikov.intellij.plugin.handler.SneakyThrowsExceptionHandler"/>
</extensions> </extensions>


<extensions defaultExtensionNs="Lombook Plugin"> <extensions defaultExtensionNs="Lombook Plugin">
Expand Down

0 comments on commit 92b1b2c

Please sign in to comment.