Replaced JetScopeUtils.getResolutionScope() with more correct utility

This commit is contained in:
Valentin Kipyatkov
2015-06-19 21:04:43 +03:00
parent 776d198ea5
commit c5f0fbf327
7 changed files with 55 additions and 71 deletions
@@ -149,29 +149,4 @@ public final class JetScopeUtils {
} }
return out.toString(); return out.toString();
} }
@Nullable
public static JetScope getResolutionScope(@NotNull PsiElement element, @NotNull BindingContext context) {
PsiElement parent = element.getParent();
if (parent instanceof JetClassBody) {
JetClassOrObject classOrObject = (JetClassOrObject) parent.getParent();
ClassDescriptor classDescriptor = context.get(BindingContext.CLASS, classOrObject);
if (classDescriptor instanceof ClassDescriptorWithResolutionScopes) {
return ((ClassDescriptorWithResolutionScopes) classDescriptor).getScopeForMemberDeclarationResolution();
}
return null;
}
if (parent instanceof JetFile) {
PackageFragmentDescriptor packageFragment = context.get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, (JetFile) parent);
if (packageFragment == null) return null;
PackageViewDescriptor packageView = packageFragment.getContainingDeclaration().getPackage(((JetFile) parent).getPackageFqName());
return packageView.getMemberScope();
}
JetExpression expression = PsiTreeUtil.getParentOfType(element, JetExpression.class, false);
return expression != null ? context.get(BindingContext.RESOLUTION_SCOPE, expression) : null;
}
} }
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings
import org.jetbrains.kotlin.idea.core.getResolutionScope
import org.jetbrains.kotlin.idea.core.refactoring.EmptyValidator import org.jetbrains.kotlin.idea.core.refactoring.EmptyValidator
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
@@ -77,7 +78,7 @@ class ParameterNameAndTypeCompletion(
public fun addFromImportedClasses(position: PsiElement, bindingContext: BindingContext, visibilityFilter: (DeclarationDescriptor) -> Boolean) { public fun addFromImportedClasses(position: PsiElement, bindingContext: BindingContext, visibilityFilter: (DeclarationDescriptor) -> Boolean) {
for ((i, prefixMatcher) in allPrefixMatchers.withIndex()) { for ((i, prefixMatcher) in allPrefixMatchers.withIndex()) {
val resolutionScope = position.getResolutionScope(bindingContext) val resolutionScope = position.getResolutionScope(bindingContext, resolutionFacade)
val classifiers = resolutionScope.getDescriptorsFiltered(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS, prefixMatcher.toClassifierNamePrefixMatcher().asNameFilter()) val classifiers = resolutionScope.getDescriptorsFiltered(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS, prefixMatcher.toClassifierNamePrefixMatcher().asNameFilter())
for (classifier in classifiers) { for (classifier in classifiers) {
@@ -90,27 +91,6 @@ class ParameterNameAndTypeCompletion(
} }
} }
private fun PsiElement.getResolutionScope(bindingContext: BindingContext): JetScope {
for (parent in parentsWithSelf) {
if (parent is JetExpression) {
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, parent]
if (scope != null) return scope
}
if (parent is JetClassOrObject) {
val classDescriptor = bindingContext[BindingContext.CLASS, parent] as? ClassDescriptorWithResolutionScopes
if (classDescriptor != null) {
return classDescriptor.getScopeForMemberDeclarationResolution()
}
}
if (parent is JetFile) {
return resolutionFacade.getFileTopLevelScope(parent)
}
}
error("Not in JetFile")
}
public fun addFromAllClasses(parameters: CompletionParameters, indicesHelper: KotlinIndicesHelper) { public fun addFromAllClasses(parameters: CompletionParameters, indicesHelper: KotlinIndicesHelper) {
for ((i, prefixMatcher) in allPrefixMatchers.withIndex()) { for ((i, prefixMatcher) in allPrefixMatchers.withIndex()) {
AllClassesCompletion(parameters, indicesHelper, prefixMatcher.toClassifierNamePrefixMatcher(), { !it.isSingleton() }) AllClassesCompletion(parameters, indicesHelper, prefixMatcher.toClassifierNamePrefixMatcher(), { !it.isSingleton() })
@@ -16,10 +16,15 @@
package org.jetbrains.kotlin.idea.core package org.jetbrains.kotlin.idea.core
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstanceToExpression import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstanceToExpression
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
import java.util.HashMap import java.util.HashMap
@@ -72,3 +77,24 @@ public fun ThisReceiver.asExpression(resolutionScope: JetScope, psiFactory: JetP
?.value ?: return null ?.value ?: return null
return expressionFactory.createExpression(psiFactory) return expressionFactory.createExpression(psiFactory)
} }
public fun PsiElement.getResolutionScope(bindingContext: BindingContext, resolutionFacade: ResolutionFacade): JetScope {
for (parent in parentsWithSelf) {
if (parent is JetExpression) {
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, parent]
if (scope != null) return scope
}
if (parent is JetClassBody) {
val classDescriptor = bindingContext[BindingContext.CLASS, parent.getParent()] as? ClassDescriptorWithResolutionScopes
if (classDescriptor != null) {
return classDescriptor.getScopeForMemberDeclarationResolution()
}
}
if (parent is JetFile) {
return resolutionFacade.getFileTopLevelScope(parent)
}
}
error("Not in JetFile")
}
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2;
import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages; import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.core.CorePackage;
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil; import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil;
import org.jetbrains.kotlin.idea.util.UtilPackage; import org.jetbrains.kotlin.idea.util.UtilPackage;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
@@ -37,7 +38,6 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilPackage
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.scopes.JetScope; import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils;
import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.JetType;
import java.util.Collections; import java.util.Collections;
@@ -103,7 +103,7 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact
JetExpression initializer = property.getInitializer(); JetExpression initializer = property.getInitializer();
if (QuickFixUtil.canEvaluateTo(initializer, expression) || if (QuickFixUtil.canEvaluateTo(initializer, expression) ||
(getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(property.getGetter(), expression))) { (getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(property.getGetter(), expression))) {
JetScope scope = JetScopeUtils.getResolutionScope(property, context); JetScope scope = CorePackage.getResolutionScope(property, context, ResolvePackage.getResolutionFacade(property));
JetType typeToInsert = UtilPackage.approximateWithResolvableType(expressionType, scope, false); JetType typeToInsert = UtilPackage.approximateWithResolvableType(expressionType, scope, false);
actions.add(new ChangeVariableTypeFix(property, typeToInsert)); actions.add(new ChangeVariableTypeFix(property, typeToInsert));
} }
@@ -117,7 +117,7 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact
? BindingContextUtilPackage.getTargetFunction((JetReturnExpression) expressionParent, context) ? BindingContextUtilPackage.getTargetFunction((JetReturnExpression) expressionParent, context)
: PsiTreeUtil.getParentOfType(expression, JetFunction.class, true); : PsiTreeUtil.getParentOfType(expression, JetFunction.class, true);
if (function instanceof JetFunction && QuickFixUtil.canFunctionOrGetterReturnExpression(function, expression)) { if (function instanceof JetFunction && QuickFixUtil.canFunctionOrGetterReturnExpression(function, expression)) {
JetScope scope = JetScopeUtils.getResolutionScope(function, context); JetScope scope = CorePackage.getResolutionScope(function, context, ResolvePackage.getResolutionFacade(function));
JetType typeToInsert = UtilPackage.approximateWithResolvableType(expressionType, scope, false); JetType typeToInsert = UtilPackage.approximateWithResolvableType(expressionType, scope, false);
actions.add(new ChangeFunctionReturnTypeFix((JetFunction) function, typeToInsert)); actions.add(new ChangeFunctionReturnTypeFix((JetFunction) function, typeToInsert));
} }
@@ -158,7 +158,7 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact
: context.getType(valueArgument.getArgumentExpression()); : context.getType(valueArgument.getArgumentExpression());
if (correspondingParameter != null && valueArgumentType != null) { if (correspondingParameter != null && valueArgumentType != null) {
JetCallableDeclaration callable = PsiTreeUtil.getParentOfType(correspondingParameter, JetCallableDeclaration.class, true); JetCallableDeclaration callable = PsiTreeUtil.getParentOfType(correspondingParameter, JetCallableDeclaration.class, true);
JetScope scope = callable != null ? JetScopeUtils.getResolutionScope(callable, context) : null; JetScope scope = callable != null ? CorePackage.getResolutionScope(callable, context, ResolvePackage.getResolutionFacade(callable)) : null;
JetType typeToInsert = UtilPackage.approximateWithResolvableType(valueArgumentType, scope, true); JetType typeToInsert = UtilPackage.approximateWithResolvableType(valueArgumentType, scope, true);
actions.add(new ChangeParameterTypeFix(correspondingParameter, typeToInsert)); actions.add(new ChangeParameterTypeFix(correspondingParameter, typeToInsert));
} }
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.core.CorePackage;
import org.jetbrains.kotlin.idea.core.refactoring.JetNameValidator; import org.jetbrains.kotlin.idea.core.refactoring.JetNameValidator;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.JetElement; import org.jetbrains.kotlin.psi.JetElement;
@@ -28,7 +29,6 @@ import org.jetbrains.kotlin.psi.JetVisitorVoid;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.resolve.scopes.JetScope; import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -89,25 +89,23 @@ public class JetNameValidatorImpl extends JetNameValidator {
@Override @Override
public void visitExpression(@NotNull JetExpression expression) { public void visitExpression(@NotNull JetExpression expression) {
JetScope resolutionScope = JetScopeUtils.getResolutionScope(expression, context); JetScope resolutionScope = CorePackage.getResolutionScope(expression, context, ResolvePackage.getResolutionFacade(expression));
if (resolutionScope != null) { if (!visitedScopes.add(resolutionScope)) return;
if (!visitedScopes.add(resolutionScope)) return;
boolean noConflict; boolean noConflict;
if (myTarget == Target.PROPERTIES) { if (myTarget == Target.PROPERTIES) {
noConflict = resolutionScope.getProperties(identifier).isEmpty() noConflict = resolutionScope.getProperties(identifier).isEmpty()
&& resolutionScope.getLocalVariable(identifier) == null; && resolutionScope.getLocalVariable(identifier) == null;
} }
else { else {
noConflict = resolutionScope.getFunctions(identifier).isEmpty() noConflict = resolutionScope.getFunctions(identifier).isEmpty()
&& resolutionScope.getClassifier(identifier) == null; && resolutionScope.getClassifier(identifier) == null;
} }
if (!noConflict) { if (!noConflict) {
result.set(false); result.set(false);
return; return;
}
} }
super.visitExpression(expression); super.visitExpression(expression);
@@ -41,12 +41,15 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.comparePossiblyOverridingDescriptors import org.jetbrains.kotlin.idea.core.comparePossiblyOverridingDescriptors
import org.jetbrains.kotlin.idea.core.getResolutionScope
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
import org.jetbrains.kotlin.idea.core.refactoring.createTempCopy import org.jetbrains.kotlin.idea.core.refactoring.createTempCopy
import org.jetbrains.kotlin.idea.core.refactoring.getContextForContainingDeclarationBody import org.jetbrains.kotlin.idea.core.refactoring.getContextForContainingDeclarationBody
import org.jetbrains.kotlin.idea.imports.importableFqNameSafe import org.jetbrains.kotlin.idea.imports.importableFqNameSafe
import org.jetbrains.kotlin.idea.kdoc.getResolutionScope
import org.jetbrains.kotlin.idea.refactoring.JetNameValidatorImpl import org.jetbrains.kotlin.idea.refactoring.JetNameValidatorImpl
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage
@@ -825,7 +828,7 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
val modifiedVarDescriptorsWithExpressions = localInstructions.getModifiedVarDescriptors(bindingContext) val modifiedVarDescriptorsWithExpressions = localInstructions.getModifiedVarDescriptors(bindingContext)
val targetScope = JetScopeUtils.getResolutionScope(targetSibling, bindingContext) val targetScope = targetSibling.getResolutionScope(bindingContext, commonParent.getResolutionFacade())
val paramsInfo = inferParametersInfo(commonParent, pseudocode, bindingContext, targetScope, modifiedVarDescriptorsWithExpressions.keySet()) val paramsInfo = inferParametersInfo(commonParent, pseudocode, bindingContext, targetScope, modifiedVarDescriptorsWithExpressions.keySet())
if (paramsInfo.errorMessage != null) { if (paramsInfo.errorMessage != null) {
return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(paramsInfo.errorMessage!!)) return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(paramsInfo.errorMessage!!))
@@ -36,7 +36,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.core.getResolutionScope
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
import org.jetbrains.kotlin.idea.core.refactoring.runRefactoringWithPostprocessing import org.jetbrains.kotlin.idea.core.refactoring.runRefactoringWithPostprocessing
import org.jetbrains.kotlin.idea.refactoring.JetNameValidatorImpl import org.jetbrains.kotlin.idea.refactoring.JetNameValidatorImpl
@@ -225,7 +227,7 @@ public open class KotlinIntroduceParameterHandler(
is ClassDescriptor -> descriptor.getUnsubstitutedPrimaryConstructor() is ClassDescriptor -> descriptor.getUnsubstitutedPrimaryConstructor()
else -> null else -> null
} ?: throw AssertionError("Unexpected element type: ${targetParent.getElementTextWithContext()}") } ?: throw AssertionError("Unexpected element type: ${targetParent.getElementTextWithContext()}")
val replacementType = expressionType.approximateWithResolvableType(JetScopeUtils.getResolutionScope(targetParent, context), false) val replacementType = expressionType.approximateWithResolvableType(targetParent.getResolutionScope(context, targetParent.getResolutionFacade()), false)
val body = when (targetParent) { val body = when (targetParent) {
is JetFunction -> targetParent.getBodyExpression() is JetFunction -> targetParent.getBodyExpression()