Light class codegen: all objects are considered static

Simplify code handling access flag computation
Fix a problem where kotlin nested object wasn't producing a nested light class
This commit is contained in:
Pavel V. Talanov
2017-03-03 16:27:35 +03:00
parent d94da5af40
commit d34b73befb
20 changed files with 114 additions and 52 deletions
@@ -128,43 +128,35 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isAbstract = false;
boolean isInterface = false;
boolean isFinal = false;
boolean isStatic;
boolean isAnnotation = false;
boolean isEnum = false;
ClassKind kind = descriptor.getKind();
if (kind == ClassKind.OBJECT) {
isStatic = isCompanionObject(descriptor);
isFinal = true;
Modality modality = descriptor.getModality();
if (modality == Modality.ABSTRACT || modality == Modality.SEALED) {
isAbstract = true;
}
else {
Modality modality = descriptor.getModality();
if (modality == Modality.ABSTRACT || modality == Modality.SEALED) {
isAbstract = true;
}
if (kind == ClassKind.INTERFACE) {
isAbstract = true;
isInterface = true;
}
else if (kind == ClassKind.ANNOTATION_CLASS) {
isAbstract = true;
isInterface = true;
isAnnotation = true;
}
else if (kind == ClassKind.ENUM_CLASS) {
isAbstract = hasAbstractMembers(descriptor);
isEnum = true;
}
if (kind == ClassKind.INTERFACE) {
isAbstract = true;
isInterface = true;
}
else if (kind == ClassKind.ANNOTATION_CLASS) {
isAbstract = true;
isInterface = true;
isAnnotation = true;
}
else if (kind == ClassKind.ENUM_CLASS) {
isAbstract = hasAbstractMembers(descriptor);
isEnum = true;
}
if (modality != Modality.OPEN && !isAbstract) {
// Light-class mode: Do not make enum classes final since PsiClass corresponding to enum is expected to be inheritable from
isFinal = !(kind == ClassKind.ENUM_CLASS && !state.getClassBuilderMode().generateBodies);
}
isStatic = !descriptor.isInner();
if (modality != Modality.OPEN && !isAbstract) {
isFinal = kind == ClassKind.OBJECT ||
// Light-class mode: Do not make enum classes final since PsiClass corresponding to enum is expected to be inheritable from
!(kind == ClassKind.ENUM_CLASS && !state.getClassBuilderMode().generateBodies);
}
int access = 0;
@@ -176,7 +168,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
// Thus we must write full accessibility flags on inner classes in this mode
access |= getVisibilityAccessFlag(descriptor);
// Same for STATIC
if (isStatic) {
if (!descriptor.isInner()) {
access |= ACC_STATIC;
}
}
@@ -0,0 +1,37 @@
public final class A {
public A() { /* compiled code */ }
public static final class B {
public B() { /* compiled code */ }
public static final class I {
public static final A.B.I INSTANCE;
private I() { /* compiled code */ }
}
public static final class II {
public static final A.B.II INSTANCE;
private II() { /* compiled code */ }
}
}
public static final class C {
public static final A.C INSTANCE;
private C() { /* compiled code */ }
public static final class D {
public static final A.C.D INSTANCE;
private D() { /* compiled code */ }
public static final class G {
public static final A.C.D.G INSTANCE;
private G() { /* compiled code */ }
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
// A
class A {
class B {
object I
object II
}
object C {
object D {
object G
}
}
}
@@ -11,7 +11,7 @@ public enum class E {
}
@kotlin.Metadata
public final class E/O {
public final static class E/O {
public final static field INSTANCE: E.O
inner class E/O
private method <init>(): void
@@ -27,7 +27,7 @@ final static class E/SUBCLASS {
}
@kotlin.Metadata
public final class E/SUBCLASS/O {
public final static class E/SUBCLASS/O {
public final static field INSTANCE: E.SUBCLASS.O
inner class E/SUBCLASS
inner class E/SUBCLASS/O
@@ -6,7 +6,7 @@ public final class A {
}
@kotlin.Metadata
public final class A/B {
public final static class A/B {
public final static field INSTANCE: A.B
inner class A/B
inner class A/B/C
@@ -14,7 +14,7 @@ public final class A/B {
}
@kotlin.Metadata
public final class A/B/C {
public final static class A/B/C {
public final static field INSTANCE: A.B.C
private final static @org.jetbrains.annotations.NotNull field ok: java.lang.String
inner class A/B
@@ -7,7 +7,7 @@ public final class A {
}
@kotlin.Metadata
public final class A/Z {
public final static class A/Z {
public final static field INSTANCE: A.Z
private final static @org.jetbrains.annotations.NotNull field p: java.lang.String
inner class A/Z
@@ -5,7 +5,7 @@ public final class C {
}
@kotlin.Metadata
public final class C/Obj {
public final static class C/Obj {
public final static field INSTANCE: C.Obj
private final static @org.jetbrains.annotations.NotNull field o: java.lang.String
inner class C/Obj
@@ -25,7 +25,7 @@ public final static class C/Obj/D {
}
@kotlin.Metadata
public final class C/Obj/InnerObj {
public final static class C/Obj/InnerObj {
public final static field INSTANCE: C.Obj.InnerObj
inner class C/Obj
inner class C/Obj/InnerObj
@@ -6,7 +6,7 @@ public final class A {
}
@kotlin.Metadata
private final class A/Foo {
private final static class A/Foo {
public final static field INSTANCE: A.Foo
private final static @org.jetbrains.annotations.NotNull field foov: java.lang.String
inner class A/Foo
@@ -17,7 +17,7 @@ private final class A/Foo {
}
@kotlin.Metadata
public final class A/Foo/Bar {
public final static class A/Foo/Bar {
public final static field INSTANCE: A.Foo.Bar
private final static @org.jetbrains.annotations.NotNull field barv: java.lang.String
inner class A/Foo
@@ -19,7 +19,7 @@ public final class Outer {
}
@kotlin.Metadata
public final class Outer/O {
public final static class Outer/O {
public final static field INSTANCE: Outer.O
inner class Outer/O
private method <init>(): void
@@ -10,7 +10,7 @@ public final class Foo {
}
@kotlin.Metadata
private final class Foo/O {
private final static class Foo/O {
public final static field INSTANCE: Foo.O
inner class Foo/O
private method <init>(): void
@@ -8,7 +8,7 @@ public class Outer {
}
@kotlin.Metadata
public final class Outer/First {
public final static class Outer/First {
public final static field INSTANCE: Outer.First
inner class Outer/First
private method <init>(): void
@@ -9,21 +9,21 @@ public class Outer {
}
@kotlin.Metadata
public final class Outer/Another {
public final static class Outer/Another {
public final static field INSTANCE: Outer.Another
inner class Outer/Another
private method <init>(): void
}
@kotlin.Metadata
public final class Outer/Inner {
public final static class Outer/Inner {
public final static field INSTANCE: Outer.Inner
inner class Outer/Inner
private method <init>(): void
}
@kotlin.Metadata
public final class Outer/Other {
public final static class Outer/Other {
public final static field INSTANCE: Outer.Other
inner class Outer/Other
private method <init>(): void
@@ -41,7 +41,7 @@ public final class S/InnerClass {
}
@kotlin.Metadata
public final class S/NonCompanionObject {
public final static class S/NonCompanionObject {
public final static field INSTANCE: S.NonCompanionObject
inner class S/NonCompanionObject
private method <init>(): void
@@ -12,14 +12,14 @@ public abstract class Season {
}
@kotlin.Metadata
public final class Season/Cold {
public final static class Season/Cold {
public final static field INSTANCE: Season.Cold
inner class Season/Cold
private method <init>(): void
}
@kotlin.Metadata
public final class Season/Warm {
public final static class Season/Warm {
public final static field INSTANCE: Season.Warm
inner class Season/Warm
private method <init>(): void
@@ -9,7 +9,7 @@ public final class A {
}
@kotlin.Metadata
public final class A/B {
public final static class A/B {
public final static field INSTANCE: A.B
private final static field prop: int
inner class A/B
@@ -19,7 +19,7 @@ public final class A/B {
}
@kotlin.Metadata
public final class A/C {
public final static class A/C {
public final static field INSTANCE: A.C
inner class A/C
private method <init>(): void
@@ -7,7 +7,7 @@ public final class A {
}
@kotlin.Metadata
public final class A/B {
public final static class A/B {
public final static field INSTANCE: A.B
private final static @org.jetbrains.annotations.NotNull field z: java.lang.String
inner class A/B
@@ -6,7 +6,7 @@ public abstract class A {
}
@kotlin.Metadata
public final class A/B {
public final static class A/B {
public final static field INSTANCE: A.B
inner class A/B
private method <init>(): void
@@ -72,6 +72,12 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
doTest(fileName);
}
@TestMetadata("NestedObjects.kt")
public void testNestedObjects() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/NestedObjects.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/asJava/lightClasses/compilationErrors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -72,6 +72,12 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
doTest(fileName);
}
@TestMetadata("NestedObjects.kt")
public void testNestedObjects() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/NestedObjects.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/asJava/lightClasses/delegation")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -72,6 +72,12 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
doTest(fileName);
}
@TestMetadata("NestedObjects.kt")
public void testNestedObjects() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/NestedObjects.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/asJava/lightClasses/compilationErrors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)