1 package com
.intellij
.testAssistant
;
3 import com
.intellij
.codeHighlighting
.Pass
;
4 import com
.intellij
.codeInsight
.AnnotationUtil
;
5 import com
.intellij
.codeInsight
.daemon
.GutterIconNavigationHandler
;
6 import com
.intellij
.codeInsight
.daemon
.LineMarkerInfo
;
7 import com
.intellij
.codeInsight
.daemon
.LineMarkerProvider
;
8 import com
.intellij
.openapi
.fileEditor
.OpenFileDescriptor
;
9 import com
.intellij
.openapi
.fileTypes
.FileType
;
10 import com
.intellij
.openapi
.fileTypes
.FileTypeManager
;
11 import com
.intellij
.openapi
.project
.Project
;
12 import com
.intellij
.openapi
.roots
.ProjectFileIndex
;
13 import com
.intellij
.openapi
.roots
.ProjectRootManager
;
14 import com
.intellij
.openapi
.ui
.popup
.PopupChooserBuilder
;
15 import com
.intellij
.openapi
.util
.text
.StringUtil
;
16 import com
.intellij
.openapi
.vfs
.LocalFileSystem
;
17 import com
.intellij
.openapi
.vfs
.VirtualFile
;
18 import com
.intellij
.psi
.*;
19 import com
.intellij
.ui
.ColoredListCellRenderer
;
20 import com
.intellij
.ui
.awt
.RelativePoint
;
21 import com
.intellij
.util
.Icons
;
22 import org
.jetbrains
.annotations
.Nullable
;
25 import java
.awt
.event
.MouseEvent
;
27 import java
.util
.ArrayList
;
28 import java
.util
.Collection
;
29 import java
.util
.Collections
;
30 import java
.util
.List
;
35 public class TestDataLineMarkerProvider
implements LineMarkerProvider
{
36 public LineMarkerInfo
getLineMarkerInfo(PsiElement element
) {
37 if (!(element
instanceof PsiMethod
)) {
40 final PsiMethod method
= (PsiMethod
)element
;
41 String name
= method
.getName();
42 if (!name
.startsWith("test")) {
45 String testDataPath
= getTestDataBasePath(method
.getContainingClass());
46 if (testDataPath
!= null) {
47 List
<String
> fileNames
= new TestDataReferenceCollector(testDataPath
, name
.substring(4)).collectTestDataReferences(method
);
48 if (fileNames
.size() > 0) {
49 return new LineMarkerInfo
<PsiMethod
>(method
, method
.getTextOffset(), Icons
.TEST_SOURCE_FOLDER
, Pass
.UPDATE_ALL
, null,
50 new TestDataNavigationHandler(fileNames
));
56 public void collectSlowLineMarkers(List
<PsiElement
> elements
, Collection
<LineMarkerInfo
> result
) {
60 private static String
getTestDataBasePath(PsiClass psiClass
) {
61 final PsiAnnotation annotation
= AnnotationUtil
.findAnnotationInHierarchy(psiClass
, Collections
.singleton("com.intellij.testFramework.TestDataPath"));
62 if (annotation
!= null) {
63 final PsiAnnotationMemberValue value
= annotation
.findAttributeValue(PsiAnnotation
.DEFAULT_REFERENCED_METHOD_NAME
);
64 if (value
instanceof PsiExpression
) {
65 final PsiConstantEvaluationHelper evaluationHelper
= JavaPsiFacade
.getInstance(value
.getProject()).getConstantEvaluationHelper();
66 final Object constantValue
= evaluationHelper
.computeConstantExpression(value
, false);
67 if (constantValue
instanceof String
) {
68 String path
= (String
) constantValue
;
69 if (path
.indexOf("$CONTENT_ROOT") >= 0) {
70 final ProjectFileIndex fileIndex
= ProjectRootManager
.getInstance(psiClass
.getProject()).getFileIndex();
71 final VirtualFile contentRoot
= fileIndex
.getContentRootForFile(psiClass
.getContainingFile().getVirtualFile());
72 if (contentRoot
== null) return null;
73 path
= path
.replace("$CONTENT_ROOT", contentRoot
.getPath());
82 private static class TestDataNavigationHandler
implements GutterIconNavigationHandler
<PsiMethod
> {
83 private List
<String
> myFileNames
;
85 public TestDataNavigationHandler(List
<String
> fileNames
) {
86 myFileNames
= fileNames
;
89 public void navigate(MouseEvent e
, final PsiMethod elt
) {
90 if (myFileNames
.size() == 1) {
91 openFileByIndex(elt
.getProject(), 0);
94 TestDataGroupVirtualFile groupFile
= getTestDataGroup();
95 if (groupFile
!= null) {
96 new OpenFileDescriptor(elt
.getProject(), groupFile
).navigate(true);
99 showNavigationPopup(elt
.getProject(), e
);
105 private TestDataGroupVirtualFile
getTestDataGroup() {
106 if (myFileNames
.size() != 2) {
109 VirtualFile file1
= LocalFileSystem
.getInstance().findFileByPath(myFileNames
.get(0));
110 VirtualFile file2
= LocalFileSystem
.getInstance().findFileByPath(myFileNames
.get(1));
111 if (file1
== null || file2
== null) {
114 final int commonPrefixLength
= StringUtil
.commonPrefixLength(file1
.getName(), file2
.getName());
115 if (file1
.getName().substring(commonPrefixLength
).toLowerCase().contains("after")) {
116 return new TestDataGroupVirtualFile(file2
, file1
);
118 if (file2
.getName().substring(commonPrefixLength
).toLowerCase().contains("after")) {
119 return new TestDataGroupVirtualFile(file1
, file2
);
124 private void showNavigationPopup(final Project project
, MouseEvent e
) {
125 List
<String
> shortNames
= new ArrayList
<String
>();
126 for (String fileName
: myFileNames
) {
127 shortNames
.add(new File(fileName
).getName());
129 final JList list
= new JList(shortNames
.toArray(new String
[shortNames
.size()]));
130 list
.setCellRenderer(new ColoredListCellRenderer() {
132 protected void customizeCellRenderer(JList list
, Object value
, int index
, boolean selected
, boolean hasFocus
) {
133 String fileName
= (String
)value
;
134 final FileType fileType
= FileTypeManager
.getInstance().getFileTypeByFileName(fileName
);
135 setIcon(fileType
.getIcon());
139 PopupChooserBuilder builder
= new PopupChooserBuilder(list
);
140 builder
.setItemChoosenCallback(new Runnable() {
142 final int[] indices
= list
.getSelectedIndices();
143 for (int index
: indices
) {
144 openFileByIndex(project
, index
);
147 }).createPopup().show(new RelativePoint(e
));
150 private void openFileByIndex(final Project project
, final int index
) {
151 final VirtualFile file
= LocalFileSystem
.getInstance().findFileByPath(myFileNames
.get(index
));
153 new OpenFileDescriptor(project
, file
).navigate(true);