001 /*
002 * Copyright 2010-2016 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.config.LanguageVersionSettings;
028 import org.jetbrains.kotlin.context.GlobalContext;
029 import org.jetbrains.kotlin.descriptors.*;
030 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
031 import org.jetbrains.kotlin.incremental.components.LookupLocation;
032 import org.jetbrains.kotlin.incremental.components.LookupTracker;
033 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
034 import org.jetbrains.kotlin.name.FqName;
035 import org.jetbrains.kotlin.name.Name;
036 import org.jetbrains.kotlin.psi.*;
037 import org.jetbrains.kotlin.resolve.*;
038 import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension;
039 import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo;
040 import org.jetbrains.kotlin.resolve.lazy.data.KtClassOrObjectInfo;
041 import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo;
042 import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory;
043 import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider;
044 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotations;
045 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl;
046 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor;
047 import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
048 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
049 import org.jetbrains.kotlin.storage.*;
050 import org.jetbrains.kotlin.utils.SmartList;
051
052 import javax.inject.Inject;
053 import java.util.Collection;
054 import java.util.Collections;
055 import java.util.List;
056
057 public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
058 private final LazyResolveStorageManager storageManager;
059 private final ExceptionTracker exceptionTracker;
060
061 private final ModuleDescriptor module;
062
063 private final BindingTrace trace;
064 private final DeclarationProviderFactory declarationProviderFactory;
065
066 private final MemoizedFunctionToNullable<FqName, LazyPackageDescriptor> packages;
067 private final PackageFragmentProvider packageFragmentProvider;
068
069 private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> fileAnnotations;
070 private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> danglingAnnotations;
071
072 private KtImportsFactory jetImportFactory;
073 private AnnotationResolver annotationResolve;
074 private DescriptorResolver descriptorResolver;
075 private FunctionDescriptorResolver functionDescriptorResolver;
076 private TypeResolver typeResolver;
077 private LazyDeclarationResolver lazyDeclarationResolver;
078 private FileScopeProvider fileScopeProvider;
079 private DeclarationScopeProvider declarationScopeProvider;
080 private LookupTracker lookupTracker;
081 private LocalDescriptorResolver localDescriptorResolver;
082 private SupertypeLoopChecker supertypeLoopsResolver;
083 private LanguageVersionSettings languageVersionSettings;
084 private DelegationFilter delegationFilter;
085
086 private final SyntheticResolveExtension syntheticResolveExtension;
087
088 @Inject
089 public void setJetImportFactory(KtImportsFactory jetImportFactory) {
090 this.jetImportFactory = jetImportFactory;
091 }
092
093 @Inject
094 public void setAnnotationResolve(AnnotationResolver annotationResolve) {
095 this.annotationResolve = annotationResolve;
096 }
097
098 @Inject
099 public void setDescriptorResolver(DescriptorResolver descriptorResolver) {
100 this.descriptorResolver = descriptorResolver;
101 }
102
103 @Inject
104 public void setFunctionDescriptorResolver(FunctionDescriptorResolver functionDescriptorResolver) {
105 this.functionDescriptorResolver = functionDescriptorResolver;
106 }
107
108 @Inject
109 public void setTypeResolver(TypeResolver typeResolver) {
110 this.typeResolver = typeResolver;
111 }
112
113 @Inject
114 public void setLazyDeclarationResolver(LazyDeclarationResolver lazyDeclarationResolver) {
115 this.lazyDeclarationResolver = lazyDeclarationResolver;
116 }
117
118 @Inject
119 public void setFileScopeProvider(@NotNull FileScopeProvider fileScopeProvider) {
120 this.fileScopeProvider = fileScopeProvider;
121 }
122
123 @Inject
124 public void setDeclarationScopeProvider(@NotNull DeclarationScopeProviderImpl declarationScopeProvider) {
125 this.declarationScopeProvider = declarationScopeProvider;
126 }
127
128 @Inject
129 public void setLookupTracker(@NotNull LookupTracker lookupTracker) {
130 this.lookupTracker = lookupTracker;
131 }
132
133 @Inject
134 public void setLanguageVersionSettings(@NotNull LanguageVersionSettings languageVersionSettings) {
135 this.languageVersionSettings = languageVersionSettings;
136 }
137
138
139 @Inject
140 public void setDelegationFilter(@NotNull DelegationFilter delegationFilter) {
141 this.delegationFilter = delegationFilter;
142 }
143
144 // Only calls from injectors expected
145 @Deprecated
146 public ResolveSession(
147 @NotNull Project project,
148 @NotNull GlobalContext globalContext,
149 @NotNull ModuleDescriptor rootDescriptor,
150 @NotNull DeclarationProviderFactory declarationProviderFactory,
151 @NotNull BindingTrace delegationTrace
152 ) {
153 LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager =
154 new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
155
156 this.storageManager = lockBasedLazyResolveStorageManager;
157 this.exceptionTracker = globalContext.getExceptionTracker();
158 this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace);
159 this.module = rootDescriptor;
160
161 this.packages =
162 storageManager.createMemoizedFunctionWithNullableValues(new Function1<FqName, LazyPackageDescriptor>() {
163 @Override
164 @Nullable
165 public LazyPackageDescriptor invoke(FqName fqName) {
166 return createPackage(fqName);
167 }
168 });
169
170 this.declarationProviderFactory = declarationProviderFactory;
171
172 this.packageFragmentProvider = new PackageFragmentProvider() {
173 @NotNull
174 @Override
175 public List<PackageFragmentDescriptor> getPackageFragments(@NotNull FqName fqName) {
176 return ContainerUtil.<PackageFragmentDescriptor>createMaybeSingletonList(getPackageFragment(fqName));
177 }
178
179 @NotNull
180 @Override
181 public Collection<FqName> getSubPackagesOf(
182 @NotNull FqName fqName, @NotNull Function1<? super Name, Boolean> nameFilter
183 ) {
184 LazyPackageDescriptor packageDescriptor = getPackageFragment(fqName);
185 if (packageDescriptor == null) {
186 return Collections.emptyList();
187 }
188 return packageDescriptor.getDeclarationProvider().getAllDeclaredSubPackages(nameFilter);
189 }
190 };
191
192 fileAnnotations = storageManager.createMemoizedFunction(new Function1<KtFile, LazyAnnotations>() {
193 @Override
194 public LazyAnnotations invoke(KtFile file) {
195 return createAnnotations(file, file.getAnnotationEntries());
196 }
197 });
198
199 danglingAnnotations = storageManager.createMemoizedFunction(new Function1<KtFile, LazyAnnotations>() {
200 @Override
201 public LazyAnnotations invoke(KtFile file) {
202 return createAnnotations(file, file.getDanglingAnnotations());
203 }
204 });
205
206 syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
207 }
208
209 private LazyAnnotations createAnnotations(KtFile file, List<KtAnnotationEntry> annotationEntries) {
210 LexicalScope scope = fileScopeProvider.getFileResolutionScope(file);
211 LazyAnnotationsContextImpl lazyAnnotationContext =
212 new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope);
213 return new LazyAnnotations(lazyAnnotationContext, annotationEntries);
214 }
215
216 @Override
217 @NotNull
218 public PackageFragmentProvider getPackageFragmentProvider() {
219 return packageFragmentProvider;
220 }
221
222 @Override
223 @Nullable
224 public LazyPackageDescriptor getPackageFragment(@NotNull FqName fqName) {
225 return packages.invoke(fqName);
226 }
227
228 @Nullable
229 private LazyPackageDescriptor createPackage(FqName fqName) {
230 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName);
231 if (provider == null) {
232 return null;
233 }
234 return new LazyPackageDescriptor(module, fqName, this, provider);
235 }
236
237 @NotNull
238 @Override
239 public ModuleDescriptor getModuleDescriptor() {
240 return module;
241 }
242
243 @NotNull
244 @Override
245 public LazyResolveStorageManager getStorageManager() {
246 return storageManager;
247 }
248
249 @NotNull
250 public ExceptionTracker getExceptionTracker() {
251 return exceptionTracker;
252 }
253
254 @Override
255 @NotNull
256 @ReadOnly
257 public Collection<ClassifierDescriptor> getTopLevelClassifierDescriptors(@NotNull FqName fqName, @NotNull final LookupLocation location) {
258 if (fqName.isRoot()) return Collections.emptyList();
259
260 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName.parent());
261 if (provider == null) return Collections.emptyList();
262
263 Collection<ClassifierDescriptor> result = new SmartList<ClassifierDescriptor>();
264
265 result.addAll(ContainerUtil.mapNotNull(
266 provider.getClassOrObjectDeclarations(fqName.shortName()),
267 new Function<KtClassLikeInfo, ClassifierDescriptor>() {
268 @Override
269 public ClassDescriptor fun(KtClassLikeInfo classLikeInfo) {
270 if (classLikeInfo instanceof KtClassOrObjectInfo) {
271 //noinspection RedundantCast
272 return getClassDescriptor(((KtClassOrObjectInfo) classLikeInfo).getCorrespondingClassOrObject(), location);
273 }
274 else if (classLikeInfo instanceof KtScriptInfo) {
275 return getScriptDescriptor(((KtScriptInfo) classLikeInfo).getScript());
276 }
277 else {
278 throw new IllegalStateException(
279 "Unexpected " + classLikeInfo + " of type " + classLikeInfo.getClass().getName()
280 );
281 }
282 }
283 }
284 ));
285
286 result.addAll(ContainerUtil.map(
287 provider.getTypeAliasDeclarations(fqName.shortName()),
288 new Function<KtTypeAlias, ClassifierDescriptor>() {
289 @Override
290 public ClassifierDescriptor fun(KtTypeAlias alias) {
291 return (ClassifierDescriptor) lazyDeclarationResolver.resolveToDescriptor(alias);
292 }
293 }
294 ));
295
296 return result;
297 }
298
299 @Override
300 @NotNull
301 public ClassDescriptor getClassDescriptor(@NotNull KtClassOrObject classOrObject, @NotNull LookupLocation location) {
302 return lazyDeclarationResolver.getClassDescriptor(classOrObject, location);
303 }
304
305 @NotNull
306 public ScriptDescriptor getScriptDescriptor(@NotNull KtScript script) {
307 return lazyDeclarationResolver.getScriptDescriptor(script, NoLookupLocation.FOR_SCRIPT);
308 }
309
310 @Override
311 @NotNull
312 public BindingContext getBindingContext() {
313 return trace.getBindingContext();
314 }
315
316 @Override
317 @NotNull
318 public BindingTrace getTrace() {
319 return trace;
320 }
321
322 @Override
323 @NotNull
324 public DeclarationProviderFactory getDeclarationProviderFactory() {
325 return declarationProviderFactory;
326 }
327
328 @Override
329 @NotNull
330 public DeclarationDescriptor resolveToDescriptor(@NotNull KtDeclaration declaration) {
331 if (!areDescriptorsCreatedForDeclaration(declaration)) {
332 throw new IllegalStateException(
333 "No descriptors are created for declarations of type " + declaration.getClass().getSimpleName()
334 + "\n. Change the caller accordingly"
335 );
336 }
337 if (!KtPsiUtil.isLocal(declaration)) {
338 return lazyDeclarationResolver.resolveToDescriptor(declaration);
339 }
340 return localDescriptorResolver.resolveLocalDeclaration(declaration);
341 }
342
343 public static boolean areDescriptorsCreatedForDeclaration(@NotNull KtDeclaration declaration) {
344 return !(declaration instanceof KtAnonymousInitializer || declaration instanceof KtDestructuringDeclaration);
345 }
346
347 @NotNull
348 public Annotations getFileAnnotations(@NotNull KtFile file) {
349 return fileAnnotations.invoke(file);
350 }
351
352 @NotNull
353 public Annotations getDanglingAnnotations(@NotNull KtFile file) {
354 return danglingAnnotations.invoke(file);
355 }
356
357 @NotNull
358 private List<LazyPackageDescriptor> getAllPackages() {
359 LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT);
360 assert rootPackage != null : "Root package must be initialized";
361
362 return collectAllPackages(Lists.<LazyPackageDescriptor>newArrayList(), rootPackage);
363 }
364
365 @NotNull
366 private List<LazyPackageDescriptor> collectAllPackages(
367 @NotNull List<LazyPackageDescriptor> result,
368 @NotNull LazyPackageDescriptor current
369 ) {
370 result.add(current);
371 for (FqName subPackage : packageFragmentProvider.getSubPackagesOf(current.getFqName(), MemberScope.Companion.getALL_NAME_FILTER())) {
372 LazyPackageDescriptor fragment = getPackageFragment(subPackage);
373 assert fragment != null : "Couldn't find fragment for " + subPackage;
374 collectAllPackages(result, fragment);
375 }
376 return result;
377 }
378
379 @Override
380 public void forceResolveAll() {
381 for (LazyPackageDescriptor lazyPackage : getAllPackages()) {
382 ForceResolveUtil.forceResolveAllContents(lazyPackage);
383 }
384 }
385
386 @NotNull
387 public KtImportsFactory getJetImportsFactory() {
388 return jetImportFactory;
389 }
390
391 @Override
392 @NotNull
393 public AnnotationResolver getAnnotationResolver() {
394 return annotationResolve;
395 }
396
397 @Override
398 @NotNull
399 public DescriptorResolver getDescriptorResolver() {
400 return descriptorResolver;
401 }
402
403 @Override
404 @NotNull
405 public TypeResolver getTypeResolver() {
406 return typeResolver;
407 }
408
409 @NotNull
410 @Override
411 public FunctionDescriptorResolver getFunctionDescriptorResolver() {
412 return functionDescriptorResolver;
413 }
414
415 @NotNull
416 @Override
417 public DeclarationScopeProvider getDeclarationScopeProvider() {
418 return declarationScopeProvider;
419 }
420
421 @Override
422 @NotNull
423 public FileScopeProvider getFileScopeProvider() {
424 return fileScopeProvider;
425 }
426
427 @NotNull
428 @Override
429 public LookupTracker getLookupTracker() {
430 return lookupTracker;
431 }
432
433 @NotNull
434 @Override
435 public SupertypeLoopChecker getSupertypeLoopChecker() {
436 return supertypeLoopsResolver;
437 }
438
439 @Inject
440 public void setSupertypeLoopsResolver(@NotNull SupertypeLoopChecker supertypeLoopsResolver) {
441 this.supertypeLoopsResolver = supertypeLoopsResolver;
442 }
443
444 @Inject
445 public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) {
446 this.localDescriptorResolver = localDescriptorResolver;
447 }
448
449 @NotNull
450 @Override
451 public LanguageVersionSettings getLanguageVersionSettings() {
452 return languageVersionSettings;
453 }
454
455 @NotNull
456 @Override
457 public DelegationFilter getDelegationFilter() {
458 return delegationFilter;
459 }
460
461 @NotNull
462 @Override
463 public SyntheticResolveExtension getSyntheticResolveExtension() {
464 return syntheticResolveExtension;
465 }
466 }