From a1ce9eefb50bb171ca93f3146f81ac94320e9770 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sat, 4 Jun 2011 15:08:14 +0400 Subject: [PATCH] JET-86: Report errors for class objects --- .../descriptors/MutableClassDescriptor.java | 4 +- .../descriptors/NamespaceDescriptorImpl.java | 2 +- .../jet/lang/descriptors/NamespaceLike.java | 8 +- .../jet/lang/resolve/AnalyzingUtils.java | 2 +- .../jet/lang/resolve/TopDownAnalyzer.java | 79 ++++++++++++------- 5 files changed, 61 insertions(+), 34 deletions(-) diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 6965692e0ac..0096fc610ae 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -40,8 +40,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @Override - public void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE; this.classObjectDescriptor = classObjectDescriptor; + return ClassObjectStatus.OK; } @Nullable diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java index 49c7950a8a7..b7673131390 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java @@ -53,7 +53,7 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp } @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"); } } diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java b/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java index 0ad5305aaa2..c09cf23ff15 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java @@ -68,5 +68,11 @@ public interface NamespaceLike extends DeclarationDescriptor { void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor); - void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor); + enum ClassObjectStatus { + OK, + DUPLICATE, + NOT_ALLOWED + } + + ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index ea7d8560e09..cee68e71770 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -107,7 +107,7 @@ public class AnalyzingUtils { } @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"); } }, Collections.singletonList(namespace)); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index ea7d345e246..43d8b2cce86 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -88,36 +88,36 @@ public class TopDownAnalyzer { public void processObject(@NotNull JetScope outerScope, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) { process(outerScope, new NamespaceLike.Adapter(containingDeclaration) { - @Override - public NamespaceDescriptorImpl getNamespace(String name) { - throw new UnsupportedOperationException(); - } + @Override + public NamespaceDescriptorImpl getNamespace(String name) { + throw new UnsupportedOperationException(); + } - @Override - public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { - throw new UnsupportedOperationException(); - } + @Override + public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + throw new UnsupportedOperationException(); + } - @Override - public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { + @Override + public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { - } + } - @Override - public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { - throw new UnsupportedOperationException(); - } + @Override + public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { + throw new UnsupportedOperationException(); + } - @Override - public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + @Override + public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { - } + } - @Override - public void setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { - - } - }, Collections.singletonList(object)); + @Override + public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + return ClassObjectStatus.NOT_ALLOWED; + } + }, Collections.singletonList(object)); } public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List declarations) { @@ -168,7 +168,12 @@ public class TopDownAnalyzer { @Override public void visitClass(JetClass klass) { - visitClassOrObject(klass, (Map) classes, owner, outerScope); + visitClassOrObject( + klass, + (Map) classes, + owner, + outerScope, + new MutableClassDescriptor(trace, owner, outerScope)); } @Override @@ -177,7 +182,13 @@ public class TopDownAnalyzer { } 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.emptyList(), true); constructorDescriptor.initialize(Collections.emptyList()); // TODO : make the constructor private? @@ -186,8 +197,7 @@ public class TopDownAnalyzer { return mutableClassDescriptor; } - private MutableClassDescriptor visitClassOrObject(@NotNull JetClassOrObject declaration, Map map, NamespaceLike owner, JetScope outerScope) { - MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope); + private void visitClassOrObject(@NotNull JetClassOrObject declaration, Map map, NamespaceLike owner, JetScope outerScope, MutableClassDescriptor mutableClassDescriptor) { mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName())); if (declaration instanceof JetClass) { @@ -199,8 +209,6 @@ public class TopDownAnalyzer { JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution(); collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations()); - - return mutableClassDescriptor; } @Override @@ -215,7 +223,18 @@ public class TopDownAnalyzer { @Override 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; + } + } } }); }