package com.jetbrains.dart.analysisServer;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.CommonProcessors;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.lang.dart.ide.findUsages.DartServerFindUsagesHandler;
import com.jetbrains.lang.dart.psi.impl.DartFileReference;
import com.jetbrains.lang.dart.util.DartTestUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
public class DartServerFindUsagesTest extends CodeInsightFixtureTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
DartTestUtils.configureDartSdk(myModule, myFixture.getTestRootDisposable(), true);
((CodeInsightTestFixtureImpl)myFixture).canChangeDocumentDuringHighlighting(true);
}
@NotNull
private Collection<UsageInfo> findUsages(@NotNull final SearchScope scope) {
final PsiElement elementToSearch = getFile().findElementAt(getEditor().getCaretModel().getOffset());
assertNotNull(elementToSearch);
final FindUsagesManager manager = ((FindManagerImpl)FindManager.getInstance(getProject())).getFindUsagesManager();
final FindUsagesHandler handler = manager.getFindUsagesHandler(elementToSearch, false);
assertInstanceOf(handler, DartServerFindUsagesHandler.class);
final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<>();
handler.processElementUsages(elementToSearch, processor, new FindUsagesOptions(scope));
return processor.getResults();
}
private void checkUsages(@NotNull final SearchScope scope, @NotNull final String... expected) {
final String[] actualResult = ContainerUtil.map2Array(findUsages(scope), String.class, info -> {
final PsiElement element = info.getElement();
assertNotNull(element);
final ProperTextRange range = info.getRangeInElement();
assertNotNull(range);
final int startOffset = element.getTextRange().getStartOffset() + range.getStartOffset();
final int endOffset = element.getTextRange().getStartOffset() + range.getEndOffset();
return element.getClass().getSimpleName() + " in " + element.getContainingFile().getName() + "@" + startOffset + ":" + endOffset +
(info.isDynamicUsage() ? " (dynamic usage)" : "") +
(info.isNonCodeUsage() ? " (non-code usage)" : "");
});
assertSameElements(actualResult, expected);
}
public void testBoolUsagesWithScope() throws Exception {
final PsiFile psiFile1 = myFixture.configureByText("file.dart", "/// [bool]\n" +
"<caret>bool foo() {\n" +
" var bool = #bool;\n" +
"}");
final PsiFile psiFile2 = myFixture.addFileToProject("file1.dart", "bool x;");
myFixture.doHighlighting(); // warm up
DartTestUtils.letAnalyzerSmellCoreFile(myFixture, "iterable.dart");
myFixture.openFileInEditor(psiFile1.getVirtualFile());
final String[] allProjectUsages = {"PsiCommentImpl in " + psiFile1.getName() + "@5:9 (non-code usage)",
"DartReferenceExpressionImpl in " + psiFile1.getName() + "@11:15",
"DartReferenceExpressionImpl in file1.dart@0:4"};
checkUsages(new LocalSearchScope(psiFile1),
"PsiCommentImpl in " + psiFile1.getName() + "@5:9 (non-code usage)",
"DartReferenceExpressionImpl in " + psiFile1.getName() + "@11:15");
checkUsages(new LocalSearchScope(psiFile2),
"DartReferenceExpressionImpl in file1.dart@0:4");
checkUsages(new LocalSearchScope(new PsiFile[]{psiFile1, psiFile2}), allProjectUsages);
checkUsages(GlobalSearchScope.fileScope(getProject(), psiFile1.getVirtualFile()),
"PsiCommentImpl in " + psiFile1.getName() + "@5:9 (non-code usage)",
"DartReferenceExpressionImpl in " + psiFile1.getName() + "@11:15");
checkUsages(GlobalSearchScope.fileScope(getProject(), psiFile2.getVirtualFile()), "DartReferenceExpressionImpl in file1.dart@0:4");
checkUsages(GlobalSearchScope.filesScope(getProject(), Arrays.asList(psiFile1.getVirtualFile(), psiFile2.getVirtualFile())),
allProjectUsages);
checkUsages(GlobalSearchScope.projectScope(getProject()), allProjectUsages);
final Collection<UsageInfo> usages = findUsages(GlobalSearchScope.allScope(getProject()));
assertTrue(String.valueOf(usages.size()), usages.size() > 15);
}
public void testDynamicAndNonCodeUsage() {
myFixture.configureByText("file.dart", "class Foo {\n" +
" /**\n" +
" * [bar] is awesome \n" +
" */\n" +
" var bar<caret>;\n" +
"}\n" +
"\n" +
"main () {\n" +
" Foo x;\n" +
" var y;\n" +
" x.bar; // hard reference \n" +
" y.bar; // potential usage \n" +
"}\n");
myFixture.doHighlighting(); // warm up
checkUsages(GlobalSearchScope.projectScope(getProject()),
"LeafPsiElement in " + getFile().getName() + "@24:27 (non-code usage)",
"DartReferenceExpressionImpl in " + getFile().getName() + "@93:96",
"DartReferenceExpressionImpl in " + getFile().getName() + "@122:125 (dynamic usage)");
}
public void testFileUsage() {
final PsiFile barFile = myFixture.configureByText("bar.dart", "");
// it is important that foo.dart is not open in the editor
myFixture.addFileToProject("foo.dart", "import '" + barFile.getName() + "';");
myFixture.doHighlighting(); // warm up
final FindUsagesManager manager = ((FindManagerImpl)FindManager.getInstance(getProject())).getFindUsagesManager();
final FindUsagesHandler handler = manager.getFindUsagesHandler(getFile(), false);
assertNotNull(handler);
assertFalse(handler instanceof DartServerFindUsagesHandler);
final Collection<PsiReference> usages = handler.findReferencesToHighlight(getFile(), GlobalSearchScope.allScope(getProject()));
assertSize(1, usages);
final PsiReference reference = usages.iterator().next();
assertInstanceOf(reference, DartFileReference.class);
assertEquals("foo.dart", reference.getElement().getContainingFile().getName());
assertEquals("import '" + barFile.getName() + "';", reference.getElement().getParent().getText());
}
}