Introduce JavaClassesSerializerExtension
It will be used to track java classes changes for incremental compilation #KT-17621 In Progress
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf
|
||||
|
||||
// It uses BuiltInSerializerProtocol for annotations serialization
|
||||
class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
|
||||
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
||||
super.serializeClass(descriptor, proto)
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateClass, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder) {
|
||||
super.serializeConstructor(descriptor, proto)
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateConstructor, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) {
|
||||
super.serializeFunction(descriptor, proto)
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateMethod, true)
|
||||
}
|
||||
|
||||
if (descriptor.dispatchReceiverParameter == null) {
|
||||
proto.setExtension(JavaClassProtoBuf.isStaticMethod, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
|
||||
super.serializeProperty(descriptor, proto)
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateField, true)
|
||||
}
|
||||
|
||||
if (descriptor.dispatchReceiverParameter == null) {
|
||||
proto.setExtension(JavaClassProtoBuf.isStaticField, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun shouldUseNormalizedVisibility() = true
|
||||
|
||||
override val customClassMembersProducer =
|
||||
object : ClassMembersProducer {
|
||||
override fun getCallableMembers(classDescriptor: ClassDescriptor) =
|
||||
arrayListOf<CallableMemberDescriptor>().apply {
|
||||
addAll(classDescriptor.unsubstitutedMemberScope.getSortedCallableDescriptors())
|
||||
addAll(classDescriptor.staticScope.getSortedCallableDescriptors())
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemberScope.getSortedCallableDescriptors(): Collection<CallableMemberDescriptor> =
|
||||
DescriptorUtils.getAllDescriptors(this).filterIsInstance<CallableMemberDescriptor>()
|
||||
.let { DescriptorSerializer.sort(it) }
|
||||
}
|
||||
+37
-26
@@ -71,7 +71,7 @@ class DescriptorSerializer private constructor(
|
||||
val builder = ProtoBuf.Class.newBuilder()
|
||||
|
||||
val flags = Flags.getClassFlags(
|
||||
hasAnnotations(classDescriptor), classDescriptor.visibility, classDescriptor.modality, classDescriptor.kind,
|
||||
hasAnnotations(classDescriptor), normalizeVisibility(classDescriptor), classDescriptor.modality, classDescriptor.kind,
|
||||
classDescriptor.isInner, classDescriptor.isCompanionObject, classDescriptor.isData, classDescriptor.isExternal,
|
||||
classDescriptor.isExpect
|
||||
)
|
||||
@@ -101,18 +101,24 @@ class DescriptorSerializer private constructor(
|
||||
builder.addConstructor(constructorProto(descriptor))
|
||||
}
|
||||
|
||||
for (descriptor in sort(DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope))) {
|
||||
if (descriptor is CallableMemberDescriptor) {
|
||||
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue
|
||||
val callableMembers =
|
||||
extension.customClassMembersProducer?.getCallableMembers(classDescriptor)
|
||||
?: sort(
|
||||
DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope)
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
)
|
||||
|
||||
when (descriptor) {
|
||||
is PropertyDescriptor -> builder.addProperty(propertyProto(descriptor))
|
||||
is FunctionDescriptor -> builder.addFunction(functionProto(descriptor))
|
||||
}
|
||||
for (descriptor in callableMembers) {
|
||||
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue
|
||||
|
||||
when (descriptor) {
|
||||
is PropertyDescriptor -> builder.addProperty(propertyProto(descriptor))
|
||||
is FunctionDescriptor -> builder.addFunction(functionProto(descriptor))
|
||||
}
|
||||
}
|
||||
|
||||
for (descriptor in sort(DescriptorUtils.getAllDescriptors(classDescriptor.unsubstitutedInnerClassesScope))) {
|
||||
val nestedClassifiers = sort(DescriptorUtils.getAllDescriptors(classDescriptor.unsubstitutedInnerClassesScope))
|
||||
for (descriptor in nestedClassifiers) {
|
||||
if (descriptor is TypeAliasDescriptor) {
|
||||
builder.addTypeAlias(typeAliasProto(descriptor))
|
||||
}
|
||||
@@ -168,7 +174,7 @@ class DescriptorSerializer private constructor(
|
||||
|
||||
val hasAnnotations = descriptor.annotations.getAllAnnotations().isNotEmpty()
|
||||
|
||||
val propertyFlags = Flags.getAccessorFlags(hasAnnotations, descriptor.visibility, descriptor.modality, false, false, false)
|
||||
val propertyFlags = Flags.getAccessorFlags(hasAnnotations, normalizeVisibility(descriptor), descriptor.modality, false, false, false)
|
||||
|
||||
val getter = descriptor.getter
|
||||
if (getter != null) {
|
||||
@@ -196,7 +202,7 @@ class DescriptorSerializer private constructor(
|
||||
}
|
||||
|
||||
val flags = Flags.getPropertyFlags(
|
||||
hasAnnotations, descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isVar,
|
||||
hasAnnotations, normalizeVisibility(descriptor), descriptor.modality, descriptor.kind, descriptor.isVar,
|
||||
hasGetter, hasSetter, hasConstant, descriptor.isConst, descriptor.isLateInit, descriptor.isExternal,
|
||||
@Suppress("DEPRECATION") descriptor.isDelegated, descriptor.isExpect
|
||||
)
|
||||
@@ -240,13 +246,20 @@ class DescriptorSerializer private constructor(
|
||||
return builder
|
||||
}
|
||||
|
||||
private fun normalizeVisibility(descriptor: DeclarationDescriptorWithVisibility) =
|
||||
// It can be necessary for Java classes serialization having package-private visibility
|
||||
if (extension.shouldUseNormalizedVisibility())
|
||||
descriptor.visibility.normalize()
|
||||
else
|
||||
descriptor.visibility
|
||||
|
||||
fun functionProto(descriptor: FunctionDescriptor): ProtoBuf.Function.Builder {
|
||||
val builder = ProtoBuf.Function.newBuilder()
|
||||
|
||||
val local = createChildSerializer(descriptor)
|
||||
|
||||
val flags = Flags.getFunctionFlags(
|
||||
hasAnnotations(descriptor), descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isOperator,
|
||||
hasAnnotations(descriptor), normalizeVisibility(descriptor), descriptor.modality, descriptor.kind, descriptor.isOperator,
|
||||
descriptor.isInfix, descriptor.isInline, descriptor.isTailrec, descriptor.isExternal, descriptor.isSuspend,
|
||||
descriptor.isExpect
|
||||
)
|
||||
@@ -308,7 +321,7 @@ class DescriptorSerializer private constructor(
|
||||
|
||||
val local = createChildSerializer(descriptor)
|
||||
|
||||
val flags = Flags.getConstructorFlags(hasAnnotations(descriptor), descriptor.visibility, !descriptor.isPrimary)
|
||||
val flags = Flags.getConstructorFlags(hasAnnotations(descriptor), normalizeVisibility(descriptor), !descriptor.isPrimary)
|
||||
if (flags != builder.flags) {
|
||||
builder.flags = flags
|
||||
}
|
||||
@@ -344,7 +357,7 @@ class DescriptorSerializer private constructor(
|
||||
val builder = ProtoBuf.TypeAlias.newBuilder()
|
||||
val local = createChildSerializer(descriptor)
|
||||
|
||||
val flags = Flags.getTypeAliasFlags(hasAnnotations(descriptor), descriptor.visibility)
|
||||
val flags = Flags.getTypeAliasFlags(hasAnnotations(descriptor), normalizeVisibility(descriptor))
|
||||
if (flags != builder.flags) {
|
||||
builder.flags = flags
|
||||
}
|
||||
@@ -664,7 +677,16 @@ class DescriptorSerializer private constructor(
|
||||
private fun getTypeParameterId(descriptor: TypeParameterDescriptor): Int =
|
||||
typeParameters.intern(descriptor)
|
||||
|
||||
|
||||
private fun getAccessorFlags(accessor: PropertyAccessorDescriptor): Int {
|
||||
return Flags.getAccessorFlags(
|
||||
hasAnnotations(accessor),
|
||||
normalizeVisibility(accessor),
|
||||
accessor.modality,
|
||||
!accessor.isDefault,
|
||||
accessor.isExternal,
|
||||
accessor.isInline
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@@ -704,17 +726,6 @@ class DescriptorSerializer private constructor(
|
||||
return serializer
|
||||
}
|
||||
|
||||
private fun getAccessorFlags(accessor: PropertyAccessorDescriptor): Int {
|
||||
return Flags.getAccessorFlags(
|
||||
hasAnnotations(accessor),
|
||||
accessor.visibility,
|
||||
accessor.modality,
|
||||
!accessor.isDefault,
|
||||
accessor.isExternal,
|
||||
accessor.isInline
|
||||
)
|
||||
}
|
||||
|
||||
private fun variance(variance: Variance): ProtoBuf.TypeParameter.Variance = when (variance) {
|
||||
Variance.INVARIANT -> ProtoBuf.TypeParameter.Variance.INV
|
||||
Variance.IN_VARIANCE -> ProtoBuf.TypeParameter.Variance.IN
|
||||
|
||||
@@ -27,6 +27,15 @@ abstract class SerializerExtension {
|
||||
val annotationSerializer by lazy { AnnotationSerializer(stringTable) }
|
||||
|
||||
open fun shouldUseTypeTable(): Boolean = false
|
||||
open fun shouldUseNormalizedVisibility(): Boolean = false
|
||||
|
||||
interface ClassMembersProducer {
|
||||
fun getCallableMembers(classDescriptor: ClassDescriptor): Collection<CallableMemberDescriptor>
|
||||
}
|
||||
|
||||
open val customClassMembersProducer: ClassMembersProducer?
|
||||
get() = null
|
||||
|
||||
|
||||
open fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user