2 * Copyright 2000-2016 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.openapi.roots.impl;
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.command.WriteCommandAction;
20 import com.intellij.openapi.fileTypes.FileTypeManager;
21 import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
22 import com.intellij.openapi.module.ModifiableModuleModel;
23 import com.intellij.openapi.module.Module;
24 import com.intellij.openapi.module.ModuleManager;
25 import com.intellij.openapi.module.StdModuleTypes;
26 import com.intellij.openapi.roots.*;
27 import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
28 import com.intellij.openapi.util.EmptyRunnable;
29 import com.intellij.openapi.util.io.FileUtil;
30 import com.intellij.openapi.vfs.*;
31 import com.intellij.testFramework.IdeaTestCase;
32 import com.intellij.testFramework.PlatformTestCase;
33 import com.intellij.testFramework.PsiTestUtil;
34 import com.intellij.testFramework.VfsTestUtil;
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;
45 @PlatformTestCase.WrapInCommand
46 public class DirectoryIndexTest extends IdeaTestCase {
47 private DirectoryIndexImpl myIndex;
49 private Module myModule2, myModule3;
50 private VirtualFile myRootVFile;
51 private VirtualFile myModule1Dir, myModule2Dir, myModule3Dir;
52 private VirtualFile mySrcDir1, mySrcDir2;
53 private VirtualFile myTestSrc1;
54 private VirtualFile myPack1Dir, myPack2Dir;
55 private VirtualFile myFileLibDir, myFileLibSrc, myFileLibCls;
56 private VirtualFile myLibDir, myLibSrcDir, myLibClsDir;
57 private VirtualFile myCvsDir;
58 private VirtualFile myExcludeDir;
59 private VirtualFile myOutputDir;
60 private VirtualFile myModule1OutputDir;
61 private VirtualFile myResDir, myTestResDir;
62 private VirtualFile myExcludedLibSrcDir, myExcludedLibClsDir;
63 private ProjectFileIndex myFileIndex;
66 protected void setUp() throws Exception {
69 final File root = createTempDirectory();
71 ApplicationManager.getApplication().runWriteAction(() -> {
97 myRootVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(root);
98 assertNotNull(myRootVFile);
100 myFileLibDir = createChildDirectory(myRootVFile, "lib");
101 myFileLibSrc = createChildData(myFileLibDir, "file.src");
102 myFileLibCls = createChildData(myFileLibDir, "file.cls");
103 myModule1Dir = createChildDirectory(myRootVFile, "module1");
104 mySrcDir1 = createChildDirectory(myModule1Dir, "src1");
105 myPack1Dir = createChildDirectory(mySrcDir1, "pack1");
106 myTestSrc1 = createChildDirectory(mySrcDir1, "testSrc");
107 myPack2Dir = createChildDirectory(myTestSrc1, "pack2");
108 myResDir = createChildDirectory(myModule1Dir, "res");
109 myTestResDir = createChildDirectory(myModule1Dir, "testRes");
111 myLibDir = createChildDirectory(myModule1Dir, "lib");
112 myLibSrcDir = createChildDirectory(myLibDir, "src");
113 myExcludedLibSrcDir = createChildDirectory(myLibSrcDir, "exc");
114 myLibClsDir = createChildDirectory(myLibDir, "cls");
115 myExcludedLibClsDir = createChildDirectory(myLibClsDir, "exc");
116 myModule2Dir = createChildDirectory(myModule1Dir, "module2");
117 mySrcDir2 = createChildDirectory(myModule2Dir, "src2");
118 myCvsDir = createChildDirectory(mySrcDir2, "CVS");
119 myExcludeDir = createChildDirectory(mySrcDir2, "excluded");
121 myModule3Dir = createChildDirectory(myRootVFile, "module3");
123 myOutputDir = createChildDirectory(myRootVFile, "out");
124 myModule1OutputDir = createChildDirectory(myOutputDir, "module1");
126 getCompilerProjectExtension().setCompilerOutputUrl(myOutputDir.getUrl());
127 ModuleManager moduleManager = ModuleManager.getInstance(myProject);
129 // fill roots of module1
131 ModuleRootModificationUtil.setModuleSdk(myModule, null);
132 PsiTestUtil.addContentRoot(myModule, myModule1Dir);
133 PsiTestUtil.addSourceRoot(myModule, mySrcDir1);
134 PsiTestUtil.addSourceRoot(myModule, myTestSrc1, true);
135 PsiTestUtil.addSourceRoot(myModule, myResDir, JavaResourceRootType.RESOURCE);
136 PsiTestUtil.addSourceRoot(myModule, myTestResDir, JavaResourceRootType.TEST_RESOURCE);
138 ModuleRootModificationUtil.addModuleLibrary(myModule, "lib.js",
139 Collections.singletonList(myFileLibCls.getUrl()), Collections
140 .singletonList(myFileLibSrc.getUrl()));
141 PsiTestUtil.addExcludedRoot(myModule, myExcludedLibClsDir);
142 PsiTestUtil.addExcludedRoot(myModule, myExcludedLibSrcDir);
145 // fill roots of module2
147 VirtualFile moduleFile = createChildData(myModule2Dir, "module2.iml");
148 myModule2 = moduleManager.newModule(moduleFile.getPath(), StdModuleTypes.JAVA.getId());
150 PsiTestUtil.addContentRoot(myModule2, myModule2Dir);
151 PsiTestUtil.addSourceRoot(myModule2, mySrcDir2);
152 PsiTestUtil.addExcludedRoot(myModule2, myExcludeDir);
153 ModuleRootModificationUtil.addModuleLibrary(myModule2, "lib",
154 Collections.singletonList(myLibClsDir.getUrl()), Collections.singletonList(myLibSrcDir.getUrl()),
155 Arrays.asList(myExcludedLibClsDir.getUrl(), myExcludedLibSrcDir.getUrl()), DependencyScope.COMPILE, true);
158 // fill roots of module3
160 VirtualFile moduleFile = createChildData(myModule3Dir, "module3.iml");
161 myModule3 = moduleManager.newModule(moduleFile.getPath(), StdModuleTypes.JAVA.getId());
163 PsiTestUtil.addContentRoot(myModule3, myModule3Dir);
164 ModuleRootModificationUtil.addDependency(myModule3, myModule2);
168 myIndex = (DirectoryIndexImpl)DirectoryIndex.getInstance(myProject);
169 myFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
170 // to not interfere with previous test firing vfs events
171 VirtualFileManager.getInstance().syncRefresh();
174 private CompilerProjectExtension getCompilerProjectExtension() {
175 final CompilerProjectExtension instance = CompilerProjectExtension.getInstance(myProject);
176 assertNotNull(instance);
180 public void testDirInfos() {
181 assertNotInProject(myRootVFile);
183 // beware: files in directory index
184 checkInfo(myFileLibSrc, null, false, true, "", null, myModule);
185 checkInfo(myFileLibCls, null, true, false, "", null, myModule);
187 checkInfo(myModule1Dir, myModule, false, false, null, null);
188 checkInfo(mySrcDir1, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
189 checkInfo(myPack1Dir, myModule, false, false, "pack1", JavaSourceRootType.SOURCE, myModule);
190 checkInfo(myTestSrc1, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule);
191 checkInfo(myPack2Dir, myModule, false, false, "pack2", JavaSourceRootType.TEST_SOURCE, myModule);
192 checkInfo(myResDir, myModule, false, false, "", JavaResourceRootType.RESOURCE, myModule);
193 checkInfo(myTestResDir, myModule, false, false, "", JavaResourceRootType.TEST_RESOURCE, myModule);
195 checkInfo(myLibDir, myModule, false, false, null, null);
196 checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3);
197 checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3);
199 assertEquals(myLibSrcDir, assertInProject(myLibSrcDir).getSourceRoot());
201 checkInfo(myModule2Dir, myModule2, false, false, null, null);
202 checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
203 assertNotInProject(myCvsDir);
204 assertExcluded(myExcludeDir, myModule2);
205 assertExcluded(myExcludedLibClsDir, myModule);
206 assertExcluded(myExcludedLibSrcDir, myModule);
208 assertEquals(myModule1Dir, assertInProject(myLibClsDir).getContentRoot());
210 checkInfo(myModule3Dir, myModule3, false, false, null, null);
212 VirtualFile cvs = createChildDirectory(myPack1Dir, "CVS");
213 assertNotInProject(cvs);
214 assertNull(myFileIndex.getPackageNameByDirectory(cvs));
217 public void testDirsByPackageName() {
218 checkPackage("", true, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibSrcDir, myLibClsDir);
219 checkPackage("", false, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibClsDir);
221 checkPackage("pack1", true, myPack1Dir);
222 checkPackage("pack1", false, myPack1Dir);
224 checkPackage("pack2", true, myPack2Dir);
225 checkPackage("pack2", false, myPack2Dir);
227 checkPackage(".pack2", false);
228 checkPackage(".pack2", true);
230 VirtualFile libClsPack = createChildDirectory(myLibClsDir, "pack1");
231 VirtualFile libSrcPack = createChildDirectory(myLibSrcDir, "pack1");
233 checkPackage("pack1", true, myPack1Dir, libSrcPack, libClsPack);
234 checkPackage("pack1", false, myPack1Dir, libClsPack);
237 public void testDirectoriesWithPackagePrefix() {
238 PsiTestUtil.addSourceRoot(myModule3, myModule3Dir);
239 WriteCommandAction.runWriteCommandAction(myProject, () -> {
240 final ModifiableRootModel model = ModuleRootManager.getInstance(myModule3).getModifiableModel();
241 model.getContentEntries()[0].getSourceFolders()[0].setPackagePrefix("pack1");
244 checkPackage("pack1", true, myPack1Dir, myModule3Dir);
247 public void testPackageDirectoriesWithDots() {
248 VirtualFile fooBar = createChildDirectory(mySrcDir1, "foo.bar");
249 VirtualFile goo1 = createChildDirectory(fooBar, "goo");
250 VirtualFile foo = createChildDirectory(mySrcDir2, "foo");
251 VirtualFile bar = createChildDirectory(foo, "bar");
252 VirtualFile goo2 = createChildDirectory(bar, "goo");
254 checkPackage("foo", false, foo);
255 checkPackage("foo.bar", false, bar, fooBar);
256 checkPackage("foo.bar.goo", false, goo2, goo1);
259 public void testCreateDir() {
260 String path = mySrcDir1.getPath().replace('/', File.separatorChar);
261 assertTrue(new File(path + File.separatorChar + "dir1" + File.separatorChar + "dir2").mkdirs());
262 assertTrue(new File(path + File.separatorChar + "CVS").mkdirs());
263 VirtualFileManager.getInstance().syncRefresh();
266 public void testDeleteDir() {
267 VirtualFile subdir1 = createChildDirectory(mySrcDir1, "subdir1");
268 VirtualFile subdir2 = createChildDirectory(subdir1, "subdir2");
269 createChildDirectory(subdir2, "subdir3");
271 VfsTestUtil.deleteFile(subdir1);
274 public void testMoveDir() {
275 VirtualFile subdir = createChildDirectory(mySrcDir2, "subdir1");
276 createChildDirectory(subdir, "subdir2");
278 move(subdir, mySrcDir1);
281 public void testRenameDir() {
282 VirtualFile subdir = createChildDirectory(mySrcDir2, "subdir1");
283 createChildDirectory(subdir, "subdir2");
285 rename(subdir, "abc.d");
288 public void testRenameRoot() {
289 rename(myModule1Dir, "newName");
292 public void testMoveRoot() {
293 move(myModule1Dir, myModule3Dir);
296 public void testAddProjectDir() {
297 new WriteCommandAction.Simple(getProject()) {
299 protected void run() throws Throwable {
300 VirtualFile newDir = createChildDirectory(myModule1Dir.getParent(), "newDir");
301 createChildDirectory(newDir, "subdir");
303 PsiTestUtil.addContentRoot(myModule, newDir);
305 }.execute().throwException();
308 public void testChangeIgnoreList() {
309 VirtualFile newDir = createChildDirectory(myModule1Dir, "newDir");
311 assertInProject(newDir);
313 final FileTypeManagerEx fileTypeManager = (FileTypeManagerEx)FileTypeManager.getInstance();
314 final String list = fileTypeManager.getIgnoredFilesList();
315 final String list1 = list + ";" + "newDir";
317 ApplicationManager.getApplication().runWriteAction(() -> fileTypeManager.setIgnoredFilesList(list1));
318 assertNotInProject(newDir);
321 ApplicationManager.getApplication().runWriteAction(() -> fileTypeManager.setIgnoredFilesList(list));
322 assertInProject(newDir);
326 public void testIgnoredFile() {
327 VirtualFile ignoredFile = createChildData(myModule1Dir, "CVS");
328 DirectoryInfo info = myIndex.getInfoForFile(ignoredFile);
329 assertTrue(info.isIgnored());
330 assertTrue(myFileIndex.isExcluded(ignoredFile));
331 assertTrue(myFileIndex.isUnderIgnored(ignoredFile));
332 assertNull(myFileIndex.getContentRootForFile(ignoredFile, false));
333 assertNull(myFileIndex.getModuleForFile(ignoredFile, false));
336 public void testAddModule() {
337 new WriteCommandAction.Simple(getProject()) {
339 protected void run() throws Throwable {
340 VirtualFile newModuleContent = createChildDirectory(myRootVFile, "newModule");
341 createChildDirectory(newModuleContent, "subDir");
342 ModuleManager moduleManager = ModuleManager.getInstance(myProject);
343 Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
344 PsiTestUtil.addContentRoot(module, newModuleContent);
346 }.execute().throwException();
349 public void testModuleUnderIgnoredDir() {
350 final VirtualFile ignored = createChildDirectory(myRootVFile, "RCS");
351 assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
352 assertTrue(myFileIndex.isExcluded(ignored));
353 assertTrue(myFileIndex.isUnderIgnored(ignored));
354 final VirtualFile module4 = createChildDirectory(ignored, "module4");
355 assertFalse(FileTypeManager.getInstance().isFileIgnored(module4));
356 assertTrue(myFileIndex.isExcluded(module4));
357 assertTrue(myFileIndex.isUnderIgnored(module4));
359 new WriteCommandAction.Simple(getProject()) {
361 protected void run() throws Throwable {
362 ModuleManager moduleManager = ModuleManager.getInstance(myProject);
363 Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
364 PsiTestUtil.addContentRoot(module, module4);
365 assertNotInProject(ignored);
366 checkInfo(module4, module, false, false, null, null);
368 }.execute().throwException();
371 public void testModuleInIgnoredDir() {
372 final VirtualFile ignored = createChildDirectory(myRootVFile, "RCS");
373 assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
375 new WriteCommandAction.Simple(getProject()) {
377 protected void run() throws Throwable {
378 ModuleManager moduleManager = ModuleManager.getInstance(myProject);
379 ModifiableModuleModel model = moduleManager.getModifiableModel();
380 model.disposeModule(myModule);
381 model.disposeModule(myModule2);
382 model.disposeModule(myModule3);
384 Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
385 PsiTestUtil.addContentRoot(module, ignored);
386 checkInfo(ignored, module, false, false, null, null);
388 }.execute().throwException();
391 public void testExcludedDirsInLibraries() {
392 assertFalse(myFileIndex.isInLibraryClasses(myExcludedLibClsDir));
393 assertTrue(myFileIndex.isExcluded(myExcludedLibClsDir));
394 assertFalse(myFileIndex.isUnderIgnored(myExcludedLibClsDir));
395 assertFalse(myFileIndex.isInLibrarySource(myExcludedLibSrcDir));
396 assertTrue(myFileIndex.isExcluded(myExcludedLibSrcDir));
397 assertFalse(myFileIndex.isUnderIgnored(myExcludedLibSrcDir));
400 public void testExplicitExcludeOfInner() {
401 PsiTestUtil.addExcludedRoot(myModule, myModule2Dir);
403 checkInfo(myModule2Dir, myModule2, false, false, null, null);
404 checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
407 public void testResettingProjectOutputPath() {
408 VirtualFile output1 = createChildDirectory(myModule1Dir, "output1");
409 VirtualFile output2 = createChildDirectory(myModule1Dir, "output2");
411 assertInProject(output1);
412 assertInProject(output2);
414 getCompilerProjectExtension().setCompilerOutputUrl(output1.getUrl());
417 assertExcluded(output1, myModule);
418 assertInProject(output2);
420 getCompilerProjectExtension().setCompilerOutputUrl(output2.getUrl());
423 assertInProject(output1);
424 assertExcluded(output2, myModule);
427 private void fireRootsChanged() {
428 ApplicationManager.getApplication().runWriteAction(() -> ProjectRootManagerEx.getInstanceEx(getProject()).makeRootsChange(EmptyRunnable.getInstance(), false, true));
431 private static OrderEntry[] toArray(Collection<OrderEntry> orderEntries) {
432 return orderEntries.toArray(new OrderEntry[orderEntries.size()]);
435 public void testModuleSourceAsLibrarySource() {
436 ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.emptyList(), Collections.singletonList(mySrcDir1.getUrl()));
438 checkInfo(mySrcDir1, myModule, false, true, "", JavaSourceRootType.SOURCE, myModule, myModule);
439 Collection<OrderEntry> entriesResult = myIndex.getOrderEntries(myIndex.getInfoForFile(mySrcDir1));
440 OrderEntry[] entries = toArray(entriesResult);
442 assertInstanceOf(entries[0], LibraryOrderEntry.class);
443 assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
445 checkInfo(myTestSrc1, myModule, false, true, "testSrc", JavaSourceRootType.TEST_SOURCE, myModule, myModule);
446 entriesResult = myIndex.getOrderEntries(myIndex.getInfoForFile(myTestSrc1));
447 entries = toArray(entriesResult);
448 assertInstanceOf(entries[0], LibraryOrderEntry.class);
449 assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
452 public void testModuleSourceAsLibraryClasses() {
453 ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.singletonList(mySrcDir1.getUrl()), Collections.emptyList());
454 checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
455 assertInstanceOf(assertOneElement(toArray(myIndex.getOrderEntries(assertInProject(mySrcDir1)))), ModuleSourceOrderEntry.class);
458 public void testModulesWithSameSourceContentRoot() {
459 // now our API allows this (ReformatCodeActionTest), although UI doesn't. Maybe API shouldn't allow it as well?
460 PsiTestUtil.addContentRoot(myModule2, myModule1Dir);
461 PsiTestUtil.addSourceRoot(myModule2, mySrcDir1);
463 checkInfo(myModule1Dir, myModule, false, false, null, null);
464 checkInfo(mySrcDir1, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule3, myModule);
465 checkInfo(myTestSrc1, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule3, myModule);
466 checkInfo(myResDir, myModule, false, false, "", JavaResourceRootType.RESOURCE, myModule);
468 checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
469 assertEquals(myModule2Dir, myIndex.getInfoForFile(mySrcDir2).getContentRoot());
472 public void testModuleWithSameSourceRoot() {
473 PsiTestUtil.addSourceRoot(myModule2, mySrcDir1);
474 checkInfo(mySrcDir1, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
475 checkInfo(myTestSrc1, myModule2, false, false, "testSrc", JavaSourceRootType.SOURCE, myModule2, myModule3);
478 public void testModuleContentUnderSourceRoot() {
479 PsiTestUtil.addContentRoot(myModule2, myPack1Dir);
480 checkInfo(myPack1Dir, myModule2, false, false, null, null);
483 public void testSameSourceAndOutput() {
484 PsiTestUtil.setCompilerOutputPath(myModule, mySrcDir1.getUrl(), false);
485 assertExcluded(mySrcDir1, myModule);
488 public void testExcludedDirShouldBeExcludedRightAfterItsCreation() {
489 VirtualFile excluded = createChildDirectory(myModule1Dir, "excluded");
490 VirtualFile projectOutput = createChildDirectory(myModule1Dir, "projectOutput");
491 VirtualFile module2Output = createChildDirectory(myModule1Dir, "module2Output");
492 VirtualFile module2TestOutput = createChildDirectory(myModule2Dir, "module2TestOutput");
494 assertInProject(excluded);
495 assertInProject(projectOutput);
496 assertInProject(module2Output);
497 assertInProject(module2TestOutput);
499 getCompilerProjectExtension().setCompilerOutputUrl(projectOutput.getUrl());
501 PsiTestUtil.addExcludedRoot(myModule, excluded);
502 PsiTestUtil.setCompilerOutputPath(myModule2, module2Output.getUrl(), false);
503 PsiTestUtil.setCompilerOutputPath(myModule2, module2TestOutput.getUrl(), true);
504 PsiTestUtil.setExcludeCompileOutput(myModule2, true);
506 assertExcluded(excluded, myModule);
507 assertExcluded(projectOutput, myModule);
508 assertExcluded(module2Output, myModule);
509 assertExcluded(module2TestOutput, myModule2);
511 VfsTestUtil.deleteFile(excluded);
512 VfsTestUtil.deleteFile(projectOutput);
513 VfsTestUtil.deleteFile(module2Output);
514 VfsTestUtil.deleteFile(module2TestOutput);
516 final List<VirtualFile> created = new ArrayList<VirtualFile>();
517 VirtualFileListener l = new VirtualFileAdapter() {
519 public void fileCreated(@NotNull VirtualFileEvent e) {
520 VirtualFile file = e.getFile();
521 String fileName = e.getFileName();
522 assertExcluded(file, fileName.contains("module2TestOutput") ? myModule2 : myModule);
526 VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable());
528 excluded = createChildDirectory(myModule1Dir, excluded.getName());
529 assertExcluded(excluded, myModule);
531 projectOutput = createChildDirectory(myModule1Dir, projectOutput.getName());
532 assertExcluded(projectOutput, myModule);
534 module2Output = createChildDirectory(myModule1Dir, module2Output.getName());
535 assertExcluded(module2Output, myModule);
537 module2TestOutput = createChildDirectory(myModule2Dir, module2TestOutput.getName());
538 assertExcluded(module2TestOutput, myModule2);
540 assertEquals(created.toString(), 4, created.size());
543 public void testExcludesShouldBeRecognizedRightOnRefresh() {
544 final VirtualFile dir = createChildDirectory(myModule1Dir, "dir");
545 final VirtualFile excluded = createChildDirectory(dir, "excluded");
546 PsiTestUtil.addExcludedRoot(myModule, excluded);
547 VfsTestUtil.deleteFile(dir);
550 boolean created = new File(myModule1Dir.getPath(), "dir/excluded/foo").mkdirs();
553 VirtualFileListener l = new VirtualFileAdapter() {
555 public void fileCreated(@NotNull VirtualFileEvent e) {
556 assertEquals("dir", e.getFileName());
558 VirtualFile file = e.getFile();
559 assertInProject(file);
560 assertExcluded(file.findFileByRelativePath("excluded"), myModule);
561 assertExcluded(file.findFileByRelativePath("excluded/foo"), myModule);
565 VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable());
566 VirtualFileManager.getInstance().syncRefresh();
569 public void testProcessingNestedContentRootsOfExcludedDirsOnCreation() {
570 String rootPath = myModule1Dir.getPath();
571 final File f = new File(rootPath, "excludedDir/dir/anotherContentRoot");
572 ApplicationManager.getApplication().runWriteAction(() -> {
573 ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
574 rootModel.getContentEntries()[0]
575 .addExcludeFolder(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(f.getParentFile().getParent())));
578 ModuleRootModificationUtil.addContentRoot(myModule2, FileUtil.toSystemIndependentName(f.getPath()));
580 assertTrue(f.getPath(), f.exists() || f.mkdirs());
581 LocalFileSystem.getInstance().refresh(false);
584 assertExcluded(LocalFileSystem.getInstance().findFileByIoFile(f.getParentFile().getParentFile()), myModule);
585 assertInProject(LocalFileSystem.getInstance().findFileByIoFile(f));
588 public void testLibraryDirInContent() {
589 ModuleRootModificationUtil.addModuleLibrary(myModule, myModule1Dir.getUrl());
591 checkInfo(myModule1Dir, myModule, true, false, "", null, myModule);
592 checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
594 checkInfo(myModule2Dir, myModule2, true, false, "module2", null, myModule);
595 checkInfo(mySrcDir2, myModule2, true, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
596 checkInfo(myExcludeDir, null, true, false, "module2.src2.excluded", null, myModule3);
598 checkInfo(myLibDir, myModule, true, false, "lib", null, myModule);
599 checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3);
601 //myModule is included into order entries instead of myModule2 because classes root for libraries dominates on source roots
602 checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3);
604 checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule);
605 assertInstanceOf(assertOneElement(toArray(myIndex.getOrderEntries(assertInProject(myResDir)))), ModuleSourceOrderEntry.class);
607 checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule);
608 checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3);
610 checkPackage("lib.src.exc", true, myExcludedLibSrcDir);
611 checkPackage("lib.cls.exc", true, myExcludedLibClsDir);
613 checkPackage("lib.src", true);
614 checkPackage("lib.cls", true);
616 checkPackage("exc", false);
617 checkPackage("exc", true);
620 public void testExcludeCompilerOutputOutsideOfContentRoot() {
621 assertTrue(myFileIndex.isExcluded(myOutputDir));
622 assertFalse(myFileIndex.isUnderIgnored(myOutputDir));
623 assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
624 assertFalse(myFileIndex.isExcluded(myOutputDir.getParent()));
625 assertExcludedFromProject(myOutputDir);
626 assertExcludedFromProject(myModule1OutputDir);
627 String moduleOutputUrl = myModule1OutputDir.getUrl();
629 VfsTestUtil.deleteFile(myOutputDir);
631 PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, false);
632 myOutputDir = createChildDirectory(myRootVFile, "out");
633 myModule1OutputDir = createChildDirectory(myOutputDir, "module1");
635 assertExcludedFromProject(myOutputDir);
636 assertExcludedFromProject(myModule1OutputDir);
637 assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
639 PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true);
640 PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, false);
641 PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, true);
642 PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, false);
643 PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, true);
645 // now no module inherits project output dir, but it still should be project-excluded
646 assertExcludedFromProject(myOutputDir);
648 // project output inside module content shouldn't be projectExcludeRoot
649 VirtualFile projectOutputUnderContent = createChildDirectory(myModule1Dir, "projectOutputUnderContent");
650 getCompilerProjectExtension().setCompilerOutputUrl(projectOutputUnderContent.getUrl());
653 assertNotExcluded(myOutputDir);
654 assertExcluded(projectOutputUnderContent, myModule);
656 VfsTestUtil.deleteFile(projectOutputUnderContent);
657 projectOutputUnderContent = createChildDirectory(myModule1Dir, "projectOutputUnderContent");
658 assertNotExcluded(myOutputDir);
659 assertExcluded(projectOutputUnderContent, myModule);
662 public void testFileContentAndSourceRoots() {
663 VirtualFile fileRoot = createChildData(myRootVFile, "fileRoot.txt");
664 VirtualFile fileSourceRoot = createChildData(myRootVFile, "fileSourceRoot.txt");
665 VirtualFile fileTestSourceRoot = createChildData(myRootVFile, "fileTestSourceRoot.txt");
667 assertNotInProject(fileRoot);
668 assertFalse(myFileIndex.isInContent(fileRoot));
669 assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot));
671 ContentEntry contentEntry = PsiTestUtil.addContentRoot(myModule, fileRoot);
672 assertNotNull(contentEntry);
673 assertEquals(fileRoot, contentEntry.getFile());
674 checkInfo(fileRoot, myModule, false, false, "", null);
675 assertTrue(myFileIndex.isInContent(fileRoot));
676 assertFalse(myFileIndex.isInSource(fileRoot));
678 PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
679 PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
680 checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
681 assertTrue(myFileIndex.isInContent(fileSourceRoot));
682 assertTrue(myFileIndex.isInSource(fileSourceRoot));
684 PsiTestUtil.addContentRoot(myModule, fileTestSourceRoot);
685 PsiTestUtil.addSourceRoot(myModule, fileTestSourceRoot, true);
686 checkInfo(fileTestSourceRoot, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule);
687 assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
688 assertTrue(myFileIndex.isInSource(fileTestSourceRoot));
690 assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
692 // removing file source root
693 PsiTestUtil.removeSourceRoot(myModule, fileTestSourceRoot);
694 checkInfo(fileTestSourceRoot, myModule, false, false, "", null);
695 assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
696 assertFalse(myFileIndex.isInSource(fileTestSourceRoot));
697 assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
699 // removing file content root
700 PsiTestUtil.removeContentEntry(myModule, contentEntry.getFile());
701 assertNotInProject(fileRoot);
702 assertFalse(myFileIndex.isInContent(fileRoot));
703 assertFalse(myFileIndex.isInSource(fileRoot));
704 assertIteratedContent(myFileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Collections.singletonList(fileRoot));
707 private static void assertIteratedContent(ProjectFileIndex fileIndex,
708 @Nullable List<VirtualFile> contains,
709 @Nullable List<VirtualFile> doesntContain) {
710 final Set<VirtualFile> collected = new THashSet<VirtualFile>();
711 fileIndex.iterateContent(new ContentIterator() {
713 public boolean processFile(VirtualFile fileOrDir) {
714 collected.add(fileOrDir);
718 if (contains != null) assertContainsElements(collected, contains);
719 if (doesntContain != null) assertDoesntContain(collected, doesntContain);
722 public void testFileSourceRootsUnderDirContentRoot() {
723 VirtualFile fileSourceRoot = createChildData(myModule1Dir, "fileSourceRoot.txt");
724 assertTrue(myFileIndex.isInContent(fileSourceRoot));
725 assertFalse(myFileIndex.isInSource(fileSourceRoot));
727 PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
728 assertTrue(myFileIndex.isInContent(fileSourceRoot));
729 assertTrue(myFileIndex.isInSource(fileSourceRoot));
730 checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
732 // removing file source root
733 PsiTestUtil.removeSourceRoot(myModule, fileSourceRoot);
734 assertTrue(myFileIndex.isInContent(fileSourceRoot));
735 assertFalse(myFileIndex.isInSource(fileSourceRoot));
738 public void testFileModuleExcludeRootUnderDirectoryRoot() {
739 VirtualFile fileExcludeRoot = createChildData(mySrcDir1, "fileExcludeRoot.txt");
740 assertTrue(myFileIndex.isInContent(fileExcludeRoot));
741 assertTrue(myFileIndex.isInSource(fileExcludeRoot));
742 assertIteratedContent(myFileIndex, Collections.singletonList(fileExcludeRoot), null);
744 PsiTestUtil.addExcludedRoot(myModule, fileExcludeRoot);
745 assertFalse(myFileIndex.isInContent(fileExcludeRoot));
746 assertFalse(myFileIndex.isInSource(fileExcludeRoot));
747 assertNull(myFileIndex.getContentRootForFile(fileExcludeRoot));
748 assertEquals(myModule1Dir, myFileIndex.getContentRootForFile(fileExcludeRoot, false));
749 assertNull(myFileIndex.getModuleForFile(fileExcludeRoot));
750 assertEquals(myModule, myFileIndex.getModuleForFile(fileExcludeRoot, false));
751 assertExcluded(fileExcludeRoot, myModule);
752 assertIteratedContent(myFileIndex, null, Collections.singletonList(fileExcludeRoot));
754 // removing file exclude root
755 PsiTestUtil.removeExcludedRoot(myModule, fileExcludeRoot);
756 assertTrue(myFileIndex.isInContent(fileExcludeRoot));
757 assertTrue(myFileIndex.isInSource(fileExcludeRoot));
758 assertIteratedContent(myFileIndex, Collections.singletonList(fileExcludeRoot), null);
761 public void testFileModuleExcludeRootUnderFileRoot() {
762 VirtualFile fileRoot = createChildData(myRootVFile, "fileRoot.txt");
763 PsiTestUtil.addContentRoot(myModule, fileRoot);
764 checkInfo(fileRoot, myModule, false, false, "", null);
765 assertTrue(myFileIndex.isInContent(fileRoot));
766 assertIteratedContent(myFileIndex, Collections.singletonList(fileRoot), null);
768 PsiTestUtil.addExcludedRoot(myModule, fileRoot);
769 assertFalse(myFileIndex.isInContent(fileRoot));
770 assertExcluded(fileRoot, myModule);
771 assertIteratedContent(myFileIndex, null, Collections.singletonList(fileRoot));
773 // removing file exclude root
774 PsiTestUtil.removeExcludedRoot(myModule, fileRoot);
775 checkInfo(fileRoot, myModule, false, false, "", null);
776 assertTrue(myFileIndex.isInContent(fileRoot));
777 assertIteratedContent(myFileIndex, Collections.singletonList(fileRoot), null);
780 public void testFileLibraryInsideFolderLibrary() {
781 VirtualFile file = createChildData(myLibSrcDir, "empty.txt");
782 ModuleRootModificationUtil.addModuleLibrary(myModule2, "lib2",
783 Collections.emptyList(), Collections.singletonList(file.getUrl()),
784 Collections.emptyList(), DependencyScope.COMPILE, true);
786 // same for the dir and for the file
787 checkInfo(file, myModule, false, true, "", null, myModule2, myModule3);
788 checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3);
791 public void testFileContentRootsModifications() {
792 assertNotInProject(myRootVFile);
793 VirtualFile temp = createChildDirectory(myRootVFile, "temp");
795 VirtualFile fileSourceRoot = createChildData(myRootVFile, "fileSourceRoot.txt");
796 assertNotInProject(fileSourceRoot);
798 PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
799 PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
800 checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
801 assertTrue(myFileIndex.isInContent(fileSourceRoot));
802 assertTrue(myFileIndex.isInSource(fileSourceRoot));
804 // delete and recreate
805 VfsTestUtil.deleteFile(fileSourceRoot);
806 assertNotInProject(fileSourceRoot);
807 assertFalse(myFileIndex.isInContent(fileSourceRoot));
808 assertFalse(myFileIndex.isInSource(fileSourceRoot));
809 fileSourceRoot = createChildData(myRootVFile, "fileSourceRoot.txt");
810 checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
811 assertTrue(myFileIndex.isInContent(fileSourceRoot));
812 assertTrue(myFileIndex.isInSource(fileSourceRoot));
814 // delete and move from another dir
815 VfsTestUtil.deleteFile(fileSourceRoot);
816 assertNotInProject(fileSourceRoot);
817 assertFalse(myFileIndex.isInContent(fileSourceRoot));
818 assertFalse(myFileIndex.isInSource(fileSourceRoot));
819 fileSourceRoot = createChildData(temp, "fileSourceRoot.txt");
820 assertNotInProject(fileSourceRoot);
821 move(fileSourceRoot, myRootVFile);
822 checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
823 assertTrue(myFileIndex.isInContent(fileSourceRoot));
824 assertTrue(myFileIndex.isInSource(fileSourceRoot));
826 // delete and copy from another dir
827 VfsTestUtil.deleteFile(fileSourceRoot);
828 assertNotInProject(fileSourceRoot);
829 assertFalse(myFileIndex.isInContent(fileSourceRoot));
830 assertFalse(myFileIndex.isInSource(fileSourceRoot));
831 fileSourceRoot = createChildData(temp, "fileSourceRoot.txt");
832 assertNotInProject(fileSourceRoot);
833 fileSourceRoot = copy(fileSourceRoot, myRootVFile, "fileSourceRoot.txt");
834 checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
835 assertTrue(myFileIndex.isInContent(fileSourceRoot));
836 assertTrue(myFileIndex.isInSource(fileSourceRoot));
838 // delete and rename from another file
839 VfsTestUtil.deleteFile(fileSourceRoot);
840 assertNotInProject(fileSourceRoot);
841 assertFalse(myFileIndex.isInContent(fileSourceRoot));
842 assertFalse(myFileIndex.isInSource(fileSourceRoot));
843 fileSourceRoot = createChildData(myRootVFile, "temp_file.txt");
844 assertNotInProject(fileSourceRoot);
845 rename(fileSourceRoot, "fileSourceRoot.txt");
846 checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
847 assertTrue(myFileIndex.isInContent(fileSourceRoot));
848 assertTrue(myFileIndex.isInSource(fileSourceRoot));
851 private void checkInfo(VirtualFile file,
852 @Nullable Module module,
854 boolean isInLibrarySource,
855 @Nullable String packageName,
856 @Nullable final JpsModuleSourceRootType<?> moduleSourceRootType,
857 Module... modulesOfOrderEntries) {
858 DirectoryInfo info = assertInProject(file);
859 assertEquals(module, info.getModule());
860 if (moduleSourceRootType != null) {
861 assertTrue("isInModuleSource", info.isInModuleSource());
862 assertEquals(moduleSourceRootType, myIndex.getSourceRootType(info));
865 assertFalse("isInModuleSource", info.isInModuleSource());
867 assertEquals(isInLibrary, info.hasLibraryClassRoot());
868 assertEquals(isInLibrarySource, info.isInLibrarySource());
870 if (file.isDirectory()) {
871 assertEquals(packageName, myFileIndex.getPackageNameByDirectory(file));
874 assertEquals(Arrays.toString(toArray(myIndex.getOrderEntries(info))), modulesOfOrderEntries.length, toArray(myIndex.getOrderEntries(info)).length);
875 for (Module aModule : modulesOfOrderEntries) {
876 OrderEntry found = ModuleFileIndexImpl.findOrderEntryWithOwnerModule(aModule, myIndex.getOrderEntries(info));
877 assertNotNull("not found: " + aModule + " in " + Arrays.toString(toArray(myIndex.getOrderEntries(info))), found);
881 private void assertNotInProject(VirtualFile file) {
882 DirectoryInfo info = myIndex.getInfoForFile(file);
883 assertFalse(info.toString(), info.isInProject());
884 assertFalse(info.toString(), info.isExcluded());
887 private void assertExcluded(VirtualFile file, Module module) {
888 DirectoryInfo info = myIndex.getInfoForFile(file);
889 assertTrue(info.toString(), info.isExcluded());
890 assertEquals(module, info.getModule());
893 private DirectoryInfo assertInProject(VirtualFile file) {
894 DirectoryInfo info = myIndex.getInfoForFile(file);
895 assertTrue(file.toString(), info.isInProject());
896 myIndex.assertConsistency(info);
900 private void assertNotExcluded(VirtualFile file) {
901 assertFalse(myIndex.getInfoForFile(file).isExcluded());
904 private void assertExcludedFromProject(VirtualFile file) {
905 assertExcluded(file, null);
908 private void checkPackage(String packageName, boolean includeLibrarySources, VirtualFile... expectedDirs) {
909 VirtualFile[] actualDirs = myIndex.getDirectoriesByPackageName(packageName, includeLibrarySources).toArray(VirtualFile.EMPTY_ARRAY);
910 assertNotNull(actualDirs);
911 assertOrderedEquals(actualDirs, expectedDirs);
913 for (VirtualFile dir : expectedDirs) {
914 String actualName = myIndex.getPackageName(dir);
915 assertEquals("Invalid package name for dir " + dir + ": " + packageName, packageName, actualName);