Prohibit local objects and enum classes

#KT-5402 Fixed
  #KT-4838 Fixed

Resolve type of object inside local object as special, not supertype('Any').
Changed visibility of constructor of anonymous object to 'internal' to be able to resolve the following:
fun box(): String {
    var foo = object {
        val bar = object {
            val baz = "ok"
        }
    }
    return foo.bar.baz
}
The containing declaration of property initializers is constructor, so 'baz' was invisible inside private constructor.
This commit is contained in:
Svetlana Isakova
2014-08-12 17:19:02 +04:00
parent eaeed78154
commit 9d366cb896
39 changed files with 158 additions and 126 deletions
@@ -180,12 +180,17 @@ public interface Errors {
DiagnosticFactory1<JetClass, ClassDescriptor> ENUM_ENTRY_SHOULD_BE_INITIALIZED = DiagnosticFactory1.create(ERROR, NAME_IDENTIFIER);
DiagnosticFactory1<JetTypeReference, ClassDescriptor> ENUM_ENTRY_ILLEGAL_TYPE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<JetClass, ClassDescriptor> LOCAL_ENUM_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, NAME_IDENTIFIER);
// Class objects
DiagnosticFactory0<JetClassObject> MANY_CLASS_OBJECTS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetClassObject> CLASS_OBJECT_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
// Objects
DiagnosticFactory1<JetObjectDeclaration, ClassDescriptor> LOCAL_OBJECT_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, NAME_IDENTIFIER);
// Type parameter declarations
DiagnosticFactory1<JetTypeReference, JetType> FINAL_UPPER_BOUND = DiagnosticFactory1.create(WARNING);
@@ -216,6 +216,8 @@ public class DefaultErrorMessages {
MAP.put(MANY_CLASS_OBJECTS, "Only one class object is allowed per class");
MAP.put(CLASS_OBJECT_NOT_ALLOWED, "A class object is not allowed here");
MAP.put(LOCAL_OBJECT_NOT_ALLOWED, "Named object ''{0}'' is a singleton and cannot be local. Try to use anonymous object instead", NAME);
MAP.put(LOCAL_ENUM_NOT_ALLOWED, "Enum class ''{0}'' cannot be local", NAME);
MAP.put(DELEGATION_IN_TRAIT, "Traits cannot use delegation");
MAP.put(DELEGATION_NOT_TO_TRAIT, "Only traits can be delegated to");
MAP.put(UNMET_TRAIT_REQUIREMENT, "Super trait ''{0}'' requires subclasses to extend ''{1}''", NAME, NAME);
@@ -835,6 +835,7 @@ public class JetPsiUtil {
JetBlockExpression.class, JetClassInitializer.class, JetProperty.class, JetFunction.class, JetParameter.class
);
if (container == null) return null;
if (container.getParent() instanceof JetScript) return null;
return (container instanceof JetClassInitializer) ? ((JetClassInitializer) container).getBody() : container;
}
@@ -182,7 +182,8 @@ public class DeclarationResolver {
scopeForPropertyInitializers,
property,
trace,
c.getOuterDataFlowInfo());
c.getOuterDataFlowInfo()
);
packageLike.addPropertyDescriptor(propertyDescriptor);
c.getProperties().put(property, propertyDescriptor);
c.registerDeclaringScope(property, scopeForPropertyInitializers);
@@ -76,7 +76,7 @@ public class DeclarationsChecker {
jetClass, classDescriptor, classDescriptor.getScopeForClassHeaderResolution(), trace);
}
else if (classOrObject instanceof JetObjectDeclaration) {
checkObject((JetObjectDeclaration) classOrObject);
checkObject((JetObjectDeclaration) classOrObject, classDescriptor);
}
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
@@ -245,8 +245,11 @@ public class DeclarationsChecker {
public abstract boolean removeNeeded(JetType subject, JetType other);
}
private void checkObject(JetObjectDeclaration declaration) {
private void checkObject(JetObjectDeclaration declaration, ClassDescriptor classDescriptor) {
reportErrorIfHasIllegalModifier(declaration);
if (declaration.isLocal() && !declaration.isClassObject() && !declaration.isObjectLiteral()) {
trace.report(LOCAL_OBJECT_NOT_ALLOWED.on(declaration, classDescriptor));
}
}
private void checkClass(BodiesResolveContext c, JetClass aClass, ClassDescriptorWithResolutionScopes classDescriptor) {
@@ -264,6 +267,9 @@ public class DeclarationsChecker {
}
else if (aClass.isEnum()) {
checkEnumModifiers(aClass);
if (aClass.isLocal()) {
trace.report(LOCAL_ENUM_NOT_ALLOWED.on(aClass, classDescriptor));
}
}
else if (aClass instanceof JetEnumEntry) {
checkEnumEntry((JetEnumEntry) aClass, classDescriptor);
@@ -37,9 +37,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import static org.jetbrains.jet.lang.diagnostics.Errors.ILLEGAL_MODIFIER;
import static org.jetbrains.jet.lang.diagnostics.Errors.ILLEGAL_PLATFORM_NAME;
import static org.jetbrains.jet.lang.diagnostics.Errors.INAPPLICABLE_ANNOTATION;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lexer.JetTokens.*;
public class ModifiersChecker {
@@ -121,16 +119,17 @@ public class ModifiersChecker {
}
private void checkInnerModifier(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
JetModifierList modifierList = modifierListOwner.getModifierList();
if (modifierList != null && modifierList.hasModifier(INNER_KEYWORD)) {
if (modifierListOwner.hasModifier(INNER_KEYWORD)) {
if (isIllegalInner(descriptor)) {
checkIllegalInThisContextModifiers(modifierList, Collections.singletonList(INNER_KEYWORD));
checkIllegalInThisContextModifiers(modifierListOwner.getModifierList(), Collections.singletonList(INNER_KEYWORD));
}
return;
}
else {
if (modifierListOwner instanceof JetClass && !(modifierListOwner instanceof JetEnumEntry) && isIllegalNestedClass(descriptor)) {
trace.report(Errors.NESTED_CLASS_NOT_ALLOWED.on((JetClass) modifierListOwner));
if (modifierListOwner instanceof JetClass && !(modifierListOwner instanceof JetEnumEntry)) {
JetClass aClass = (JetClass) modifierListOwner;
boolean localEnumError = aClass.isLocal() && aClass.isEnum();
if (!localEnumError && isIllegalNestedClass(descriptor)) {
trace.report(NESTED_CLASS_NOT_ALLOWED.on(aClass));
}
}
}
@@ -61,15 +61,6 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(klass, klass, descriptor));
}
@Override
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
if (declaration.getParent() instanceof JetObjectLiteralExpression) {
super.visitObjectDeclaration(declaration);
} else {
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(declaration, declaration, descriptor));
}
}
@Override
public void visitNamedFunction(@NotNull JetNamedFunction function) {
if (function.getParent().getParent() instanceof JetObjectDeclaration) {
@@ -181,7 +181,8 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
trace,
// this relies on the assumption that a lazily resolved declaration is not a local one,
// thus doesn't have a surrounding data flow
DataFlowInfo.EMPTY);
DataFlowInfo.EMPTY
);
result.add(propertyDescriptor);
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor, trace);
}