package com.google.jstestdriver.idea.assertFramework.jstd; import com.google.jstestdriver.idea.assertFramework.jstd.jsSrc.JstdDefaultAssertionFrameworkSrcMarker; import com.google.jstestdriver.idea.assertFramework.library.JstdLibraryUtil; import com.google.jstestdriver.idea.assertFramework.support.AbstractMethodBasedInspection; import com.google.jstestdriver.idea.assertFramework.support.ChooseScopeAndCreateLibraryDialog; import com.google.jstestdriver.idea.util.JstdResolveUtil; import com.google.jstestdriver.idea.util.VfsUtils; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.lang.javascript.psi.JSCallExpression; import com.intellij.lang.javascript.psi.JSFile; import com.intellij.lang.javascript.psi.JSReferenceExpression; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.FileContentUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.webcore.ScriptingFrameworkDescriptor; import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.List; public class JstdAssertionFrameworkSupportInspection extends AbstractMethodBasedInspection { private static final AddJstdLibraryIntentionAction ADD_JSTD_LIBRARY_INTENTION_ACTION = new AddJstdLibraryIntentionAction(); @Override protected boolean isSuitableElement(@NotNull JSFile jsFile, @NotNull JSCallExpression callExpression) { JstdTestFileStructure structure = JstdTestFileStructureBuilder.getInstance().fetchCachedTestFileStructure(jsFile); String name = structure.getNameByPsiElement(callExpression.getMethodExpression()); return name != null; } @Override protected IntentionAction getFix() { return ADD_JSTD_LIBRARY_INTENTION_ACTION; } @Override protected String getProblemDescription() { return "No coding assistance for JsTestDriver assertion framework"; } @Override protected boolean isResolved(@NotNull JSReferenceExpression methodExpression) { if (JstdResolveUtil.isResolvedToFunction(methodExpression)) { return true; } VirtualFile virtualFile = PsiUtilCore.getVirtualFile(methodExpression); if (virtualFile != null) { return JstdLibraryUtil.isFileInJstdLibScope(methodExpression.getProject(), virtualFile); } return true; } private static class AddJstdLibraryIntentionAction implements IntentionAction { @NotNull @Override public String getText() { return "Add JsTestDriver assertion framework support"; } @NotNull @Override public String getFamilyName() { return getText(); } @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return file != null && file.isValid(); } @Override public void invoke(@NotNull final Project project, Editor editor, final PsiFile file) throws IncorrectOperationException { List<VirtualFile> sources = getLibrarySourceFiles(); final VirtualFile fileRequestor = PsiUtilCore.getVirtualFile(file); DialogWrapper dialog = new ChooseScopeAndCreateLibraryDialog( project, JstdLibraryUtil.LIBRARY_NAME, sources, new ScriptingFrameworkDescriptor(JstdLibraryUtil.LIBRARY_NAME, "1.3.5"), fileRequestor, false ); boolean done = dialog.showAndGet(); if (done) { FileContentUtil.reparseFiles(project, Collections.singletonList(fileRequestor), true); } } @Override public boolean startInWriteAction() { return false; } @NotNull private static List<VirtualFile> getLibrarySourceFiles() { return VfsUtils.findVirtualFilesByResourceNames( JstdDefaultAssertionFrameworkSrcMarker.class, new String[]{"Asserts.js", "TestCase.js"} ); } } }