package de.espend.idea.android.linemarker; import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import de.espend.idea.android.AndroidView; import de.espend.idea.android.utils.AndroidUtils; import de.espend.idea.android.utils.AndroidViewUtil; import icons.AndroidIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Collection; import java.util.List; public class ViewInflateLineMarker implements LineMarkerProvider { @Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) { return null; } @Override public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) { for(PsiElement psiElement : elements) { if(psiElement instanceof PsiMethodCallExpression) { attachFindViewByIdInflate((PsiMethodCallExpression) psiElement, result); attachFindViewByIdSetContentViews((PsiMethodCallExpression) psiElement, result); } } } private void attachFindViewByIdInflate(PsiMethodCallExpression psiMethodCallExpression, @NotNull Collection<LineMarkerInfo> result) { AndroidView androidView = AndroidViewUtil.getAndroidView(psiMethodCallExpression); if(androidView != null) { attachLineIcon(androidView, psiMethodCallExpression, result); } } private void attachFindViewByIdSetContentViews(PsiMethodCallExpression psiMethodCallExpression, @NotNull Collection<LineMarkerInfo> result) { PsiExpression[] psiExpressions = psiMethodCallExpression.getArgumentList().getExpressions(); if(psiExpressions.length == 0) { return; } PsiMethod psiMethodResolved = psiMethodCallExpression.resolveMethod(); if(psiMethodResolved == null) { return; } if("findViewById".equals(psiMethodResolved.getName())) { String viewId = psiExpressions[0].getText(); PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiMethodCallExpression, PsiMethod.class); if(psiMethod != null) { for(PsiFile psiFile : AndroidViewUtil.findLayoutFilesInsideMethod(psiMethod)) { AndroidView androidView = AndroidUtils.getViewType(psiFile, viewId); if(androidView != null) { attachLineIcon(androidView, psiMethodCallExpression, result); } } } } } private void attachLineIcon(@NotNull AndroidView view, @NotNull PsiElement psiElement, @NotNull Collection<LineMarkerInfo> result) { JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(psiElement.getProject()); PsiClass psiClass = psiFacade.findClass(view.getName(), GlobalSearchScope.allScope(psiElement.getProject())); if(psiClass == null) { return; } Icon icon = AndroidViewUtil.getCoreIconWithExtends(view, psiClass); if(icon == null) { icon = AndroidIcons.Views.View; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(icon). setTooltipText(view.getName()). setTargets(view.getXmlTarget()); result.add(builder.createLineMarkerInfo(psiElement)); } }