bdce338f5965582a2affa7652fd0b9a1352b6f1f
[idea/community.git] / platform / lang-impl / src / com / intellij / openapi / roots / impl / ModuleRootManagerComponent.java
1 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.openapi.roots.impl;
3
4 import com.intellij.openapi.components.*;
5 import com.intellij.openapi.module.Module;
6 import com.intellij.openapi.module.impl.ModuleEx;
7 import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
8 import com.intellij.openapi.roots.impl.storage.ClassPathStorageUtil;
9 import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
10 import com.intellij.openapi.roots.libraries.LibraryTable;
11 import com.intellij.openapi.util.registry.Registry;
12 import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
13 import com.intellij.util.SmartList;
14 import org.jetbrains.annotations.NotNull;
15 import org.jetbrains.annotations.TestOnly;
16
17 import java.util.List;
18
19 /**
20  * @author yole
21  */
22 @State(
23   name = "NewModuleRootManager",
24   storages = {
25     @Storage(StoragePathMacros.MODULE_FILE),
26     @Storage(storageClass = ClasspathStorage.class)
27   },
28   // will be changed only on actual user change, so, to speed up module loading, disable
29   useLoadedStateAsExisting = false
30 )
31 public class ModuleRootManagerComponent extends ModuleRootManagerImpl implements
32                                                                       PersistentStateComponentWithModificationTracker<ModuleRootManagerImpl.ModuleRootManagerState>,
33                                                                       StateStorageChooserEx {
34   public ModuleRootManagerComponent(Module module,
35                                     ProjectRootManagerImpl projectRootManager,
36                                     VirtualFilePointerManager filePointerManager) {
37     super(module, projectRootManager, filePointerManager);
38   }
39
40   @NotNull
41   @Override
42   public Resolution getResolution(@NotNull Storage storage, @NotNull StateStorageOperation operation) {
43     boolean isClasspathStorage = storage.storageClass() == ClasspathStorage.class;
44     boolean isEffectiveStorage = ClassPathStorageUtil.isClasspathStorage(getModule()) == isClasspathStorage;
45     if (operation == StateStorageOperation.READ) {
46       return isEffectiveStorage ? Resolution.DO : Resolution.SKIP;
47     }
48     else {
49       // IDEA-133480 Eclipse integration: .iml content is not reduced on setting Dependencies Storage Format = Eclipse
50       // We clear any storage except eclipse (because we must not clear shared files).
51       // Currently there is only one known non-default storage - ExternalProjectStorage.
52       return isEffectiveStorage ? Resolution.DO : isClasspathStorage ? Resolution.SKIP : Resolution.CLEAR;
53     }
54   }
55
56   @Override
57   public long getStateModificationCount() {
58     Module module = getModule();
59     if (!module.isLoaded() || !(module instanceof ModuleEx)) {
60       return myModificationTracker.getModificationCount();
61     }
62
63     final long[] result = {myModificationTracker.getModificationCount()};
64     result[0] += ((ModuleEx)module).getOptionsModificationCount();
65     final List<String> handledLibraryTables = new SmartList<>();
66     getRootModel().orderEntries().forEachLibrary(library -> {
67       LibraryTable table = library.getTable();
68       if (table instanceof LibraryTableBase && !handledLibraryTables.contains(table.getTableLevel())) {
69         handledLibraryTables.add(table.getTableLevel());
70         long count = ((LibraryTableBase)table).getStateModificationCount();
71         if (count > 0 && Registry.is("store.track.module.root.manager.changes", false)) {
72           LOG.error("modification count changed due to library  " + library.getName() + " change (" + count + "), module " + getModule().getName());
73         }
74         result[0] += count;
75       }
76       return true;
77     });
78     return result[0] + myRootModel.getStateModificationCount();
79   }
80
81   @Override
82   @TestOnly
83   public long getModificationCountForTests() {
84     return getStateModificationCount();
85   }
86 }