KT-5854 Incorrect 'Nested class should be qualified'
#KT-5854 Fixed
This commit is contained in:
+24
-3
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.types.ErrorUtils
|
|||||||
import org.jetbrains.jet.lang.types.JetType
|
import org.jetbrains.jet.lang.types.JetType
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.resolve.LibrarySourceHacks.filterOutMembersFromLibrarySource
|
import org.jetbrains.jet.lang.resolve.LibrarySourceHacks.filterOutMembersFromLibrarySource
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils.isStaticNestedClass
|
||||||
|
|
||||||
public trait CallableDescriptorCollector<D : CallableDescriptor> {
|
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 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>
|
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> {
|
override fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
|
||||||
val receiverScope = receiver.getMemberScope()
|
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> {
|
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
|
||||||
return scope.getFunctions(name).filter { it.getExtensionReceiverParameter() != null }
|
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)
|
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
|
// Constructors of singletons shouldn't be callable from the code
|
||||||
|| classifier.getKind().isSingleton()) {
|
|| classifier.getKind().isSingleton()) {
|
||||||
return listOf()
|
return listOf()
|
||||||
@@ -106,6 +115,10 @@ private object VariableCollector : CallableDescriptorCollector<VariableDescripto
|
|||||||
return (memberScope.getProperties(name) + getFakeDescriptorForObject(memberScope, name)).filterNotNull()
|
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> {
|
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
|
// 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()
|
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))
|
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> {
|
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
|
||||||
return filterProperties(VARIABLES_COLLECTOR.getExtensionsByName(scope, name, bindingTrace))
|
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))
|
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> {
|
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<D> {
|
||||||
return filterOutMembersFromLibrarySource(delegate.getExtensionsByName(scope, name, bindingTrace))
|
return filterOutMembersFromLibrarySource(delegate.getExtensionsByName(scope, name, bindingTrace))
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-14
@@ -119,6 +119,7 @@ public class TaskPrioritizer {
|
|||||||
Collection<ReceiverValue> implicitReceivers = Sets.newLinkedHashSet(JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope));
|
Collection<ReceiverValue> implicitReceivers = Sets.newLinkedHashSet(JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope));
|
||||||
if (receiver.exists()) {
|
if (receiver.exists()) {
|
||||||
addCandidatesForExplicitReceiver(receiver, implicitReceivers, c, /*isExplicit=*/true);
|
addCandidatesForExplicitReceiver(receiver, implicitReceivers, c, /*isExplicit=*/true);
|
||||||
|
addMembers(receiver, c, /*static=*/true, /*isExplicit=*/true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addCandidatesForNoReceiver(implicitReceivers, c);
|
addCandidatesForNoReceiver(implicitReceivers, c);
|
||||||
@@ -130,20 +131,7 @@ public class TaskPrioritizer {
|
|||||||
@NotNull TaskPrioritizerContext<D, F> c,
|
@NotNull TaskPrioritizerContext<D, F> c,
|
||||||
boolean isExplicit
|
boolean isExplicit
|
||||||
) {
|
) {
|
||||||
|
addMembers(explicitReceiver, c, /*static=*/false, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
|
for (CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
|
||||||
//member extensions
|
//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) {
|
private static ExplicitReceiverKind createKind(ExplicitReceiverKind kind, boolean isExplicit) {
|
||||||
if (isExplicit) return kind;
|
if (isExplicit) return kind;
|
||||||
return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER;
|
return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER;
|
||||||
@@ -206,6 +216,11 @@ public class TaskPrioritizer {
|
|||||||
|
|
||||||
//nonlocals
|
//nonlocals
|
||||||
c.result.addCandidates(nonlocalsList);
|
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(
|
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);
|
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")
|
@TestMetadata("localClass.kt")
|
||||||
public void testLocalClass() throws Exception {
|
public void testLocalClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/localClass.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/localClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user