001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.resolve.lazy;
018
019 import com.google.common.collect.Lists;
020 import com.intellij.openapi.project.Project;
021 import com.intellij.util.Function;
022 import com.intellij.util.containers.ContainerUtil;
023 import kotlin.jvm.functions.Function1;
024 import org.jetbrains.annotations.NotNull;
025 import org.jetbrains.annotations.Nullable;
026 import org.jetbrains.annotations.ReadOnly;
027 import org.jetbrains.kotlin.context.GlobalContext;
028 import org.jetbrains.kotlin.descriptors.*;
029 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
030 import org.jetbrains.kotlin.incremental.components.LookupLocation;
031 import org.jetbrains.kotlin.incremental.components.LookupTracker;
032 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
033 import org.jetbrains.kotlin.name.FqName;
034 import org.jetbrains.kotlin.name.Name;
035 import org.jetbrains.kotlin.psi.*;
036 import org.jetbrains.kotlin.resolve.*;
037 import org.jetbrains.kotlin.resolve.lazy.data.JetClassLikeInfo;
038 import org.jetbrains.kotlin.resolve.lazy.data.JetClassOrObjectInfo;
039 import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo;
040 import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory;
041 import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider;
042 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotations;
043 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl;
044 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor;
045 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
046 import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
047 import org.jetbrains.kotlin.storage.*;
048
049 import javax.inject.Inject;
050 import java.util.Collection;
051 import java.util.Collections;
052 import java.util.List;
053
054 public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
055 private final LazyResolveStorageManager storageManager;
056 private final ExceptionTracker exceptionTracker;
057
058 private final ModuleDescriptor module;
059
060 private final BindingTrace trace;
061 private final DeclarationProviderFactory declarationProviderFactory;
062
063 private final MemoizedFunctionToNullable<FqName, LazyPackageDescriptor> packages;
064 private final PackageFragmentProvider packageFragmentProvider;
065
066 private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> fileAnnotations;
067 private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> danglingAnnotations;
068
069 private KtImportsFactory jetImportFactory;
070 private AnnotationResolver annotationResolve;
071 private DescriptorResolver descriptorResolver;
072 private FunctionDescriptorResolver functionDescriptorResolver;
073 private TypeResolver typeResolver;
074 private LazyDeclarationResolver lazyDeclarationResolver;
075 private FileScopeProvider fileScopeProvider;
076 private DeclarationScopeProvider declarationScopeProvider;
077 private LookupTracker lookupTracker;
078 private LocalDescriptorResolver localDescriptorResolver;
079 private SupertypeLoopChecker supertypeLoopsResolver;
080
081 @Inject
082 public void setJetImportFactory(KtImportsFactory jetImportFactory) {
083 this.jetImportFactory = jetImportFactory;
084 }
085
086 @Inject
087 public void setAnnotationResolve(AnnotationResolver annotationResolve) {
088 this.annotationResolve = annotationResolve;
089 }
090
091 @Inject
092 public void setDescriptorResolver(DescriptorResolver descriptorResolver) {
093 this.descriptorResolver = descriptorResolver;
094 }
095
096 @Inject
097 public void setFunctionDescriptorResolver(FunctionDescriptorResolver functionDescriptorResolver) {
098 this.functionDescriptorResolver = functionDescriptorResolver;
099 }
100
101 @Inject
102 public void setTypeResolver(TypeResolver typeResolver) {
103 this.typeResolver = typeResolver;
104 }
105
106 @Inject
107 public void setLazyDeclarationResolver(LazyDeclarationResolver lazyDeclarationResolver) {
108 this.lazyDeclarationResolver = lazyDeclarationResolver;
109 }
110
111 @Inject
112 public void setFileScopeProvider(@NotNull FileScopeProviderImpl fileScopeProvider) {
113 this.fileScopeProvider = fileScopeProvider;
114 }
115
116 @Inject
117 public void setDeclarationScopeProvider(@NotNull DeclarationScopeProviderImpl declarationScopeProvider) {
118 this.declarationScopeProvider = declarationScopeProvider;
119 }
120
121 @Inject
122 public void setLookupTracker(@NotNull LookupTracker lookupTracker) {
123 this.lookupTracker = lookupTracker;
124 }
125
126 // Only calls from injectors expected
127 @Deprecated
128 public ResolveSession(
129 @NotNull Project project,
130 @NotNull GlobalContext globalContext,
131 @NotNull ModuleDescriptor rootDescriptor,
132 @NotNull DeclarationProviderFactory declarationProviderFactory,
133 @NotNull BindingTrace delegationTrace
134 ) {
135 LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager =
136 new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
137
138 this.storageManager = lockBasedLazyResolveStorageManager;
139 this.exceptionTracker = globalContext.getExceptionTracker();
140 this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace);
141 this.module = rootDescriptor;
142
143 this.packages =
144 storageManager.createMemoizedFunctionWithNullableValues(new Function1<FqName, LazyPackageDescriptor>() {
145 @Override
146 @Nullable
147 public LazyPackageDescriptor invoke(FqName fqName) {
148 return createPackage(fqName);
149 }
150 });
151
152 this.declarationProviderFactory = declarationProviderFactory;
153
154 this.packageFragmentProvider = new PackageFragmentProvider() {
155 @NotNull
156 @Override
157 public List<PackageFragmentDescriptor> getPackageFragments(@NotNull FqName fqName) {
158 return ContainerUtil.<PackageFragmentDescriptor>createMaybeSingletonList(getPackageFragment(fqName));
159 }
160
161 @NotNull
162 @Override
163 public Collection<FqName> getSubPackagesOf(
164 @NotNull FqName fqName, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
165 ) {
166 LazyPackageDescriptor packageDescriptor = getPackageFragment(fqName);
167 if (packageDescriptor == null) {
168 return Collections.emptyList();
169 }
170 return packageDescriptor.getDeclarationProvider().getAllDeclaredSubPackages(nameFilter);
171 }
172 };
173
174 fileAnnotations = storageManager.createMemoizedFunction(new Function1<KtFile, LazyAnnotations>() {
175 @Override
176 public LazyAnnotations invoke(KtFile file) {
177 return createAnnotations(file, file.getAnnotationEntries());
178 }
179 });
180
181 danglingAnnotations = storageManager.createMemoizedFunction(new Function1<KtFile, LazyAnnotations>() {
182 @Override
183 public LazyAnnotations invoke(KtFile file) {
184 return createAnnotations(file, file.getDanglingAnnotations());
185 }
186 });
187 }
188
189 private LazyAnnotations createAnnotations(KtFile file, List<KtAnnotationEntry> annotationEntries) {
190 LexicalScope scope = fileScopeProvider.getFileResolutionScope(file);
191 LazyAnnotationsContextImpl lazyAnnotationContext =
192 new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope);
193 return new LazyAnnotations(lazyAnnotationContext, annotationEntries);
194 }
195
196 @Override
197 @NotNull
198 public PackageFragmentProvider getPackageFragmentProvider() {
199 return packageFragmentProvider;
200 }
201
202 @Override
203 @Nullable
204 public LazyPackageDescriptor getPackageFragment(@NotNull FqName fqName) {
205 return packages.invoke(fqName);
206 }
207
208 @Nullable
209 private LazyPackageDescriptor createPackage(FqName fqName) {
210 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName);
211 if (provider == null) {
212 return null;
213 }
214 return new LazyPackageDescriptor(module, fqName, this, provider);
215 }
216
217 @NotNull
218 @Override
219 public ModuleDescriptor getModuleDescriptor() {
220 return module;
221 }
222
223 @NotNull
224 @Override
225 public LazyResolveStorageManager getStorageManager() {
226 return storageManager;
227 }
228
229 @NotNull
230 public ExceptionTracker getExceptionTracker() {
231 return exceptionTracker;
232 }
233
234 @Override
235 @NotNull
236 @ReadOnly
237 public Collection<ClassDescriptor> getTopLevelClassDescriptors(@NotNull FqName fqName, @NotNull final LookupLocation location) {
238 if (fqName.isRoot()) return Collections.emptyList();
239
240 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName.parent());
241 if (provider == null) return Collections.emptyList();
242
243 return ContainerUtil.mapNotNull(
244 provider.getClassOrObjectDeclarations(fqName.shortName()),
245 new Function<JetClassLikeInfo, ClassDescriptor>() {
246 @Override
247 public ClassDescriptor fun(JetClassLikeInfo classLikeInfo) {
248 if (classLikeInfo instanceof JetClassOrObjectInfo) {
249 //noinspection RedundantCast
250 return getClassDescriptor(((JetClassOrObjectInfo) classLikeInfo).getCorrespondingClassOrObject(), location);
251 }
252 else if (classLikeInfo instanceof JetScriptInfo) {
253 return getScriptDescriptor(((JetScriptInfo) classLikeInfo).getScript());
254 }
255 else {
256 throw new IllegalStateException(
257 "Unexpected " + classLikeInfo + " of type " + classLikeInfo.getClass().getName()
258 );
259 }
260 }
261 }
262 );
263 }
264
265 @Override
266 @NotNull
267 public ClassDescriptor getClassDescriptor(@NotNull KtClassOrObject classOrObject, @NotNull LookupLocation location) {
268 return lazyDeclarationResolver.getClassDescriptor(classOrObject, location);
269 }
270
271 @NotNull
272 public ScriptDescriptor getScriptDescriptor(@NotNull KtScript script) {
273 return lazyDeclarationResolver.getScriptDescriptor(script, NoLookupLocation.FOR_SCRIPT);
274 }
275
276 @Override
277 @NotNull
278 public BindingContext getBindingContext() {
279 return trace.getBindingContext();
280 }
281
282 @Override
283 @NotNull
284 public BindingTrace getTrace() {
285 return trace;
286 }
287
288 @Override
289 @NotNull
290 public DeclarationProviderFactory getDeclarationProviderFactory() {
291 return declarationProviderFactory;
292 }
293
294 @Override
295 @NotNull
296 public DeclarationDescriptor resolveToDescriptor(@NotNull KtDeclaration declaration) {
297 if (!KtPsiUtil.isLocal(declaration)) {
298 return lazyDeclarationResolver.resolveToDescriptor(declaration);
299 }
300 return localDescriptorResolver.resolveLocalDeclaration(declaration);
301 }
302
303 @NotNull
304 public Annotations getFileAnnotations(@NotNull KtFile file) {
305 return fileAnnotations.invoke(file);
306 }
307
308 @NotNull
309 public Annotations getDanglingAnnotations(@NotNull KtFile file) {
310 return danglingAnnotations.invoke(file);
311 }
312
313 @NotNull
314 private List<LazyPackageDescriptor> getAllPackages() {
315 LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT);
316 assert rootPackage != null : "Root package must be initialized";
317
318 return collectAllPackages(Lists.<LazyPackageDescriptor>newArrayList(), rootPackage);
319 }
320
321 @NotNull
322 private List<LazyPackageDescriptor> collectAllPackages(
323 @NotNull List<LazyPackageDescriptor> result,
324 @NotNull LazyPackageDescriptor current
325 ) {
326 result.add(current);
327 for (FqName subPackage : packageFragmentProvider.getSubPackagesOf(current.getFqName(), MemberScope.Companion.getALL_NAME_FILTER())) {
328 LazyPackageDescriptor fragment = getPackageFragment(subPackage);
329 assert fragment != null : "Couldn't find fragment for " + subPackage;
330 collectAllPackages(result, fragment);
331 }
332 return result;
333 }
334
335 @Override
336 public void forceResolveAll() {
337 for (LazyPackageDescriptor lazyPackage : getAllPackages()) {
338 ForceResolveUtil.forceResolveAllContents(lazyPackage);
339 }
340 }
341
342 @NotNull
343 public KtImportsFactory getJetImportsFactory() {
344 return jetImportFactory;
345 }
346
347 @Override
348 @NotNull
349 public AnnotationResolver getAnnotationResolver() {
350 return annotationResolve;
351 }
352
353 @Override
354 @NotNull
355 public DescriptorResolver getDescriptorResolver() {
356 return descriptorResolver;
357 }
358
359 @Override
360 @NotNull
361 public TypeResolver getTypeResolver() {
362 return typeResolver;
363 }
364
365 @NotNull
366 @Override
367 public FunctionDescriptorResolver getFunctionDescriptorResolver() {
368 return functionDescriptorResolver;
369 }
370
371 @NotNull
372 @Override
373 public DeclarationScopeProvider getDeclarationScopeProvider() {
374 return declarationScopeProvider;
375 }
376
377 @Override
378 @NotNull
379 public FileScopeProvider getFileScopeProvider() {
380 return fileScopeProvider;
381 }
382
383 @NotNull
384 @Override
385 public LookupTracker getLookupTracker() {
386 return lookupTracker;
387 }
388
389 @NotNull
390 @Override
391 public SupertypeLoopChecker getSupertypeLoopChecker() {
392 return supertypeLoopsResolver;
393 }
394
395 @Inject
396 public void setSupertypeLoopsResolver(@NotNull SupertypeLoopChecker supertypeLoopsResolver) {
397 this.supertypeLoopsResolver = supertypeLoopsResolver;
398 }
399
400 @Inject
401 public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) {
402 this.localDescriptorResolver = localDescriptorResolver;
403 }
404 }