From 924d706e799530d17cde5a9fe897dad2fe539cb6 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 1 Feb 2016 17:24:12 +0300 Subject: [PATCH] Release original Java descriptors while enhancing It's both more correct and helps to release memory retained by descriptor before enhancement --- .../sam/SamAdapterConstructorDescriptor.java | 27 ++++++++++++++ .../synthetic/SamAdapterFunctionsScope.kt | 5 +-- .../JavaConstructorDescriptor.java | 20 ++++++++-- .../descriptors/JavaMethodDescriptor.java | 6 +-- .../typeEnhancement/signatureEnhancement.kt | 2 +- .../impl/FunctionDescriptorImpl.java | 37 ++++++++++++++----- .../impl/PropertyDescriptorImpl.java | 2 +- .../impl/SimpleFunctionDescriptorImpl.java | 6 ++- 8 files changed, 80 insertions(+), 25 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterConstructorDescriptor.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterConstructorDescriptor.java index 88df44fe8ae..e2f9026d5ea 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterConstructorDescriptor.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterConstructorDescriptor.java @@ -17,6 +17,9 @@ package org.jetbrains.kotlin.load.java.sam; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor; import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor; @@ -31,6 +34,30 @@ import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor; setHasSynthesizedParameterNames(declaration.hasSynthesizedParameterNames()); } + private SamAdapterConstructorDescriptor( + @NotNull ClassDescriptor containingDeclaration, + @Nullable JavaConstructorDescriptor original, + @NotNull Annotations annotations, + boolean isPrimary, + @NotNull Kind kind, + @NotNull SourceElement source, + @NotNull JavaConstructorDescriptor declaration + ) { + super(containingDeclaration, original, annotations, isPrimary, kind, source); + this.declaration = declaration; + } + + @NotNull + @Override + protected JavaConstructorDescriptor createDescriptor( + @NotNull ClassDescriptor newOwner, + @Nullable JavaConstructorDescriptor original, + @NotNull Kind kind, + @NotNull SourceElement sourceElement + ) { + return new SamAdapterConstructorDescriptor(newOwner, original, getAnnotations(), isPrimary, kind, sourceElement, declaration); + } + @NotNull @Override public JavaConstructorDescriptor getOriginForSam() { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt index 6833167a0d4..3205ceb1300 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -22,7 +22,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils -import org.jetbrains.kotlin.load.java.typeEnhancement.enhanceSignature import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf @@ -47,9 +46,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope if (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all? if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null if (function.returnType == null) return null - //TODO: it's a temporary hack while original returns a function with platform types - val enhancedFunction = function.enhanceSignature() - return MyFunctionDescriptor.create(enhancedFunction) + return MyFunctionDescriptor.create(function) } override fun getSyntheticExtensionFunctions(receiverTypes: Collection, name: Name, location: LookupLocation): Collection { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java index 27f69fc62dd..b0137f53df3 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java @@ -91,14 +91,26 @@ public class JavaConstructorDescriptor extends ConstructorDescriptorImpl impleme assert newName == null : "Attempt to rename constructor: " + this; - JavaConstructorDescriptor result = new JavaConstructorDescriptor( - (ClassDescriptor) newOwner, this, getAnnotations(), isPrimary, kind, getSourceToUseForCopy(preserveSource, original) - ); + JavaConstructorDescriptor result = createDescriptor((ClassDescriptor) newOwner, (JavaConstructorDescriptor) original, kind, + getSourceToUseForCopy(preserveSource, original)); result.setHasStableParameterNames(hasStableParameterNames()); result.setHasSynthesizedParameterNames(hasSynthesizedParameterNames()); return result; } + @NotNull + protected JavaConstructorDescriptor createDescriptor( + @NotNull ClassDescriptor newOwner, + @Nullable JavaConstructorDescriptor original, + @NotNull Kind kind, + @NotNull SourceElement sourceElement + ) { + return new JavaConstructorDescriptor( + newOwner, original, getAnnotations(), isPrimary, kind, + sourceElement + ); + } + @Override @NotNull public JavaConstructorDescriptor enhance( @@ -106,7 +118,7 @@ public class JavaConstructorDescriptor extends ConstructorDescriptorImpl impleme @NotNull List enhancedValueParametersTypes, @NotNull KotlinType enhancedReturnType ) { - JavaConstructorDescriptor enhanced = createSubstitutedCopy(getContainingDeclaration(), getOriginal(), getKind(), null, false); + JavaConstructorDescriptor enhanced = createSubstitutedCopy(getContainingDeclaration(), /* original = */ null, getKind(), null, false); // We do not use doSubstitute here as in JavaMethodDescriptor.enhance because type parameters of constructor belongs to class enhanced.initialize( enhancedReceiverType, diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java index 3cca55c9bd2..165573867f0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java @@ -138,15 +138,13 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement List enhancedValueParameters = UtilKt.copyValueParameters(enhancedValueParametersTypes, getValueParameters(), this); - // We use `doSubstitute` here because it does exactly what we need: - // 1. creates full copy of descriptor - // 2. copies method's type parameters (with new containing declaration) and properly substitute to them in value parameters, return type and etc. JavaMethodDescriptor enhancedMethod = (JavaMethodDescriptor) newCopyBuilder() .setValueParameters(enhancedValueParameters) .setReturnType(enhancedReturnType) .setExtensionReceiverType(enhancedReceiverType) - .setOriginal(getOriginal()) + .setDropOriginalInContainingParts() + .setPreserveSourceElement() .build(); assert enhancedMethod != null : "null after substitution while enhancing " + toString(); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt index 5d922feb89e..6dacab1460d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt @@ -26,7 +26,7 @@ fun enhanceSignatures(platformSignatures: Collect } } -fun D.enhanceSignature(): D { +private fun D.enhanceSignature(): D { // TODO type parameters // TODO use new type parameters while enhancing other types // TODO Propagation into generic type arguments diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java index 0d5c7384397..5d011bc53cc 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java @@ -291,8 +291,10 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo protected @Nullable KotlinType newExtensionReceiverParameterType; protected @NotNull KotlinType newReturnType; protected @Nullable Name name; - protected boolean copyOverrides; - protected boolean signatureChange; + protected boolean copyOverrides = true; + protected boolean signatureChange = false; + protected boolean preserveSourceElement = false; + protected boolean dropOriginalInContainingParts = false; private boolean isHiddenToOvercomeSignatureClash; private List newTypeParameters = null; @@ -316,8 +318,6 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo this.newExtensionReceiverParameterType = newExtensionReceiverParameterType; this.newReturnType = newReturnType; this.name = name; - this.copyOverrides = true; - this.signatureChange = false; this.isHiddenToOvercomeSignatureClash = isHiddenToOvercomeSignatureClash(); } @@ -391,12 +391,25 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo return this; } + @NotNull + public CopyConfiguration setPreserveSourceElement() { + this.preserveSourceElement = true; + return this; + } + + @NotNull + public CopyConfiguration setDropOriginalInContainingParts() { + this.dropOriginalInContainingParts = true; + return this; + } + @NotNull public CopyConfiguration setHidden() { isHiddenToOvercomeSignatureClash = true; return this; } + @Nullable public FunctionDescriptor build() { return doSubstitute(this); } @@ -429,7 +442,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo protected FunctionDescriptor doSubstitute(@NotNull CopyConfiguration configuration) { FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy( configuration.newOwner, configuration.original, configuration.kind, configuration.name, - /* preserveSource = */ configuration.signatureChange); + configuration.preserveSourceElement); List substitutedTypeParameters; TypeSubstitutor substitutor; @@ -474,7 +487,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo } List substitutedValueParameters = getSubstitutedValueParameters( - substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor + substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor, configuration.dropOriginalInContainingParts ); if (substitutedValueParameters == null) { return null; @@ -511,7 +524,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo if (configuration.copyOverrides) { for (FunctionDescriptor overriddenFunction : overriddenFunctions) { - substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor)); + if (configuration.originalSubstitutor.isEmpty()) { + substitutedDescriptor.addOverriddenDescriptor(overriddenFunction); + } + else { + substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor)); + } } } @@ -543,7 +561,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo public static List getSubstitutedValueParameters( FunctionDescriptor substitutedDescriptor, @NotNull List unsubstitutedValueParameters, - @NotNull TypeSubstitutor substitutor + @NotNull TypeSubstitutor substitutor, + boolean dropOriginal ) { List result = new ArrayList(unsubstitutedValueParameters.size()); for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) { @@ -556,7 +575,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo result.add( new ValueParameterDescriptorImpl( substitutedDescriptor, - unsubstitutedValueParameter, + dropOriginal ? null : unsubstitutedValueParameter, unsubstitutedValueParameter.getIndex(), unsubstitutedValueParameter.getAnnotations(), unsubstitutedValueParameter.getName(), diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java index 008aa17ab61..4231c64a82c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java @@ -272,7 +272,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp ); if (newSetter != null) { List substitutedValueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters( - newSetter, setter.getValueParameters(), substitutor + newSetter, setter.getValueParameters(), substitutor, /* dropOriginal = */ false ); if (substitutedValueParameters == null) { // The setter is projected out, e.g. in this case: diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java index ea84c96cfc2..8df53746d09 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java @@ -113,14 +113,16 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme @Override public SimpleFunctionDescriptor createRenamedCopy(@NotNull Name name) { //noinspection ConstantConditions - return (SimpleFunctionDescriptor) newCopyBuilder().setName(name).setSignatureChange().build(); + return (SimpleFunctionDescriptor) newCopyBuilder().setName(name).setSignatureChange().setPreserveSourceElement().build(); } @NotNull @Override public SimpleFunctionDescriptor createCopyWithNewValueParameters(@NotNull List valueParameters) { //noinspection ConstantConditions - return (SimpleFunctionDescriptor) newCopyBuilder().setValueParameters(valueParameters).setSignatureChange().build(); + return (SimpleFunctionDescriptor) newCopyBuilder() + .setValueParameters(valueParameters) + .setSignatureChange().setPreserveSourceElement().build(); } @NotNull