KT-394 Make class object members visible inside the owning class

KT-588 Unresolved static method
This commit is contained in:
Andrey Breslav
2011-11-23 20:27:38 +03:00
parent ba700ebdbe
commit 9cb0cc9fa6
7 changed files with 78 additions and 24 deletions
@@ -5,7 +5,9 @@ import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
@@ -43,10 +45,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
private JetType superclassType;
private ClassReceiver implicitReceiver;
// public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
// this(trace, containingDeclaration, outerScope, ClassKind.CLASS);
// }
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) {
super(containingDeclaration);
TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace);
@@ -66,6 +64,23 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
}
assert classObjectDescriptor.getKind() == ClassKind.OBJECT;
this.classObjectDescriptor = classObjectDescriptor;
// Members of the class object are accessible from the class
// The scope must be lazy, because classObjectDescriptor may not by fully built yet
scopeForMemberResolution.importScope(new AbstractScopeAdapter() {
@NotNull
@Override
protected JetScope getWorkerScope() {
return MutableClassDescriptor.this.classObjectDescriptor.getDefaultType().getMemberScope();
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
return MutableClassDescriptor.this.classObjectDescriptor.getImplicitReceiver();
}
}
);
return ClassObjectStatus.OK;
}
@@ -98,8 +98,16 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
}
doComputeTasks(scope, explicitReceiver, call, name, result, AutoCastService.NO_AUTO_CASTS);
ReceiverDescriptor receiverToCast = explicitReceiver.exists() ? explicitReceiver : scope.getImplicitReceiver();
if (receiverToCast.exists()) {
List<ReceiverDescriptor> receivers;
if (explicitReceiver.exists()) {
receivers = Collections.singletonList(explicitReceiver);
}
else {
receivers = Lists.newArrayList();
scope.getImplicitReceiversHierarchy(receivers);
}
for (ReceiverDescriptor receiverToCast : receivers) {
assert receiverToCast.exists();
doComputeTasks(scope, receiverToCast, call, name, result, new AutoCastServiceImpl(dataFlowInfo, bindingContext));
}
return result;
@@ -232,15 +232,6 @@ public class WritableScopeImpl extends WritableScopeWithImports {
return super.getClassifier(name);
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
if (implicitReceiver == null) {
return super.getImplicitReceiver();
}
return implicitReceiver;
}
@Override
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors();
@@ -272,6 +263,15 @@ public class WritableScopeImpl extends WritableScopeWithImports {
return super.getNamespace(name);
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
if (implicitReceiver == null) {
return super.getImplicitReceiver();
}
return implicitReceiver;
}
@Override
public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) {
if (this.implicitReceiver != null) {
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.ArrayList;
import java.util.Collections;
@@ -50,6 +51,20 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
currentIndividualImportScope = null;
}
@Override
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
super.getImplicitReceiversHierarchy(result);
// Imported scopes come with their receivers
// Example: class member resolution scope imports a scope of it's class object
// members of the class object must be able to find it as an implicit receiver
for (JetScope scope : getImports()) {
ReceiverDescriptor definedReceiver = scope.getImplicitReceiver();
if (definedReceiver.exists()) {
result.add(0, definedReceiver);
}
}
}
@Override
public VariableDescriptor getVariable(@NotNull String name) {
// Meaningful lookup goes here
@@ -111,13 +111,6 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
private FunctionDescriptorImpl createFunctionDescriptor(JetFunctionLiteralExpression expression, ExpressionTypingContext context, boolean functionTypeExpected) {
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef();
final JetType receiverType;
if (receiverTypeRef != null) {
receiverType = context.getTypeResolver().resolveType(context.scope, receiverTypeRef);
} else {
ReceiverDescriptor implicitReceiver = context.scope.getImplicitReceiver();
receiverType = implicitReceiver.exists() ? implicitReceiver.getType() : null;
}
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
context.scope.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), "<anonymous>");
@@ -133,7 +126,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
}
}
else {
effectiveReceiverType = receiverType;
effectiveReceiverType = context.getTypeResolver().resolveType(context.scope, receiverTypeRef);
}
functionDescriptor.initialize(effectiveReceiverType, NO_RECEIVER, Collections.<TypeParameterDescriptor>emptyList(), valueParameterDescriptors, null, Modality.FINAL, Visibility.LOCAL);
context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor);
@@ -0,0 +1,11 @@
// KT-394 Make class object members visible inside the owning class
class X() {
// class Y {}
class object{
class Y() {}
}
val y : Y = Y()
}
@@ -0,0 +1,12 @@
// KT-588 Unresolved static method
class Test() : Thread("Test") {
class object {
fun init2() {
}
}
override fun run() {
init2() // unresolved
Test.init2() // ok
}
}