39
39
import org .jetbrains .kotlin .descriptors .*;
40
40
import org .jetbrains .kotlin .incremental .components .NoLookupLocation ;
41
41
import org .jetbrains .kotlin .lexer .KtTokens ;
42
- import org .jetbrains .kotlin .load .java .JvmAbi ;
43
42
import org .jetbrains .kotlin .load .java .descriptors .JavaClassDescriptor ;
44
43
import org .jetbrains .kotlin .name .FqName ;
45
44
import org .jetbrains .kotlin .name .Name ;
76
75
import static org .jetbrains .kotlin .codegen .CodegenUtilKt .isNonGenericToArray ;
77
76
import static org .jetbrains .kotlin .codegen .JvmCodegenUtil .*;
78
77
import static org .jetbrains .kotlin .codegen .binding .CodegenBinding .enumEntryNeedSubclass ;
78
+ import static org .jetbrains .kotlin .load .java .JvmAbi .*;
79
79
import static org .jetbrains .kotlin .resolve .BindingContextUtils .getDelegationConstructorCall ;
80
80
import static org .jetbrains .kotlin .resolve .BindingContextUtils .getNotNull ;
81
81
import static org .jetbrains .kotlin .resolve .DescriptorToSourceUtils .descriptorToDeclaration ;
@@ -344,6 +344,8 @@ protected void generateSyntheticParts() {
344
344
345
345
generateFieldForSingleton ();
346
346
347
+ initializeObjects ();
348
+
347
349
generateCompanionObjectBackingFieldCopies ();
348
350
349
351
generateTraitMethods ();
@@ -798,21 +800,21 @@ private void generateEnumValueOfMethod() {
798
800
}
799
801
800
802
private void generateFieldForSingleton () {
803
+ if (isCompanionObjectInInterfaceNotIntrinsic (descriptor )) {
804
+ StackValue .Field field = StackValue .createSingletonViaInstance (descriptor , typeMapper , HIDDEN_INSTANCE_FIELD );
805
+ //hidden instance in interface companion
806
+ v .newField (JvmDeclarationOriginKt .OtherOrigin (descriptor ),
807
+ ACC_SYNTHETIC | ACC_STATIC | ACC_FINAL , field .name , field .type .getDescriptor (), null , null );
808
+ }
809
+
801
810
if (isEnumEntry (descriptor ) || isCompanionObject (descriptor )) return ;
802
811
803
812
if (isNonCompanionObject (descriptor )) {
804
- StackValue .Field field = StackValue .singletonViaInstance (descriptor , typeMapper );
813
+ StackValue .Field field = StackValue .createSingletonViaInstance (descriptor , typeMapper , INSTANCE_FIELD );
805
814
v .newField (JvmDeclarationOriginKt .OtherOrigin (myClass ),
806
815
ACC_PUBLIC | ACC_STATIC | ACC_FINAL ,
807
816
field .name , field .type .getDescriptor (), null , null );
808
817
809
- if (!state .getClassBuilderMode ().generateBodies ) return ;
810
- // Invoke the object constructor but ignore the result because INSTANCE will be initialized in the first line of <init>
811
- InstructionAdapter v = createOrGetClInitCodegen ().v ;
812
- markLineNumberForElement (element .getPsiOrParent (), v );
813
- v .anew (classAsmType );
814
- v .invokespecial (classAsmType .getInternalName (), "<init>" , "()V" , false );
815
-
816
818
return ;
817
819
}
818
820
@@ -828,6 +830,60 @@ private void generateFieldForSingleton() {
828
830
ACC_PUBLIC | ACC_STATIC | ACC_FINAL , field .name , field .type .getDescriptor (), null , null );
829
831
}
830
832
833
+ private void initializeObjects () {
834
+ if (!DescriptorUtils .isObject (descriptor )) return ;
835
+ if (!state .getClassBuilderMode ().generateBodies ) return ;
836
+
837
+ boolean isNonCompanionObject = isNonCompanionObject (descriptor );
838
+ boolean isInterfaceCompanion = isCompanionObjectInInterfaceNotIntrinsic (descriptor );
839
+ boolean isMappedIntrinsicCompanionObject = isMappedIntrinsicCompanionObject (descriptor );
840
+ if (isNonCompanionObject || isInterfaceCompanion || isMappedIntrinsicCompanionObject ) {
841
+ ExpressionCodegen clInitCodegen = createOrGetClInitCodegen ();
842
+ InstructionAdapter v = clInitCodegen .v ;
843
+ markLineNumberForElement (element .getPsiOrParent (), v );
844
+ v .anew (classAsmType );
845
+ v .dup ();
846
+ v .invokespecial (classAsmType .getInternalName (), "<init>" , "()V" , false );
847
+
848
+ //local0 emulates this in object constructor
849
+ int local0Index = clInitCodegen .getFrameMap ().enterTemp (classAsmType );
850
+ assert local0Index == 0 : "Local variable with index 0 in clInit should be used only for singleton instance keeping" ;
851
+ StackValue .Local local0 = StackValue .local (0 , classAsmType );
852
+ local0 .store (StackValue .onStack (classAsmType ), clInitCodegen .v );
853
+ StackValue .Field singleton =
854
+ StackValue .createSingletonViaInstance (
855
+ descriptor , typeMapper , isInterfaceCompanion ? HIDDEN_INSTANCE_FIELD : INSTANCE_FIELD
856
+ );
857
+ singleton .store (local0 , clInitCodegen .v );
858
+
859
+ generateInitializers (clInitCodegen );
860
+
861
+ if (isInterfaceCompanion ) {
862
+ //initialize singleton instance in outer by hidden instance
863
+ StackValue .singleton (descriptor , typeMapper ).store (
864
+ singleton , getParentCodegen ().createOrGetClInitCodegen ().v , true
865
+ );
866
+ }
867
+ }
868
+ else if (isCompanionObjectWithBackingFieldsInOuter (descriptor )) {
869
+ ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen ) getParentCodegen ();
870
+ ExpressionCodegen parentClInitCodegen = parentCodegen .createOrGetClInitCodegen ();
871
+ InstructionAdapter parentVisitor = parentClInitCodegen .v ;
872
+
873
+ FunctionDescriptor constructor = (FunctionDescriptor ) parentCodegen .context .accessibleDescriptor (
874
+ CollectionsKt .single (descriptor .getConstructors ()), /* superCallExpression = */ null
875
+ );
876
+ parentCodegen .generateMethodCallTo (constructor , null , parentVisitor );
877
+ StackValue instance = StackValue .onStack (parentCodegen .typeMapper .mapClass (descriptor ));
878
+ StackValue .singleton (descriptor , parentCodegen .typeMapper ).store (instance , parentVisitor , true );
879
+
880
+ generateInitializers (parentClInitCodegen );
881
+ }
882
+ else {
883
+ assert false : "Unknown object type: " + descriptor ;
884
+ }
885
+ }
886
+
831
887
private void generateCompanionObjectBackingFieldCopies () {
832
888
if (companionObjectPropertiesToCopy == null ) return ;
833
889
@@ -875,17 +931,6 @@ private void copyFieldFromCompanionObject(PropertyDescriptor propertyDescriptor)
875
931
field .store (property , codegen .v );
876
932
}
877
933
878
- private void generateCompanionObjectInitializer (@ NotNull ClassDescriptor companionObject ) {
879
- ExpressionCodegen codegen = createOrGetClInitCodegen ();
880
-
881
- FunctionDescriptor constructor = (FunctionDescriptor ) context .accessibleDescriptor (
882
- CollectionsKt .single (companionObject .getConstructors ()), /* superCallExpression = */ null
883
- );
884
- generateMethodCallTo (constructor , null , codegen .v );
885
- StackValue instance = StackValue .onStack (typeMapper .mapClass (companionObject ));
886
- StackValue .singleton (companionObject , typeMapper ).store (instance , codegen .v , true );
887
- }
888
-
889
934
private void generatePrimaryConstructor (DelegationFieldsInfo delegationFieldsInfo ) {
890
935
if (isInterface (descriptor ) || isAnnotationClass (descriptor )) return ;
891
936
@@ -953,10 +998,6 @@ private void generatePrimaryConstructorImpl(
953
998
generateDelegatorToConstructorCall (iv , codegen , constructorDescriptor ,
954
999
getDelegationConstructorCall (bindingContext , constructorDescriptor ));
955
1000
956
- if (isNonCompanionObject (descriptor )) {
957
- StackValue .singletonViaInstance (descriptor , typeMapper ).store (StackValue .LOCAL_0 , iv );
958
- }
959
-
960
1001
for (KtSuperTypeListEntry specifier : myClass .getSuperTypeListEntries ()) {
961
1002
if (specifier instanceof KtDelegatedSuperTypeEntry ) {
962
1003
genCallToDelegatorByExpressionSpecifier (iv , codegen , (KtDelegatedSuperTypeEntry ) specifier , fieldsInfo );
@@ -978,18 +1019,10 @@ private void generatePrimaryConstructorImpl(
978
1019
curParam ++;
979
1020
}
980
1021
981
- if (isCompanionObject (descriptor )) {
982
- ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen ) getParentCodegen ();
983
- parentCodegen .generateCompanionObjectInitializer (descriptor );
984
- }
985
-
986
- if (JvmAbi .isCompanionObjectWithBackingFieldsInOuter (descriptor )) {
987
- generateInitializers (((ImplementationBodyCodegen ) getParentCodegen ())::createOrGetClInitCodegen );
988
- }
989
- else {
1022
+ //object initialization was moved to initializeObjects()
1023
+ if (!isObject (descriptor )) {
990
1024
generateInitializers (codegen );
991
1025
}
992
-
993
1026
iv .visitInsn (RETURN );
994
1027
}
995
1028
@@ -1125,7 +1158,7 @@ private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<KtSuperTypeLi
1125
1158
KotlinType expressionType = expression != null ? bindingContext .getType (expression ) : null ;
1126
1159
Type asmType =
1127
1160
expressionType != null ? typeMapper .mapType (expressionType ) : typeMapper .mapType (getSuperClass (specifier ));
1128
- result .addField ((KtDelegatedSuperTypeEntry ) specifier , asmType , JvmAbi . DELEGATE_SUPER_FIELD_PREFIX + n );
1161
+ result .addField ((KtDelegatedSuperTypeEntry ) specifier , asmType , DELEGATE_SUPER_FIELD_PREFIX + n );
1129
1162
}
1130
1163
n ++;
1131
1164
}
0 commit comments