From a689f6d24334527d7fc39983a84b13a244686e47 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 13 Oct 2014 18:44:13 +0400 Subject: [PATCH] Tracking if there is something to reify in members --- .../jet/codegen/ExpressionCodegen.java | 59 +++++++++++++++++-- .../jetbrains/jet/codegen/MemberCodegen.java | 9 +++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index ba7f0944f29..9a1918b5d3c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -61,6 +61,7 @@ import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.receivers.*; import org.jetbrains.jet.lang.types.Approximation; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -183,7 +184,7 @@ public class ExpressionCodegen extends JetVisitor implem } @NotNull - public ClassDescriptor generateObjectLiteral(@NotNull JetObjectLiteralExpression literal) { + public ObjectLiteralResult generateObjectLiteral(@NotNull JetObjectLiteralExpression literal) { JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration(); ClassDescriptor classDescriptor = bindingContext.get(CLASS, objectDeclaration); @@ -197,9 +198,44 @@ public class ExpressionCodegen extends JetVisitor implem ); ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION); - new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state, getParentCodegen()).generate(); - return classDescriptor; + MemberCodegen literalCodegen = new ImplementationBodyCodegen( + objectDeclaration, objectContext, classBuilder, state, getParentCodegen() + ); + literalCodegen.generate(); + + if (containsReifiedParametersInSupertypes(classDescriptor)) { + literalCodegen.setWereReifierMarkers(true); + } + + if (literalCodegen.wereReifierMarkers()) { + getParentCodegen().setWereReifierMarkers(true); + } + + return new ObjectLiteralResult(literalCodegen.wereReifierMarkers(), classDescriptor); + } + + private static boolean containsReifiedParametersInSupertypes(@NotNull ClassDescriptor descriptor) { + for (JetType type : descriptor.getTypeConstructor().getSupertypes()) { + for (TypeProjection supertypeArgument : type.getArguments()) { + TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(supertypeArgument.getType()); + if (parameterDescriptor != null && parameterDescriptor.isReified()) { + return true; + } + } + } + + return false; + } + + private static class ObjectLiteralResult { + private final boolean wereReifiedMarkers; + private final ClassDescriptor classDescriptor; + + public ObjectLiteralResult(boolean wereReifiedMarkers, @NotNull ClassDescriptor classDescriptor) { + this.wereReifiedMarkers = wereReifiedMarkers; + this.classDescriptor = classDescriptor; + } } @NotNull @@ -1341,20 +1377,34 @@ public class ExpressionCodegen extends JetVisitor implem @Nullable SamType samType, @NotNull KotlinSyntheticClass.Kind kind ) { + boolean wereReifiedMarkers = parentCodegen.wereReifierMarkers(); + parentCodegen.setWereReifierMarkers(false); + ClosureCodegen closureCodegen = new ClosureCodegen( state, declaration, descriptor, samType, context, kind, this, strategy, parentCodegen ); closureCodegen.gen(); + if (parentCodegen.wereReifierMarkers()) { + ReifiedTypeInliner.putNeedClassReificationMarker(v); + } + if (wereReifiedMarkers) { + parentCodegen.setWereReifierMarkers(true); + } + return closureCodegen.putInstanceOnStack(v, this); } @Override public StackValue visitObjectLiteralExpression(@NotNull JetObjectLiteralExpression expression, StackValue receiver) { - ClassDescriptor classDescriptor = generateObjectLiteral(expression); + ObjectLiteralResult objectLiteralResult = generateObjectLiteral(expression); + ClassDescriptor classDescriptor = objectLiteralResult.classDescriptor; Type type = typeMapper.mapType(classDescriptor); + if (objectLiteralResult.wereReifiedMarkers) { + ReifiedTypeInliner.putNeedClassReificationMarker(v); + } v.anew(type); v.dup(); @@ -3824,6 +3874,7 @@ The "returned" value of try expression with no finally is either the last expres public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull JetType type, @NotNull String markerMethodName) { TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type); if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) { + parentCodegen.setWereReifierMarkers(true); v.iconst(typeParameterDescriptor.getIndex()); v.invokestatic( IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName, diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index f763f555c3f..530f288c9bc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -70,6 +70,7 @@ public abstract class MemberCodegen getContext() { return context; } + + public boolean wereReifierMarkers() { + return wereReifierMarkers; + } + + public void setWereReifierMarkers(boolean wereReifierMarkers) { + this.wereReifierMarkers = wereReifierMarkers; + } }