Report error on generating calls to binary incompatible classes
This commit is contained in:
+3
-1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.signature
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||
@@ -26,7 +27,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper
|
||||
|
||||
class KotlinToJvmSignatureMapperImpl : KotlinToJvmSignatureMapper {
|
||||
// We use empty BindingContext, because it is only used by JetTypeMapper for purposes irrelevant to the needs of this class
|
||||
private val typeMapper: JetTypeMapper = JetTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider, null, JvmAbi.DEFAULT_MODULE_NAME)
|
||||
private val typeMapper = JetTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider, null,
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME)
|
||||
|
||||
override fun mapToJvmMethodSignature(function: FunctionDescriptor) = typeMapper.mapSignature(function)
|
||||
}
|
||||
|
||||
+2
-1
@@ -51,7 +51,8 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
) : SignatureCollectingClassBuilderFactory(builderFactory) {
|
||||
|
||||
// Avoid errors when some classes are not loaded for some reason
|
||||
private val typeMapper = JetTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, incrementalCache, moduleName)
|
||||
private val typeMapper = JetTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, incrementalCache,
|
||||
IncompatibleClassTracker.DoNothing, moduleName)
|
||||
private val reportDiagnosticsTasks = ArrayList<() -> Unit>()
|
||||
|
||||
fun reportDiagnostics() {
|
||||
|
||||
@@ -95,7 +95,7 @@ class GenerationState @JvmOverloads constructor(
|
||||
incrementalCompilationComponents.getIncrementalCache(targetId)
|
||||
else null
|
||||
|
||||
private val extraJvmDiagnosticsTrace: BindingTrace = DelegatingBindingTrace(bindingContext, false, "For extra diagnostics in ${this.javaClass}")
|
||||
val extraJvmDiagnosticsTrace: BindingTrace = DelegatingBindingTrace(bindingContext, false, "For extra diagnostics in ${this.javaClass}")
|
||||
private val interceptedBuilderFactory: ClassBuilderFactory
|
||||
private var used = false
|
||||
|
||||
@@ -109,7 +109,10 @@ class GenerationState @JvmOverloads constructor(
|
||||
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
|
||||
val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState")
|
||||
val bindingContext: BindingContext = bindingTrace.bindingContext
|
||||
val typeMapper: JetTypeMapper = JetTypeMapper(this.bindingContext, classBuilderMode, fileClassesProvider, getIncrementalCacheForThisTarget(), this.moduleName)
|
||||
val typeMapper: JetTypeMapper = JetTypeMapper(
|
||||
this.bindingContext, classBuilderMode, fileClassesProvider, getIncrementalCacheForThisTarget(),
|
||||
IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace), this.moduleName
|
||||
)
|
||||
val intrinsics: IntrinsicMethods = IntrinsicMethods()
|
||||
val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
|
||||
val inlineCycleReporter: InlineCycleReporter = InlineCycleReporter(diagnostics)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.state
|
||||
|
||||
import org.jetbrains.kotlin.load.java.components.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.util.slicedMap.Slices
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
|
||||
|
||||
interface IncompatibleClassTracker {
|
||||
fun record(binaryClass: KotlinJvmBinaryClass)
|
||||
|
||||
object DoNothing : IncompatibleClassTracker {
|
||||
override fun record(binaryClass: KotlinJvmBinaryClass) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IncompatibleClassTrackerImpl(val trace: BindingTrace) : IncompatibleClassTracker {
|
||||
private val classes = linkedSetOf<String>()
|
||||
|
||||
override fun record(binaryClass: KotlinJvmBinaryClass) {
|
||||
if (classes.add(binaryClass.location)) {
|
||||
val errorData = IncompatibleVersionErrorData(binaryClass.classHeader.bytecodeVersion, binaryClass.location, binaryClass.classId)
|
||||
trace.record(BYTECODE_VERSION_ERRORS, binaryClass.location, errorData)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val BYTECODE_VERSION_ERRORS: WritableSlice<String, IncompatibleVersionErrorData> = Slices.createCollectiveSlice()
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen.state;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.Pair;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment;
|
||||
@@ -38,10 +38,15 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
|
||||
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment;
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass;
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement;
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
|
||||
import org.jetbrains.kotlin.name.*;
|
||||
@@ -66,6 +71,7 @@ import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -90,6 +96,7 @@ public class JetTypeMapper {
|
||||
private final ClassBuilderMode classBuilderMode;
|
||||
private final JvmFileClassesProvider fileClassesProvider;
|
||||
private final IncrementalCache incrementalCache;
|
||||
private final IncompatibleClassTracker incompatibleClassTracker;
|
||||
private final String moduleName;
|
||||
|
||||
public JetTypeMapper(
|
||||
@@ -97,12 +104,14 @@ public class JetTypeMapper {
|
||||
@NotNull ClassBuilderMode classBuilderMode,
|
||||
@NotNull JvmFileClassesProvider fileClassesProvider,
|
||||
@Nullable IncrementalCache incrementalCache,
|
||||
@NotNull IncompatibleClassTracker incompatibleClassTracker,
|
||||
@NotNull String moduleName
|
||||
) {
|
||||
this.bindingContext = bindingContext;
|
||||
this.classBuilderMode = classBuilderMode;
|
||||
this.fileClassesProvider = fileClassesProvider;
|
||||
this.incrementalCache = incrementalCache;
|
||||
this.incompatibleClassTracker = incompatibleClassTracker;
|
||||
this.moduleName = moduleName;
|
||||
}
|
||||
|
||||
@@ -978,12 +987,17 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind,
|
||||
List<ValueParameterDescriptor> valueParameters) {
|
||||
public JvmMethodSignature mapSignature(
|
||||
@NotNull FunctionDescriptor f,
|
||||
@NotNull OwnerKind kind,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters
|
||||
) {
|
||||
if (f instanceof FunctionImportedFromObject) {
|
||||
return mapSignature(((FunctionImportedFromObject) f).getCallableFromObject());
|
||||
}
|
||||
|
||||
checkOwnerCompatibility(f);
|
||||
|
||||
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
|
||||
|
||||
if (f instanceof ConstructorDescriptor) {
|
||||
@@ -1036,6 +1050,33 @@ public class JetTypeMapper {
|
||||
return signature;
|
||||
}
|
||||
|
||||
private void checkOwnerCompatibility(@NotNull FunctionDescriptor descriptor) {
|
||||
if (!(descriptor instanceof DeserializedCallableMemberDescriptor)) return;
|
||||
|
||||
KotlinJvmBinaryClass ownerClass = null;
|
||||
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (container instanceof DeserializedClassDescriptor) {
|
||||
SourceElement source = ((DeserializedClassDescriptor) container).getSource();
|
||||
if (source instanceof KotlinJvmBinarySourceElement) {
|
||||
ownerClass = ((KotlinJvmBinarySourceElement) source).getBinaryClass();
|
||||
}
|
||||
}
|
||||
else if (container instanceof LazyJavaPackageFragment) {
|
||||
SourceElement source = ((LazyJavaPackageFragment) container).getSource();
|
||||
if (source instanceof KotlinJvmBinaryPackageSourceElement) {
|
||||
ownerClass = ((KotlinJvmBinaryPackageSourceElement) source).getRepresentativeBinaryClass();
|
||||
}
|
||||
}
|
||||
|
||||
if (ownerClass != null) {
|
||||
JvmBytecodeBinaryVersion version = ownerClass.getClassHeader().getBytecodeVersion();
|
||||
if (!version.isCompatible()) {
|
||||
incompatibleClassTracker.record(ownerClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean writeCustomParameter(
|
||||
@NotNull FunctionDescriptor f,
|
||||
@NotNull ValueParameterDescriptor parameter,
|
||||
|
||||
Reference in New Issue
Block a user