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
This commit is contained in:
committed by
Roman Elizarov
parent
9e6b706a03
commit
527ccaff16
@@ -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<KtPureClassOrObject
|
||||
genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) companionObjectDescriptor);
|
||||
}
|
||||
|
||||
// Generate synthetic nested classes
|
||||
Collection<DeclarationDescriptor> 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<KtPureClassOrObject
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected List<KtParameter> getPrimaryConstructorParameters() {
|
||||
public List<KtParameter> getPrimaryConstructorParameters() {
|
||||
if (myClass instanceof KtClass) {
|
||||
return myClass.getPrimaryConstructorParameters();
|
||||
}
|
||||
|
||||
@@ -516,7 +516,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
public void beforeMethodBody(@NotNull MethodVisitor mv) {
|
||||
}
|
||||
|
||||
private void initializeProperty(@NotNull ExpressionCodegen codegen, @NotNull KtProperty property) {
|
||||
// Requires public access, because it is used by serialization plugin to generate initializer in synthetic constructor
|
||||
public void initializeProperty(@NotNull ExpressionCodegen codegen, @NotNull KtProperty property) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
||||
assert propertyDescriptor != null;
|
||||
|
||||
@@ -541,7 +542,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
propValue.store(delegateValue, codegen.v);
|
||||
}
|
||||
|
||||
protected boolean shouldInitializeProperty(@NotNull KtProperty property) {
|
||||
// Public accessible for serialization plugin to check whether call to initializeProperty(..) is legal.
|
||||
public boolean shouldInitializeProperty(@NotNull KtProperty property) {
|
||||
if (!property.hasDelegateExpressionOrInitializer()) return false;
|
||||
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
||||
|
||||
+4
-2
@@ -53,6 +53,7 @@ class SyntheticClassOrObjectDescriptor(
|
||||
outerScope: LexicalScope,
|
||||
private val modality: Modality,
|
||||
private val visibility: Visibility,
|
||||
constructorVisibility: Visibility,
|
||||
private val kind: ClassKind,
|
||||
private val isCompanionObject: Boolean
|
||||
) : ClassDescriptorBase(c.storageManager, containingDeclaration, name, source, false), ClassDescriptorWithResolutionScopes {
|
||||
@@ -63,7 +64,7 @@ class SyntheticClassOrObjectDescriptor(
|
||||
private val resolutionScopesSupport = ClassResolutionScopesSupport(thisDescriptor, c.storageManager, { outerScope })
|
||||
private val syntheticSupertypes = mutableListOf<KotlinType>().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
|
||||
}
|
||||
|
||||
+30
-10
@@ -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<Name> =
|
||||
instances.flatMap { it.getSyntheticNestedClassNames(thisDescriptor) }
|
||||
|
||||
override fun generateSyntheticClasses(thisDescriptor: ClassDescriptor, name: Name,
|
||||
ctx: LazyClassContext, declarationProvider: ClassMemberDeclarationProvider,
|
||||
result: MutableSet<ClassDescriptor>) =
|
||||
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<KotlinType>) =
|
||||
instances.forEach { it.addSyntheticSupertypes(thisDescriptor, supertypes) }
|
||||
instances.forEach { it.addSyntheticSupertypes(thisDescriptor, supertypes) }
|
||||
|
||||
// todo revert
|
||||
override fun generateSyntheticMethods(thisDescriptor: ClassDescriptor, name: Name,
|
||||
fromSupertypes: List<SimpleFunctionDescriptor>,
|
||||
result: MutableCollection<SimpleFunctionDescriptor>) =
|
||||
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<PropertyDescriptor>,
|
||||
result: MutableSet<PropertyDescriptor>) =
|
||||
instances.forEach { it.generateSyntheticProperties(thisDescriptor, name, fromSupertypes, result) }
|
||||
result: MutableSet<PropertyDescriptor>) =
|
||||
instances.forEach { it.generateSyntheticProperties(thisDescriptor, name, fromSupertypes, result) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name?
|
||||
fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? = null
|
||||
|
||||
fun getSyntheticNestedClassNames(thisDescriptor: ClassDescriptor): List<Name> = emptyList()
|
||||
|
||||
fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {}
|
||||
|
||||
fun generateSyntheticClasses(thisDescriptor: ClassDescriptor,
|
||||
name: Name,
|
||||
ctx: LazyClassContext,
|
||||
declarationProvider: ClassMemberDeclarationProvider,
|
||||
result: MutableSet<ClassDescriptor>) {
|
||||
}
|
||||
|
||||
fun generateSyntheticMethods(thisDescriptor: ClassDescriptor,
|
||||
name: Name,
|
||||
fromSupertypes: List<SimpleFunctionDescriptor>,
|
||||
result: MutableCollection<SimpleFunctionDescriptor>) {}
|
||||
result: MutableCollection<SimpleFunctionDescriptor>) {
|
||||
}
|
||||
|
||||
fun generateSyntheticProperties(thisDescriptor: ClassDescriptor,
|
||||
name: Name,
|
||||
fromSupertypes:
|
||||
ArrayList<PropertyDescriptor>,
|
||||
result: MutableSet<PropertyDescriptor>) {}
|
||||
fromSupertypes: ArrayList<PropertyDescriptor>,
|
||||
result: MutableSet<PropertyDescriptor>) {
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+6
-2
@@ -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<ClassDescriptor>) {
|
||||
generateSyntheticCompanionObject(name, result)
|
||||
c.syntheticResolveExtension.generateSyntheticClasses(thisDescriptor, name, c, declarationProvider, result)
|
||||
}
|
||||
|
||||
override fun getNonDeclaredFunctions(name: Name, result: MutableSet<SimpleFunctionDescriptor>) {
|
||||
@@ -220,6 +220,10 @@ open class LazyClassMemberScope(
|
||||
result.add(descriptor)
|
||||
}
|
||||
|
||||
private fun addSyntheticNestedClasses(result: MutableCollection<DeclarationDescriptor>, location: LookupLocation) {
|
||||
result.addAll(c.syntheticResolveExtension.getSyntheticNestedClassNames(thisDescriptor).mapNotNull { getContributedClassifier(it, location) }.toList())
|
||||
}
|
||||
|
||||
private fun generateSyntheticCompanionObject(name: Name, result: MutableSet<ClassDescriptor>) {
|
||||
val syntheticCompanionName = c.syntheticResolveExtension.getSyntheticCompanionObjectNameIfNeeded(thisDescriptor) ?: return
|
||||
if (name == syntheticCompanionName && result.none { it.isCompanionObject }) {
|
||||
|
||||
Reference in New Issue
Block a user