fix "IDEA-221944 Deadlock on opening second project" and support preloading for proje...
[idea/community.git] / platform / core-impl / src / com / intellij / core / CoreProjectEnvironment.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.core;
3
4 import com.intellij.lang.injection.InjectedLanguageManager;
5 import com.intellij.mock.MockDumbService;
6 import com.intellij.mock.MockFileIndexFacade;
7 import com.intellij.mock.MockProject;
8 import com.intellij.mock.MockResolveScopeManager;
9 import com.intellij.openapi.Disposable;
10 import com.intellij.openapi.extensions.ExtensionPointName;
11 import com.intellij.openapi.project.DumbService;
12 import com.intellij.openapi.roots.FileIndexFacade;
13 import com.intellij.openapi.util.Disposer;
14 import com.intellij.psi.PsiDocumentManager;
15 import com.intellij.psi.PsiFileFactory;
16 import com.intellij.psi.PsiManager;
17 import com.intellij.psi.SmartPointerManager;
18 import com.intellij.psi.impl.*;
19 import com.intellij.psi.impl.file.PsiDirectoryFactory;
20 import com.intellij.psi.impl.file.PsiDirectoryFactoryImpl;
21 import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl;
22 import com.intellij.psi.impl.source.resolve.ResolveCache;
23 import com.intellij.psi.search.ProjectScopeBuilder;
24 import com.intellij.psi.util.CachedValuesManager;
25 import com.intellij.psi.util.PsiModificationTracker;
26 import com.intellij.util.CachedValuesManagerImpl;
27 import com.intellij.util.messages.MessageBus;
28 import org.jetbrains.annotations.NotNull;
29 import org.picocontainer.PicoContainer;
30
31 public class CoreProjectEnvironment {
32   private final Disposable myParentDisposable;
33   private final CoreApplicationEnvironment myEnvironment;
34
35   protected final FileIndexFacade myFileIndexFacade;
36   protected final PsiManagerImpl myPsiManager;
37   protected final MockProject myProject;
38   protected final MessageBus myMessageBus;
39
40   public CoreProjectEnvironment(@NotNull Disposable parentDisposable, @NotNull CoreApplicationEnvironment applicationEnvironment) {
41     myParentDisposable = parentDisposable;
42     myEnvironment = applicationEnvironment;
43     myProject = createProject(myEnvironment.getApplication().getPicoContainer(), myParentDisposable);
44
45     preregisterServices();
46
47     myFileIndexFacade = createFileIndexFacade();
48     myMessageBus = myProject.getMessageBus();
49
50     PsiModificationTrackerImpl modificationTracker = new PsiModificationTrackerImpl(myProject);
51     myProject.registerService(PsiModificationTracker.class, modificationTracker);
52     myProject.registerService(FileIndexFacade.class, myFileIndexFacade);
53     myProject.registerService(ResolveCache.class, new ResolveCache(myProject));
54
55     myPsiManager = new PsiManagerImpl(myProject);
56     myProject.registerService(PsiManager.class, myPsiManager);
57     myProject.registerService(SmartPointerManager.class, SmartPointerManagerImpl.class);
58     myProject.registerService(DocumentCommitProcessor.class, new MockDocumentCommitProcessor());
59     myProject.registerService(PsiDocumentManager.class, new CorePsiDocumentManager(myProject));
60
61     myProject.registerService(ResolveScopeManager.class, createResolveScopeManager(myPsiManager));
62
63     myProject.registerService(PsiFileFactory.class, new PsiFileFactoryImpl(myPsiManager));
64     myProject.registerService(CachedValuesManager.class, new CachedValuesManagerImpl(myProject, new PsiCachedValuesFactory(myPsiManager)));
65     myProject.registerService(PsiDirectoryFactory.class, new PsiDirectoryFactoryImpl(myProject));
66     myProject.registerService(ProjectScopeBuilder.class, createProjectScopeBuilder());
67     myProject.registerService(DumbService.class, new MockDumbService(myProject));
68     myProject.registerService(CoreEncodingProjectManager.class, CoreEncodingProjectManager.class);
69     myProject.registerService(InjectedLanguageManager.class, new CoreInjectedLanguageManager());
70   }
71
72   @NotNull
73   protected MockProject createProject(@NotNull PicoContainer parent, @NotNull Disposable parentDisposable) {
74     return new MockProject(parent, parentDisposable);
75   }
76
77   @NotNull
78   protected ProjectScopeBuilder createProjectScopeBuilder() {
79     return new CoreProjectScopeBuilder(myProject, myFileIndexFacade);
80   }
81
82   protected void preregisterServices() {
83
84   }
85
86   @NotNull
87   protected FileIndexFacade createFileIndexFacade() {
88     return new MockFileIndexFacade(myProject);
89   }
90
91   @NotNull
92   protected ResolveScopeManager createResolveScopeManager(@NotNull PsiManager psiManager) {
93     return new MockResolveScopeManager(psiManager.getProject());
94   }
95
96   public <T> void registerProjectExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName,
97                                                 @NotNull Class<? extends T> aClass) {
98     CoreApplicationEnvironment.registerExtensionPoint(myProject.getExtensionArea(), extensionPointName, aClass);
99   }
100
101   public <T> void addProjectExtension(@NotNull ExtensionPointName<T> name, @NotNull final T extension) {
102     //noinspection TestOnlyProblems
103     name.getPoint(myProject).registerExtension(extension, myParentDisposable);
104   }
105
106   public <T> void registerProjectComponent(@NotNull Class<T> interfaceClass, @NotNull T implementation) {
107     CoreApplicationEnvironment.registerComponentInstance(myProject.getPicoContainer(), interfaceClass, implementation);
108     if (implementation instanceof Disposable) {
109       Disposer.register(myProject, (Disposable) implementation);
110     }
111   }
112
113   @NotNull
114   public Disposable getParentDisposable() {
115     return myParentDisposable;
116   }
117
118   @NotNull
119   public CoreApplicationEnvironment getEnvironment() {
120     return myEnvironment;
121   }
122
123   @NotNull
124   public MockProject getProject() {
125     return myProject;
126   }
127 }