Do not report NO_CLASS_OBJECT when namespacesAllowed=true
Now with nested classes the expression "A.something" makes sense even when A
doesn't have a class object ("something" could be a nested class)
Also "A" expression now gets a NamespaceType with the scope of all static
nested classes of A
#KT-1174 In Progress
This commit is contained in:
+20
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.lang.types.expressions;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.intellij.lang.ASTNode;
|
||||
@@ -39,6 +40,7 @@ import org.jetbrains.jet.lang.resolve.constants.*;
|
||||
import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
||||
import org.jetbrains.jet.lang.resolve.name.LabelName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.FilteringScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
@@ -104,14 +106,30 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
// To report NO_CLASS_OBJECT when no namespace found
|
||||
if (classifier != null) {
|
||||
context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
|
||||
if (!context.namespacesAllowed) {
|
||||
context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
|
||||
}
|
||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||
return classifier.getDefaultType();
|
||||
JetScope scopeForStaticMembersResolution = classifier instanceof ClassDescriptor
|
||||
? getStaticNestedClassesScope((ClassDescriptor) classifier)
|
||||
: JetScope.EMPTY;
|
||||
return new NamespaceType(referencedName, scopeForStaticMembersResolution);
|
||||
}
|
||||
temporaryTrace.commit();
|
||||
return result[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) {
|
||||
JetScope innerClassesScope = descriptor.getUnsubstitutedInnerClassesScope();
|
||||
return new FilteringScope(innerClassesScope, new Predicate<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
|
||||
return descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).isInner();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected boolean furtherNameLookup(@NotNull JetSimpleNameExpression expression, @NotNull Name referencedName, @NotNull JetType[] result, ExpressionTypingContext context) {
|
||||
if (context.namespacesAllowed) {
|
||||
result[0] = lookupNamespaceType(expression, referencedName, context);
|
||||
|
||||
@@ -21,7 +21,7 @@ object b {
|
||||
}
|
||||
|
||||
val a = A.x
|
||||
val c = <!NO_CLASS_OBJECT!>B<!>.x
|
||||
val c = B.<!UNRESOLVED_REFERENCE!>x<!>
|
||||
val d = b.<!UNRESOLVED_REFERENCE!>x<!>
|
||||
|
||||
val s = <!NO_CLASS_OBJECT!>System<!> // error
|
||||
|
||||
@@ -11,5 +11,4 @@ package Jet86
|
||||
}
|
||||
|
||||
val a = `A`A.`A.x`x
|
||||
val c = `B`B.`B.x`x
|
||||
val d = B().`B.x`x
|
||||
@@ -20,7 +20,7 @@ object b {
|
||||
}
|
||||
|
||||
val a = A.x
|
||||
val c = <error>B</error>.x
|
||||
val c = B.<error>x</error>
|
||||
val d = b.<error>x</error>
|
||||
|
||||
val s = <error>System</error> // error
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
fun <T> foo() {
|
||||
fun <T> foo() where class object T : Any {
|
||||
T.<caret>toString()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user