Cache resolve session under OUT_OF_BLOCK_MODIFICATION_TRACKER
This commit is contained in:
@@ -71,7 +71,6 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
private final InjectorForLazyResolve injector;
|
private final InjectorForLazyResolve injector;
|
||||||
|
|
||||||
private final Function<FqName, Name> classifierAliases;
|
private final Function<FqName, Name> classifierAliases;
|
||||||
private final ResolveElementCache resolveElementCache;
|
|
||||||
|
|
||||||
public ResolveSession(
|
public ResolveSession(
|
||||||
@NotNull Project project,
|
@NotNull Project project,
|
||||||
@@ -122,7 +121,6 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
rootDescriptor.setRootNamespace(rootPackage);
|
rootDescriptor.setRootNamespace(rootPackage);
|
||||||
|
|
||||||
this.declarationProviderFactory = declarationProviderFactory;
|
this.declarationProviderFactory = declarationProviderFactory;
|
||||||
this.resolveElementCache = new ResolveElementCache(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -352,11 +350,6 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public BindingContext resolveElement(@NotNull JetElement jetElement) {
|
|
||||||
return resolveElementCache.resolveElement(jetElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Name resolveClassifierAlias(@NotNull FqName packageName, @NotNull Name alias) {
|
public Name resolveClassifierAlias(@NotNull FqName packageName, @NotNull Name alias) {
|
||||||
// TODO: creating a new FqName object every time...
|
// TODO: creating a new FqName object every time...
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.plugin.completion;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.CompletionProgressIndicator;
|
||||||
|
import com.intellij.codeInsight.completion.CompletionService;
|
||||||
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
|
|
||||||
|
public class CompletionProgressIndicatorUtil {
|
||||||
|
private CompletionProgressIndicatorUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProcessCanceledException rethrowWithCancelIndicator(ProcessCanceledException exception) {
|
||||||
|
CompletionProgressIndicator indicator = (CompletionProgressIndicator) CompletionService.getCompletionService().getCurrentCompletion();
|
||||||
|
assert indicator != null;
|
||||||
|
|
||||||
|
// Force cancel to avoid deadlock in CompletionThreading.delegateWeighing()
|
||||||
|
if (!indicator.isCanceled()) {
|
||||||
|
indicator.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.plugin.completion;
|
package org.jetbrains.jet.plugin.completion;
|
||||||
|
|
||||||
import com.intellij.codeInsight.completion.*;
|
import com.intellij.codeInsight.completion.*;
|
||||||
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
import com.intellij.patterns.PlatformPatterns;
|
import com.intellij.patterns.PlatformPatterns;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiReference;
|
import com.intellij.psi.PsiReference;
|
||||||
@@ -50,19 +51,24 @@ public class JetCompletionContributor extends CompletionContributor {
|
|||||||
|
|
||||||
JetSimpleNameReference jetReference = getJetReference(parameters);
|
JetSimpleNameReference jetReference = getJetReference(parameters);
|
||||||
if (jetReference != null) {
|
if (jetReference != null) {
|
||||||
result.restartCompletionWhenNothingMatches();
|
try {
|
||||||
|
result.restartCompletionWhenNothingMatches();
|
||||||
|
|
||||||
CompletionSession session = new CompletionSession(parameters, result, jetReference, position);
|
CompletionSession session = new CompletionSession(parameters, result, jetReference, position);
|
||||||
session.completeForReference();
|
|
||||||
|
|
||||||
if (!session.getJetResult().isSomethingAdded() && session.getParameters().getInvocationCount() < 2) {
|
|
||||||
// Rerun completion if nothing was found
|
|
||||||
session = new CompletionSession(parameters.withInvocationCount(2), result, jetReference, position);
|
|
||||||
session.completeForReference();
|
session.completeForReference();
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent from adding reference variants from standard reference contributor
|
if (!session.getJetResult().isSomethingAdded() && session.getParameters().getInvocationCount() < 2) {
|
||||||
result.stopHere();
|
// Rerun completion if nothing was found
|
||||||
|
session = new CompletionSession(parameters.withInvocationCount(2), result, jetReference, position);
|
||||||
|
session.completeForReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent from adding reference variants from standard reference contributor
|
||||||
|
result.stopHere();
|
||||||
|
}
|
||||||
|
catch (ProcessCanceledException e) {
|
||||||
|
throw CompletionProgressIndicatorUtil.rethrowWithCancelIndicator(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.plugin.completion;
|
|||||||
|
|
||||||
import com.intellij.codeInsight.completion.*;
|
import com.intellij.codeInsight.completion.*;
|
||||||
import com.intellij.codeInsight.lookup.LookupElement;
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
import com.intellij.patterns.ElementPattern;
|
import com.intellij.patterns.ElementPattern;
|
||||||
import com.intellij.patterns.PlatformPatterns;
|
import com.intellij.patterns.PlatformPatterns;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
@@ -66,21 +67,26 @@ public class JetPackagesContributor extends CompletionContributor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int prefixLength = parameters.getOffset() - simpleNameReference.getExpression().getTextOffset();
|
try {
|
||||||
result = result.withPrefixMatcher(new PlainPrefixMatcher(name.substring(0, prefixLength)));
|
int prefixLength = parameters.getOffset() - simpleNameReference.getExpression().getTextOffset();
|
||||||
|
result = result.withPrefixMatcher(new PlainPrefixMatcher(name.substring(0, prefixLength)));
|
||||||
|
|
||||||
CancelableResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveResultForFile(
|
CancelableResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveResultForFile(
|
||||||
(JetFile) simpleNameReference.getExpression().getContainingFile());
|
(JetFile) simpleNameReference.getExpression().getContainingFile());
|
||||||
BindingContext bindingContext = resolveSession.resolveToElement(simpleNameReference.getExpression());
|
BindingContext bindingContext = resolveSession.resolveToElement(simpleNameReference.getExpression());
|
||||||
|
|
||||||
for (LookupElement variant : DescriptorLookupConverter.collectLookupElements(
|
for (LookupElement variant : DescriptorLookupConverter.collectLookupElements(
|
||||||
resolveSession, bindingContext, TipsManager.getPackageReferenceVariants(simpleNameReference.getExpression(), bindingContext))) {
|
resolveSession, bindingContext, TipsManager.getPackageReferenceVariants(simpleNameReference.getExpression(), bindingContext))) {
|
||||||
if (!variant.getLookupString().contains(DUMMY_IDENTIFIER)) {
|
if (!variant.getLookupString().contains(DUMMY_IDENTIFIER)) {
|
||||||
result.addElement(variant);
|
result.addElement(variant);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
result.stopHere();
|
result.stopHere();
|
||||||
|
}
|
||||||
|
catch (ProcessCanceledException e) {
|
||||||
|
throw CompletionProgressIndicatorUtil.rethrowWithCancelIndicator(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ public final class AnalyzerFacadeWithCache {
|
|||||||
|
|
||||||
ResolveSession resolveSession =
|
ResolveSession resolveSession =
|
||||||
AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).getLazyResolveSession(fileProject, files);
|
AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).getLazyResolveSession(fileProject, files);
|
||||||
return Result.create(new CancelableResolveSession(file, resolveSession), PsiModificationTracker.MODIFICATION_COUNT);
|
return Result.create(new CancelableResolveSession(file, resolveSession), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
|
|||||||
@@ -40,18 +40,20 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
public class CancelableResolveSession implements KotlinCodeAnalyzer, ModificationTracker {
|
public class CancelableResolveSession implements KotlinCodeAnalyzer, ModificationTracker {
|
||||||
private final JetFile file;
|
private final JetFile file;
|
||||||
private final ResolveSession resolveSession;
|
private final ResolveSession resolveSession;
|
||||||
|
private final ResolveElementCache resolveElementCache;
|
||||||
private final AtomicLong canceledTracker = new AtomicLong();
|
private final AtomicLong canceledTracker = new AtomicLong();
|
||||||
|
|
||||||
public CancelableResolveSession(JetFile file, ResolveSession resolveSession) {
|
public CancelableResolveSession(@NotNull JetFile file, @NotNull ResolveSession resolveSession) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.resolveSession = resolveSession;
|
this.resolveSession = resolveSession;
|
||||||
|
this.resolveElementCache = new ResolveElementCache(resolveSession, file.getProject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public BindingContext resolveToElement(final JetElement element) {
|
public BindingContext resolveToElement(final JetElement element) {
|
||||||
return computableWithProcessingCancel(new Computable<BindingContext>() {
|
return computableWithProcessingCancel(new Computable<BindingContext>() {
|
||||||
@Override
|
@Override
|
||||||
public BindingContext compute() {
|
public BindingContext compute() {
|
||||||
return resolveSession.resolveElement(element);
|
return resolveElementCache.resolveElement(element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+97
-74
@@ -14,21 +14,27 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.lazy;
|
package org.jetbrains.jet.plugin.project;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Functions;
|
import com.google.common.base.Functions;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.*;
|
||||||
import com.intellij.util.Function;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.di.InjectorForBodyResolve;
|
import org.jetbrains.jet.di.InjectorForBodyResolve;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
|
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.LazyDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor;
|
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyPackageDescriptor;
|
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyPackageDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNotNull;
|
import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNotNull;
|
||||||
@@ -44,32 +50,39 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
class ResolveElementCache {
|
public class ResolveElementCache {
|
||||||
@SuppressWarnings("unchecked")
|
private static final BodyResolveContextForLazy EMPTY_CONTEXT = new BodyResolveContextForLazy(Functions.<JetScope>constant(null));
|
||||||
private static final BodyResolveContextForLazy EMPTY_CONTEXT = new BodyResolveContextForLazy((com.google.common.base.Function) Functions.constant(null));
|
|
||||||
|
|
||||||
|
private final CachedValue<MemoizedFunctionToNotNull<JetElement, BindingContext>> additionalResolveCache;
|
||||||
private final ResolveSession resolveSession;
|
private final ResolveSession resolveSession;
|
||||||
private final MemoizedFunctionToNotNull<JetElement, BindingContext> resolveElementCache;
|
|
||||||
|
|
||||||
ResolveElementCache(ResolveSession resolveSession) {
|
public ResolveElementCache(ResolveSession resolveSession, Project project) {
|
||||||
this.resolveSession = resolveSession;
|
this.resolveSession = resolveSession;
|
||||||
|
|
||||||
this.resolveElementCache = resolveSession.getStorageManager().createMemoizedFunction(new Function<JetElement, BindingContext>() {
|
// Recreate internal cache after change of modification count
|
||||||
@Override
|
this.additionalResolveCache =
|
||||||
public BindingContext fun(JetElement namedFunction) {
|
CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<MemoizedFunctionToNotNull<JetElement, BindingContext>>() {
|
||||||
return computeResolveElement(namedFunction);
|
@Nullable
|
||||||
}
|
@Override
|
||||||
}, StorageManager.ReferenceKind.WEAK);
|
public Result<MemoizedFunctionToNotNull<JetElement, BindingContext>> compute() {
|
||||||
|
StorageManager manager = ResolveElementCache.this.resolveSession.getStorageManager();
|
||||||
|
MemoizedFunctionToNotNull<JetElement, BindingContext> elementsCacheFunction =
|
||||||
|
manager.createMemoizedFunction(new com.intellij.util.Function<JetElement, BindingContext>() {
|
||||||
|
@Override
|
||||||
|
public BindingContext fun(JetElement jetElement) {
|
||||||
|
return elementAdditionalResolve(jetElement);
|
||||||
|
}
|
||||||
|
}, StorageManager.ReferenceKind.WEAK);
|
||||||
|
|
||||||
|
return Result.create(elementsCacheFunction, PsiModificationTracker.MODIFICATION_COUNT);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
BindingContext resolveElement(@NotNull JetElement jetElement) {
|
public BindingContext resolveElement(@NotNull JetElement jetElement) {
|
||||||
return resolveElementCache.fun(jetElement);
|
@SuppressWarnings("unchecked") JetElement elementOfAdditionalResolve = (JetElement) JetPsiUtil.getTopmostParentOfTypes(
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private BindingContext computeResolveElement(@NotNull JetElement jetElement) {
|
|
||||||
@SuppressWarnings("unchecked") PsiElement resolveElement = JetPsiUtil.getTopmostParentOfTypes(
|
|
||||||
jetElement,
|
jetElement,
|
||||||
JetNamedFunction.class,
|
JetNamedFunction.class,
|
||||||
JetClassInitializer.class,
|
JetClassInitializer.class,
|
||||||
@@ -81,49 +94,12 @@ class ResolveElementCache {
|
|||||||
JetTypeConstraint.class,
|
JetTypeConstraint.class,
|
||||||
JetNamespaceHeader.class);
|
JetNamespaceHeader.class);
|
||||||
|
|
||||||
if (resolveElement != null) {
|
if (elementOfAdditionalResolve != null) {
|
||||||
// All additional resolve should be done to separate trace
|
if (elementOfAdditionalResolve instanceof JetNamespaceHeader) {
|
||||||
BindingTrace trace = resolveSession.getStorageManager().createSafeTrace(
|
elementOfAdditionalResolve = jetElement;
|
||||||
new DelegatingBindingTrace(resolveSession.getBindingContext(), "trace to resolve element", jetElement));
|
|
||||||
|
|
||||||
JetFile file = (JetFile) jetElement.getContainingFile();
|
|
||||||
|
|
||||||
if (resolveElement instanceof JetNamedFunction) {
|
|
||||||
functionAdditionalResolve(resolveSession, (JetNamedFunction) resolveElement, trace, file);
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetClassInitializer) {
|
|
||||||
initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file);
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetProperty) {
|
|
||||||
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file);
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetDelegationSpecifierList) {
|
|
||||||
delegationSpecifierAdditionalResolve(resolveSession, (JetDelegationSpecifierList) resolveElement, trace, file);
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetImportDirective) {
|
|
||||||
JetImportDirective importDirective = (JetImportDirective) resolveElement;
|
|
||||||
JetScope scope = resolveSession.getInjector().getScopeProvider().getFileScope((JetFile) importDirective.getContainingFile());
|
|
||||||
|
|
||||||
// Get all descriptors to force resolving all imports
|
|
||||||
scope.getAllDescriptors();
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetAnnotationEntry) {
|
|
||||||
annotationAdditionalResolve(resolveSession, (JetAnnotationEntry) resolveElement);
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetTypeParameter) {
|
|
||||||
typeParameterAdditionalResolve(resolveSession, (JetTypeParameter) resolveElement);
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetTypeConstraint) {
|
|
||||||
typeConstraintAdditionalResolve(resolveSession, jetElement);
|
|
||||||
}
|
|
||||||
else if (resolveElement instanceof JetNamespaceHeader) {
|
|
||||||
namespaceRefAdditionalResolve(resolveSession, (JetNamespaceHeader) resolveElement, trace, jetElement);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert false : "Invalid type of the topmost parent";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return trace.getBindingContext();
|
return additionalResolveCache.getValue().fun(elementOfAdditionalResolve);
|
||||||
}
|
}
|
||||||
|
|
||||||
JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetElement, JetDeclaration.class, false);
|
JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetElement, JetDeclaration.class, false);
|
||||||
@@ -135,11 +111,57 @@ class ResolveElementCache {
|
|||||||
return resolveSession.getBindingContext();
|
return resolveSession.getBindingContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void namespaceRefAdditionalResolve(
|
@NotNull
|
||||||
ResolveSession resolveSession,
|
private BindingContext elementAdditionalResolve(@NotNull JetElement resolveElement) {
|
||||||
JetNamespaceHeader header, BindingTrace trace, JetElement jetElement
|
// All additional resolve should be done to separate trace
|
||||||
) {
|
BindingTrace trace = resolveSession.getStorageManager().createSafeTrace(
|
||||||
|
new DelegatingBindingTrace(resolveSession.getBindingContext(), "trace to resolve element", resolveElement));
|
||||||
|
|
||||||
|
JetFile file = (JetFile) resolveElement.getContainingFile();
|
||||||
|
|
||||||
|
if (resolveElement instanceof JetNamedFunction) {
|
||||||
|
functionAdditionalResolve(resolveSession, (JetNamedFunction) resolveElement, trace, file);
|
||||||
|
}
|
||||||
|
else if (resolveElement instanceof JetClassInitializer) {
|
||||||
|
initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file);
|
||||||
|
}
|
||||||
|
else if (resolveElement instanceof JetProperty) {
|
||||||
|
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file);
|
||||||
|
}
|
||||||
|
else if (resolveElement instanceof JetDelegationSpecifierList) {
|
||||||
|
delegationSpecifierAdditionalResolve(resolveSession, (JetDelegationSpecifierList) resolveElement, trace, file);
|
||||||
|
}
|
||||||
|
else if (resolveElement instanceof JetImportDirective) {
|
||||||
|
JetImportDirective importDirective = (JetImportDirective) resolveElement;
|
||||||
|
JetScope scope = resolveSession.getInjector().getScopeProvider().getFileScope((JetFile) importDirective.getContainingFile());
|
||||||
|
|
||||||
|
// Get all descriptors to force resolving all imports
|
||||||
|
scope.getAllDescriptors();
|
||||||
|
}
|
||||||
|
else if (resolveElement instanceof JetAnnotationEntry) {
|
||||||
|
annotationAdditionalResolve(resolveSession, (JetAnnotationEntry) resolveElement);
|
||||||
|
}
|
||||||
|
else if (resolveElement instanceof JetTypeParameter) {
|
||||||
|
typeParameterAdditionalResolve(resolveSession, (JetTypeParameter) resolveElement);
|
||||||
|
}
|
||||||
|
else if (resolveElement instanceof JetTypeConstraint) {
|
||||||
|
typeConstraintAdditionalResolve(resolveSession, (JetTypeConstraint) resolveElement);
|
||||||
|
}
|
||||||
|
else if (PsiTreeUtil.getParentOfType(resolveElement, JetNamespaceHeader.class) != null) {
|
||||||
|
namespaceRefAdditionalResolve(resolveSession, trace, resolveElement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert false : "Invalid type of the topmost parent";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trace.getBindingContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void namespaceRefAdditionalResolve(ResolveSession resolveSession, BindingTrace trace, JetElement jetElement) {
|
||||||
if (jetElement instanceof JetSimpleNameExpression) {
|
if (jetElement instanceof JetSimpleNameExpression) {
|
||||||
|
JetNamespaceHeader header = PsiTreeUtil.getParentOfType(jetElement, JetNamespaceHeader.class);
|
||||||
|
assert header != null;
|
||||||
|
|
||||||
JetSimpleNameExpression packageNameExpression = (JetSimpleNameExpression) jetElement;
|
JetSimpleNameExpression packageNameExpression = (JetSimpleNameExpression) jetElement;
|
||||||
if (trace.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, packageNameExpression) == null) {
|
if (trace.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, packageNameExpression) == null) {
|
||||||
JetScope scope = getExpressionMemberScope(resolveSession, packageNameExpression);
|
JetScope scope = getExpressionMemberScope(resolveSession, packageNameExpression);
|
||||||
@@ -160,8 +182,8 @@ class ResolveElementCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void typeConstraintAdditionalResolve(KotlinCodeAnalyzer analyzer, JetElement jetElement) {
|
private static void typeConstraintAdditionalResolve(KotlinCodeAnalyzer analyzer, JetTypeConstraint jetTypeConstraint) {
|
||||||
JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetElement, JetDeclaration.class);
|
JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetTypeConstraint, JetDeclaration.class);
|
||||||
DeclarationDescriptor descriptor = analyzer.resolveToDescriptor(declaration);
|
DeclarationDescriptor descriptor = analyzer.resolveToDescriptor(declaration);
|
||||||
|
|
||||||
assert (descriptor instanceof ClassDescriptor);
|
assert (descriptor instanceof ClassDescriptor);
|
||||||
@@ -212,7 +234,7 @@ class ResolveElementCache {
|
|||||||
final JetScope propertyResolutionScope = resolveSession.getInjector().getScopeProvider().getResolutionScopeForDeclaration(
|
final JetScope propertyResolutionScope = resolveSession.getInjector().getScopeProvider().getResolutionScopeForDeclaration(
|
||||||
jetProperty);
|
jetProperty);
|
||||||
|
|
||||||
BodyResolveContextForLazy bodyResolveContext = new BodyResolveContextForLazy(new com.google.common.base.Function<JetDeclaration, JetScope>() {
|
BodyResolveContextForLazy bodyResolveContext = new BodyResolveContextForLazy(new Function<JetDeclaration, JetScope>() {
|
||||||
@Override
|
@Override
|
||||||
public JetScope apply(JetDeclaration declaration) {
|
public JetScope apply(JetDeclaration declaration) {
|
||||||
assert declaration.getParent() == jetProperty : "Must be called only for property accessors, but called for " + declaration;
|
assert declaration.getParent() == jetProperty : "Must be called only for property accessors, but called for " + declaration;
|
||||||
@@ -287,7 +309,7 @@ class ResolveElementCache {
|
|||||||
return provider.getResolutionScopeForDeclaration(parentDeclaration);
|
return provider.getResolutionScopeForDeclaration(parentDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JetScope getExpressionMemberScope(@NotNull ResolveSession resolveSession, @NotNull JetExpression expression) {
|
private static JetScope getExpressionMemberScope(@NotNull ResolveSession resolveSession, @NotNull JetExpression expression) {
|
||||||
BindingTrace trace = resolveSession.getStorageManager().createSafeTrace(new DelegatingBindingTrace(
|
BindingTrace trace = resolveSession.getStorageManager().createSafeTrace(new DelegatingBindingTrace(
|
||||||
resolveSession.getBindingContext(), "trace to resolve a member scope of expression", expression));
|
resolveSession.getBindingContext(), "trace to resolve a member scope of expression", expression));
|
||||||
|
|
||||||
@@ -363,9 +385,9 @@ class ResolveElementCache {
|
|||||||
|
|
||||||
private static class BodyResolveContextForLazy implements BodiesResolveContext {
|
private static class BodyResolveContextForLazy implements BodiesResolveContext {
|
||||||
|
|
||||||
private final com.google.common.base.Function<JetDeclaration, JetScope> declaringScopes;
|
private final Function<? super JetDeclaration, JetScope> declaringScopes;
|
||||||
|
|
||||||
private BodyResolveContextForLazy(@NotNull com.google.common.base.Function<JetDeclaration, JetScope> declaringScopes) {
|
private BodyResolveContextForLazy(@NotNull Function<? super JetDeclaration, JetScope> declaringScopes) {
|
||||||
this.declaringScopes = declaringScopes;
|
this.declaringScopes = declaringScopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,8 +417,9 @@ class ResolveElementCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public com.google.common.base.Function<JetDeclaration, JetScope> getDeclaringScopes() {
|
public Function<JetDeclaration, JetScope> getDeclaringScopes() {
|
||||||
return declaringScopes;
|
//noinspection unchecked
|
||||||
|
return (Function<JetDeclaration, JetScope>) declaringScopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Reference in New Issue
Block a user