From 8cc2e0f68d60f5619564f80c8d9e8488834bf60f Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Thu, 13 Aug 2015 16:30:46 +0300 Subject: [PATCH] Always use class file as inline fun source --- .../kotlin/codegen/inline/InlineCodegen.java | 64 ++----------------- .../codegen/inline/inlineCodegenUtils.kt | 53 +++++++++++++++ .../kotlin/incremental/FileSourceElement.kt | 5 +- .../IncrementalPackageFragmentProvider.kt | 5 +- .../jps/incremental/IncrementalCacheImpl.kt | 30 ++++----- 5 files changed, 76 insertions(+), 81 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index e672196be55..bfdcba9c013 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -30,11 +30,7 @@ import org.jetbrains.kotlin.codegen.context.PackageContext; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass; -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement; import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; -import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass; -import org.jetbrains.kotlin.load.kotlin.incremental.FileSourceElement; import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents; import org.jetbrains.kotlin.load.kotlin.incremental.components.InlineRegistering; @@ -52,7 +48,6 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; -import org.jetbrains.kotlin.resolve.source.PsiSourceElement; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor; import org.jetbrains.kotlin.types.expressions.LabelResolver; import org.jetbrains.org.objectweb.asm.Label; @@ -73,6 +68,8 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLASS_FOR_SCRIPT; import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker; import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getConstant; +import static org.jetbrains.kotlin.codegen.inline.InlinePackage.getClassFilePath; +import static org.jetbrains.kotlin.codegen.inline.InlinePackage.getSourceFilePath; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionLiteral; import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCallWithAssert; @@ -755,64 +752,13 @@ public class InlineCodegen extends CallGenerator { if (incrementalCompilationComponents == null || target == null) return; - String sourceFile = getFilePath(sourceDescriptor); - String targetFile = getFilePath(targetDescriptor); - - if (sourceFile == null) { - DeclarationDescriptor containingDeclaration = sourceDescriptor.getContainingDeclaration(); - - if (containingDeclaration instanceof DeclarationDescriptorWithSource) { - DeclarationDescriptorWithSource withSource = (DeclarationDescriptorWithSource) containingDeclaration; - sourceFile = getFilePath(withSource); - } - } - + IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(target); + String sourceFile = getClassFilePath(sourceDescriptor, incrementalCache); + String targetFile = getSourceFilePath(targetDescriptor); assert sourceFile != null: "No source file for inline fun: " + jvmSignature; assert targetFile != null: "No target file for inline fun: " + jvmSignature; - IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(target); InlineRegistering inlineRegistering = incrementalCache.getInlineRegistering(); inlineRegistering.registerInline(sourceFile, jvmSignature.toString(), targetFile); } - - @Nullable - private static String getFilePath(@NotNull DeclarationDescriptorWithSource descriptor) { - SourceElement source = descriptor.getSource(); - - if (source instanceof FileSourceElement) { - return ((FileSourceElement) source).getPath(); - } - - VirtualFile file = null; - - if (source instanceof PsiSourceElement) { - file = getFile((PsiSourceElement) source); - } - else if (source instanceof KotlinJvmBinarySourceElement) { - file = getFile((KotlinJvmBinarySourceElement) source); - } - - if (file == null) return null; - - return file.getCanonicalPath(); - } - - @Nullable - private static VirtualFile getFile(@NotNull PsiSourceElement sourceElement) { - PsiElement psi = sourceElement.getPsi(); - if (psi == null) return null; - - return psi.getContainingFile().getVirtualFile(); - } - - @Nullable - private static VirtualFile getFile(@NotNull KotlinJvmBinarySourceElement sourceElement) { - KotlinJvmBinaryClass binaryClass = sourceElement.getBinaryClass(); - if (binaryClass instanceof VirtualFileKotlinClass) { - return ((VirtualFileKotlinClass) binaryClass).getFile(); - } - - return null; - } - } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt new file mode 100644 index 00000000000..3c46cfe2a06 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt @@ -0,0 +1,53 @@ +/* + * 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 org.jetbrains.kotlin.codegen.inline + +import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement +import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass +import org.jetbrains.kotlin.load.kotlin.incremental.FileSourceElement +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache +import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import org.jetbrains.kotlin.resolve.source.PsiSourceElement + +public val FunctionDescriptor.sourceFilePath: String? + get() { + val source = source as? PsiSourceElement + val containingFile = source?.psi?.containingFile + return containingFile?.virtualFile?.canonicalPath + } + +public fun FunctionDescriptor.getClassFilePath(cache: IncrementalCache): String? { + val container = containingDeclaration as? DeclarationDescriptorWithSource + val source = container?.source + + return when (source) { + is FileSourceElement -> + source.file.canonicalPath + is KotlinJvmBinarySourceElement -> { + val kotlinClass = source.binaryClass as? VirtualFileKotlinClass + kotlinClass?.file?.canonicalPath + } + else -> { + val classId = InlineCodegenUtil.getContainerClassId(this) + val className = classId?.let { JvmClassName.byClassId(it) }?.internalName + + if (className != null) cache.getClassFilePath(className) else null + } + } +} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/FileSourceElement.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/FileSourceElement.kt index 4615a269c3a..cc3140dba3b 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/FileSourceElement.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/FileSourceElement.kt @@ -19,7 +19,4 @@ package org.jetbrains.kotlin.load.kotlin.incremental import org.jetbrains.kotlin.descriptors.SourceElement import java.io.File -public class FileSourceElement(private val file: File) : SourceElement { - public val path: String - get() = file.canonicalPath -} \ No newline at end of file +public class FileSourceElement(public val file: File) : SourceElement \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt index 21abff3dd7d..c7a19dd98b7 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt @@ -102,8 +102,9 @@ public class IncrementalPackageFragmentProvider( private val sourceElement: SourceElement by lazy { val incrementalCache = this@IncrementalPackageFragmentProvider.incrementalCache - val packageClassName = PackageClassUtils.getPackageClassName(fqName) - val classFilePath = incrementalCache.getClassFilePath(packageClassName) + val classId = PackageClassUtils.getPackageClassId(fqName) + val className = JvmClassName.byClassId(classId) + val classFilePath = incrementalCache.getClassFilePath(className.internalName) FileSourceElement(File(classFilePath)) } 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 a2718bf2b42..d6cfe82cb32 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt @@ -184,27 +184,25 @@ public class IncrementalCacheImpl( val result = THashSet(FileUtil.PATH_HASHING_STRATEGY) for ((className, functions) in dirtyInlineFunctionsMap.getEntries()) { - val sourceFiles = classToSourcesMap[className] - - for (sourceFile in sourceFiles) { - val targetFiles = functions.flatMap { hasInlineTo[sourceFile, it] } - result.addAll(targetFiles) - } - - var internalName = className.internalName - - if (packagePartMap.isPackagePart(className)) { - val packageInternalName = PackageClassUtils.getPackageClassInternalName(className.packageFqName) - val packageJvmName = JvmClassName.byInternalName(packageInternalName) - internalName = packageJvmName.internalName - } + val internalName = + if (packagePartMap.isPackagePart(className)) { + val packageInternalName = PackageClassUtils.getPackageClassInternalName(className.packageFqName) + val packageJvmName = JvmClassName.byInternalName(packageInternalName) + packageJvmName.internalName + } + else { + className.internalName + } val classFilePath = getClassFilePath(internalName) - for (dependent in dependents) { - val targetFiles = functions.flatMap { dependent.hasInlineTo[classFilePath, it] } + fun addFilesAffectedByChangedInlineFuns(cache: IncrementalCacheImpl) { + val targetFiles = functions.flatMap { cache.hasInlineTo[classFilePath, it] } result.addAll(targetFiles) } + + addFilesAffectedByChangedInlineFuns(this) + dependents.forEach(::addFilesAffectedByChangedInlineFuns) } dirtyInlineFunctionsMap.clean()