Always use class file as inline fun source

This commit is contained in:
Alexey Tsvetkov
2015-08-13 16:30:46 +03:00
parent f9fe01047d
commit 8cc2e0f68d
5 changed files with 76 additions and 81 deletions
@@ -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;
}
}
@@ -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
}
}
}
@@ -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
}
public class FileSourceElement(public val file: File) : SourceElement
@@ -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))
}
@@ -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()