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:
Alexander Udalov
2013-01-14 19:46:38 +04:00
parent 85bd41dfa5
commit c4b5577555
5 changed files with 23 additions and 6 deletions
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -1,3 +1,3 @@
fun <T> foo() {
fun <T> foo() where class object T : Any {
T.<caret>toString()
}