From e050ff3271b35ed6261360d7788d2e85702cdad9 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 25 Aug 2015 17:37:01 +0300 Subject: [PATCH] Generate ex-package parts as file facades. Support new facade kind in stub building and incremental compilation. --- .../kotlin/codegen/PackagePartCodegen.java | 12 +++------ .../kotlin/load/java/JvmAnnotationNames.java | 1 + .../load/kotlin/header/KotlinClassHeader.kt | 2 ++ ...eadKotlinClassHeaderAnnotationVisitor.java | 11 +++++++- .../kotlin/jvm/internal/KotlinFileFacade.java | 27 +++++++++++++++++++ .../stubBuilder/KotlinClsStubBuilder.kt | 3 ++- .../idea/versions/KotlinAbiVersionIndex.kt | 3 ++- .../jps/incremental/IncrementalCacheImpl.kt | 2 ++ 8 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 core/runtime.jvm/src/kotlin/jvm/internal/KotlinFileFacade.java diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java index 97915126cbf..5452dcb2c96 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses; import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.ABI_VERSION_FIELD_NAME; import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass; import static org.jetbrains.org.objectweb.asm.Opcodes.*; @@ -111,14 +112,6 @@ public class PackagePartCodegen extends MemberCodegen { } } - AnnotationVisitor av = v.newAnnotation(Type.getObjectType(KotlinSyntheticClass.CLASS_NAME.getInternalName()).getDescriptor(), true); - av.visit(ABI_VERSION_FIELD_NAME, JvmAbi.VERSION); - av.visitEnum( - JvmAnnotationNames.KIND_FIELD_NAME, - Type.getObjectType(KotlinSyntheticClass.KIND_INTERNAL_NAME).getDescriptor(), - KotlinSyntheticClass.Kind.PACKAGE_PART.toString() - ); - JvmSerializationBindings bindings = v.getSerializationBindings(); DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(bindings, state.getTypeMapper())); @@ -140,7 +133,8 @@ public class PackagePartCodegen extends MemberCodegen { NameResolver nameResolver = new NameResolver(strings.serializeSimpleNames(), strings.serializeQualifiedNames()); PackageData data = new PackageData(nameResolver, packageProto); - + AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true); + av.visit(ABI_VERSION_FIELD_NAME, JvmAbi.VERSION); AnnotationVisitor array = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME); for (String string : BitEncoding.encodeBytes(SerializationUtil.serializePackageData(data))) { array.visit(null, string); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index 1a49df0d87c..76e6728c97f 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -30,6 +30,7 @@ import java.util.Set; public final class JvmAnnotationNames { public static final FqName KOTLIN_CLASS = KotlinClass.CLASS_NAME.getFqNameForClassNameWithoutDollars(); public static final FqName KOTLIN_PACKAGE = new FqName("kotlin.jvm.internal.KotlinPackage"); + public static final FqName KOTLIN_FILE_FACADE = new FqName("kotlin.jvm.internal.KotlinFileFacade"); public static final FqName KOTLIN_CALLABLE = new FqName("kotlin.jvm.internal.KotlinCallable"); public static final FqName KOTLIN_SIGNATURE = new FqName("kotlin.jvm.KotlinSignature"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/KotlinClassHeader.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/KotlinClassHeader.kt index 224359a8c41..ed45de67539 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/KotlinClassHeader.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/KotlinClassHeader.kt @@ -32,6 +32,7 @@ public class KotlinClassHeader( public enum class Kind { CLASS, PACKAGE_FACADE, + FILE_FACADE, SYNTHETIC_CLASS } @@ -44,4 +45,5 @@ public class KotlinClassHeader( public fun KotlinClassHeader.isCompatibleClassKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.CLASS public fun KotlinClassHeader.isCompatiblePackageFacadeKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.PACKAGE_FACADE +public fun KotlinClassHeader.isCompatibleFileFacadeKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.FILE_FACADE public fun KotlinClassHeader.isCompatibleSyntheticClassKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java index e4e16a6a476..b67a61cda86 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java @@ -41,6 +41,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor static { HEADER_KINDS.put(KotlinClass.CLASS_NAME, CLASS); HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE), PACKAGE_FACADE); + HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_FILE_FACADE), FILE_FACADE); HEADER_KINDS.put(KotlinSyntheticClass.CLASS_NAME, SYNTHETIC_CLASS); initOldAnnotations(); @@ -77,7 +78,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor return new KotlinClassHeader(headerKind, version, null, classKind, syntheticClassKind); } - if ((headerKind == CLASS || headerKind == PACKAGE_FACADE) && annotationData == null) { + if ((headerKind == CLASS || headerKind == PACKAGE_FACADE || headerKind == FILE_FACADE) && annotationData == null) { // This means that the annotation is found and its ABI version is compatible, but there's no "data" string array in it. // We tell the outside world that there's really no annotation at all return null; @@ -105,6 +106,8 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor return new ClassHeaderReader(); case PACKAGE_FACADE: return new PackageHeaderReader(); + case FILE_FACADE: + return new FileFacadeHeaderReader(); case SYNTHETIC_CLASS: return new SyntheticClassHeaderReader(); default: @@ -201,6 +204,12 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor } } + private class FileFacadeHeaderReader extends HeaderAnnotationArgumentVisitor { + public FileFacadeHeaderReader() { + super(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_FILE_FACADE)); + } + } + private class SyntheticClassHeaderReader extends HeaderAnnotationArgumentVisitor { public SyntheticClassHeaderReader() { super(KotlinSyntheticClass.CLASS_NAME); diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/KotlinFileFacade.java b/core/runtime.jvm/src/kotlin/jvm/internal/KotlinFileFacade.java new file mode 100644 index 00000000000..9b69edd5ab8 --- /dev/null +++ b/core/runtime.jvm/src/kotlin/jvm/internal/KotlinFileFacade.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2015 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 kotlin.jvm.internal; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface KotlinFileFacade { + int abiVersion(); + + String[] data(); +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt index 9328a2f2ef7..175804b9920 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind import org.jetbrains.kotlin.load.kotlin.header.isCompatibleSyntheticClassKind import org.jetbrains.kotlin.name.FqName @@ -75,7 +76,7 @@ public open class KotlinClsStubBuilder : ClsStubBuilder() { val context = components.createContext(classData.getNameResolver(), packageFqName) createTopLevelClassStub(classId, classData.getClassProto(), context) } - header.isCompatibleSyntheticClassKind() && header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART -> { + header.isCompatibleFileFacadeKind() -> { val packageData = JvmProtoBufUtil.readPackageDataFrom(annotationData) val context = components.createContext(packageData.getNameResolver(), packageFqName) createPackageFacadeFileStub(packageData.getPackageProto(), packageFqName, context) diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinAbiVersionIndex.kt b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinAbiVersionIndex.kt index 1224d265317..9667b009bf3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinAbiVersionIndex.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinAbiVersionIndex.kt @@ -44,7 +44,8 @@ public object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase() { inputData: FileContent -> diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt index ed13a80f55b..98d10853da4 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.PackageClassUtils import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.name.FqName @@ -169,6 +170,7 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen JvmAnnotationNames.KotlinClass.Kind.LOCAL_CLASS, JvmAnnotationNames.KotlinClass.Kind.ANONYMOUS_OBJECT -> DO_NOTHING } + header.isCompatibleFileFacadeKind() || header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART -> { assert(sourceFiles.size() == 1) { "Package part from several source files: $sourceFiles" }