ProjectFileIndex: added methods to find content root and module for files under exclu...
[idea/community.git] / java / java-tests / testSrc / com / intellij / openapi / roots / impl / DirectoryIndexTest.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.roots.impl;
17
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.command.WriteCommandAction;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.fileTypes.FileTypeManager;
22 import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
23 import com.intellij.openapi.module.ModifiableModuleModel;
24 import com.intellij.openapi.module.Module;
25 import com.intellij.openapi.module.ModuleManager;
26 import com.intellij.openapi.module.StdModuleTypes;
27 import com.intellij.openapi.roots.*;
28 import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
29 import com.intellij.openapi.util.EmptyRunnable;
30 import com.intellij.openapi.util.io.FileUtil;
31 import com.intellij.openapi.vfs.*;
32 import com.intellij.testFramework.IdeaTestCase;
33 import com.intellij.testFramework.PlatformTestCase;
34 import com.intellij.testFramework.PsiTestUtil;
35 import gnu.trove.THashSet;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
38 import org.jetbrains.jps.model.java.JavaResourceRootType;
39 import org.jetbrains.jps.model.java.JavaSourceRootType;
40 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
41
42 import java.io.File;
43 import java.io.IOException;
44 import java.util.*;
45
46 import static java.util.Collections.singletonList;
47
48 @PlatformTestCase.WrapInCommand
49 public class DirectoryIndexTest extends IdeaTestCase {
50   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexTest");
51
52   private DirectoryIndexImpl myIndex;
53
54   private Module myModule2, myModule3;
55   private VirtualFile myRootVFile;
56   private VirtualFile myModule1Dir, myModule2Dir, myModule3Dir;
57   private VirtualFile mySrcDir1, mySrcDir2;
58   private VirtualFile myTestSrc1;
59   private VirtualFile myPack1Dir, myPack2Dir;
60   private VirtualFile myFileLibDir, myFileLibSrc, myFileLibCls;
61   private VirtualFile myLibDir, myLibSrcDir, myLibClsDir;
62   private VirtualFile myCvsDir;
63   private VirtualFile myExcludeDir;
64   private VirtualFile myOutputDir;
65   private VirtualFile myModule1OutputDir;
66   private VirtualFile myResDir, myTestResDir;
67   private VirtualFile myExcludedLibSrcDir, myExcludedLibClsDir;
68   private ProjectFileIndex myFileIndex;
69
70   @Override
71   protected void setUp() throws Exception {
72     super.setUp();
73
74     final File root = createTempDirectory();
75
76     ApplicationManager.getApplication().runWriteAction(new Runnable() {
77       @Override
78       public void run() {
79         try {
80           /*
81             root
82                 lib
83                     file.src
84                     file.cls
85                 module1
86                     src1
87                         pack1
88                         testSrc
89                             pack2
90                     res
91                     testRes
92                     lib
93                         src
94                           exc
95                         cls
96                           exc
97                     module2
98                         src2
99                             CVS
100                             excluded
101                 module3
102                 out
103                     module1
104           */
105           myRootVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(root);
106           assertNotNull(myRootVFile);
107
108           myFileLibDir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "lib");
109           myFileLibSrc = myFileLibDir.createChildData(DirectoryIndexTest.this, "file.src");
110           myFileLibCls = myFileLibDir.createChildData(DirectoryIndexTest.this, "file.cls");
111           myModule1Dir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "module1");
112           mySrcDir1 = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "src1");
113           myPack1Dir = mySrcDir1.createChildDirectory(DirectoryIndexTest.this, "pack1");
114           myTestSrc1 = mySrcDir1.createChildDirectory(DirectoryIndexTest.this, "testSrc");
115           myPack2Dir = myTestSrc1.createChildDirectory(DirectoryIndexTest.this, "pack2");
116           myResDir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "res");
117           myTestResDir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "testRes");
118
119           myLibDir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "lib");
120           myLibSrcDir = myLibDir.createChildDirectory(DirectoryIndexTest.this, "src");
121           myExcludedLibSrcDir = myLibSrcDir.createChildDirectory(DirectoryIndexTest.this, "exc");
122           myLibClsDir = myLibDir.createChildDirectory(DirectoryIndexTest.this, "cls");
123           myExcludedLibClsDir = myLibClsDir.createChildDirectory(DirectoryIndexTest.this, "exc");
124           myModule2Dir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "module2");
125           mySrcDir2 = myModule2Dir.createChildDirectory(DirectoryIndexTest.this, "src2");
126           myCvsDir = mySrcDir2.createChildDirectory(DirectoryIndexTest.this, "CVS");
127           myExcludeDir = mySrcDir2.createChildDirectory(DirectoryIndexTest.this, "excluded");
128
129           myModule3Dir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "module3");
130
131           myOutputDir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "out");
132           myModule1OutputDir = myOutputDir.createChildDirectory(DirectoryIndexTest.this, "module1");
133
134           getCompilerProjectExtension().setCompilerOutputUrl(myOutputDir.getUrl());
135           ModuleManager moduleManager = ModuleManager.getInstance(myProject);
136
137           // fill roots of module1
138           {
139             ModuleRootModificationUtil.setModuleSdk(myModule, null);
140             PsiTestUtil.addContentRoot(myModule, myModule1Dir);
141             PsiTestUtil.addSourceRoot(myModule, mySrcDir1);
142             PsiTestUtil.addSourceRoot(myModule, myTestSrc1, true);
143             PsiTestUtil.addSourceRoot(myModule, myResDir, JavaResourceRootType.RESOURCE);
144             PsiTestUtil.addSourceRoot(myModule, myTestResDir, JavaResourceRootType.TEST_RESOURCE);
145
146             ModuleRootModificationUtil.addModuleLibrary(myModule, "lib.js",
147                                                         singletonList(myFileLibCls.getUrl()), singletonList(myFileLibSrc.getUrl()));
148             PsiTestUtil.addExcludedRoot(myModule, myExcludedLibClsDir);
149             PsiTestUtil.addExcludedRoot(myModule, myExcludedLibSrcDir);
150           }
151
152           // fill roots of module2
153           {
154             VirtualFile moduleFile = myModule2Dir.createChildData(DirectoryIndexTest.this, "module2.iml");
155             myModule2 = moduleManager.newModule(moduleFile.getPath(), StdModuleTypes.JAVA.getId());
156
157             PsiTestUtil.addContentRoot(myModule2, myModule2Dir);
158             PsiTestUtil.addSourceRoot(myModule2, mySrcDir2);
159             PsiTestUtil.addExcludedRoot(myModule2, myExcludeDir);
160             ModuleRootModificationUtil.addModuleLibrary(myModule2, "lib",
161                                                         singletonList(myLibClsDir.getUrl()), singletonList(myLibSrcDir.getUrl()),
162                                                         Arrays.asList(myExcludedLibClsDir.getUrl(), myExcludedLibSrcDir.getUrl()), DependencyScope.COMPILE, true);
163           }
164
165           // fill roots of module3
166           {
167             VirtualFile moduleFile = myModule3Dir.createChildData(DirectoryIndexTest.this, "module3.iml");
168             myModule3 = moduleManager.newModule(moduleFile.getPath(), StdModuleTypes.JAVA.getId());
169
170             PsiTestUtil.addContentRoot(myModule3, myModule3Dir);
171             ModuleRootModificationUtil.addDependency(myModule3, myModule2);
172           }
173         }
174         catch (IOException e) {
175           LOG.error(e);
176         }
177       }
178     });
179
180     myIndex = (DirectoryIndexImpl)DirectoryIndex.getInstance(myProject);
181     myFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
182     // to not interfere with previous test firing vfs events
183     VirtualFileManager.getInstance().syncRefresh();
184   }
185
186   private CompilerProjectExtension getCompilerProjectExtension() {
187     final CompilerProjectExtension instance = CompilerProjectExtension.getInstance(myProject);
188     assertNotNull(instance);
189     return instance;
190   }
191
192   public void testDirInfos() throws IOException {
193     assertNotInProject(myRootVFile);
194
195     // beware: files in directory index
196     checkInfo(myFileLibSrc, null, false, true, "", null, myModule);
197     checkInfo(myFileLibCls, null, true, false, "", null, myModule);
198
199     checkInfo(myModule1Dir, myModule, false, false, null, null);
200     checkInfo(mySrcDir1, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
201     checkInfo(myPack1Dir, myModule, false, false, "pack1", JavaSourceRootType.SOURCE, myModule);
202     checkInfo(myTestSrc1, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule);
203     checkInfo(myPack2Dir, myModule, false, false, "pack2", JavaSourceRootType.TEST_SOURCE, myModule);
204     checkInfo(myResDir, myModule, false, false, "", JavaResourceRootType.RESOURCE, myModule);
205     checkInfo(myTestResDir, myModule, false, false, "", JavaResourceRootType.TEST_RESOURCE, myModule);
206
207     checkInfo(myLibDir, myModule, false, false, null, null);
208     checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3);
209     checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3);
210     
211     assertEquals(myLibSrcDir, assertInProject(myLibSrcDir).getSourceRoot());
212
213     checkInfo(myModule2Dir, myModule2, false, false, null, null);
214     checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
215     assertNotInProject(myCvsDir);
216     assertExcluded(myExcludeDir, myModule2);
217     assertExcluded(myExcludedLibClsDir, myModule);
218     assertExcluded(myExcludedLibSrcDir, myModule);
219
220     assertEquals(myModule1Dir, assertInProject(myLibClsDir).getContentRoot());
221
222     checkInfo(myModule3Dir, myModule3, false, false, null, null);
223
224     VirtualFile cvs = myPack1Dir.createChildDirectory(this, "CVS");
225     assertNotInProject(cvs);
226     assertNull(myFileIndex.getPackageNameByDirectory(cvs));
227   }
228
229   public void testDirsByPackageName() throws IOException {
230     checkPackage("", true, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibSrcDir, myLibClsDir);
231     checkPackage("", false, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibClsDir);
232     
233     checkPackage("pack1", true, myPack1Dir);
234     checkPackage("pack1", false, myPack1Dir);
235     
236     checkPackage("pack2", true, myPack2Dir);
237     checkPackage("pack2", false, myPack2Dir);
238     
239     checkPackage(".pack2", false);
240     checkPackage(".pack2", true);
241
242     VirtualFile libClsPack = myLibClsDir.createChildDirectory(this, "pack1");
243     VirtualFile libSrcPack = myLibSrcDir.createChildDirectory(this, "pack1");
244     fireRootsChanged();
245     checkPackage("pack1", true, myPack1Dir, libSrcPack, libClsPack);
246     checkPackage("pack1", false, myPack1Dir, libClsPack);
247   }
248
249   public void testDirectoriesWithPackagePrefix() {
250     PsiTestUtil.addSourceRoot(myModule3, myModule3Dir);
251     WriteCommandAction.runWriteCommandAction(myProject, new Runnable() {
252       @Override
253       public void run() {
254         final ModifiableRootModel model = ModuleRootManager.getInstance(myModule3).getModifiableModel();
255         model.getContentEntries()[0].getSourceFolders()[0].setPackagePrefix("pack1");
256         model.commit();
257       }
258     });
259     checkPackage("pack1", true, myPack1Dir, myModule3Dir);
260   }
261
262   public void testPackageDirectoriesWithDots() throws IOException {
263     VirtualFile fooBar = mySrcDir1.createChildDirectory(this, "foo.bar");
264     VirtualFile goo1 = fooBar.createChildDirectory(this, "goo");
265     VirtualFile foo = mySrcDir2.createChildDirectory(this, "foo");
266     VirtualFile bar = foo.createChildDirectory(this, "bar");
267     VirtualFile goo2 = bar.createChildDirectory(this, "goo");
268
269     checkPackage("foo", false, foo);
270     checkPackage("foo.bar", false, bar, fooBar);
271     checkPackage("foo.bar.goo", false, goo2, goo1);
272   }
273
274   public void testCreateDir() throws Exception {
275     String path = mySrcDir1.getPath().replace('/', File.separatorChar);
276     assertTrue(new File(path + File.separatorChar + "dir1" + File.separatorChar + "dir2").mkdirs());
277     assertTrue(new File(path + File.separatorChar + "CVS").mkdirs());
278     VirtualFileManager.getInstance().syncRefresh();
279
280     myIndex.checkConsistency();
281   }
282
283   public void testDeleteDir() throws Exception {
284     VirtualFile subdir1 = mySrcDir1.createChildDirectory(this, "subdir1");
285     VirtualFile subdir2 = subdir1.createChildDirectory(this, "subdir2");
286     subdir2.createChildDirectory(this, "subdir3");
287
288     myIndex.checkConsistency();
289
290     subdir1.delete(this);
291
292     myIndex.checkConsistency();
293   }
294
295   public void testMoveDir() throws Exception {
296     VirtualFile subdir = mySrcDir2.createChildDirectory(this, "subdir1");
297     subdir.createChildDirectory(this, "subdir2");
298
299     myIndex.checkConsistency();
300
301     subdir.move(this, mySrcDir1);
302
303     myIndex.checkConsistency();
304   }
305
306   public void testRenameDir() throws Exception {
307     VirtualFile subdir = mySrcDir2.createChildDirectory(this, "subdir1");
308     subdir.createChildDirectory(this, "subdir2");
309
310     myIndex.checkConsistency();
311
312     subdir.rename(this, "abc.d");
313
314     myIndex.checkConsistency();
315   }
316
317   public void testRenameRoot() throws Exception {
318     myModule1Dir.rename(this, "newName");
319
320     myIndex.checkConsistency();
321   }
322
323   public void testMoveRoot() throws Exception {
324     myModule1Dir.move(this, myModule3Dir);
325
326     myIndex.checkConsistency();
327   }
328
329   public void testAddProjectDir() throws Exception {
330     new WriteCommandAction.Simple(getProject()) {
331       @Override
332       protected void run() throws Throwable {
333         VirtualFile newDir = myModule1Dir.getParent().createChildDirectory(DirectoryIndexTest.this, "newDir");
334         newDir.createChildDirectory(DirectoryIndexTest.this, "subdir");
335
336         myIndex.checkConsistency();
337         PsiTestUtil.addContentRoot(myModule, newDir);
338       }
339     }.execute().throwException();
340
341
342     myIndex.checkConsistency();
343   }
344
345   public void testChangeIgnoreList() throws Exception {
346     VirtualFile newDir = myModule1Dir.createChildDirectory(this, "newDir");
347     
348     myIndex.checkConsistency();
349     assertInProject(newDir);
350
351     final FileTypeManagerEx fileTypeManager = (FileTypeManagerEx)FileTypeManager.getInstance();
352     final String list = fileTypeManager.getIgnoredFilesList();
353     final String list1 = list + ";" + "newDir";
354     try {
355       ApplicationManager.getApplication().runWriteAction(new Runnable() {
356         @Override
357         public void run() {
358           fileTypeManager.setIgnoredFilesList(list1);
359         }
360       });
361       myIndex.checkConsistency();
362       assertNotInProject(newDir);
363     }
364     finally {
365       ApplicationManager.getApplication().runWriteAction(new Runnable() {
366         @Override
367         public void run() {
368           fileTypeManager.setIgnoredFilesList(list);
369         }
370       });
371       assertInProject(newDir);
372     }
373   }
374
375   public void testIgnoredFile() throws IOException {
376     VirtualFile ignoredFile = myModule1Dir.createChildData(this, "CVS");
377     DirectoryInfo info = myIndex.getInfoForFile(ignoredFile);
378     assertTrue(info.isIgnored());
379     assertTrue(myFileIndex.isExcluded(ignoredFile));
380     assertTrue(myFileIndex.isUnderIgnored(ignoredFile));
381     assertNull(myFileIndex.getContentRootForFile(ignoredFile, false));
382     assertNull(myFileIndex.getModuleForFile(ignoredFile, false));
383   }
384
385   public void testAddModule() throws Exception {
386     myIndex.checkConsistency();
387
388     new WriteCommandAction.Simple(getProject()) {
389       @Override
390       protected void run() throws Throwable {
391         VirtualFile newModuleContent = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "newModule");
392         newModuleContent.createChildDirectory(DirectoryIndexTest.this, "subDir");
393         ModuleManager moduleManager = ModuleManager.getInstance(myProject);
394         Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
395         PsiTestUtil.addContentRoot(module, newModuleContent);
396       }
397     }.execute().throwException();
398
399
400     myIndex.checkConsistency();
401   }
402
403   public void testModuleUnderIgnoredDir() throws IOException {
404     final VirtualFile ignored = myRootVFile.createChildDirectory(this, "RCS");
405     assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
406     assertTrue(myFileIndex.isExcluded(ignored));
407     assertTrue(myFileIndex.isUnderIgnored(ignored));
408     final VirtualFile module4 = ignored.createChildDirectory(this, "module4");
409     assertFalse(FileTypeManager.getInstance().isFileIgnored(module4));
410     assertTrue(myFileIndex.isExcluded(module4));
411     assertTrue(myFileIndex.isUnderIgnored(module4));
412
413     new WriteCommandAction.Simple(getProject()) {
414       @Override
415       protected void run() throws Throwable {
416         ModuleManager moduleManager = ModuleManager.getInstance(myProject);
417         Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
418         PsiTestUtil.addContentRoot(module, module4);
419         assertNotInProject(ignored);
420         checkInfo(module4, module, false, false, null, null);
421       }
422     }.execute().throwException();
423
424   }
425
426   public void testModuleInIgnoredDir() throws IOException {
427     final VirtualFile ignored = myRootVFile.createChildDirectory(this, "RCS");
428     assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
429     
430     new WriteCommandAction.Simple(getProject()) {
431       @Override
432       protected void run() throws Throwable {
433         ModuleManager moduleManager = ModuleManager.getInstance(myProject);
434         ModifiableModuleModel model = moduleManager.getModifiableModel();
435         model.disposeModule(myModule);
436         model.disposeModule(myModule2);
437         model.disposeModule(myModule3);
438         model.commit();
439         Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
440         PsiTestUtil.addContentRoot(module, ignored);
441         checkInfo(ignored, module, false, false, null, null);
442       }
443     }.execute().throwException();
444   }
445
446   public void testExcludedDirsInLibraries() {
447     assertFalse(myFileIndex.isInLibraryClasses(myExcludedLibClsDir));
448     assertTrue(myFileIndex.isExcluded(myExcludedLibClsDir));
449     assertFalse(myFileIndex.isUnderIgnored(myExcludedLibClsDir));
450     assertFalse(myFileIndex.isInLibrarySource(myExcludedLibSrcDir));
451     assertTrue(myFileIndex.isExcluded(myExcludedLibSrcDir));
452     assertFalse(myFileIndex.isUnderIgnored(myExcludedLibSrcDir));
453   }
454
455   public void testExplicitExcludeOfInner() throws Exception {
456     PsiTestUtil.addExcludedRoot(myModule, myModule2Dir);
457
458     myIndex.checkConsistency();
459
460     checkInfo(myModule2Dir, myModule2, false, false, null, null);
461     checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
462   }
463
464   public void testResettingProjectOutputPath() throws Exception {
465     VirtualFile output1 = myModule1Dir.createChildDirectory(this, "output1");
466     VirtualFile output2 = myModule1Dir.createChildDirectory(this, "output2");
467
468     assertInProject(output1);
469     assertInProject(output2);
470
471     getCompilerProjectExtension().setCompilerOutputUrl(output1.getUrl());
472     fireRootsChanged();
473
474     assertExcluded(output1, myModule);
475     assertInProject(output2);
476
477     getCompilerProjectExtension().setCompilerOutputUrl(output2.getUrl());
478     fireRootsChanged();
479
480     assertInProject(output1);
481     assertExcluded(output2, myModule);
482   }
483
484   private void fireRootsChanged() {
485     ProjectRootManagerEx.getInstanceEx(getProject()).makeRootsChange(EmptyRunnable.getInstance(), false, true);
486   }
487
488   public void testModuleSourceAsLibrarySource() throws Exception {
489     ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.<String>emptyList(), Arrays.asList(mySrcDir1.getUrl()));
490     
491     checkInfo(mySrcDir1, myModule, false, true, "", JavaSourceRootType.SOURCE, myModule, myModule);
492     OrderEntry[] entries = myIndex.getOrderEntries(myIndex.getInfoForFile(mySrcDir1));
493     assertInstanceOf(entries[0], LibraryOrderEntry.class);
494     assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
495
496     checkInfo(myTestSrc1, myModule, false, true, "testSrc", JavaSourceRootType.TEST_SOURCE, myModule, myModule);
497     entries = myIndex.getOrderEntries(myIndex.getInfoForFile(myTestSrc1));
498     assertInstanceOf(entries[0], LibraryOrderEntry.class);
499     assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
500   }
501
502   public void testModuleSourceAsLibraryClasses() throws Exception {
503     ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Arrays.asList(mySrcDir1.getUrl()), Collections.<String>emptyList());
504     checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
505     assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(mySrcDir1))), ModuleSourceOrderEntry.class);
506   }
507
508   public void testModulesWithSameSourceContentRoot() {
509     // now our API allows this (ReformatCodeActionTest), although UI doesn't. Maybe API shouldn't allow it as well?
510     PsiTestUtil.addContentRoot(myModule2, myModule1Dir);
511     PsiTestUtil.addSourceRoot(myModule2, mySrcDir1);
512
513     checkInfo(myModule1Dir, myModule, false, false, null, null);
514     checkInfo(mySrcDir1, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule3, myModule);
515     checkInfo(myTestSrc1, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule3, myModule);
516     checkInfo(myResDir, myModule, false, false, "", JavaResourceRootType.RESOURCE, myModule);
517
518     checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
519     assertEquals(myModule2Dir, myIndex.getInfoForFile(mySrcDir2).getContentRoot());
520   }
521
522   public void testModuleWithSameSourceRoot() {
523     PsiTestUtil.addSourceRoot(myModule2, mySrcDir1);
524     checkInfo(mySrcDir1, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
525     checkInfo(myTestSrc1, myModule2, false, false, "testSrc", JavaSourceRootType.SOURCE, myModule2, myModule3);
526   }
527
528   public void testModuleContentUnderSourceRoot() {
529     PsiTestUtil.addContentRoot(myModule2, myPack1Dir);
530     checkInfo(myPack1Dir, myModule2, false, false, null, null);
531   }
532
533   public void testSameSourceAndOutput() {
534     PsiTestUtil.setCompilerOutputPath(myModule, mySrcDir1.getUrl(), false);
535     assertExcluded(mySrcDir1, myModule);
536   }
537
538   public void testExcludedDirShouldBeExcludedRightAfterItsCreation() throws Exception {
539     VirtualFile excluded = myModule1Dir.createChildDirectory(this, "excluded");
540     VirtualFile projectOutput = myModule1Dir.createChildDirectory(this, "projectOutput");
541     VirtualFile module2Output = myModule1Dir.createChildDirectory(this, "module2Output");
542     VirtualFile module2TestOutput = myModule2Dir.createChildDirectory(this, "module2TestOutput");
543
544     assertInProject(excluded);
545     assertInProject(projectOutput);
546     assertInProject(module2Output);
547     assertInProject(module2TestOutput);
548
549     getCompilerProjectExtension().setCompilerOutputUrl(projectOutput.getUrl());
550
551     PsiTestUtil.addExcludedRoot(myModule, excluded);
552     PsiTestUtil.setCompilerOutputPath(myModule2, module2Output.getUrl(), false);
553     PsiTestUtil.setCompilerOutputPath(myModule2, module2TestOutput.getUrl(), true);
554     PsiTestUtil.setExcludeCompileOutput(myModule2, true);
555
556     assertExcluded(excluded, myModule);
557     assertExcluded(projectOutput, myModule);
558     assertExcluded(module2Output, myModule);
559     assertExcluded(module2TestOutput, myModule2);
560
561     excluded.delete(this);
562     projectOutput.delete(this);
563     module2Output.delete(this);
564     module2TestOutput.delete(this);
565
566     final List<VirtualFile> created = new ArrayList<VirtualFile>();
567     VirtualFileListener l = new VirtualFileAdapter() {
568       @Override
569       public void fileCreated(@NotNull VirtualFileEvent e) {
570         VirtualFile file = e.getFile();
571         String fileName = e.getFileName();
572         assertExcluded(file, fileName.contains("module2TestOutput") ? myModule2 : myModule);
573         created.add(file);
574       }
575     };
576     VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable());
577     
578     excluded = myModule1Dir.createChildDirectory(this, excluded.getName());
579     assertExcluded(excluded, myModule);
580
581     projectOutput = myModule1Dir.createChildDirectory(this, projectOutput.getName());
582     assertExcluded(projectOutput, myModule);
583
584     module2Output = myModule1Dir.createChildDirectory(this, module2Output.getName());
585     assertExcluded(module2Output, myModule);
586
587     module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName());
588     assertExcluded(module2TestOutput, myModule2);
589
590     assertEquals(created.toString(), 4, created.size());
591   }
592
593   public void testExcludesShouldBeRecognizedRightOnRefresh() throws Exception {
594     final VirtualFile dir = myModule1Dir.createChildDirectory(this, "dir");
595     final VirtualFile excluded = dir.createChildDirectory(this, "excluded");
596     PsiTestUtil.addExcludedRoot(myModule, excluded);
597     new WriteCommandAction.Simple(getProject()) {
598       @Override
599       protected void run() throws Throwable {
600         dir.delete(DirectoryIndexTest.this);
601       }
602     }.execute().throwException();
603
604
605     boolean created = new File(myModule1Dir.getPath(), "dir/excluded/foo").mkdirs();
606     assertTrue(created);
607
608     VirtualFileListener l = new VirtualFileAdapter() {
609       @Override
610       public void fileCreated(@NotNull VirtualFileEvent e) {
611         assertEquals("dir", e.getFileName());
612
613         VirtualFile file = e.getFile();
614         assertInProject(file);
615         assertExcluded(file.findFileByRelativePath("excluded"), myModule);
616         assertExcluded(file.findFileByRelativePath("excluded/foo"), myModule);
617       }
618     };
619
620     VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable());
621     VirtualFileManager.getInstance().syncRefresh();
622   }
623
624   public void testProcessingNestedContentRootsOfExcludedDirsOnCreation() {
625     String rootPath = myModule1Dir.getPath();
626     final File f = new File(rootPath, "excludedDir/dir/anotherContentRoot");
627     ApplicationManager.getApplication().runWriteAction(new Runnable() {
628       @Override
629       public void run() {
630         ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
631         rootModel.getContentEntries()[0]
632           .addExcludeFolder(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(f.getParentFile().getParent())));
633         rootModel.commit();
634
635         rootModel = ModuleRootManager.getInstance(myModule2).getModifiableModel();
636         rootModel.addContentEntry(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(f.getPath())));
637         rootModel.commit();
638
639         assertTrue(f.getPath(), f.exists() || f.mkdirs());
640         LocalFileSystem.getInstance().refresh(false);
641       }
642     });
643
644
645     assertExcluded(LocalFileSystem.getInstance().findFileByIoFile(f.getParentFile().getParentFile()), myModule);
646     assertInProject(LocalFileSystem.getInstance().findFileByIoFile(f));
647   }
648
649   public void testLibraryDirInContent() throws Exception {
650     ModuleRootModificationUtil.addModuleLibrary(myModule, myModule1Dir.getUrl());
651
652     myIndex.checkConsistency();
653
654     checkInfo(myModule1Dir, myModule, true, false, "", null, myModule);
655     checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
656
657     checkInfo(myModule2Dir, myModule2, true, false, "module2", null, myModule);
658     checkInfo(mySrcDir2, myModule2, true, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
659     checkInfo(myExcludeDir, null, true, false, "module2.src2.excluded", null, myModule3);
660
661     checkInfo(myLibDir, myModule, true, false, "lib", null, myModule);
662     checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3);
663
664     //myModule is included into order entries instead of myModule2 because classes root for libraries dominates on source roots
665     checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3);
666     
667     checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule);
668     assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(myResDir))), ModuleSourceOrderEntry.class);
669
670     checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule);
671     checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3);
672
673     checkPackage("lib.src.exc", true, myExcludedLibSrcDir);
674     checkPackage("lib.cls.exc", true, myExcludedLibClsDir);
675     
676     checkPackage("lib.src", true);
677     checkPackage("lib.cls", true);
678     
679     checkPackage("exc", false);
680     checkPackage("exc", true);
681   }
682
683   public void testExcludeCompilerOutputOutsideOfContentRoot() throws Exception {
684     assertTrue(myFileIndex.isExcluded(myOutputDir));
685     assertFalse(myFileIndex.isUnderIgnored(myOutputDir));
686     assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
687     assertFalse(myFileIndex.isExcluded(myOutputDir.getParent()));
688     assertExcludedFromProject(myOutputDir);
689     assertExcludedFromProject(myModule1OutputDir);
690     String moduleOutputUrl = myModule1OutputDir.getUrl();
691
692     myOutputDir.delete(this);
693
694     PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, false);
695     myOutputDir = myRootVFile.createChildDirectory(this, "out");
696     myModule1OutputDir = myOutputDir.createChildDirectory(this, "module1");
697
698     assertExcludedFromProject(myOutputDir);
699     assertExcludedFromProject(myModule1OutputDir);
700     assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
701
702     PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true);
703     PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, false);
704     PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, true);
705     PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, false);
706     PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, true);
707     
708     // now no module inherits project output dir, but it still should be project-excluded
709     assertExcludedFromProject(myOutputDir);
710
711     // project output inside module content shouldn't be projectExcludeRoot
712     VirtualFile projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent");
713     getCompilerProjectExtension().setCompilerOutputUrl(projectOutputUnderContent.getUrl());
714     fireRootsChanged();
715
716     assertNotExcluded(myOutputDir);
717     assertExcluded(projectOutputUnderContent, myModule);
718
719     projectOutputUnderContent.delete(this);
720     projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent");
721     assertNotExcluded(myOutputDir);
722     assertExcluded(projectOutputUnderContent, myModule);
723   }
724
725   public void testFileContentAndSourceRoots() throws IOException {
726     VirtualFile fileRoot = myRootVFile.createChildData(this, "fileRoot.txt");
727     VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
728     VirtualFile fileTestSourceRoot = myRootVFile.createChildData(this, "fileTestSourceRoot.txt");
729
730     assertNotInProject(fileRoot);
731     assertFalse(myFileIndex.isInContent(fileRoot));
732     assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot));
733
734     ContentEntry contentEntry = PsiTestUtil.addContentRoot(myModule, fileRoot);
735     assertEquals(fileRoot, contentEntry.getFile());
736     checkInfo(fileRoot, myModule, false, false, "", null);
737     assertTrue(myFileIndex.isInContent(fileRoot));
738     assertFalse(myFileIndex.isInSource(fileRoot));
739  
740     PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
741     PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
742     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
743     assertTrue(myFileIndex.isInContent(fileSourceRoot));
744     assertTrue(myFileIndex.isInSource(fileSourceRoot));
745  
746     PsiTestUtil.addContentRoot(myModule, fileTestSourceRoot);
747     PsiTestUtil.addSourceRoot(myModule, fileTestSourceRoot, true);
748     checkInfo(fileTestSourceRoot, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule);
749     assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
750     assertTrue(myFileIndex.isInSource(fileTestSourceRoot));
751
752     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
753
754     // removing file source root
755     PsiTestUtil.removeSourceRoot(myModule, fileTestSourceRoot);
756     checkInfo(fileTestSourceRoot, myModule, false, false, "", null);
757     assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
758     assertFalse(myFileIndex.isInSource(fileTestSourceRoot));
759     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
760  
761     // removing file content root
762     PsiTestUtil.removeContentEntry(myModule, contentEntry.getFile());
763     assertNotInProject(fileRoot);
764     assertFalse(myFileIndex.isInContent(fileRoot));
765     assertFalse(myFileIndex.isInSource(fileRoot));
766     assertIteratedContent(myFileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Arrays.asList(fileRoot));
767   }
768
769   private void assertIteratedContent(ProjectFileIndex fileIndex,
770                                      @Nullable List<VirtualFile> contains,
771                                      @Nullable List<VirtualFile> doesntContain) {
772     final Set<VirtualFile> collected = new THashSet<VirtualFile>();
773     fileIndex.iterateContent(new ContentIterator() {
774       @Override
775       public boolean processFile(VirtualFile fileOrDir) {
776         collected.add(fileOrDir);
777         return true;
778       }
779     });
780     if (contains != null) assertContainsElements(collected, contains);
781     if (doesntContain != null) assertDoesntContain(collected, doesntContain);
782   }
783
784   public void testFileSourceRootsUnderDirContentRoot() throws IOException {
785     VirtualFile fileSourceRoot = myModule1Dir.createChildData(this, "fileSourceRoot.txt");
786     assertTrue(myFileIndex.isInContent(fileSourceRoot));
787     assertFalse(myFileIndex.isInSource(fileSourceRoot));
788
789     PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
790     assertTrue(myFileIndex.isInContent(fileSourceRoot));
791     assertTrue(myFileIndex.isInSource(fileSourceRoot));
792     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
793
794     // removing file source root
795     PsiTestUtil.removeSourceRoot(myModule, fileSourceRoot);
796     assertTrue(myFileIndex.isInContent(fileSourceRoot));
797     assertFalse(myFileIndex.isInSource(fileSourceRoot));
798   }
799
800   public void testFileModuleExcludeRootUnderDirectoryRoot() throws IOException {
801     VirtualFile fileExcludeRoot = mySrcDir1.createChildData(this, "fileExcludeRoot.txt");
802     assertTrue(myFileIndex.isInContent(fileExcludeRoot));
803     assertTrue(myFileIndex.isInSource(fileExcludeRoot));
804     assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
805
806     PsiTestUtil.addExcludedRoot(myModule, fileExcludeRoot);
807     assertFalse(myFileIndex.isInContent(fileExcludeRoot));
808     assertFalse(myFileIndex.isInSource(fileExcludeRoot));
809     assertNull(myFileIndex.getContentRootForFile(fileExcludeRoot));
810     assertEquals(myModule1Dir, myFileIndex.getContentRootForFile(fileExcludeRoot, false));
811     assertNull(myFileIndex.getModuleForFile(fileExcludeRoot));
812     assertEquals(myModule, myFileIndex.getModuleForFile(fileExcludeRoot, false));
813     assertExcluded(fileExcludeRoot, myModule);
814     assertIteratedContent(myFileIndex, null, Arrays.asList(fileExcludeRoot));
815
816     // removing file exclude root
817     PsiTestUtil.removeExcludedRoot(myModule, fileExcludeRoot);
818     assertTrue(myFileIndex.isInContent(fileExcludeRoot));
819     assertTrue(myFileIndex.isInSource(fileExcludeRoot));
820     assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
821   }
822
823   public void testFileModuleExcludeRootUnderFileRoot() throws IOException {
824     VirtualFile fileRoot = myRootVFile.createChildData(this, "fileRoot.txt");
825     PsiTestUtil.addContentRoot(myModule, fileRoot);
826     checkInfo(fileRoot, myModule, false, false, "", null);
827     assertTrue(myFileIndex.isInContent(fileRoot));
828     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
829     
830     PsiTestUtil.addExcludedRoot(myModule, fileRoot);
831     assertFalse(myFileIndex.isInContent(fileRoot));
832     assertExcluded(fileRoot, myModule);
833     assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot));
834  
835     // removing file exclude root
836     PsiTestUtil.removeExcludedRoot(myModule, fileRoot);
837     checkInfo(fileRoot, myModule, false, false, "", null);
838     assertTrue(myFileIndex.isInContent(fileRoot));
839     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
840   }
841
842   public void testFileLibraryInsideFolderLibrary() throws IOException {
843     VirtualFile file = myLibSrcDir.createChildData(this, "empty.txt");
844     ModuleRootModificationUtil.addModuleLibrary(myModule2, "lib2",
845                                                 Collections.<String>emptyList(), singletonList(file.getUrl()),
846                                                 Collections.<String>emptyList(), DependencyScope.COMPILE, true);
847
848     // same for the dir and for the file
849     checkInfo(file, myModule, false, true, "", null, myModule2, myModule3);
850     checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3);
851   }
852
853   public void testFileContentRootsModifications() throws IOException {
854     VirtualFile temp = myRootVFile.createChildDirectory(this, "temp");
855
856     VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
857     assertNotInProject(fileSourceRoot);
858
859     PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
860     PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
861     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
862     assertTrue(myFileIndex.isInContent(fileSourceRoot));
863     assertTrue(myFileIndex.isInSource(fileSourceRoot));
864
865     // delete and recreate
866     fileSourceRoot.delete(this);
867     assertNotInProject(fileSourceRoot);
868     assertFalse(myFileIndex.isInContent(fileSourceRoot));
869     assertFalse(myFileIndex.isInSource(fileSourceRoot));
870     fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
871     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
872     assertTrue(myFileIndex.isInContent(fileSourceRoot));
873     assertTrue(myFileIndex.isInSource(fileSourceRoot));
874
875     // delete and move from another dir 
876     fileSourceRoot.delete(this);
877     assertNotInProject(fileSourceRoot);
878     assertFalse(myFileIndex.isInContent(fileSourceRoot));
879     assertFalse(myFileIndex.isInSource(fileSourceRoot));
880     fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
881     assertNotInProject(fileSourceRoot);
882     fileSourceRoot.move(this, myRootVFile);
883     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
884     assertTrue(myFileIndex.isInContent(fileSourceRoot));
885     assertTrue(myFileIndex.isInSource(fileSourceRoot));
886
887     // delete and copy from another dir 
888     fileSourceRoot.delete(this);
889     assertNotInProject(fileSourceRoot);
890     assertFalse(myFileIndex.isInContent(fileSourceRoot));
891     assertFalse(myFileIndex.isInSource(fileSourceRoot));
892     fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
893     assertNotInProject(fileSourceRoot);
894     fileSourceRoot = fileSourceRoot.copy(this, myRootVFile, "fileSourceRoot.txt");
895     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
896     assertTrue(myFileIndex.isInContent(fileSourceRoot));
897     assertTrue(myFileIndex.isInSource(fileSourceRoot));
898     
899     // delete and rename from another file
900     fileSourceRoot.delete(this);
901     assertNotInProject(fileSourceRoot);
902     assertFalse(myFileIndex.isInContent(fileSourceRoot));
903     assertFalse(myFileIndex.isInSource(fileSourceRoot));
904     fileSourceRoot = myRootVFile.createChildData(this, "temp_file.txt");
905     assertNotInProject(fileSourceRoot);
906     fileSourceRoot.rename(this, "fileSourceRoot.txt");
907     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
908     assertTrue(myFileIndex.isInContent(fileSourceRoot));
909     assertTrue(myFileIndex.isInSource(fileSourceRoot));
910   }
911
912   private void checkInfo(VirtualFile file,
913                          @Nullable Module module,
914                          boolean isInLibrary,
915                          boolean isInLibrarySource,
916                          @Nullable String packageName, 
917                          @Nullable final JpsModuleSourceRootType<?> moduleSourceRootType,
918                          Module... modulesOfOrderEntries) {
919     DirectoryInfo info = assertInProject(file);
920     assertEquals(module, info.getModule());
921     if (moduleSourceRootType != null) {
922       assertTrue("isInModuleSource", info.isInModuleSource());
923       assertEquals(moduleSourceRootType, myIndex.getSourceRootType(info));
924     }
925     else {
926       assertFalse("isInModuleSource", info.isInModuleSource());
927     }
928     assertEquals(isInLibrary, info.hasLibraryClassRoot());
929     assertEquals(isInLibrarySource, info.isInLibrarySource());
930
931     if (file.isDirectory()) {
932       assertEquals(packageName, myFileIndex.getPackageNameByDirectory(file));
933     }
934
935     assertEquals(Arrays.toString(myIndex.getOrderEntries(info)), modulesOfOrderEntries.length, myIndex.getOrderEntries(info).length);
936     for (Module aModule : modulesOfOrderEntries) {
937       OrderEntry found = ModuleFileIndexImpl.findOrderEntryWithOwnerModule(aModule, myIndex.getOrderEntries(info));
938       assertNotNull("not found: " + aModule + " in " + Arrays.toString(myIndex.getOrderEntries(info)), found);
939     }
940   }
941
942   private void assertNotInProject(VirtualFile file) {
943     DirectoryInfo info = myIndex.getInfoForFile(file);
944     assertFalse(info.toString(), info.isInProject());
945     assertFalse(info.toString(), info.isExcluded());
946   }
947
948   private void assertExcluded(VirtualFile file, Module module) {
949     DirectoryInfo info = myIndex.getInfoForFile(file);
950     assertTrue(info.toString(), info.isExcluded());
951     assertEquals(module, info.getModule());
952   }
953
954   private DirectoryInfo assertInProject(VirtualFile file) {
955     DirectoryInfo info = myIndex.getInfoForFile(file);
956     assertTrue(file.toString(), info.isInProject());
957     myIndex.assertConsistency(info);
958     return info;
959   }
960
961   private void assertNotExcluded(VirtualFile file) {
962     assertFalse(myIndex.getInfoForFile(file).isExcluded());
963   }
964
965   private void assertExcludedFromProject(VirtualFile file) {
966     assertExcluded(file, null);
967   }
968
969   private void checkPackage(String packageName, boolean includeLibrarySources, VirtualFile... expectedDirs) {
970     VirtualFile[] actualDirs = myIndex.getDirectoriesByPackageName(packageName, includeLibrarySources).toArray(VirtualFile.EMPTY_ARRAY);
971     assertNotNull(actualDirs);
972     assertOrderedEquals(actualDirs, expectedDirs);
973
974     for (VirtualFile dir : expectedDirs) {
975       String actualName = myIndex.getPackageName(dir);
976       assertEquals("Invalid package name for dir " + dir + ": " + packageName, packageName, actualName);
977     }
978   }
979
980 }