From 527ccaff16ecebbfbcecabd5fbc8af808a296915 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Fri, 21 Jul 2017 15:27:20 +0300 Subject: [PATCH] Changes required for serialization plugin to work: * Support for generation of synthetic nested classes (for implementations of user-defined serial annotations): 1. Compiler extenstion points for contributing names and descriptoprs of nested classes 2. Control on synthetic class primary constructor visibility * Public functions for generating initializing expressions for optional properties --- .../kotlin/codegen/ClassBodyCodegen.java | 15 ++++++- .../kotlin/codegen/MemberCodegen.java | 6 ++- .../SyntheticClassOrObjectDescriptor.kt | 6 ++- .../extensions/SyntheticResolveExtension.kt | 40 ++++++++++++++----- .../lazy/descriptors/LazyClassDescriptor.java | 3 +- .../lazy/descriptors/LazyClassMemberScope.kt | 8 +++- 6 files changed, 60 insertions(+), 18 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java index 6bc205e7852..50618dc020d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java @@ -27,8 +27,11 @@ import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor; import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptorKt; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; +import org.jetbrains.kotlin.resolve.scopes.MemberScope; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -101,6 +104,16 @@ public abstract class ClassBodyCodegen extends MemberCodegen classifiers = descriptor + .getUnsubstitutedMemberScope() + .getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.Companion.getALL_NAME_FILTER()); + for (DeclarationDescriptor memberDescriptor : classifiers) { + if (memberDescriptor instanceof SyntheticClassOrObjectDescriptor) { + genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) memberDescriptor); + } + } + if (generateNonClassMembers) { generateBridges(); } @@ -182,7 +195,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen getPrimaryConstructorParameters() { + public List getPrimaryConstructorParameters() { if (myClass instanceof KtClass) { return myClass.getPrimaryConstructorParameters(); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index dcdcbca488e..7c0a3b0858a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -516,7 +516,8 @@ public abstract class MemberCodegen().apply { c.syntheticResolveExtension.addSyntheticSupertypes(thisDescriptor, this) } private val unsubstitutedMemberScope = LazyClassMemberScope(c, SyntheticClassMemberDeclarationProvider(syntheticDeclaration), this, c.trace) - private val unsubstitutedPrimaryConstructor = createUnsubstitutedPrimaryConstructor() + private val unsubstitutedPrimaryConstructor = createUnsubstitutedPrimaryConstructor(constructorVisibility) override val annotations: Annotations get() = Annotations.EMPTY @@ -104,8 +105,9 @@ class SyntheticClassOrObjectDescriptor( override fun toString(): String = "synthetic class " + name.toString() + " in " + containingDeclaration - private fun createUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor { + private fun createUnsubstitutedPrimaryConstructor(constructorVisibility: Visibility): ClassConstructorDescriptor { val constructor = DescriptorFactory.createPrimaryConstructorForObject(thisDescriptor, source) + constructor.visibility = constructorVisibility constructor.returnType = getDefaultType() return constructor } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt index fd4ec1e3e95..96727f8616e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt @@ -22,6 +22,8 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.lazy.LazyClassContext +import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import java.util.* @@ -37,38 +39,56 @@ interface SyntheticResolveExtension { if (instances.size == 1) return instances.single() // return list combiner here return object : SyntheticResolveExtension { + override fun getSyntheticNestedClassNames(thisDescriptor: ClassDescriptor): List = + instances.flatMap { it.getSyntheticNestedClassNames(thisDescriptor) } + + override fun generateSyntheticClasses(thisDescriptor: ClassDescriptor, name: Name, + ctx: LazyClassContext, declarationProvider: ClassMemberDeclarationProvider, + result: MutableSet) = + instances.forEach { it.generateSyntheticClasses(thisDescriptor, name, ctx, declarationProvider, result) } + override fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? = - instances.firstNotNullResult { it.getSyntheticCompanionObjectNameIfNeeded(thisDescriptor) } + instances.firstNotNullResult { it.getSyntheticCompanionObjectNameIfNeeded(thisDescriptor) } override fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList) = - instances.forEach { it.addSyntheticSupertypes(thisDescriptor, supertypes) } + instances.forEach { it.addSyntheticSupertypes(thisDescriptor, supertypes) } // todo revert override fun generateSyntheticMethods(thisDescriptor: ClassDescriptor, name: Name, fromSupertypes: List, result: MutableCollection) = - instances.forEach { it.generateSyntheticMethods(thisDescriptor, name, fromSupertypes, result) } + instances.forEach { it.generateSyntheticMethods(thisDescriptor, name, fromSupertypes, result) } override fun generateSyntheticProperties(thisDescriptor: ClassDescriptor, name: Name, fromSupertypes: ArrayList, - result: MutableSet) = - instances.forEach { it.generateSyntheticProperties(thisDescriptor, name, fromSupertypes, result) } + result: MutableSet) = + instances.forEach { it.generateSyntheticProperties(thisDescriptor, name, fromSupertypes, result) } } } } - fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? + fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? = null + + fun getSyntheticNestedClassNames(thisDescriptor: ClassDescriptor): List = emptyList() fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList) {} + fun generateSyntheticClasses(thisDescriptor: ClassDescriptor, + name: Name, + ctx: LazyClassContext, + declarationProvider: ClassMemberDeclarationProvider, + result: MutableSet) { + } + fun generateSyntheticMethods(thisDescriptor: ClassDescriptor, name: Name, fromSupertypes: List, - result: MutableCollection) {} + result: MutableCollection) { + } fun generateSyntheticProperties(thisDescriptor: ClassDescriptor, name: Name, - fromSupertypes: - ArrayList, - result: MutableSet) {} + fromSupertypes: ArrayList, + result: MutableSet) { + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 7590744da29..0d25178a0f2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -60,6 +60,7 @@ import java.util.Collections; import java.util.List; import static kotlin.collections.CollectionsKt.firstOrNull; +import static org.jetbrains.kotlin.descriptors.Visibilities.PRIVATE; import static org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC; import static org.jetbrains.kotlin.diagnostics.Errors.*; import static org.jetbrains.kotlin.resolve.BindingContext.TYPE; @@ -424,7 +425,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes /* parentClassOrObject= */ classOrObject, this, syntheticCompanionName, getSource(), /* outerScope= */ getOuterScope(), - Modality.FINAL, PUBLIC, ClassKind.OBJECT, true); + Modality.FINAL, PUBLIC, PRIVATE, ClassKind.OBJECT, true); } @Nullable diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt index 3a618bfca7d..0ae1f8099be 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt @@ -32,7 +32,6 @@ import org.jetbrains.kotlin.incremental.record import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtTypeReference import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.lazy.LazyClassContext @@ -42,7 +41,6 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.NotNullLazyValue import org.jetbrains.kotlin.storage.NullableLazyValue -import org.jetbrains.kotlin.types.DeferredType import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -83,6 +81,7 @@ open class LazyClassMemberScope( addDataClassMethods(result, location) addSyntheticCompanionObject(result, location) + addSyntheticNestedClasses(result, location) result.trimToSize() return result @@ -131,6 +130,7 @@ open class LazyClassMemberScope( override fun getNonDeclaredClasses(name: Name, result: MutableSet) { generateSyntheticCompanionObject(name, result) + c.syntheticResolveExtension.generateSyntheticClasses(thisDescriptor, name, c, declarationProvider, result) } override fun getNonDeclaredFunctions(name: Name, result: MutableSet) { @@ -220,6 +220,10 @@ open class LazyClassMemberScope( result.add(descriptor) } + private fun addSyntheticNestedClasses(result: MutableCollection, location: LookupLocation) { + result.addAll(c.syntheticResolveExtension.getSyntheticNestedClassNames(thisDescriptor).mapNotNull { getContributedClassifier(it, location) }.toList()) + } + private fun generateSyntheticCompanionObject(name: Name, result: MutableSet) { val syntheticCompanionName = c.syntheticResolveExtension.getSyntheticCompanionObjectNameIfNeeded(thisDescriptor) ?: return if (name == syntheticCompanionName && result.none { it.isCompanionObject }) {