diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java index 1836de88af9..7a7b5a6d4e1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java @@ -66,7 +66,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { Collections.singleton((funDescriptor.getReceiverParameter() != null ? KotlinBuiltIns.getInstance().getExtensionFunction(arity) : KotlinBuiltIns.getInstance().getFunction(arity)).getDefaultType()), JetScope.EMPTY, - Collections.emptySet(), null); + Collections.emptySet(), + null, + false); assert PsiCodegenPredictor.checkPredictedClassNameForFun(bindingContext, funDescriptor, classDescriptor); bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java index dda565110fa..b7423f3895a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java @@ -124,7 +124,8 @@ public class CodegenBinding { Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType()), JetScope.EMPTY, Collections.emptySet(), - null); + null, + false); recordClosure(bindingTrace, null, classDescriptor, null, className, false); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java index 98bfcb78192..f89d125ed12 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java @@ -36,9 +36,10 @@ public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite { public ClassDescriptorFromJvmBytecode( @NotNull DeclarationDescriptor containingDeclaration, - @NotNull ClassKind kind + @NotNull ClassKind kind, + boolean isInner ) { - super(containingDeclaration, kind); + super(containingDeclaration, kind, isInner); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java index f187f6f237f..0f91bc0803d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java @@ -106,7 +106,7 @@ public final class JavaClassObjectResolver { FqName fqName = new FqName(qualifiedName); ClassPsiDeclarationProvider classObjectData = semanticServices.getPsiDeclarationProviderFactory().createBinaryClassData(classObjectPsiClass); ClassDescriptorFromJvmBytecode classObjectDescriptor - = new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT); + = new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false); classObjectDescriptor.setSupertypes(supertypesResolver.getSupertypes(classObjectDescriptor, new PsiClassWrapper(classObjectPsiClass), classObjectData, @@ -143,7 +143,8 @@ public final class JavaClassObjectResolver { @NotNull PsiClass psiClass ) { FqNameUnsafe fqName = DescriptorResolverUtils.getFqNameForClassObject(psiClass); - ClassDescriptorFromJvmBytecode classObjectDescriptor = new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT); + ClassDescriptorFromJvmBytecode classObjectDescriptor = + new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false); ClassPsiDeclarationProvider data = semanticServices.getPsiDeclarationProviderFactory().createSyntheticClassObjectClassData(psiClass); setUpClassObjectDescriptor(classObjectDescriptor, containing, fqName, data, getClassObjectName(containing.getName().getName())); return classObjectDescriptor; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index efeeaefd2db..4177c1a43e7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -219,7 +219,8 @@ public final class JavaClassResolver { JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass); ClassKind kind = getClassKind(psiClass, jetClassAnnotation); ClassPsiDeclarationProvider classData = semanticServices.getPsiDeclarationProviderFactory().createBinaryClassData(psiClass); - ClassDescriptorFromJvmBytecode classDescriptor = new ClassDescriptorFromJvmBytecode(containingDeclaration, kind); + ClassDescriptorFromJvmBytecode classDescriptor = new ClassDescriptorFromJvmBytecode(containingDeclaration, kind, + isInnerClass(psiClass)); cache(javaClassToKotlinFqName(fqName), classDescriptor); classDescriptor.setName(Name.identifier(psiClass.getName())); @@ -338,6 +339,10 @@ public final class JavaClassResolver { return psiClass.getContainingClass() != null; } + private static boolean isInnerClass(@NotNull PsiClass psiClass) { + return isContainedInClass(psiClass) && !psiClass.hasModifierProperty(PsiModifier.STATIC); + } + @NotNull private ClassOrNamespaceDescriptor resolveParentClass(@NotNull PsiClass psiClass) { PsiClass containingClass = psiClass.getContainingClass(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java index 06fce396e8d..8d15f8abe56 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java @@ -201,7 +201,8 @@ public final class JavaPropertyResolver { true, Collections.emptyList(), Collections.emptyList(), JetScope.EMPTY, - Collections.emptySet(), null); + Collections.emptySet(), null, + false); trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, dummyClassDescriptorForEnumEntryObject); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java index 3b9bac3532e..a32145b465c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java @@ -70,6 +70,11 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor, @NotNull Visibility getVisibility(); + /** + * @return true if this class contains a reference to its outer class (as opposed to static nested class) + */ + boolean isInner(); + @NotNull ReceiverParameterDescriptor getThisAsReceiverParameter(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java index fb8baac9a35..a7b2dfce051 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java @@ -40,6 +40,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implem private final Modality modality; private ClassDescriptor classObjectDescriptor; private final ClassKind kind; + private boolean isInner; public ClassDescriptorImpl( @NotNull DeclarationDescriptor containingDeclaration, @@ -68,13 +69,14 @@ public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implem @NotNull Collection supertypes, @NotNull JetScope memberDeclarations, @NotNull Set constructors, - @Nullable ConstructorDescriptor primaryConstructor + @Nullable ConstructorDescriptor primaryConstructor, + boolean isInner ) { this.typeConstructor = new TypeConstructorImpl(this, getAnnotations(), sealed, getName().getName(), typeParameters, supertypes); this.memberDeclarations = memberDeclarations; this.constructors = constructors; this.primaryConstructor = primaryConstructor; - this.classObjectDescriptor = classObjectDescriptor; + this.isInner = isInner; return this; } @@ -165,6 +167,11 @@ public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implem return Visibilities.PUBLIC; } + @Override + public boolean isInner() { + return isInner; + } + @NotNull @Override public ReceiverParameterDescriptor getThisAsReceiverParameter() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java index f58188525f5..ab5228f7b41 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java @@ -174,6 +174,11 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { return original.getVisibility(); } + @Override + public boolean isInner() { + return original.isInner(); + } + @Override public boolean isClassObjectAValue() { return original.isClassObjectAValue(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 1b1275d9120..225f9e8df1b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -48,8 +48,8 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite { private WritableScope scopeForInitializers = null; //contains members + primary constructor value parameters + map for backing fields public MutableClassDescriptor(@NotNull DeclarationDescriptor containingDeclaration, - @NotNull JetScope outerScope, ClassKind kind, Name name) { - super(containingDeclaration, kind); + @NotNull JetScope outerScope, ClassKind kind, boolean isInner, Name name) { + super(containingDeclaration, kind, isInner); RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java index ae48fe7b8ed..61df63aa3fd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java @@ -45,6 +45,8 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase { private Modality modality; private Visibility visibility; + private final boolean isInner; + private MutableClassDescriptorLite classObjectDescriptor; private JetType classObjectType; private final ClassKind kind; @@ -58,9 +60,12 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase { private final DeclarationDescriptor containingDeclaration; public MutableClassDescriptorLite(@NotNull DeclarationDescriptor containingDeclaration, - @NotNull ClassKind kind) { + @NotNull ClassKind kind, + boolean isInner + ) { this.containingDeclaration = containingDeclaration; this.kind = kind; + this.isInner = isInner; } @NotNull @@ -176,6 +181,11 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase { return visibility; } + @Override + public boolean isInner() { + return isInner; + } + public Collection getSupertypes() { return supertypes; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ScriptDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ScriptDescriptor.java index fe9079270e9..665667c4c9a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ScriptDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ScriptDescriptor.java @@ -77,7 +77,8 @@ public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl { Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType()), classScope, new HashSet(), - null); + null, + false); } public void initialize(@NotNull JetType returnType, JetScript declaration, BindingContext bindingContext) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java index 77a4fe222aa..9cabb0973e3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java @@ -192,6 +192,10 @@ public class ModifiersChecker { return defaultVisibility; } + public static boolean isInnerClass(@Nullable JetModifierList modifierList) { + return modifierList != null && modifierList.hasModifier(INNER_KEYWORD); + } + @NotNull public static Visibility getDefaultClassVisibility(@NotNull ClassDescriptor descriptor) { ClassKind kind = descriptor.getKind(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 8ef9b1a7c21..e05fe5b00fa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -585,7 +585,7 @@ public class TypeHierarchyResolver { @NotNull Visibility visibility ) { MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor( - classDescriptor, outerScope, ClassKind.CLASS_OBJECT, getClassObjectName(classDescriptor.getName())); + classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false, getClassObjectName(classDescriptor.getName())); classObjectDescriptor.setModality(Modality.FINAL); classObjectDescriptor.setVisibility(visibility); classObjectDescriptor.setTypeParameterDescriptors(new ArrayList(0)); @@ -600,8 +600,12 @@ public class TypeHierarchyResolver { @NotNull JetClass klass, @NotNull DeclarationDescriptor containingDeclaration ) { + ClassKind kind = getClassKind(klass); + // Kind check is needed in order to not consider enums as inner in any case + // (otherwise it would be impossible to create a class object in the enum) + boolean isInner = kind == ClassKind.CLASS && klass.isInner(); MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( - containingDeclaration, outerScope, getClassKind(klass), JetPsiUtil.safeName(klass.getName())); + containingDeclaration, outerScope, kind, isInner, JetPsiUtil.safeName(klass.getName())); context.getClasses().put(klass, mutableClassDescriptor); trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(klass), mutableClassDescriptor); @@ -620,7 +624,7 @@ public class TypeHierarchyResolver { @NotNull JetScope scope, @NotNull Name name, @NotNull ClassKind kind ) { MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( - owner.getOwnerForChildren(), scope, kind, name); + owner.getOwnerForChildren(), scope, kind, false, name); context.getObjects().put(declaration, mutableClassDescriptor); JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution(); @@ -638,7 +642,7 @@ public class TypeHierarchyResolver { ) { MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( owner.getOwnerForChildren(), getStaticScope(declaration, owner), ClassKind.ENUM_ENTRY, - JetPsiUtil.safeName(declaration.getName())); + false, JetPsiUtil.safeName(declaration.getName())); context.getClasses().put(declaration, mutableClassDescriptor); prepareForDeferredCall(mutableClassDescriptor.getScopeForMemberResolution(), mutableClassDescriptor, declaration); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index 2de739fbae9..8d22f3cdd4b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -26,10 +26,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.AnnotationResolver; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.DescriptorResolver; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.lazy.data.FilteringClassLikeInfo; import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil; import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo; @@ -65,6 +62,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc private final Modality modality; private final Visibility visibility; private final ClassKind kind; + private final boolean isInner; private ReceiverParameterDescriptor thisAsReceiverParameter; private List annotations; @@ -102,17 +100,17 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc this.typeConstructor = new LazyClassTypeConstructor(); + JetModifierList modifierList = classLikeInfo.getModifierList(); this.kind = classLikeInfo.getClassKind(); if (kind.isObject()) { this.modality = Modality.FINAL; } else { Modality defaultModality = kind == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL; - JetModifierList modifierList = classLikeInfo.getModifierList(); this.modality = resolveModalityFromModifiers(modifierList, defaultModality); } - JetModifierList modifierList = classLikeInfo.getModifierList(); this.visibility = resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this)); + this.isInner = isInnerClass(modifierList); } @Override @@ -266,6 +264,11 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc return visibility; } + @Override + public boolean isInner() { + return isInner; + } + @NotNull @Override public ReceiverParameterDescriptor getThisAsReceiverParameter() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 7816747bd2c..744fd70add0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -140,7 +140,8 @@ public class ErrorUtils { static { ERROR_CLASS.initialize( - true, Collections.emptyList(), Collections.emptyList(), createErrorScope("ERROR_CLASS"), ERROR_CONSTRUCTOR_GROUP, ERROR_CONSTRUCTOR); + true, Collections.emptyList(), Collections.emptyList(), createErrorScope("ERROR_CLASS"), ERROR_CONSTRUCTOR_GROUP, + ERROR_CONSTRUCTOR, false); } public static JetScope createErrorScope(String debugMessage) { diff --git a/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java b/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java index 4d890c54007..54a034e1b18 100644 --- a/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java +++ b/compiler/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java @@ -92,7 +92,7 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture { } private MutableClassDescriptor createClassDescriptor(ClassKind kind, JetClass aClass) { - MutableClassDescriptor classDescriptor = new MutableClassDescriptor(root, scope, kind, Name.identifier(aClass.getName())); + MutableClassDescriptor classDescriptor = new MutableClassDescriptor(root, scope, kind, false, Name.identifier(aClass.getName())); descriptorResolver.resolveMutableClassDescriptor(aClass, classDescriptor, JetTestUtils.DUMMY_TRACE); return classDescriptor; }