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:
@@ -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);
|
||||
|
||||
+2
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-9
@@ -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) {
|
||||
|
||||
+2
-1
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user