Transform OverloadUtil into OverloadChecker component.

This commit is contained in:
Stanislav Erokhin
2016-04-28 14:25:53 +03:00
parent c4778bfe5a
commit 921eb8402c
17 changed files with 88 additions and 59 deletions
@@ -69,6 +69,7 @@ public class BodyResolver {
@NotNull private final ValueParameterResolver valueParameterResolver; @NotNull private final ValueParameterResolver valueParameterResolver;
@NotNull private final BodyResolveCache bodyResolveCache; @NotNull private final BodyResolveCache bodyResolveCache;
@NotNull private final KotlinBuiltIns builtIns; @NotNull private final KotlinBuiltIns builtIns;
@NotNull private final OverloadChecker overloadChecker;
public BodyResolver( public BodyResolver(
@NotNull AnnotationResolver annotationResolver, @NotNull AnnotationResolver annotationResolver,
@@ -82,7 +83,8 @@ public class BodyResolver {
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull ValueParameterResolver valueParameterResolver, @NotNull ValueParameterResolver valueParameterResolver,
@NotNull AnnotationChecker annotationChecker, @NotNull AnnotationChecker annotationChecker,
@NotNull KotlinBuiltIns builtIns @NotNull KotlinBuiltIns builtIns,
@NotNull OverloadChecker overloadChecker
) { ) {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver;
this.bodyResolveCache = bodyResolveCache; this.bodyResolveCache = bodyResolveCache;
@@ -93,6 +95,7 @@ public class BodyResolver {
this.expressionTypingServices = expressionTypingServices; this.expressionTypingServices = expressionTypingServices;
this.functionAnalyzerExtension = functionAnalyzerExtension; this.functionAnalyzerExtension = functionAnalyzerExtension;
this.annotationChecker = annotationChecker; this.annotationChecker = annotationChecker;
this.overloadChecker = overloadChecker;
this.trace = new ObservableBindingTrace(trace); this.trace = new ObservableBindingTrace(trace);
this.valueParameterResolver = valueParameterResolver; this.valueParameterResolver = valueParameterResolver;
this.builtIns = builtIns; this.builtIns = builtIns;
@@ -259,7 +262,7 @@ public class BodyResolver {
final LexicalScope scopeForConstructor = final LexicalScope scopeForConstructor =
primaryConstructor == null primaryConstructor == null
? null ? null
: FunctionDescriptorUtil.getFunctionInnerScope(scopeForConstructorResolution, primaryConstructor, trace); : FunctionDescriptorUtil.getFunctionInnerScope(scopeForConstructorResolution, primaryConstructor, trace, overloadChecker);
final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow
final Map<KtTypeReference, KotlinType> supertypes = Maps.newLinkedHashMap(); final Map<KtTypeReference, KotlinType> supertypes = Maps.newLinkedHashMap();
@@ -778,7 +781,7 @@ public class BodyResolver {
@Nullable Function1<LexicalScope, LexicalScope> headerScopeFactory @Nullable Function1<LexicalScope, LexicalScope> headerScopeFactory
) { ) {
PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace); PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace);
LexicalScope innerScope = FunctionDescriptorUtil.getFunctionInnerScope(scope, functionDescriptor, trace); LexicalScope innerScope = FunctionDescriptorUtil.getFunctionInnerScope(scope, functionDescriptor, trace, overloadChecker);
List<KtParameter> valueParameters = function.getValueParameters(); List<KtParameter> valueParameters = function.getValueParameters();
List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters(); List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters();
@@ -76,6 +76,7 @@ public class DescriptorResolver {
@NotNull private final SupertypeLoopChecker supertypeLoopsResolver; @NotNull private final SupertypeLoopChecker supertypeLoopsResolver;
@NotNull private final VariableTypeResolver variableTypeResolver; @NotNull private final VariableTypeResolver variableTypeResolver;
@NotNull private final ExpressionTypingServices expressionTypingServices; @NotNull private final ExpressionTypingServices expressionTypingServices;
@NotNull private final OverloadChecker overloadChecker;
public DescriptorResolver( public DescriptorResolver(
@NotNull AnnotationResolver annotationResolver, @NotNull AnnotationResolver annotationResolver,
@@ -84,7 +85,8 @@ public class DescriptorResolver {
@NotNull TypeResolver typeResolver, @NotNull TypeResolver typeResolver,
@NotNull SupertypeLoopChecker supertypeLoopsResolver, @NotNull SupertypeLoopChecker supertypeLoopsResolver,
@NotNull VariableTypeResolver variableTypeResolver, @NotNull VariableTypeResolver variableTypeResolver,
@NotNull ExpressionTypingServices expressionTypingServices @NotNull ExpressionTypingServices expressionTypingServices,
@NotNull OverloadChecker overloadChecker
) { ) {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver;
this.builtIns = builtIns; this.builtIns = builtIns;
@@ -93,6 +95,7 @@ public class DescriptorResolver {
this.supertypeLoopsResolver = supertypeLoopsResolver; this.supertypeLoopsResolver = supertypeLoopsResolver;
this.variableTypeResolver = variableTypeResolver; this.variableTypeResolver = variableTypeResolver;
this.expressionTypingServices = expressionTypingServices; this.expressionTypingServices = expressionTypingServices;
this.overloadChecker = overloadChecker;
} }
public List<KotlinType> resolveSupertypes( public List<KotlinType> resolveSupertypes(
@@ -722,7 +725,7 @@ public class DescriptorResolver {
} }
else { else {
LexicalWritableScope writableScope = new LexicalWritableScope( LexicalWritableScope writableScope = new LexicalWritableScope(
scope, containingDeclaration, false, null, new TraceBasedLocalRedeclarationChecker(trace), scope, containingDeclaration, false, null, new TraceBasedLocalRedeclarationChecker(trace, overloadChecker),
LexicalScopeKind.PROPERTY_HEADER); LexicalScopeKind.PROPERTY_HEADER);
typeParameterDescriptors = resolveTypeParametersForCallableDescriptor( typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(
propertyDescriptor, writableScope, scope, typeParameters, trace); propertyDescriptor, writableScope, scope, typeParameters, trace);
@@ -61,7 +61,8 @@ class FunctionDescriptorResolver(
private val storageManager: StorageManager, private val storageManager: StorageManager,
private val expressionTypingServices: ExpressionTypingServices, private val expressionTypingServices: ExpressionTypingServices,
private val builtIns: KotlinBuiltIns, private val builtIns: KotlinBuiltIns,
private val modifiersChecker: ModifiersChecker private val modifiersChecker: ModifiersChecker,
private val overloadChecker: OverloadChecker
) { ) {
fun resolveFunctionDescriptor( fun resolveFunctionDescriptor(
containingDescriptor: DeclarationDescriptor, containingDescriptor: DeclarationDescriptor,
@@ -142,7 +143,7 @@ class FunctionDescriptorResolver(
expectedFunctionType: KotlinType expectedFunctionType: KotlinType
) { ) {
val innerScope = LexicalWritableScope(scope, functionDescriptor, true, null, val innerScope = LexicalWritableScope(scope, functionDescriptor, true, null,
TraceBasedLocalRedeclarationChecker(trace), LexicalScopeKind.FUNCTION_HEADER) TraceBasedLocalRedeclarationChecker(trace, overloadChecker), LexicalScopeKind.FUNCTION_HEADER)
val typeParameterDescriptors = descriptorResolver. val typeParameterDescriptors = descriptorResolver.
resolveTypeParametersForCallableDescriptor(functionDescriptor, innerScope, scope, function.typeParameters, trace) resolveTypeParametersForCallableDescriptor(functionDescriptor, innerScope, scope, function.typeParameters, trace)
@@ -285,7 +286,7 @@ class FunctionDescriptorResolver(
scope, scope,
constructorDescriptor, constructorDescriptor,
false, null, false, null,
TraceBasedLocalRedeclarationChecker(trace), TraceBasedLocalRedeclarationChecker(trace, overloadChecker),
LexicalScopeKind.CONSTRUCTOR_HEADER LexicalScopeKind.CONSTRUCTOR_HEADER
) )
val constructor = constructorDescriptor.initialize( val constructor = constructorDescriptor.initialize(
@@ -53,9 +53,10 @@ public class FunctionDescriptorUtil {
@NotNull @NotNull
public static LexicalScope getFunctionInnerScope( public static LexicalScope getFunctionInnerScope(
@NotNull LexicalScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace @NotNull LexicalScope outerScope, @NotNull FunctionDescriptor descriptor,
@NotNull BindingTrace trace, @NotNull OverloadChecker overloadChecker
) { ) {
return getFunctionInnerScope(outerScope, descriptor, new TraceBasedLocalRedeclarationChecker(trace)); return getFunctionInnerScope(outerScope, descriptor, new TraceBasedLocalRedeclarationChecker(trace, overloadChecker));
} }
@NotNull @NotNull
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -31,11 +31,11 @@ import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.singletonOrEmptyList import org.jetbrains.kotlin.utils.singletonOrEmptyList
object OverloadUtil { class OverloadChecker {
/** /**
* Does not check names. * Does not check names.
*/ */
@JvmStatic fun isOverloadable(a: DeclarationDescriptor, b: DeclarationDescriptor): Boolean { fun isOverloadable(a: DeclarationDescriptor, b: DeclarationDescriptor): Boolean {
val aCategory = getDeclarationCategory(a) val aCategory = getDeclarationCategory(a)
val bCategory = getDeclarationCategory(b) val bCategory = getDeclarationCategory(b)
@@ -96,7 +96,7 @@ object OverloadUtil {
error("Unexpected declaration kind: $a") error("Unexpected declaration kind: $a")
} }
@JvmStatic fun groupModulePackageMembersByFqName( fun groupModulePackageMembersByFqName(
c: BodiesResolveContext, c: BodiesResolveContext,
overloadFilter: OverloadFilter overloadFilter: OverloadFilter
): MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot> { ): MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot> {
@@ -172,7 +172,7 @@ object OverloadUtil {
this is DeclarationDescriptorWithVisibility && this is DeclarationDescriptorWithVisibility &&
Visibilities.isPrivate(this.visibility) Visibilities.isPrivate(this.visibility)
@JvmStatic fun getPossibleRedeclarationGroups( fun getPossibleRedeclarationGroups(
members: Collection<DeclarationDescriptorNonRoot> members: Collection<DeclarationDescriptorNonRoot>
): Collection<Collection<DeclarationDescriptorNonRoot>> { ): Collection<Collection<DeclarationDescriptorNonRoot>> {
val result = arrayListOf<Collection<DeclarationDescriptorNonRoot>>() val result = arrayListOf<Collection<DeclarationDescriptorNonRoot>>()
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -26,7 +26,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.check
class OverloadResolver( class OverloadResolver(
private val trace: BindingTrace, private val trace: BindingTrace,
private val overloadFilter: OverloadFilter) { private val overloadFilter: OverloadFilter,
private val overloadChecker: OverloadChecker
) {
fun checkOverloads(c: BodiesResolveContext) { fun checkOverloads(c: BodiesResolveContext) {
val inClasses = findConstructorsInNestedClasses(c) val inClasses = findConstructorsInNestedClasses(c)
@@ -63,7 +65,7 @@ class OverloadResolver(
} }
private fun checkOverloadsInPackages(c: BodiesResolveContext) { private fun checkOverloadsInPackages(c: BodiesResolveContext) {
val membersByName = OverloadUtil.groupModulePackageMembersByFqName(c, overloadFilter) val membersByName = overloadChecker.groupModulePackageMembersByFqName(c, overloadFilter)
for (e in membersByName.entrySet()) { for (e in membersByName.entrySet()) {
checkOverloadsInPackage(e.value) checkOverloadsInPackage(e.value)
@@ -91,7 +93,7 @@ class OverloadResolver(
private fun checkOverloadsInPackage(members: Collection<DeclarationDescriptorNonRoot>) { private fun checkOverloadsInPackage(members: Collection<DeclarationDescriptorNonRoot>) {
if (members.size == 1) return if (members.size == 1) return
for (redeclarationGroup in OverloadUtil.getPossibleRedeclarationGroups(members)) { for (redeclarationGroup in overloadChecker.getPossibleRedeclarationGroups(members)) {
reportRedeclarations(findRedeclarations(redeclarationGroup)) reportRedeclarations(findRedeclarations(redeclarationGroup))
} }
} }
@@ -114,7 +116,7 @@ class OverloadResolver(
if (isConstructorsOfDifferentRedeclaredClasses(member1, member2)) continue if (isConstructorsOfDifferentRedeclaredClasses(member1, member2)) continue
if (isTopLevelMainInDifferentFiles(member1, member2)) continue if (isTopLevelMainInDifferentFiles(member1, member2)) continue
if (!OverloadUtil.isOverloadable(member1, member2)) { if (!overloadChecker.isOverloadable(member1, member2)) {
val ktDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(member1) as KtDeclaration? val ktDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(member1) as KtDeclaration?
redeclarations.add(ktDeclaration to member1) redeclarations.add(ktDeclaration to member1)
} }
@@ -22,10 +22,10 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverloadUtil import org.jetbrains.kotlin.resolve.OverloadChecker
abstract class AbstractLocalRedeclarationChecker : LocalRedeclarationChecker { abstract class AbstractLocalRedeclarationChecker(val overloadChecker: OverloadChecker) : LocalRedeclarationChecker {
override fun checkBeforeAddingToScope(scope: LexicalScope, newDescriptor: DeclarationDescriptor) { override fun checkBeforeAddingToScope(scope: LexicalScope, newDescriptor: DeclarationDescriptor) {
val name = newDescriptor.name val name = newDescriptor.name
val location = NoLookupLocation.WHEN_CHECK_REDECLARATIONS val location = NoLookupLocation.WHEN_CHECK_REDECLARATIONS
@@ -47,7 +47,7 @@ abstract class AbstractLocalRedeclarationChecker : LocalRedeclarationChecker {
otherFunctions otherFunctions
for (overloadedDescriptor in potentiallyConflictingOverloads) { for (overloadedDescriptor in potentiallyConflictingOverloads) {
if (!OverloadUtil.isOverloadable(overloadedDescriptor, newDescriptor)) { if (!overloadChecker.isOverloadable(overloadedDescriptor, newDescriptor)) {
handleConflictingOverloads(newDescriptor, overloadedDescriptor) handleConflictingOverloads(newDescriptor, overloadedDescriptor)
break break
} }
@@ -61,7 +61,7 @@ abstract class AbstractLocalRedeclarationChecker : LocalRedeclarationChecker {
protected abstract fun handleConflictingOverloads(first: CallableMemberDescriptor, second: CallableMemberDescriptor) protected abstract fun handleConflictingOverloads(first: CallableMemberDescriptor, second: CallableMemberDescriptor)
} }
object ThrowingLocalRedeclarationChecker : AbstractLocalRedeclarationChecker() { class ThrowingLocalRedeclarationChecker(overloadChecker: OverloadChecker) : AbstractLocalRedeclarationChecker(overloadChecker) {
override fun handleRedeclaration(first: DeclarationDescriptor, second: DeclarationDescriptor) { override fun handleRedeclaration(first: DeclarationDescriptor, second: DeclarationDescriptor) {
throw IllegalStateException(String.format("Redeclaration: %s (%s) and %s (%s) (no line info available)", throw IllegalStateException(String.format("Redeclaration: %s (%s) and %s (%s) (no line info available)",
DescriptorUtils.getFqName(first), first, DescriptorUtils.getFqName(first), first,
@@ -75,7 +75,7 @@ object ThrowingLocalRedeclarationChecker : AbstractLocalRedeclarationChecker() {
} }
} }
class TraceBasedLocalRedeclarationChecker(val trace: BindingTrace): AbstractLocalRedeclarationChecker() { class TraceBasedLocalRedeclarationChecker(val trace: BindingTrace, overloadChecker: OverloadChecker): AbstractLocalRedeclarationChecker(overloadChecker) {
override fun handleRedeclaration(first: DeclarationDescriptor, second: DeclarationDescriptor) { override fun handleRedeclaration(first: DeclarationDescriptor, second: DeclarationDescriptor) {
reportRedeclaration(first) reportRedeclaration(first)
reportRedeclaration(second) reportRedeclaration(second)
@@ -1118,11 +1118,12 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
KotlinTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context.replaceExpectedType(booleanType), facade); KotlinTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context.replaceExpectedType(booleanType), facade);
DataFlowInfo dataFlowInfo = leftTypeInfo.getDataFlowInfo(); DataFlowInfo dataFlowInfo = leftTypeInfo.getDataFlowInfo();
LexicalWritableScope leftScope = newWritableScopeImpl(context, LexicalScopeKind.LEFT_BOOLEAN_EXPRESSION); LexicalWritableScope leftScope = newWritableScopeImpl(context, LexicalScopeKind.LEFT_BOOLEAN_EXPRESSION, facade.getComponents().overloadChecker);
// TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition
boolean isAnd = operationType == KtTokens.ANDAND; boolean isAnd = operationType == KtTokens.ANDAND;
DataFlowInfo flowInfoLeft = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(left, isAnd, context).and(dataFlowInfo); DataFlowInfo flowInfoLeft = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(left, isAnd, context).and(dataFlowInfo);
LexicalWritableScope rightScope = isAnd ? leftScope : newWritableScopeImpl(context, LexicalScopeKind.RIGHT_BOOLEAN_EXPRESSION); LexicalWritableScope rightScope = isAnd ? leftScope : newWritableScopeImpl(context, LexicalScopeKind.RIGHT_BOOLEAN_EXPRESSION,
facade.getComponents().overloadChecker);
ExpressionTypingContext contextForRightExpr = ExpressionTypingContext contextForRightExpr =
context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope).replaceExpectedType(booleanType); context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope).replaceExpectedType(booleanType);
@@ -41,7 +41,10 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope; import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.CommonSupertypes;
import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct; import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct;
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt; import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
@@ -97,8 +100,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
KtExpression elseBranch = ifExpression.getElse(); KtExpression elseBranch = ifExpression.getElse();
KtExpression thenBranch = ifExpression.getThen(); KtExpression thenBranch = ifExpression.getThen();
LexicalWritableScope thenScope = newWritableScopeImpl(context, LexicalScopeKind.THEN); LexicalWritableScope thenScope = newWritableScopeImpl(context, LexicalScopeKind.THEN, components.overloadChecker);
LexicalWritableScope elseScope = newWritableScopeImpl(context, LexicalScopeKind.ELSE); LexicalWritableScope elseScope = newWritableScopeImpl(context, LexicalScopeKind.ELSE, components.overloadChecker);
DataFlowInfo thenInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo); DataFlowInfo thenInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo);
DataFlowInfo elseInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo); DataFlowInfo elseInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo);
@@ -234,7 +237,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
KotlinTypeInfo bodyTypeInfo; KotlinTypeInfo bodyTypeInfo;
DataFlowInfo conditionInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo); DataFlowInfo conditionInfo = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo);
if (body != null) { if (body != null) {
LexicalWritableScope scopeToExtend = newWritableScopeImpl(context, LexicalScopeKind.WHILE_BODY); LexicalWritableScope scopeToExtend = newWritableScopeImpl(context, LexicalScopeKind.WHILE_BODY, components.overloadChecker);
bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
scopeToExtend, Collections.singletonList(body), scopeToExtend, Collections.singletonList(body),
CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo)); CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo));
@@ -330,7 +333,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
bodyTypeInfo = facade.getTypeInfo(body, context.replaceScope(context.scope)); bodyTypeInfo = facade.getTypeInfo(body, context.replaceScope(context.scope));
} }
else if (body != null) { else if (body != null) {
LexicalWritableScope writableScope = newWritableScopeImpl(context, LexicalScopeKind.DO_WHILE_BODY); LexicalWritableScope writableScope = newWritableScopeImpl(context, LexicalScopeKind.DO_WHILE_BODY, components.overloadChecker);
conditionScope = writableScope; conditionScope = writableScope;
List<KtExpression> block; List<KtExpression> block;
if (body instanceof KtBlockExpression) { if (body instanceof KtBlockExpression) {
@@ -398,7 +401,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
loopRangeInfo = TypeInfoFactoryKt.noTypeInfo(context); loopRangeInfo = TypeInfoFactoryKt.noTypeInfo(context);
} }
LexicalWritableScope loopScope = newWritableScopeImpl(context, LexicalScopeKind.FOR); LexicalWritableScope loopScope = newWritableScopeImpl(context, LexicalScopeKind.FOR, components.overloadChecker);
KtParameter loopParameter = expression.getLoopParameter(); KtParameter loopParameter = expression.getLoopParameter();
if (loopParameter != null) { if (loopParameter != null) {
@@ -497,7 +500,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
KotlinType throwableType = components.builtIns.getThrowable().getDefaultType(); KotlinType throwableType = components.builtIns.getThrowable().getDefaultType();
components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType)); components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType));
if (catchBody != null) { if (catchBody != null) {
LexicalWritableScope catchScope = newWritableScopeImpl(context, LexicalScopeKind.CATCH); LexicalWritableScope catchScope = newWritableScopeImpl(context, LexicalScopeKind.CATCH, components.overloadChecker);
catchScope.addVariableDescriptor(variableDescriptor); catchScope.addVariableDescriptor(variableDescriptor);
KotlinType type = facade.getTypeInfo(catchBody, context.replaceScope(catchScope)).getType(); KotlinType type = facade.getTypeInfo(catchBody, context.replaceScope(catchScope)).getType();
if (type != null) { if (type != null) {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -61,6 +61,7 @@ public class ExpressionTypingComponents {
/*package*/ LocalVariableResolver localVariableResolver; /*package*/ LocalVariableResolver localVariableResolver;
/*package*/ LookupTracker lookupTracker; /*package*/ LookupTracker lookupTracker;
/*package*/ DelegatedPropertyResolver delegatedPropertyResolver; /*package*/ DelegatedPropertyResolver delegatedPropertyResolver;
/*package*/ OverloadChecker overloadChecker;
@Inject @Inject
public void setGlobalContext(@NotNull GlobalContext globalContext) { public void setGlobalContext(@NotNull GlobalContext globalContext) {
@@ -206,4 +207,9 @@ public class ExpressionTypingComponents {
public void setDelegatedPropertyResolver(DelegatedPropertyResolver delegatedPropertyResolver) { public void setDelegatedPropertyResolver(DelegatedPropertyResolver delegatedPropertyResolver) {
this.delegatedPropertyResolver = delegatedPropertyResolver; this.delegatedPropertyResolver = delegatedPropertyResolver;
} }
@Inject
public void setOverloadChecker(OverloadChecker overloadChecker) {
this.overloadChecker = overloadChecker;
}
} }
@@ -163,8 +163,10 @@ public class ExpressionTypingServices {
List<KtExpression> block = StatementFilterKt.filterStatements(statementFilter, expression); List<KtExpression> block = StatementFilterKt.filterStatements(statementFilter, expression);
DeclarationDescriptor containingDescriptor = context.scope.getOwnerDescriptor(); DeclarationDescriptor containingDescriptor = context.scope.getOwnerDescriptor();
LexicalWritableScope scope = new LexicalWritableScope(context.scope, containingDescriptor, false, null, TraceBasedLocalRedeclarationChecker redeclarationChecker
new TraceBasedLocalRedeclarationChecker(context.trace), LexicalScopeKind.CODE_BLOCK); = new TraceBasedLocalRedeclarationChecker(context.trace, expressionTypingComponents.overloadChecker);
LexicalWritableScope scope = new LexicalWritableScope(context.scope, containingDescriptor, false, null, redeclarationChecker,
LexicalScopeKind.CODE_BLOCK);
KotlinTypeInfo r; KotlinTypeInfo r;
if (block.isEmpty()) { if (block.isEmpty()) {
@@ -194,7 +196,8 @@ public class ExpressionTypingServices {
) { ) {
KtExpression bodyExpression = function.getBodyExpression(); KtExpression bodyExpression = function.getBodyExpression();
assert bodyExpression != null; assert bodyExpression != null;
LexicalScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); LexicalScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace,
expressionTypingComponents.overloadChecker);
ExpressionTypingContext context = ExpressionTypingContext.newContext( ExpressionTypingContext context = ExpressionTypingContext.newContext(
trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.ObservableBindingTrace; import org.jetbrains.kotlin.resolve.ObservableBindingTrace;
import org.jetbrains.kotlin.resolve.OverloadChecker;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind; import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope; import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
@@ -80,9 +81,10 @@ public class ExpressionTypingUtils {
} }
@NotNull @NotNull
public static LexicalWritableScope newWritableScopeImpl(ExpressionTypingContext context, @NotNull LexicalScopeKind scopeKind) { public static LexicalWritableScope newWritableScopeImpl(
@NotNull ExpressionTypingContext context, @NotNull LexicalScopeKind scopeKind, @NotNull OverloadChecker overloadChecker) {
return new LexicalWritableScope(context.scope, context.scope.getOwnerDescriptor(), false, null, return new LexicalWritableScope(context.scope, context.scope.getOwnerDescriptor(), false, null,
new TraceBasedLocalRedeclarationChecker(context.trace), scopeKind); new TraceBasedLocalRedeclarationChecker(context.trace, overloadChecker), scopeKind);
} }
public static KtExpression createFakeExpressionOfType( public static KtExpression createFakeExpressionOfType(
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -158,7 +158,7 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
protected ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) { protected ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) {
return new ExpressionTypingVisitorForStatements(this, return new ExpressionTypingVisitorForStatements(this,
ExpressionTypingUtils.newWritableScopeImpl(context, LexicalScopeKind.CODE_BLOCK), ExpressionTypingUtils.newWritableScopeImpl(context, LexicalScopeKind.CODE_BLOCK, components.overloadChecker),
basic, controlStructures, patterns, functions); basic, controlStructures, patterns, functions);
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -100,7 +100,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
ForceResolveUtil.forceResolveAllContents(functionDescriptor.returnType) ForceResolveUtil.forceResolveAllContents(functionDescriptor.returnType)
} }
else { else {
val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace) val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace, components.overloadChecker)
components.expressionTypingServices.checkFunctionReturnType( components.expressionTypingServices.checkFunctionReturnType(
functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace
) )
@@ -208,7 +208,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
val functionLiteral = expression.functionLiteral val functionLiteral = expression.functionLiteral
val expectedType = expectedReturnType ?: NO_EXPECTED_TYPE val expectedType = expectedReturnType ?: NO_EXPECTED_TYPE
val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace) val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace, components.overloadChecker)
val newContext = context.replaceScope(functionInnerScope).replaceExpectedType(expectedType) val newContext = context.replaceScope(functionInnerScope).replaceExpectedType(expectedType)
// This is needed for ControlStructureTypingVisitor#visitReturnExpression() to properly type-check returned expressions // This is needed for ControlStructureTypingVisitor#visitReturnExpression() to properly type-check returned expressions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.psi.KtNamedFunction; import org.jetbrains.kotlin.psi.KtNamedFunction;
import org.jetbrains.kotlin.psi.KtPsiFactoryKt; import org.jetbrains.kotlin.psi.KtPsiFactoryKt;
import org.jetbrains.kotlin.resolve.FunctionDescriptorResolver; import org.jetbrains.kotlin.resolve.FunctionDescriptorResolver;
import org.jetbrains.kotlin.resolve.OverloadUtil; import org.jetbrains.kotlin.resolve.OverloadChecker;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.test.ConfigurationKind; import org.jetbrains.kotlin.test.ConfigurationKind;
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.tests.di.InjectionKt;
public class KotlinOverloadTest extends KotlinTestWithEnvironment { public class KotlinOverloadTest extends KotlinTestWithEnvironment {
private final ModuleDescriptor root = KotlinTestUtils.createEmptyModule("<test_root>"); private final ModuleDescriptor root = KotlinTestUtils.createEmptyModule("<test_root>");
private FunctionDescriptorResolver functionDescriptorResolver; private FunctionDescriptorResolver functionDescriptorResolver;
private final OverloadChecker overloadChecker = new OverloadChecker();
@Override @Override
protected KotlinCoreEnvironment createEnvironment() { protected KotlinCoreEnvironment createEnvironment() {
@@ -154,10 +155,12 @@ public class KotlinOverloadTest extends KotlinTestWithEnvironment {
FunctionDescriptor a = makeFunction(funA); FunctionDescriptor a = makeFunction(funA);
FunctionDescriptor b = makeFunction(funB); FunctionDescriptor b = makeFunction(funB);
boolean aOverloadableWithB = OverloadUtil.isOverloadable(a, b);
boolean aOverloadableWithB = overloadChecker.isOverloadable(a, b);
assertEquals(expectedIsError, !aOverloadableWithB); assertEquals(expectedIsError, !aOverloadableWithB);
boolean bOverloadableWithA = OverloadUtil.isOverloadable(b, a); boolean bOverloadableWithA = overloadChecker.isOverloadable(b, a);
assertEquals(expectedIsError, !bOverloadableWithA); assertEquals(expectedIsError, !bOverloadableWithA);
} }
@@ -39,10 +39,7 @@ import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.KtPsiFactoryKt; import org.jetbrains.kotlin.psi.KtPsiFactoryKt;
import org.jetbrains.kotlin.psi.KtTypeReference; import org.jetbrains.kotlin.psi.KtTypeReference;
import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.AnalyzingUtils; import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.BindingTraceContext;
import org.jetbrains.kotlin.resolve.lazy.LazyResolveTestUtil; import org.jetbrains.kotlin.resolve.lazy.LazyResolveTestUtil;
import org.jetbrains.kotlin.resolve.scopes.*; import org.jetbrains.kotlin.resolve.scopes.*;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt; import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
@@ -93,8 +90,9 @@ public class TypeSubstitutorTest extends KotlinTestWithEnvironment {
LexicalScope topLevelScope = trace.get(BindingContext.LEXICAL_SCOPE, jetFile); LexicalScope topLevelScope = trace.get(BindingContext.LEXICAL_SCOPE, jetFile);
final ClassifierDescriptor contextClass = ScopeUtilsKt.findClassifier(topLevelScope, Name.identifier("___Context"), NoLookupLocation.FROM_TEST); final ClassifierDescriptor contextClass = ScopeUtilsKt.findClassifier(topLevelScope, Name.identifier("___Context"), NoLookupLocation.FROM_TEST);
assert contextClass instanceof ClassDescriptor; assert contextClass instanceof ClassDescriptor;
LocalRedeclarationChecker redeclarationChecker = new ThrowingLocalRedeclarationChecker(new OverloadChecker());
LexicalScope typeParameters = new LexicalScopeImpl(topLevelScope, module, false, null, LexicalScopeKind.SYNTHETIC, LexicalScope typeParameters = new LexicalScopeImpl(topLevelScope, module, false, null, LexicalScopeKind.SYNTHETIC,
ThrowingLocalRedeclarationChecker.INSTANCE, redeclarationChecker,
new Function1<LexicalScopeImpl.InitializeHandler, Unit>() { new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
@Override @Override
public Unit invoke(LexicalScopeImpl.InitializeHandler handler) { public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,17 +23,19 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
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.resolve.frontendService
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverloadUtil import org.jetbrains.kotlin.resolve.OverloadChecker
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
import java.util.ArrayList import java.util.*
class KotlinMemberInfoStorage( class KotlinMemberInfoStorage(
classOrObject: PsiNamedElement, classOrObject: KtClassOrObject,
filter: (KtNamedDeclaration) -> Boolean = { true } filter: (KtNamedDeclaration) -> Boolean = { true }
): AbstractMemberInfoStorage<KtNamedDeclaration, PsiNamedElement, KotlinMemberInfo>(classOrObject, filter) { ): AbstractMemberInfoStorage<KtNamedDeclaration, PsiNamedElement, KotlinMemberInfo>(classOrObject, filter) {
override fun memberConflict(member1: KtNamedDeclaration, member: KtNamedDeclaration): Boolean { override fun memberConflict(member1: KtNamedDeclaration, member: KtNamedDeclaration): Boolean {
@@ -43,7 +45,8 @@ class KotlinMemberInfoStorage(
return when { return when {
descriptor1 is FunctionDescriptor && descriptor is FunctionDescriptor -> { descriptor1 is FunctionDescriptor && descriptor is FunctionDescriptor -> {
!OverloadUtil.isOverloadable(descriptor1, descriptor) val overloadUtil = member1.getResolutionFacade().frontendService<OverloadChecker>()
!overloadUtil.isOverloadable(descriptor1, descriptor)
} }
descriptor1 is PropertyDescriptor && descriptor is PropertyDescriptor || descriptor1 is PropertyDescriptor && descriptor is PropertyDescriptor ||
descriptor1 is ClassDescriptor && descriptor is ClassDescriptor -> true descriptor1 is ClassDescriptor && descriptor is ClassDescriptor -> true