api: annotate classes and interfaces from project model API as NonExtendable
[idea/community.git] / platform / projectModel-api / src / com / intellij / openapi / roots / OrderEnumerator.java
1 /*
2  * Copyright 2000-2017 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;
17
18 import com.intellij.openapi.module.Module;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.roots.libraries.Library;
21 import com.intellij.openapi.util.Condition;
22 import com.intellij.openapi.vfs.VirtualFile;
23 import com.intellij.util.NotNullFunction;
24 import com.intellij.util.PathsList;
25 import com.intellij.util.Processor;
26 import org.jetbrains.annotations.ApiStatus;
27 import org.jetbrains.annotations.NotNull;
28
29 import java.util.List;
30
31 /**
32  * <p>Interface for convenient processing dependencies of a module or a project. Allows to process {@link OrderEntry}s
33  * and collect classes and source roots.</p>
34  *
35  * <p>Use {@link #orderEntries(Module)} or {@link ModuleRootModel#orderEntries()} to process dependencies of a module
36  * and use {@link #orderEntries(Project)} to process dependencies of all modules in a project.</p>
37  *
38  * <p>Note that all configuration methods modify {@link OrderEnumerator} instance instead of creating a new one.</p>
39  *
40  * @author nik
41  */
42 @ApiStatus.NonExtendable
43 public abstract class OrderEnumerator {
44   /**
45    * Skip test dependencies
46    *
47    * @return this instance
48    */
49   @NotNull
50   public abstract OrderEnumerator productionOnly();
51
52   /**
53    * Skip runtime-only dependencies
54    *
55    * @return this instance
56    */
57   @NotNull
58   public abstract OrderEnumerator compileOnly();
59
60   /**
61    * Skip compile-only dependencies
62    *
63    * @return this instance
64    */
65   @NotNull
66   public abstract OrderEnumerator runtimeOnly();
67
68   @NotNull
69   public abstract OrderEnumerator withoutSdk();
70
71   @NotNull
72   public abstract OrderEnumerator withoutLibraries();
73
74   @NotNull
75   public abstract OrderEnumerator withoutDepModules();
76
77   /**
78    * Skip root module's entries
79    * @return this
80    */
81   @NotNull
82   public abstract OrderEnumerator withoutModuleSourceEntries();
83
84   @NotNull
85   public OrderEnumerator librariesOnly() {
86     return withoutSdk().withoutDepModules().withoutModuleSourceEntries();
87   }
88
89   @NotNull
90   public OrderEnumerator sdkOnly() {
91     return withoutDepModules().withoutLibraries().withoutModuleSourceEntries();
92   }
93
94   @NotNull
95   public VirtualFile[] getAllLibrariesAndSdkClassesRoots() {
96     return withoutModuleSourceEntries().withoutDepModules().recursively().exportedOnly().classes().usingCache().getRoots();
97   }
98
99   @NotNull
100   public VirtualFile[] getAllSourceRoots() {
101     return recursively().exportedOnly().sources().usingCache().getRoots();
102   }
103
104   /**
105    * Recursively process modules on which the module depends. This flag is ignored for modules imported from Maven because for such modules
106    * transitive dependencies are propagated to the root module during importing.
107    *
108    * @return this instance
109    */
110   @NotNull
111   public abstract OrderEnumerator recursively();
112
113   /**
114    * Skip not exported dependencies. If this method is called after {@link #recursively()} direct non-exported dependencies won't be skipped
115    *
116    * @return this instance
117    */
118   @NotNull
119   public abstract OrderEnumerator exportedOnly();
120
121   /**
122    * Process only entries which satisfies the specified condition
123    *
124    * @param condition filtering condition
125    * @return this instance
126    */
127   @NotNull
128   public abstract OrderEnumerator satisfying(@NotNull Condition<? super OrderEntry> condition);
129
130   /**
131    * Use {@code provider.getRootModel()} to process module dependencies
132    *
133    * @param provider provider
134    * @return this instance
135    */
136   @NotNull
137   public abstract OrderEnumerator using(@NotNull RootModelProvider provider);
138
139   /**
140    * Determine if, given the current enumerator settings and handlers for a module, should the
141    * enumerator recurse to further modules based on the given ModuleOrderEntry?
142    *
143    * @param entry the ModuleOrderEntry in question (m1 -> m2)
144    * @param handlers custom handlers registered to the module
145    * @return true if the enumerator would have recursively processed the given ModuleOrderEntry.
146    */
147   public abstract boolean shouldRecurse(@NotNull ModuleOrderEntry entry, @NotNull List<? extends OrderEnumerationHandler> handlers);
148
149   /**
150    * @return {@link OrderRootsEnumerator} instance for processing classes roots
151    */
152   @NotNull
153   public abstract OrderRootsEnumerator classes();
154
155   /**
156    * @return {@link OrderRootsEnumerator} instance for processing source roots
157    */
158   @NotNull
159   public abstract OrderRootsEnumerator sources();
160
161   /**
162    * @param rootType root type
163    * @return {@link OrderRootsEnumerator} instance for processing roots of the specified type
164    */
165   @NotNull
166   public abstract OrderRootsEnumerator roots(@NotNull OrderRootType rootType);
167
168   /**
169    * @param rootTypeProvider custom root type provider
170    * @return {@link OrderRootsEnumerator} instance for processing roots of the provided type
171    */
172   @NotNull
173   public abstract OrderRootsEnumerator roots(@NotNull NotNullFunction<? super OrderEntry, ? extends OrderRootType> rootTypeProvider);
174
175   /**
176    * @return classes roots for all entries processed by this enumerator
177    */
178   @NotNull
179   public VirtualFile[] getClassesRoots() {
180     return classes().getRoots();
181   }
182
183   /**
184    * @return source roots for all entries processed by this enumerator
185    */
186   @NotNull
187   public VirtualFile[] getSourceRoots() {
188     return sources().getRoots();
189   }
190
191   /**
192    * @return list containing classes roots for all entries processed by this enumerator
193    */
194   @NotNull
195   public PathsList getPathsList() {
196     return classes().getPathsList();
197   }
198
199   /**
200    * @return list containing source roots for all entries processed by this enumerator
201    */
202   @NotNull
203   public PathsList getSourcePathsList() {
204     return sources().getPathsList();
205   }
206
207   /**
208    * Runs {@code processor.process()} for each entry processed by this enumerator.
209    *
210    * @param processor processor
211    */
212   public abstract void forEach(@NotNull Processor<? super OrderEntry> processor);
213
214   /**
215    * Runs {@code processor.process()} for each library processed by this enumerator.
216    *
217    * @param processor processor
218    */
219   public abstract void forEachLibrary(@NotNull Processor<? super Library> processor);
220
221   /**
222    * Runs {@code processor.process()} for each module processed by this enumerator.
223    *
224    * @param processor processor
225    */
226   public abstract void forEachModule(@NotNull Processor<? super Module> processor);
227
228   /**
229    * Passes order entries to the specified visitor.
230    *
231    * @param policy       the visitor to accept.
232    * @param initialValue the default value to be returned by the visit process.
233    * @return the value returned by the visitor.
234    * @see OrderEntry#accept(RootPolicy, Object)
235    */
236   public abstract <R> R process(@NotNull RootPolicy<R> policy, R initialValue);
237
238   /**
239    * Creates new enumerator instance to process dependencies of {@code module}
240    *
241    * @param module module
242    * @return new enumerator instance
243    */
244   @NotNull
245   public static OrderEnumerator orderEntries(@NotNull Module module) {
246     return ModuleRootManager.getInstance(module).orderEntries();
247   }
248
249   /**
250    * Creates new enumerator instance to process dependencies of all modules in {@code project}. Only first level dependencies of
251    * modules are processed so {@link #recursively()} option is ignored and {@link #withoutDepModules()} option is forced
252    *
253    * @param project project
254    * @return new enumerator instance
255    */
256   @NotNull
257   public static OrderEnumerator orderEntries(@NotNull Project project) {
258     return ProjectRootManager.getInstance(project).orderEntries();
259   }
260 }