JET-86: Report errors for class objects

This commit is contained in:
Andrey Breslav
2011-06-04 15:08:14 +04:00
parent e2d6df7047
commit a1ce9eefb5
5 changed files with 61 additions and 34 deletions
@@ -40,8 +40,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE;
this.classObjectDescriptor = classObjectDescriptor; this.classObjectDescriptor = classObjectDescriptor;
return ClassObjectStatus.OK;
} }
@Nullable @Nullable
@@ -53,7 +53,7 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp
} }
@Override @Override
public void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
throw new IllegalStateException("Must be guaranteed not to happen by the parser"); throw new IllegalStateException("Must be guaranteed not to happen by the parser");
} }
} }
@@ -68,5 +68,11 @@ public interface NamespaceLike extends DeclarationDescriptor {
void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor); void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor);
void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor); enum ClassObjectStatus {
OK,
DUPLICATE,
NOT_ALLOWED
}
ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor);
} }
@@ -107,7 +107,7 @@ public class AnalyzingUtils {
} }
@Override @Override
public void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
throw new IllegalStateException("Must be guaranteed not to happen by the parser"); throw new IllegalStateException("Must be guaranteed not to happen by the parser");
} }
}, Collections.<JetDeclaration>singletonList(namespace)); }, Collections.<JetDeclaration>singletonList(namespace));
@@ -88,36 +88,36 @@ public class TopDownAnalyzer {
public void processObject(@NotNull JetScope outerScope, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) { public void processObject(@NotNull JetScope outerScope, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) {
process(outerScope, new NamespaceLike.Adapter(containingDeclaration) { process(outerScope, new NamespaceLike.Adapter(containingDeclaration) {
@Override @Override
public NamespaceDescriptorImpl getNamespace(String name) { public NamespaceDescriptorImpl getNamespace(String name) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
} }
@Override @Override
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
} }
@Override @Override
public void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
return ClassObjectStatus.NOT_ALLOWED;
} }
}, Collections.<JetDeclaration>singletonList(object)); }, Collections.<JetDeclaration>singletonList(object));
} }
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) { public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
@@ -168,7 +168,12 @@ public class TopDownAnalyzer {
@Override @Override
public void visitClass(JetClass klass) { public void visitClass(JetClass klass) {
visitClassOrObject(klass, (Map) classes, owner, outerScope); visitClassOrObject(
klass,
(Map) classes,
owner,
outerScope,
new MutableClassDescriptor(trace, owner, outerScope));
} }
@Override @Override
@@ -177,7 +182,13 @@ public class TopDownAnalyzer {
} }
private MutableClassDescriptor createClassDescriptorForObject(@NotNull JetObjectDeclaration declaration) { private MutableClassDescriptor createClassDescriptorForObject(@NotNull JetObjectDeclaration declaration) {
MutableClassDescriptor mutableClassDescriptor = visitClassOrObject(declaration, (Map) objects, owner, outerScope); MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope) {
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
return ClassObjectStatus.NOT_ALLOWED;
}
};
visitClassOrObject(declaration, (Map) objects, owner, outerScope, mutableClassDescriptor);
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<Annotation>emptyList(), true); ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<Annotation>emptyList(), true);
constructorDescriptor.initialize(Collections.<ValueParameterDescriptor>emptyList()); constructorDescriptor.initialize(Collections.<ValueParameterDescriptor>emptyList());
// TODO : make the constructor private? // TODO : make the constructor private?
@@ -186,8 +197,7 @@ public class TopDownAnalyzer {
return mutableClassDescriptor; return mutableClassDescriptor;
} }
private MutableClassDescriptor visitClassOrObject(@NotNull JetClassOrObject declaration, Map<JetClassOrObject, MutableClassDescriptor> map, NamespaceLike owner, JetScope outerScope) { private void visitClassOrObject(@NotNull JetClassOrObject declaration, Map<JetClassOrObject, MutableClassDescriptor> map, NamespaceLike owner, JetScope outerScope, MutableClassDescriptor mutableClassDescriptor) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope);
mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName())); mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName()));
if (declaration instanceof JetClass) { if (declaration instanceof JetClass) {
@@ -199,8 +209,6 @@ public class TopDownAnalyzer {
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution(); JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations()); collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations());
return mutableClassDescriptor;
} }
@Override @Override
@@ -215,7 +223,18 @@ public class TopDownAnalyzer {
@Override @Override
public void visitClassObject(JetClassObject classObject) { public void visitClassObject(JetClassObject classObject) {
owner.setClassObjectDescriptor(createClassDescriptorForObject(classObject.getObjectDeclaration())); JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
if (objectDeclaration != null) {
NamespaceLike.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration));
switch (status) {
case DUPLICATE:
trace.getErrorHandler().genericError(classObject.getNode(), "Only one class object is allowed per class");
break;
case NOT_ALLOWED:
trace.getErrorHandler().genericError(classObject.getNode(), "A class object is not allowed here");
break;
}
}
} }
}); });
} }