KT-5854 Incorrect 'Nested class should be qualified'

#KT-5854 Fixed
This commit is contained in:
Svetlana Isakova
2014-10-03 17:02:16 +04:00
parent 29fa87ee7c
commit b20327770b
5 changed files with 86 additions and 17 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.types.ErrorUtils
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.LibrarySourceHacks.filterOutMembersFromLibrarySource
import org.jetbrains.jet.lang.resolve.DescriptorUtils.isStaticNestedClass
public trait CallableDescriptorCollector<D : CallableDescriptor> {
@@ -32,6 +33,8 @@ public trait CallableDescriptorCollector<D : CallableDescriptor> {
public fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<D>
public fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<D>
public fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<D>
}
@@ -63,16 +66,22 @@ private object FunctionCollector : CallableDescriptorCollector<FunctionDescripto
override fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
val receiverScope = receiver.getMemberScope()
return receiverScope.getFunctions(name) + getConstructors(receiverScope, name)
return receiverScope.getFunctions(name) + getConstructors(receiverScope, name, { !isStaticNestedClass(it) })
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
return getConstructors(receiver.getMemberScope(), name, { isStaticNestedClass(it) })
}
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
return scope.getFunctions(name).filter { it.getExtensionReceiverParameter() != null }
}
private fun getConstructors(scope: JetScope, name: Name): Collection<FunctionDescriptor> {
private fun getConstructors(
scope: JetScope, name: Name, filterClassPredicate: (ClassDescriptor) -> Boolean = { true }
): Collection<FunctionDescriptor> {
val classifier = scope.getClassifier(name)
if (classifier !is ClassDescriptor || ErrorUtils.isError(classifier)
if (classifier !is ClassDescriptor || ErrorUtils.isError(classifier) || !filterClassPredicate(classifier)
// Constructors of singletons shouldn't be callable from the code
|| classifier.getKind().isSingleton()) {
return listOf()
@@ -106,6 +115,10 @@ private object VariableCollector : CallableDescriptorCollector<VariableDescripto
return (memberScope.getProperties(name) + getFakeDescriptorForObject(memberScope, name)).filterNotNull()
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return listOf()
}
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
// property may have an extension function type, we check the applicability later to avoid an early computing of deferred types
return (listOf(scope.getLocalVariable(name)) + scope.getProperties(name)).filterNotNull()
@@ -126,6 +139,10 @@ private object PropertyCollector : CallableDescriptorCollector<VariableDescripto
return filterProperties(VARIABLES_COLLECTOR.getMembersByName(receiver, name, bindingTrace))
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getStaticMembersByName(receiver, name, bindingTrace))
}
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getExtensionsByName(scope, name, bindingTrace))
}
@@ -143,6 +160,10 @@ private class FilteredCollector<D : CallableDescriptor>(private val delegate: Ca
return filterOutMembersFromLibrarySource(delegate.getMembersByName(receiver, name, bindingTrace))
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<D> {
return filterOutMembersFromLibrarySource(delegate.getStaticMembersByName(receiver, name, bindingTrace))
}
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<D> {
return filterOutMembersFromLibrarySource(delegate.getExtensionsByName(scope, name, bindingTrace))
}
@@ -119,6 +119,7 @@ public class TaskPrioritizer {
Collection<ReceiverValue> implicitReceivers = Sets.newLinkedHashSet(JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope));
if (receiver.exists()) {
addCandidatesForExplicitReceiver(receiver, implicitReceivers, c, /*isExplicit=*/true);
addMembers(receiver, c, /*static=*/true, /*isExplicit=*/true);
return;
}
addCandidatesForNoReceiver(implicitReceivers, c);
@@ -130,20 +131,7 @@ public class TaskPrioritizer {
@NotNull TaskPrioritizerContext<D, F> c,
boolean isExplicit
) {
List<JetType> variantsForExplicitReceiver = SmartCastUtils.getSmartCastVariants(explicitReceiver, c.context);
//members
for (CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
for (JetType type : variantsForExplicitReceiver) {
Collection<D> membersForThisVariant =
callableDescriptorCollector.getMembersByName(type, c.name, c.context.trace);
convertWithReceivers(membersForThisVariant, explicitReceiver,
NO_RECEIVER, members, createKind(DISPATCH_RECEIVER, isExplicit), c.context.call);
}
c.result.addCandidates(members);
}
addMembers(explicitReceiver, c, /*static=*/false, isExplicit);
for (CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
//member extensions
@@ -159,6 +147,28 @@ public class TaskPrioritizer {
}
}
private static <D extends CallableDescriptor, F extends D> void addMembers(
ReceiverValue explicitReceiver,
TaskPrioritizerContext<D, F> c,
boolean staticMembers,
boolean isExplicit
) {
List<JetType> variantsForExplicitReceiver = SmartCastUtils.getSmartCastVariants(explicitReceiver, c.context);
for (CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
for (JetType type : variantsForExplicitReceiver) {
Collection<D> membersForThisVariant =
staticMembers
? callableDescriptorCollector.getStaticMembersByName(type, c.name, c.context.trace)
: callableDescriptorCollector.getMembersByName(type, c.name, c.context.trace);
convertWithReceivers(membersForThisVariant, explicitReceiver,
NO_RECEIVER, members, createKind(DISPATCH_RECEIVER, isExplicit), c.context.call);
}
c.result.addCandidates(members);
}
}
private static ExplicitReceiverKind createKind(ExplicitReceiverKind kind, boolean isExplicit) {
if (isExplicit) return kind;
return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER;
@@ -206,6 +216,11 @@ public class TaskPrioritizer {
//nonlocals
c.result.addCandidates(nonlocalsList);
//static (only for better error reporting)
for (ReceiverValue implicitReceiver : implicitReceivers) {
addMembers(implicitReceiver, c, /*static=*/true, /*isExplicit=*/false);
}
}
private static <D extends CallableDescriptor, F extends D> void addCandidatesForInvoke(
@@ -0,0 +1,11 @@
//KT-5854 Incorrect 'Nested class should be qualified'
class A {
class Nested {
}
fun foo() {
Nested(<!TOO_MANY_ARGUMENTS!>1<!>) //two errors here, the first one is wrong
}
}
@@ -0,0 +1,16 @@
package
internal final class A {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final class Nested {
public constructor Nested()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -5979,6 +5979,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("kt5854.kt")
public void testKt5854() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/kt5854.kt");
doTest(fileName);
}
@TestMetadata("localClass.kt")
public void testLocalClass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/localClass.kt");