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.JetScriptInfo;
039 import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory;
040 import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider;
041 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotations;
042 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl;
043 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor;
044 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor;
045 import org.jetbrains.kotlin.resolve.scopes.JetScope;
046 import org.jetbrains.kotlin.storage.*;
047
048 import javax.inject.Inject;
049 import java.util.Collection;
050 import java.util.Collections;
051 import java.util.List;
052
053 public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
054 private final LazyResolveStorageManager storageManager;
055 private final ExceptionTracker exceptionTracker;
056
057 private final ModuleDescriptor module;
058
059 private final BindingTrace trace;
060 private final DeclarationProviderFactory declarationProviderFactory;
061
062 private final MemoizedFunctionToNullable<FqName, LazyPackageDescriptor> packages;
063 private final PackageFragmentProvider packageFragmentProvider;
064
065 private final MemoizedFunctionToNotNull<JetScript, LazyScriptDescriptor> scriptDescriptors;
066
067 private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> fileAnnotations;
068 private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> danglingAnnotations;
069
070 private JetImportsFactory jetImportFactory;
071 private AnnotationResolver annotationResolve;
072 private DescriptorResolver descriptorResolver;
073 private FunctionDescriptorResolver functionDescriptorResolver;
074 private TypeResolver typeResolver;
075 private QualifiedExpressionResolver qualifiedExpressionResolver;
076 private ScriptBodyResolver scriptBodyResolver;
077 private LazyDeclarationResolver lazyDeclarationResolver;
078 private FileScopeProvider fileScopeProvider;
079 private DeclarationScopeProvider declarationScopeProvider;
080 private LookupTracker lookupTracker;
081 private LocalDescriptorResolver localDescriptorResolver;
082
083 @Inject
084 public void setJetImportFactory(JetImportsFactory jetImportFactory) {
085 this.jetImportFactory = jetImportFactory;
086 }
087
088 @Inject
089 public void setAnnotationResolve(AnnotationResolver annotationResolve) {
090 this.annotationResolve = annotationResolve;
091 }
092
093 @Inject
094 public void setDescriptorResolver(DescriptorResolver descriptorResolver) {
095 this.descriptorResolver = descriptorResolver;
096 }
097
098 @Inject
099 public void setFunctionDescriptorResolver(FunctionDescriptorResolver functionDescriptorResolver) {
100 this.functionDescriptorResolver = functionDescriptorResolver;
101 }
102
103 @Inject
104 public void setTypeResolver(TypeResolver typeResolver) {
105 this.typeResolver = typeResolver;
106 }
107
108 @Inject
109 public void setQualifiedExpressionResolver(QualifiedExpressionResolver qualifiedExpressionResolver) {
110 this.qualifiedExpressionResolver = qualifiedExpressionResolver;
111 }
112
113 @Inject
114 public void setScriptBodyResolver(ScriptBodyResolver scriptBodyResolver) {
115 this.scriptBodyResolver = scriptBodyResolver;
116 }
117
118 @Inject
119 public void setLazyDeclarationResolver(LazyDeclarationResolver lazyDeclarationResolver) {
120 this.lazyDeclarationResolver = lazyDeclarationResolver;
121 }
122
123 @Inject
124 public void setFileScopeProvider(@NotNull FileScopeProviderImpl fileScopeProvider) {
125 this.fileScopeProvider = fileScopeProvider;
126 }
127
128 @Inject
129 public void setDeclarationScopeProvider(@NotNull DeclarationScopeProviderImpl declarationScopeProvider) {
130 this.declarationScopeProvider = declarationScopeProvider;
131 }
132
133 @Inject
134 public void setLookupTracker(@NotNull LookupTracker lookupTracker) {
135 this.lookupTracker = lookupTracker;
136 }
137
138 // Only calls from injectors expected
139 @Deprecated
140 public ResolveSession(
141 @NotNull Project project,
142 @NotNull GlobalContext globalContext,
143 @NotNull ModuleDescriptor rootDescriptor,
144 @NotNull DeclarationProviderFactory declarationProviderFactory,
145 @NotNull BindingTrace delegationTrace
146 ) {
147 LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager =
148 new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
149
150 this.storageManager = lockBasedLazyResolveStorageManager;
151 this.exceptionTracker = globalContext.getExceptionTracker();
152 this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace);
153 this.module = rootDescriptor;
154
155 this.packages =
156 storageManager.createMemoizedFunctionWithNullableValues(new Function1<FqName, LazyPackageDescriptor>() {
157 @Override
158 @Nullable
159 public LazyPackageDescriptor invoke(FqName fqName) {
160 return createPackage(fqName);
161 }
162 });
163
164 this.declarationProviderFactory = declarationProviderFactory;
165
166 this.packageFragmentProvider = new PackageFragmentProvider() {
167 @NotNull
168 @Override
169 public List<PackageFragmentDescriptor> getPackageFragments(@NotNull FqName fqName) {
170 return ContainerUtil.<PackageFragmentDescriptor>createMaybeSingletonList(getPackageFragment(fqName));
171 }
172
173 @NotNull
174 @Override
175 public Collection<FqName> getSubPackagesOf(
176 @NotNull FqName fqName, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
177 ) {
178 LazyPackageDescriptor packageDescriptor = getPackageFragment(fqName);
179 if (packageDescriptor == null) {
180 return Collections.emptyList();
181 }
182 return packageDescriptor.getDeclarationProvider().getAllDeclaredSubPackages(nameFilter);
183 }
184 };
185
186 this.scriptDescriptors = storageManager.createMemoizedFunction(
187 new Function1<JetScript, LazyScriptDescriptor>() {
188 @Override
189 public LazyScriptDescriptor invoke(JetScript script) {
190 return new LazyScriptDescriptor(
191 ResolveSession.this,
192 scriptBodyResolver,
193 script,
194 ScriptPriorities.getScriptPriority(script)
195 );
196 }
197 }
198 );
199
200 fileAnnotations = storageManager.createMemoizedFunction(new Function1<JetFile, LazyAnnotations>() {
201 @Override
202 public LazyAnnotations invoke(JetFile file) {
203 return createAnnotations(file, file.getAnnotationEntries());
204 }
205 });
206
207 danglingAnnotations = storageManager.createMemoizedFunction(new Function1<JetFile, LazyAnnotations>() {
208 @Override
209 public LazyAnnotations invoke(JetFile file) {
210 return createAnnotations(file, file.getDanglingAnnotations());
211 }
212 });
213 }
214
215 private LazyAnnotations createAnnotations(JetFile file, List<JetAnnotationEntry> annotationEntries) {
216 LazyFileScope scope = fileScopeProvider.getFileScope(file);
217 LazyAnnotationsContextImpl lazyAnnotationContext =
218 new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope);
219 return new LazyAnnotations(lazyAnnotationContext, annotationEntries);
220 }
221
222 @Override
223 @NotNull
224 public PackageFragmentProvider getPackageFragmentProvider() {
225 return packageFragmentProvider;
226 }
227
228 @Override
229 @Nullable
230 public LazyPackageDescriptor getPackageFragment(@NotNull FqName fqName) {
231 return packages.invoke(fqName);
232 }
233
234 @Nullable
235 private LazyPackageDescriptor createPackage(FqName fqName) {
236 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName);
237 if (provider == null) {
238 return null;
239 }
240 return new LazyPackageDescriptor(module, fqName, this, provider);
241 }
242
243 @NotNull
244 @Override
245 public ModuleDescriptor getModuleDescriptor() {
246 return module;
247 }
248
249 @NotNull
250 @Override
251 public LazyResolveStorageManager getStorageManager() {
252 return storageManager;
253 }
254
255 @NotNull
256 public ExceptionTracker getExceptionTracker() {
257 return exceptionTracker;
258 }
259
260 @Override
261 @NotNull
262 @ReadOnly
263 public Collection<ClassDescriptor> getTopLevelClassDescriptors(@NotNull FqName fqName, @NotNull final LookupLocation location) {
264 if (fqName.isRoot()) return Collections.emptyList();
265
266 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName.parent());
267 if (provider == null) return Collections.emptyList();
268
269 return ContainerUtil.mapNotNull(
270 provider.getClassOrObjectDeclarations(fqName.shortName()),
271 new Function<JetClassLikeInfo, ClassDescriptor>() {
272 @Override
273 public ClassDescriptor fun(JetClassLikeInfo classLikeInfo) {
274 if (classLikeInfo instanceof JetScriptInfo) {
275 return getClassDescriptorForScript(((JetScriptInfo) classLikeInfo).getScript());
276 }
277 JetClassOrObject classOrObject = classLikeInfo.getCorrespondingClassOrObject();
278 if (classOrObject == null) return null;
279 return getClassDescriptor(classOrObject, location);
280 }
281 }
282 );
283 }
284
285 @Override
286 @NotNull
287 public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject, @NotNull LookupLocation location) {
288 return lazyDeclarationResolver.getClassDescriptor(classOrObject, location);
289 }
290
291 @NotNull
292 public ClassDescriptor getClassDescriptorForScript(@NotNull JetScript script) {
293 JetScope memberScope = lazyDeclarationResolver.getMemberScopeDeclaredIn(script, NoLookupLocation.FOR_SCRIPT);
294 FqName fqName = ScriptNameUtil.classNameForScript(script);
295 ClassifierDescriptor classifier = memberScope.getClassifier(fqName.shortName(), NoLookupLocation.FOR_SCRIPT);
296 assert classifier != null : "No descriptor for " + fqName + " in file " + script.getContainingFile();
297 return (ClassDescriptor) classifier;
298 }
299
300 @Override
301 @NotNull
302 public ScriptDescriptor getScriptDescriptor(@NotNull JetScript script) {
303 return scriptDescriptors.invoke(script);
304 }
305
306 @Override
307 @NotNull
308 public BindingContext getBindingContext() {
309 return trace.getBindingContext();
310 }
311
312 @Override
313 @NotNull
314 public BindingTrace getTrace() {
315 return trace;
316 }
317
318 @Override
319 @NotNull
320 public DeclarationProviderFactory getDeclarationProviderFactory() {
321 return declarationProviderFactory;
322 }
323
324 @Override
325 @NotNull
326 public DeclarationDescriptor resolveToDescriptor(@NotNull JetDeclaration declaration) {
327 if (!JetPsiUtil.isLocal(declaration)) {
328 return lazyDeclarationResolver.resolveToDescriptor(declaration);
329 }
330 return localDescriptorResolver.resolveLocalDeclaration(declaration);
331 }
332
333 @NotNull
334 public Annotations getFileAnnotations(@NotNull JetFile file) {
335 return fileAnnotations.invoke(file);
336 }
337
338 @NotNull
339 public Annotations getDanglingAnnotations(@NotNull JetFile file) {
340 return danglingAnnotations.invoke(file);
341 }
342
343 @NotNull
344 private List<LazyPackageDescriptor> getAllPackages() {
345 LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT);
346 assert rootPackage != null : "Root package must be initialized";
347
348 return collectAllPackages(Lists.<LazyPackageDescriptor>newArrayList(), rootPackage);
349 }
350
351 @NotNull
352 private List<LazyPackageDescriptor> collectAllPackages(
353 @NotNull List<LazyPackageDescriptor> result,
354 @NotNull LazyPackageDescriptor current
355 ) {
356 result.add(current);
357 for (FqName subPackage : packageFragmentProvider.getSubPackagesOf(current.getFqName(), JetScope.ALL_NAME_FILTER)) {
358 LazyPackageDescriptor fragment = getPackageFragment(subPackage);
359 assert fragment != null : "Couldn't find fragment for " + subPackage;
360 collectAllPackages(result, fragment);
361 }
362 return result;
363 }
364
365 @Override
366 public void forceResolveAll() {
367 for (LazyPackageDescriptor lazyPackage : getAllPackages()) {
368 ForceResolveUtil.forceResolveAllContents(lazyPackage);
369 }
370 }
371
372 @NotNull
373 public JetImportsFactory getJetImportsFactory() {
374 return jetImportFactory;
375 }
376
377 @Override
378 @NotNull
379 public AnnotationResolver getAnnotationResolver() {
380 return annotationResolve;
381 }
382
383 @Override
384 @NotNull
385 public DescriptorResolver getDescriptorResolver() {
386 return descriptorResolver;
387 }
388
389 @Override
390 @NotNull
391 public TypeResolver getTypeResolver() {
392 return typeResolver;
393 }
394
395 @NotNull
396 public QualifiedExpressionResolver getQualifiedExpressionResolver() {
397 return qualifiedExpressionResolver;
398 }
399
400 @NotNull
401 @Override
402 public FunctionDescriptorResolver getFunctionDescriptorResolver() {
403 return functionDescriptorResolver;
404 }
405
406 @NotNull
407 @Override
408 public DeclarationScopeProvider getDeclarationScopeProvider() {
409 return declarationScopeProvider;
410 }
411
412 @Override
413 @NotNull
414 public FileScopeProvider getFileScopeProvider() {
415 return fileScopeProvider;
416 }
417
418 @NotNull
419 @Override
420 public LookupTracker getLookupTracker() {
421 return lookupTracker;
422 }
423
424 @Inject
425 public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) {
426 this.localDescriptorResolver = localDescriptorResolver;
427 }
428 }