mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-02 00:21:31 +00:00
Compare commits
1 Commits
rr/mb/code
...
rr/FIR/sem
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42d681b8d6 |
@@ -20,9 +20,11 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.mapToIndex
|
||||
|
||||
class ArgumentAndDeclIndex(val arg: ResolvedValueArgument, val declIndex: Int)
|
||||
@@ -68,8 +70,12 @@ abstract class ArgumentGenerator {
|
||||
generateExpression(declIndex, argument)
|
||||
}
|
||||
is DefaultValueArgument -> {
|
||||
defaultArgs.mark(declIndex)
|
||||
generateDefault(declIndex, argument)
|
||||
if (calleeDescriptor?.defaultValueFromJava(declIndex) == true) {
|
||||
generateDefaultJava(declIndex, argument)
|
||||
} else {
|
||||
defaultArgs.mark(declIndex)
|
||||
generateDefault(declIndex, argument)
|
||||
}
|
||||
}
|
||||
is VarargValueArgument -> {
|
||||
generateVararg(declIndex, argument)
|
||||
@@ -97,6 +103,10 @@ abstract class ArgumentGenerator {
|
||||
throw UnsupportedOperationException("Unsupported vararg value argument #$i: $argument")
|
||||
}
|
||||
|
||||
protected open fun generateDefaultJava(i: Int, argument: DefaultValueArgument) {
|
||||
throw UnsupportedOperationException("Unsupported default java argument #$i: $argument")
|
||||
}
|
||||
|
||||
protected open fun generateOther(i: Int, argument: ResolvedValueArgument) {
|
||||
throw UnsupportedOperationException("Unsupported value argument #$i: $argument")
|
||||
}
|
||||
@@ -106,6 +116,28 @@ abstract class ArgumentGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private fun CallableDescriptor.defaultValueFromJava(index: Int): Boolean = DFS.ifAny(
|
||||
listOf(this),
|
||||
{ current -> current.original.overriddenDescriptors.map { it.original } },
|
||||
{ descriptor ->
|
||||
descriptor.original.overriddenDescriptors.isEmpty() &&
|
||||
descriptor is JavaCallableMemberDescriptor &&
|
||||
descriptor.valueParameters[index].declaresDefaultValue()
|
||||
}
|
||||
)
|
||||
|
||||
fun shouldInvokeDefaultArgumentsStub(resolvedCall: ResolvedCall<*>): Boolean {
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
val valueArgumentsByIndex = resolvedCall.valueArgumentsByIndex ?: return false
|
||||
for (index in valueArgumentsByIndex.indices) {
|
||||
val resolvedValueArgument = valueArgumentsByIndex[index]
|
||||
if (resolvedValueArgument is DefaultValueArgument && !descriptor.defaultValueFromJava(index)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getFunctionWithDefaultArguments(functionDescriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
if (functionDescriptor.containingDeclaration !is ClassDescriptor) return functionDescriptor
|
||||
if (functionDescriptor.overriddenDescriptors.isEmpty()) return functionDescriptor
|
||||
@@ -123,4 +155,4 @@ fun getFunctionWithDefaultArguments(functionDescriptor: FunctionDescriptor): Fun
|
||||
function.valueParameters.any { valueParameter -> valueParameter.hasDefaultValue() }
|
||||
}
|
||||
?: functionDescriptor
|
||||
}
|
||||
}
|
||||
@@ -72,6 +72,12 @@ class CallBasedArgumentGenerator(
|
||||
callGenerator.putValueIfNeeded(getJvmKotlinType(i), lazyVararg, ValueKind.GENERAL_VARARG, i)
|
||||
}
|
||||
|
||||
override fun generateDefaultJava(i: Int, argument: DefaultValueArgument) {
|
||||
val argumentValue = valueParameters[i].findJavaDefaultArgumentValue(valueParameterTypes[i], codegen.typeMapper)
|
||||
|
||||
callGenerator.putValueIfNeeded(getJvmKotlinType(i), argumentValue)
|
||||
}
|
||||
|
||||
override fun reorderArgumentsIfNeeded(args: List<ArgumentAndDeclIndex>) {
|
||||
callGenerator.reorderArgumentsIfNeeded(args, valueParameterTypes)
|
||||
}
|
||||
|
||||
@@ -74,10 +74,7 @@ import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluatorKt;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmConstantsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.resolve.jvm.*;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
@@ -2693,7 +2690,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Callable resolveToCallable(@NotNull FunctionDescriptor fd, boolean superCall, @NotNull ResolvedCall<?> resolvedCall) {
|
||||
Callable resolveToCallable(@NotNull FunctionDescriptor fd, boolean superCall, @NotNull ResolvedCall resolvedCall) {
|
||||
IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(fd);
|
||||
if (intrinsic != null) {
|
||||
return intrinsic.toCallable(fd, superCall, resolvedCall, this);
|
||||
@@ -2701,8 +2698,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
fd = SamCodegenUtil.resolveSamAdapter(fd);
|
||||
|
||||
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
|
||||
if (valueArguments != null && valueArguments.stream().anyMatch(it -> it instanceof DefaultValueArgument)) {
|
||||
if (ArgumentGeneratorKt.shouldInvokeDefaultArgumentsStub(resolvedCall)) {
|
||||
// When we invoke a function with some arguments mapped as defaults,
|
||||
// we later reroute this call to an overridden function in a base class that processes the default arguments.
|
||||
// If the base class is generic, this overridden function can have a different Kotlin signature
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.annotations.ThrowUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
@@ -1105,7 +1105,7 @@ public class FunctionCodegen {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(ThrowUtilKt.JVM_THROWS_ANNOTATION_FQ_NAME);
|
||||
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(AnnotationUtilKt.JVM_THROWS_ANNOTATION_FQ_NAME);
|
||||
if (annotation == null) return Collections.emptyList();
|
||||
|
||||
Collection<ConstantValue<?>> values = annotation.getAllValueArguments().values();
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
internal class ObjectSuperCallArgumentGenerator(
|
||||
@@ -64,6 +65,12 @@ internal class ObjectSuperCallArgumentGenerator(
|
||||
pushDefaultValueOnStack(type, iv)
|
||||
}
|
||||
|
||||
public override fun generateDefaultJava(i: Int, argument: DefaultValueArgument) {
|
||||
val type = parameters[i].asmType
|
||||
val value = superValueParameters[i].findJavaDefaultArgumentValue(type, typeMapper)
|
||||
value.put(type, iv)
|
||||
}
|
||||
|
||||
public override fun generateVararg(i: Int, argument: VarargValueArgument) {
|
||||
generateSuperCallArgument(i)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.unboxPrimitiveTypeOrNull
|
||||
import org.jetbrains.kotlin.codegen.StackValue.*
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.Constant
|
||||
import org.jetbrains.kotlin.load.java.EnumEntry
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.getDefaultValueFromAnnotation
|
||||
import org.jetbrains.kotlin.load.java.lexicalCastFrom
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
@@ -75,3 +86,40 @@ class FunctionCallStackValue(
|
||||
resultKotlinType: KotlinType?,
|
||||
lambda: (v: InstructionAdapter) -> Unit
|
||||
) : OperationStackValue(resultType, resultKotlinType, lambda)
|
||||
|
||||
fun ValueParameterDescriptor.findJavaDefaultArgumentValue(targetType: Type, typeMapper: KotlinTypeMapper): StackValue {
|
||||
val descriptorWithDefaultValue = DFS.dfs(
|
||||
listOf(this.original),
|
||||
{ it.original.overriddenDescriptors.map(ValueParameterDescriptor::getOriginal) },
|
||||
object : DFS.AbstractNodeHandler<ValueParameterDescriptor, ValueParameterDescriptor?>() {
|
||||
var result: ValueParameterDescriptor? = null
|
||||
|
||||
override fun beforeChildren(current: ValueParameterDescriptor?): Boolean {
|
||||
if (current?.declaresDefaultValue() == true && current.getDefaultValueFromAnnotation() != null) {
|
||||
result = current
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun result(): ValueParameterDescriptor? = result
|
||||
}
|
||||
) ?: error("Should be at least one descriptor with default value: $this")
|
||||
|
||||
val defaultValue = descriptorWithDefaultValue.getDefaultValueFromAnnotation()
|
||||
if (defaultValue is NullDefaultValue) {
|
||||
return constant(null, targetType)
|
||||
}
|
||||
|
||||
val value = (defaultValue as StringDefaultValue).value
|
||||
val castResult = type.lexicalCastFrom(value) ?: error("Should be checked in frontend")
|
||||
|
||||
return when (castResult) {
|
||||
is EnumEntry -> enumEntry(castResult.descriptor, typeMapper)
|
||||
is Constant -> {
|
||||
val unboxedType = unboxPrimitiveTypeOrNull(targetType) ?: targetType
|
||||
return coercion(constant(castResult.value, unboxedType), targetType, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,29 +462,6 @@ class AnonymousObjectTransformer(
|
||||
val indexToFunctionalArgument = transformationInfo.functionalArguments
|
||||
val capturedParams = HashSet<Int>()
|
||||
|
||||
// Possible cases where we need to add each lambda's captures separately:
|
||||
//
|
||||
// 1. Top-level object in an inline lambda that is *not* being inlined into another object. In this case, we
|
||||
// have no choice but to add a separate field for each captured variable. `capturedLambdas` is either empty
|
||||
// (already have the fields) or contains the parent lambda object (captures used to be read from it, but
|
||||
// the object will be removed and its contents inlined).
|
||||
//
|
||||
// 2. Top-level object in a named inline function. Again, there's no option but to add separate fields.
|
||||
// `capturedLambdas` contains all lambdas used by this object and nested objects.
|
||||
//
|
||||
// 3. Nested object, either in an inline lambda or an inline function. This case has two subcases:
|
||||
// * The object's captures are passed as separate arguments (e.g. KT-28064 style object that used to be in a lambda);
|
||||
// we *could* group them into `this$0` now, but choose not to. Lambdas are replaced by their captures to match.
|
||||
// * The object's captures are already grouped into `this$0`; this includes captured lambda parameters (for objects in
|
||||
// inline functions) and a reference to the outer object or lambda (for objects in lambdas), so `capturedLambdas` is
|
||||
// empty anyway.
|
||||
//
|
||||
// The only remaining case is a top-level object inside a (crossinline) lambda that is inlined into another object.
|
||||
// Then, the reference to the soon-to-be-removed lambda class containing the captures (and it exists, or else the object
|
||||
// would not have needed regeneration in the first place) is simply replaced with a reference to the outer object, and
|
||||
// that object will contain loose fields for everything we need to capture.
|
||||
val topLevelInCrossinlineLambda = parentFieldRemapper is InlinedLambdaRemapper && !parentFieldRemapper.parent!!.isRoot
|
||||
|
||||
//load captured parameters and patch instruction list
|
||||
// NB: there is also could be object fields
|
||||
val toDelete = arrayListOf<AbstractInsnNode>()
|
||||
@@ -493,12 +470,10 @@ class AnonymousObjectTransformer(
|
||||
val parameterAload = fieldNode.previous as VarInsnNode
|
||||
val varIndex = parameterAload.`var`
|
||||
val functionalArgument = indexToFunctionalArgument[varIndex]
|
||||
// If an outer `this` is already captured by this object, rename it if any inline lambda will capture
|
||||
// one of the same type, causing the code below to create a clash. Note that the values can be different.
|
||||
// TODO: this is only really necessary if there will be a name *and* type clash.
|
||||
val shouldRename = !topLevelInCrossinlineLambda && isThis0(fieldName) &&
|
||||
indexToFunctionalArgument.values.any { it is LambdaInfo && it.capturedVars.any { it.fieldName == fieldName } }
|
||||
val newFieldName = if (shouldRename) addUniqueField(fieldName + INLINE_FUN_THIS_0_SUFFIX) else fieldName
|
||||
val newFieldName = if (isThis0(fieldName) && shouldRenameThis0(parentFieldRemapper, indexToFunctionalArgument.values))
|
||||
getNewFieldName(fieldName, true)
|
||||
else
|
||||
fieldName
|
||||
val info = capturedParamBuilder.addCapturedParam(
|
||||
Type.getObjectType(transformationInfo.oldClassName), fieldName, newFieldName,
|
||||
Type.getType(fieldNode.desc), functionalArgument is LambdaInfo, null
|
||||
@@ -533,17 +508,35 @@ class AnonymousObjectTransformer(
|
||||
//For all inlined lambdas add their captured parameters
|
||||
//TODO: some of such parameters could be skipped - we should perform additional analysis
|
||||
val allRecapturedParameters = ArrayList<CapturedParamDesc>()
|
||||
if (!topLevelInCrossinlineLambda) {
|
||||
val capturedOuterThisTypes = mutableSetOf<String>()
|
||||
if (parentFieldRemapper !is InlinedLambdaRemapper || parentFieldRemapper.parent!!.isRoot) {
|
||||
// Possible cases:
|
||||
//
|
||||
// 1. Top-level object in an inline lambda that is *not* being inlined into another object. In this case, we
|
||||
// have no choice but to add a separate field for each captured variable. `capturedLambdas` is either empty
|
||||
// (already have the fields) or contains the parent lambda object (captures used to be read from it, but
|
||||
// the object will be removed and its contents inlined).
|
||||
//
|
||||
// 2. Top-level object in a named inline function. Again, there's no option but to add separate fields.
|
||||
// `capturedLambdas` contains all lambdas used by this object and nested objects.
|
||||
//
|
||||
// 3. Nested object, either in an inline lambda or an inline function. This case has two subcases:
|
||||
// * The object's captures are passed as separate arguments (e.g. KT-28064 style object that used to be in a lambda);
|
||||
// we could group them into `this$0` now, but choose not to. Lambdas are replaced by their captures.
|
||||
// * The object's captures are already grouped into `this$0`; this includes captured lambda parameters (for objects in
|
||||
// inline functions) and a reference to the outer object or lambda (for objects in lambdas), so `capturedLambdas` is
|
||||
// empty and the choice doesn't matter.
|
||||
//
|
||||
val alreadyAdded = HashMap<String, CapturedParamInfo>()
|
||||
for (info in capturedLambdas) {
|
||||
for (desc in info.capturedVars) {
|
||||
// Merge all outer `this` of the same type captured by inlined lambdas, since they have to be the same
|
||||
// object. Outer `this` captured by the original object itself should have been renamed above,
|
||||
// and can have a different value even if the same type is captured by a lambda.
|
||||
val recapturedParamInfo = if (isThis0(desc.fieldName))
|
||||
capturedParamBuilder.addCapturedParam(desc, desc.fieldName, !capturedOuterThisTypes.add(desc.type.className))
|
||||
else
|
||||
capturedParamBuilder.addCapturedParam(desc, addUniqueField(desc.fieldName + INLINE_TRANSFORMATION_SUFFIX), false)
|
||||
val key = desc.fieldName + "$$$" + desc.type.className
|
||||
val alreadyAddedParam = alreadyAdded[key]
|
||||
|
||||
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(
|
||||
desc,
|
||||
alreadyAddedParam?.newFieldName ?: getNewFieldName(desc.fieldName, false),
|
||||
alreadyAddedParam != null
|
||||
)
|
||||
if (info is ExpressionLambda && info.isCapturedSuspend(desc)) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
}
|
||||
@@ -558,6 +551,10 @@ class AnonymousObjectTransformer(
|
||||
allRecapturedParameters.add(desc)
|
||||
|
||||
constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.newFieldName).remapValue = composed
|
||||
|
||||
if (isThis0(desc.fieldName)) {
|
||||
alreadyAdded.put(key, recapturedParamInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (capturedLambdas.isNotEmpty()) {
|
||||
@@ -582,6 +579,24 @@ class AnonymousObjectTransformer(
|
||||
return constructorAdditionalFakeParams
|
||||
}
|
||||
|
||||
private fun shouldRenameThis0(parentFieldRemapper: FieldRemapper, values: Collection<FunctionalArgument>): Boolean {
|
||||
return if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) {
|
||||
values.any { it is LambdaInfo && it.capturedVars.any { isThis0(it.fieldName) } }
|
||||
} else false
|
||||
}
|
||||
|
||||
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
||||
if (AsmUtil.CAPTURED_THIS_FIELD == oldName) {
|
||||
return if (!originalField) {
|
||||
oldName
|
||||
} else {
|
||||
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
|
||||
addUniqueField(oldName + INLINE_FUN_THIS_0_SUFFIX)
|
||||
}
|
||||
}
|
||||
return addUniqueField(oldName + INLINE_TRANSFORMATION_SUFFIX)
|
||||
}
|
||||
|
||||
private fun addUniqueField(name: String): String {
|
||||
val existNames = fieldNames.getOrPut(name) { LinkedList() }
|
||||
val suffix = if (existNames.isEmpty()) "" else "$" + existNames.size
|
||||
@@ -589,4 +604,7 @@ class AnonymousObjectTransformer(
|
||||
existNames.add(newName)
|
||||
return newName
|
||||
}
|
||||
|
||||
private fun isFirstDeclSiteLambdaFieldRemapper(parentRemapper: FieldRemapper): Boolean =
|
||||
parentRemapper !is RegeneratedLambdaFieldRemapper && parentRemapper !is InlinedLambdaRemapper
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ class GenerationState private constructor(
|
||||
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
||||
val runtimeStringConcat =
|
||||
if (target.majorVersion >= JvmTarget.JVM_9.majorVersion)
|
||||
configuration.get(JVMConfigurationKeys.STRING_CONCAT) ?: JvmStringConcat.INDY_WITH_CONSTANTS
|
||||
configuration.get(JVMConfigurationKeys.STRING_CONCAT) ?: JvmStringConcat.INLINE
|
||||
else JvmStringConcat.INLINE
|
||||
|
||||
val samConversionsScheme = run {
|
||||
|
||||
@@ -114,14 +114,6 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var doNotClearBindingContext: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xparallel-backend-threads",
|
||||
description = "When using the IR backend, run lowerings by file in N parallel threads.\n" +
|
||||
"0 means use a thread per processor core.\n" +
|
||||
"Default value is 1"
|
||||
)
|
||||
var parallelBackendThreads: String by FreezableVar("1")
|
||||
|
||||
@Argument(value = "-Xmodule-path", valueDescription = "<path>", description = "Paths where to find Java 9+ modules")
|
||||
var javaModulePath: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@@ -369,9 +361,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
description = """Select code generation scheme for string concatenation.
|
||||
-Xstring-concat=indy-with-constants Concatenate strings using `invokedynamic` `makeConcatWithConstants`. Requires `-jvm-target 9` or greater.
|
||||
-Xstring-concat=indy Concatenate strings using `invokedynamic` `makeConcat`. Requires `-jvm-target 9` or greater.
|
||||
-Xstring-concat=inline Concatenate strings using `StringBuilder`
|
||||
default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise"""
|
||||
|
||||
-Xstring-concat=inline Concatenate strings using `StringBuilder`"""
|
||||
)
|
||||
var stringConcat: String? by NullableStringFreezableVar(JvmStringConcat.INLINE.description)
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ fun buildKLib(
|
||||
configuration = configuration,
|
||||
allDependencies = allDependencies,
|
||||
friendDependencies = emptyList(),
|
||||
irFactory = PersistentIrFactory(), // TODO: IrFactoryImpl?
|
||||
irFactory = PersistentIrFactory,
|
||||
outputKlibPath = outputPath,
|
||||
nopack = true
|
||||
)
|
||||
|
||||
@@ -199,7 +199,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
configuration = config.configuration,
|
||||
allDependencies = resolvedLibraries,
|
||||
friendDependencies = friendDependencies,
|
||||
irFactory = PersistentIrFactory(), // TODO IrFactoryImpl?
|
||||
irFactory = PersistentIrFactory,
|
||||
outputKlibPath = outputFile.path,
|
||||
nopack = arguments.irProduceKlibDir
|
||||
)
|
||||
|
||||
@@ -291,10 +291,6 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
|
||||
}
|
||||
|
||||
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||
|
||||
val nThreadsRaw = arguments.parallelBackendThreads.toIntOrNull() ?: 1
|
||||
val nThreads = if (nThreadsRaw == 0) Runtime.getRuntime().availableProcessors() else nThreadsRaw
|
||||
put(CommonConfigurationKeys.PARALLEL_BACKEND_THREADS, nThreads)
|
||||
}
|
||||
|
||||
fun CompilerConfiguration.configureKlibPaths(arguments: K2JVMCompilerArguments) {
|
||||
|
||||
@@ -50,10 +50,6 @@ object CommonConfigurationKeys {
|
||||
|
||||
@JvmField
|
||||
val USE_FIR_EXTENDED_CHECKERS = CompilerConfigurationKey.create<Boolean>("fir extended checkers")
|
||||
|
||||
@JvmField
|
||||
val PARALLEL_BACKEND_THREADS =
|
||||
CompilerConfigurationKey.create<Int>("When using the IR backend, run lowerings by file in N parallel threads")
|
||||
}
|
||||
|
||||
var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
@@ -1484,6 +1484,24 @@ public class FirTypeEnhancementTestGenerated extends AbstractFirTypeEnhancementT
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadJava/compiledJava/signatureAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SignatureAnnotations extends AbstractFirTypeEnhancementTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSignatureAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/loadJava/compiledJava/signatureAnnotations"), Pattern.compile("^(.+)\\.java$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("StableName.java")
|
||||
public void testStableName() throws Exception {
|
||||
runTest("compiler/testData/loadJava/compiledJava/signatureAnnotations/StableName.java");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -132,4 +132,67 @@ public class OwnFirTypeEnhancementTestGenerated extends AbstractOwnFirTypeEnhanc
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/enhancement/mapping"), Pattern.compile("^(.+)\\.java$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SignatureAnnotations extends AbstractOwnFirTypeEnhancementTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSignatureAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations"), Pattern.compile("^(.+)\\.java$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultEnum.java")
|
||||
public void testDefaultEnum() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultLongLiteral.java")
|
||||
public void testDefaultLongLiteral() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultLongLiteral.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultNull.java")
|
||||
public void testDefaultNull() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultNull.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultNullAndParameter.java")
|
||||
public void testDefaultNullAndParameter() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultNullAndParameter.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultParameter.java")
|
||||
public void testDefaultParameter() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultParameter.java");
|
||||
}
|
||||
|
||||
@TestMetadata("EmptyParameterName.java")
|
||||
public void testEmptyParameterName() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/EmptyParameterName.java");
|
||||
}
|
||||
|
||||
@TestMetadata("ReorderedParameterNames.java")
|
||||
public void testReorderedParameterNames() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/ReorderedParameterNames.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SameParameterName.java")
|
||||
public void testSameParameterName() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/SameParameterName.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SpecialCharsParameterName.java")
|
||||
public void testSpecialCharsParameterName() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/SpecialCharsParameterName.java");
|
||||
}
|
||||
|
||||
@TestMetadata("StaticMethodWithDefaultValue.java")
|
||||
public void testStaticMethodWithDefaultValue() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/StaticMethodWithDefaultValue.java");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,9 @@ abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
|
||||
|
||||
private fun createEnvironment(content: String): KotlinCoreEnvironment {
|
||||
val classpath = mutableListOf(getAnnotationsJar(), ForTestCompileRuntime.runtimeJarForTests())
|
||||
if (InTextDirectivesUtils.isDirectiveDefined(content, "ANDROID_ANNOTATIONS")) {
|
||||
classpath.add(ForTestCompileRuntime.androidAnnotationsForTests())
|
||||
}
|
||||
if (InTextDirectivesUtils.isDirectiveDefined(content, "JVM_ANNOTATIONS")) {
|
||||
classpath.add(ForTestCompileRuntime.jvmAnnotationsForTests())
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
Most FIR enhancement tests use compiler/testData/loadJava/compiledJava
|
||||
Most FIR enhancement tests use compiler/testData/loadJava/compilerJava
|
||||
33
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.fir.txt
vendored
Normal file
33
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.fir.txt
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
public/*package*/ open class A : R|kotlin/Any| {
|
||||
public open fun a(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(HELLO)) arg: R|ft<@FlexibleNullability Signs, Signs?>!| = R|/Signs.HELLO|): R|ft<@FlexibleNullability Signs, Signs?>!|
|
||||
|
||||
public open fun bar(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(X)) arg: R|ft<@FlexibleNullability Signs, Signs?>!| = R|/Signs.X|): R|ft<@FlexibleNullability Signs, Signs?>!|
|
||||
|
||||
public open fun baz(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(NOT_ENTRY_EITHER)) arg: R|ft<@FlexibleNullability Signs, Signs?>!|): R|ft<@FlexibleNullability Signs, Signs?>!|
|
||||
|
||||
public open fun bam(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(NOT_ENTRY_EITHER)) arg: R|ft<@FlexibleNullability Mixed, Mixed?>!| = R|/Mixed.NOT_ENTRY_EITHER|): R|ft<@FlexibleNullability Mixed, Mixed?>!|
|
||||
|
||||
public/*package*/ constructor(): R|A|
|
||||
|
||||
}
|
||||
public final enum class Mixed : R|kotlin/Enum<ft<@FlexibleNullability Mixed, Mixed?>!>| {
|
||||
public final static enum entry NOT_ENTRY_EITHER: R|@FlexibleNullability Mixed|
|
||||
public final static fun values(): R|kotlin/Array<Mixed>| {
|
||||
}
|
||||
|
||||
public final static fun valueOf(value: R|kotlin/String|): R|Mixed| {
|
||||
}
|
||||
|
||||
}
|
||||
public final enum class Signs : R|kotlin/Enum<ft<@FlexibleNullability Signs, Signs?>!>| {
|
||||
public final static enum entry HELLO: R|@FlexibleNullability Signs|
|
||||
public final static enum entry WORLD: R|@FlexibleNullability Signs|
|
||||
public final static field X: R|ft<@FlexibleNullability Signs, Signs?>!|
|
||||
|
||||
public final static fun values(): R|kotlin/Array<Signs>| {
|
||||
}
|
||||
|
||||
public final static fun valueOf(value: R|kotlin/String|): R|Signs| {
|
||||
}
|
||||
|
||||
}
|
||||
39
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.java
vendored
Normal file
39
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultEnum.java
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// FILE: Signs.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
public enum Signs {
|
||||
HELLO,
|
||||
WORLD;
|
||||
|
||||
public static final Signs X;
|
||||
public static final class NOT_ENTRY_EITHER {}
|
||||
}
|
||||
|
||||
// FILE: Mixed.java
|
||||
public enum Mixed {
|
||||
NOT_ENTRY_EITHER;
|
||||
|
||||
public static final class NOT_ENTRY_EITHER {}
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public Signs a(@DefaultValue("HELLO") Signs arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Signs bar(@DefaultValue("X") Signs arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Signs baz(@DefaultValue("NOT_ENTRY_EITHER") Signs arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Mixed bam(@DefaultValue("NOT_ENTRY_EITHER") Mixed arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
}
|
||||
24
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultLongLiteral.fir.txt
vendored
Normal file
24
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultLongLiteral.fir.txt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open fun first(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0x1F)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!| = Long(31)): R|kotlin/Unit|
|
||||
|
||||
public open fun second(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0X1F)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!| = Long(31)): R|kotlin/Unit|
|
||||
|
||||
public open fun third(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0b1010)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!| = Long(10)): R|kotlin/Unit|
|
||||
|
||||
public open fun fourth(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0B1010)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!| = Long(10)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public open class B : R|kotlin/Any| {
|
||||
public open fun first(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0x)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!|): R|kotlin/Unit|
|
||||
|
||||
public open fun second(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0xZZ)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!|): R|kotlin/Unit|
|
||||
|
||||
public open fun third(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0b)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!|): R|kotlin/Unit|
|
||||
|
||||
public open fun fourth(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0B1234)) value: R|ft<@FlexibleNullability kotlin/Long, kotlin/Long?>!|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|B|
|
||||
|
||||
}
|
||||
36
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultLongLiteral.java
vendored
Normal file
36
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultLongLiteral.java
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void first(@DefaultValue("0x1F") Long value) {
|
||||
}
|
||||
|
||||
public void second(@DefaultValue("0X1F") Long value) {
|
||||
}
|
||||
|
||||
public void third(@DefaultValue("0b1010") Long value) {
|
||||
}
|
||||
|
||||
public void fourth(@DefaultValue("0B1010") Long value) {
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class B {
|
||||
public void first(@DefaultValue("0x") Long value) {
|
||||
}
|
||||
|
||||
public void second(@DefaultValue("0xZZ") Long value) {
|
||||
}
|
||||
|
||||
public void third(@DefaultValue("0b") Long value) {
|
||||
}
|
||||
|
||||
public void fourth(@DefaultValue("0B1234") Long value) {
|
||||
}
|
||||
}
|
||||
|
||||
14
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultNull.fir.txt
vendored
Normal file
14
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultNull.fir.txt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open fun foo(@R|kotlin/annotations/jvm/internal/DefaultNull|() x: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open fun bar(@R|kotlin/annotations/jvm/internal/DefaultNull|() x: R|kotlin/Int| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public open class B<T : R|ft<kotlin/Any, kotlin/Any?>!|> : R|kotlin/Any| {
|
||||
public open fun foo(@R|kotlin/annotations/jvm/internal/DefaultNull|() t: R|ft<@FlexibleNullability T, T?>!| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public constructor<T : R|ft<kotlin/Any, kotlin/Any?>!|>(): R|B<T>|
|
||||
|
||||
}
|
||||
17
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultNull.java
vendored
Normal file
17
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultNull.java
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void foo(@DefaultNull Integer x) {}
|
||||
public void bar(@DefaultNull int x) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class B<T> {
|
||||
public void foo(@DefaultNull T t) { }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open fun foo(@R|kotlin/annotations/jvm/internal/DefaultNull|() i: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open fun bar(@R|kotlin/annotations/jvm/internal/DefaultNull|() a: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open fun bam(@R|kotlin/annotations/jvm/internal/DefaultNull|() a: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open fun baz(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public abstract interface AInt : R|kotlin/Any| {
|
||||
public abstract fun foo(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) i: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public abstract fun bar(@R|kotlin/annotations/jvm/internal/DefaultNull|() a: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open class B : R|A| {
|
||||
public open fun foo(i: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!|): R|kotlin/Unit|
|
||||
|
||||
public open fun bar(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public open fun bam(@R|kotlin/annotations/jvm/internal/DefaultNull|() @R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!| = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|B|
|
||||
|
||||
}
|
||||
public open class C : R|A|, R|AInt| {
|
||||
public constructor(): R|C|
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void foo(@DefaultNull Integer i) {}
|
||||
|
||||
public void bar(@DefaultNull Integer a) {}
|
||||
|
||||
public void bam(@DefaultNull Integer a) {}
|
||||
|
||||
public void baz(@DefaultValue("42") Integer a) {}
|
||||
}
|
||||
|
||||
// FILE: AInt.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public interface AInt {
|
||||
public void foo(@DefaultValue("42") Integer i) {}
|
||||
public void bar(@DefaultNull Integer a) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class B extends A {
|
||||
public void foo(Integer i) {}
|
||||
|
||||
public void bar(@DefaultValue("42") Integer a) {}
|
||||
|
||||
public void bam(@DefaultNull @DefaultValue("42") Integer a) {}
|
||||
}
|
||||
|
||||
// FILE: C.java
|
||||
public class C extends A implements AInt {
|
||||
}
|
||||
|
||||
14
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultParameter.fir.txt
vendored
Normal file
14
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultParameter.fir.txt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
public/*package*/ open class A : R|kotlin/Any| {
|
||||
public open fun first(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(hello)) value: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!| = String(hello)): R|kotlin/Unit|
|
||||
|
||||
public open fun second(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(first)) a: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!| = String(first), @R|kotlin/annotations/jvm/internal/DefaultValue|(String(second)) b: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!| = String(second)): R|kotlin/Unit|
|
||||
|
||||
public open fun third(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(first)) a: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!| = String(first), b: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|): R|kotlin/Unit|
|
||||
|
||||
public open fun fourth(first: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|, @R|kotlin/annotations/jvm/internal/DefaultValue|(String(second)) second: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!| = String(second)): R|kotlin/Unit|
|
||||
|
||||
public open fun wrong(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(hello)) i: R|ft<@FlexibleNullability kotlin/Int, kotlin/Int?>!|): R|kotlin/Unit|
|
||||
|
||||
public/*package*/ constructor(): R|A|
|
||||
|
||||
}
|
||||
23
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultParameter.java
vendored
Normal file
23
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/DefaultParameter.java
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public void first(@DefaultValue("hello") String value) {
|
||||
}
|
||||
|
||||
public void second(@DefaultValue("first") String a, @DefaultValue("second") String b) {
|
||||
}
|
||||
|
||||
public void third(@DefaultValue("first") String a, String b) {
|
||||
}
|
||||
|
||||
public void fourth(String first, @DefaultValue("second") String second) {
|
||||
}
|
||||
|
||||
public void wrong(@DefaultValue("hello") Integer i) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/EmptyParameterName.fir.txt
vendored
Normal file
10
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/EmptyParameterName.fir.txt
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
public/*package*/ open class A : R|kotlin/Any| {
|
||||
public open fun emptyName(@R|kotlin/annotations/jvm/internal/ParameterName|(String()) first: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|, @R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) second: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public open fun missingName(@R|kotlin/annotations/jvm/internal/ParameterName|() first: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|): R|kotlin/Unit|
|
||||
|
||||
public open fun numberName(@R|kotlin/annotations/jvm/internal/ParameterName|(Int(42)) first: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|): R|kotlin/Unit|
|
||||
|
||||
public/*package*/ constructor(): R|A|
|
||||
|
||||
}
|
||||
16
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/EmptyParameterName.java
vendored
Normal file
16
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/EmptyParameterName.java
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public void emptyName(@ParameterName("") String first, @ParameterName("ok") int second) {
|
||||
}
|
||||
|
||||
public void missingName(@ParameterName() String first) {
|
||||
}
|
||||
|
||||
public void numberName(@ParameterName(42) String first) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open fun connect(@R|kotlin/annotations/jvm/internal/ParameterName|(String(host)) host: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|, @R|kotlin/annotations/jvm/internal/ParameterName|(String(port)) port: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void connect(@ParameterName("host") String host, @ParameterName("port") int port) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open fun same(@R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) first: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|, @R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) second: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
10
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/SameParameterName.java
vendored
Normal file
10
compiler/fir/analysis-tests/testData/enhancement/signatureAnnotations/SameParameterName.java
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void same(@ParameterName("ok") String first, @ParameterName("ok") String second) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open fun dollarName(@R|kotlin/annotations/jvm/internal/ParameterName|(String($)) host: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|): R|kotlin/Unit|
|
||||
|
||||
public open fun numberName(@R|kotlin/annotations/jvm/internal/ParameterName|(String(42)) field: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
import kotlin.internal.*;
|
||||
|
||||
public class A {
|
||||
public void dollarName(@ParameterName("$") String host) {
|
||||
}
|
||||
|
||||
public void numberName(@ParameterName("42") String field) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
public/*package*/ open class A : R|kotlin/Any| {
|
||||
public open static fun withDefault(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(OK)) arg: R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!| = String(OK)): R|ft<@FlexibleNullability kotlin/String, kotlin/String?>!|
|
||||
|
||||
public/*package*/ constructor(): R|A|
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public static String withDefault(@DefaultValue("OK") String arg) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,36 +3,36 @@ object Delegate {
|
||||
operator fun setValue(instance: Any?, property: Any, value: String) {}
|
||||
}
|
||||
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var test: Int
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var kest by Delegate
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var test: Int<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var kest by Delegate<!>
|
||||
|
||||
lateinit var good: String
|
||||
|
||||
class A {
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> val fest = "10"
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit val fest = "10"<!>
|
||||
lateinit var mest: String
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var xest: String?
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var nest: Int
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var west: Char
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var qest: Boolean
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var aest: Short
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var hest: Byte
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var jest: Long
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> val dest: String
|
||||
get() = "KEKER"
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var xest: String?<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var nest: Int<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var west: Char<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var qest: Boolean<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var aest: Short<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var hest: Byte<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var jest: Long<!>
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit val dest: String
|
||||
get() = "KEKER"<!>
|
||||
}
|
||||
|
||||
class B<T> {
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var best: T
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var best: T<!>
|
||||
}
|
||||
|
||||
class C<K : Any> {
|
||||
lateinit var pest: K
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var vest: K?
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var vest: K?<!>
|
||||
}
|
||||
|
||||
fun rest() {
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var i: Int
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var i: Int<!>
|
||||
lateinit var a: A
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var b: B<String> = B()
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var b: B<String> = B()<!>
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class SomeClass : SomeInterface {
|
||||
get() = true
|
||||
set(value) {}
|
||||
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var fau: Double
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit var fau: Double<!>
|
||||
}
|
||||
|
||||
inline class InlineClass
|
||||
|
||||
@@ -16428,6 +16428,42 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/signatureAnnotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultEnum.kt")
|
||||
public void testDefaultEnum() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/defaultEnum.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultLongLiteral.kt")
|
||||
public void testDefaultLongLiteral() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/defaultLongLiteral.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultNull.kt")
|
||||
public void testDefaultNull() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/defaultNull.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultNullAndParameter.kt")
|
||||
public void testDefaultNullAndParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/defaultNullAndParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultParameter.kt")
|
||||
public void testDefaultParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/defaultParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("emptyParameterName.kt")
|
||||
public void testEmptyParameterName() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/emptyParameterName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullVarargOverride.kt")
|
||||
public void testNotNullVarargOverride() throws Exception {
|
||||
@@ -16439,6 +16475,48 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
public void testNullableVarargOverride() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/nullableVarargOverride.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overridesDefaultValue.kt")
|
||||
public void testOverridesDefaultValue() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/overridesDefaultValue.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overridesParameterName.kt")
|
||||
public void testOverridesParameterName() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/overridesParameterName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reorderedParameterNames.kt")
|
||||
public void testReorderedParameterNames() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/reorderedParameterNames.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sameParameterName.kt")
|
||||
public void testSameParameterName() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/sameParameterName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCharsParameterName.kt")
|
||||
public void testSpecialCharsParameterName() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/specialCharsParameterName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("stableParameterName.kt")
|
||||
public void testStableParameterName() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/stableParameterName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("staticMethodWithDefaultValue.kt")
|
||||
public void testStaticMethodWithDefaultValue() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/signatureAnnotations/staticMethodWithDefaultValue.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -24496,12 +24574,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/sealed/interfaces/inheritorInDifferentModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sealedFunInterface.kt")
|
||||
public void testSealedFunInterface() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/sealed/interfaces/sealedFunInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sealedInterfacesDisabled.kt")
|
||||
public void testSealedInterfacesDisabled() throws Exception {
|
||||
|
||||
@@ -15,6 +15,7 @@ data class DiagnosticData(
|
||||
val psiType: KType,
|
||||
val parameters: List<DiagnosticParameter>,
|
||||
val positioningStrategy: PositioningStrategy,
|
||||
val group: String?,
|
||||
)
|
||||
|
||||
data class DiagnosticParameter(
|
||||
@@ -41,7 +42,6 @@ enum class PositioningStrategy(private val strategy: String) {
|
||||
WHEN_EXPRESSION("WHEN_EXPRESSION"),
|
||||
IF_EXPRESSION("IF_EXPRESSION"),
|
||||
VARIANCE_MODIFIER("VARIANCE_MODIFIER"),
|
||||
LATEINIT_MODIFIER("LATEINIT_MODIFIER"),
|
||||
|
||||
;
|
||||
|
||||
@@ -54,4 +54,8 @@ enum class PositioningStrategy(private val strategy: String) {
|
||||
|
||||
|
||||
fun DiagnosticData.hasDefaultPositioningStrategy(): Boolean =
|
||||
positioningStrategy == PositioningStrategy.DEFAULT
|
||||
positioningStrategy == PositioningStrategy.DEFAULT
|
||||
|
||||
data class DiagnosticList(
|
||||
val diagnostics: List<DiagnosticData>,
|
||||
)
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import kotlin.properties.PropertyDelegateProvider
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
abstract class DiagnosticGroup @PrivateForInline constructor(val name: String) {
|
||||
@Suppress("PropertyName")
|
||||
@PrivateForInline
|
||||
val _diagnostics = mutableListOf<DiagnosticData>()
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
val diagnostics: List<DiagnosticData>
|
||||
get() = _diagnostics
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <reified E : FirSourceElement, reified P : PsiElement> error(
|
||||
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
|
||||
crossinline init: DiagnosticBuilder.() -> Unit = {}
|
||||
) = diagnosticDelegateProvider<E, P>(Severity.ERROR, positioningStrategy, init)
|
||||
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <reified E : FirSourceElement, reified P : PsiElement> warning(
|
||||
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
|
||||
crossinline init: DiagnosticBuilder.() -> Unit = {}
|
||||
) = diagnosticDelegateProvider<E, P>(Severity.WARNING, positioningStrategy, init)
|
||||
|
||||
@PrivateForInline
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
inline fun <reified E : FirSourceElement, reified P : PsiElement> diagnosticDelegateProvider(
|
||||
severity: Severity,
|
||||
positioningStrategy: PositioningStrategy,
|
||||
crossinline init: DiagnosticBuilder.() -> Unit = {}
|
||||
) = PropertyDelegateProvider<Any?, ReadOnlyProperty<DiagnosticGroup, DiagnosticData>> { _, property ->
|
||||
val diagnostic = DiagnosticBuilder(
|
||||
severity,
|
||||
name = property.name,
|
||||
sourceElementType = typeOf<E>(),
|
||||
psiType = typeOf<P>(),
|
||||
positioningStrategy,
|
||||
).apply(init).build()
|
||||
_diagnostics += diagnostic
|
||||
ReadOnlyProperty { _, _ -> diagnostic }
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
abstract class DiagnosticList {
|
||||
@Suppress("PropertyName")
|
||||
@PrivateForInline
|
||||
val _groups = mutableListOf<DiagnosticGroup>()
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
val groups: List<DiagnosticGroup>
|
||||
get() = _groups
|
||||
|
||||
val allDiagnostics: List<DiagnosticData>
|
||||
get() = groups.flatMap { it.diagnostics }
|
||||
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
operator fun DiagnosticGroup.provideDelegate(
|
||||
thisRef: DiagnosticList,
|
||||
prop: KProperty<*>
|
||||
): ReadOnlyProperty<DiagnosticList, DiagnosticGroup> {
|
||||
val group = this
|
||||
_groups += group
|
||||
return ReadOnlyProperty { _, _ -> group }
|
||||
}
|
||||
}
|
||||
|
||||
class DiagnosticBuilder(
|
||||
private val severity: Severity,
|
||||
private val name: String,
|
||||
private val sourceElementType: KType,
|
||||
private val psiType: KType,
|
||||
private val positioningStrategy: PositioningStrategy,
|
||||
) {
|
||||
@PrivateForInline
|
||||
val parameters = mutableListOf<DiagnosticParameter>()
|
||||
|
||||
@OptIn(PrivateForInline::class, ExperimentalStdlibApi::class)
|
||||
inline fun <reified T> parameter(name: String) {
|
||||
if (parameters.size == 3) {
|
||||
error("Diagnostic cannot have more than 3 parameters")
|
||||
}
|
||||
parameters += DiagnosticParameter(
|
||||
name = name,
|
||||
type = typeOf<T>()
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun build() = DiagnosticData(
|
||||
severity,
|
||||
name,
|
||||
sourceElementType,
|
||||
psiType,
|
||||
parameters,
|
||||
positioningStrategy,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import kotlin.properties.PropertyDelegateProvider
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
class DiagnosticListBuilder private constructor() {
|
||||
@PrivateForInline
|
||||
val diagnostics = mutableListOf<DiagnosticData>()
|
||||
|
||||
@PrivateForInline
|
||||
var currentGroupName: String? = null
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun group(groupName: String, inner: () -> Unit) {
|
||||
if (currentGroupName != null) {
|
||||
error("Groups can not be nested ")
|
||||
}
|
||||
currentGroupName = groupName
|
||||
inner()
|
||||
currentGroupName = null
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <reified E : FirSourceElement, reified P : PsiElement> error(
|
||||
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
|
||||
crossinline init: DiagnosticBuilder.() -> Unit = {}
|
||||
) = diagnosticDelegateProvider<E, P>(Severity.ERROR, positioningStrategy, init)
|
||||
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <reified E : FirSourceElement, reified P : PsiElement> warning(
|
||||
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
|
||||
crossinline init: DiagnosticBuilder.() -> Unit = {}
|
||||
) = diagnosticDelegateProvider<E, P>(Severity.WARNING, positioningStrategy, init)
|
||||
|
||||
@PrivateForInline
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
inline fun <reified E : FirSourceElement, reified P : PsiElement> diagnosticDelegateProvider(
|
||||
severity: Severity,
|
||||
positioningStrategy: PositioningStrategy,
|
||||
crossinline init: DiagnosticBuilder.() -> Unit = {}
|
||||
) = PropertyDelegateProvider<Any?, AlwaysReturningUnitPropertyDelegate> { _, property ->
|
||||
diagnostics += DiagnosticBuilder(
|
||||
severity,
|
||||
name = property.name,
|
||||
sourceElementType = typeOf<E>(),
|
||||
psiType = typeOf<P>(),
|
||||
positioningStrategy,
|
||||
group = currentGroupName,
|
||||
).apply(init).build()
|
||||
AlwaysReturningUnitPropertyDelegate
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
object AlwaysReturningUnitPropertyDelegate : ReadOnlyProperty<Any?, Unit> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>) = Unit
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
private fun build() = DiagnosticList(diagnostics)
|
||||
|
||||
companion object {
|
||||
fun buildDiagnosticList(init: DiagnosticListBuilder.() -> Unit) =
|
||||
DiagnosticListBuilder().apply(init).build()
|
||||
}
|
||||
}
|
||||
|
||||
class DiagnosticBuilder(
|
||||
private val severity: Severity,
|
||||
private val name: String,
|
||||
private val sourceElementType: KType,
|
||||
private val psiType: KType,
|
||||
private val positioningStrategy: PositioningStrategy,
|
||||
private val group: String?
|
||||
) {
|
||||
@PrivateForInline
|
||||
val parameters = mutableListOf<DiagnosticParameter>()
|
||||
|
||||
@OptIn(PrivateForInline::class, ExperimentalStdlibApi::class)
|
||||
inline fun <reified T> parameter(name: String) {
|
||||
if (parameters.size == 3) {
|
||||
error("Diagnostic cannot have more than 3 parameters")
|
||||
}
|
||||
parameters += DiagnosticParameter(
|
||||
name = name,
|
||||
type = typeOf<T>()
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun build() = DiagnosticData(
|
||||
severity,
|
||||
name,
|
||||
sourceElementType,
|
||||
psiType,
|
||||
parameters,
|
||||
positioningStrategy,
|
||||
group
|
||||
)
|
||||
}
|
||||
@@ -33,18 +33,19 @@ object ErrorListDiagnosticListRenderer : DiagnosticListRenderer() {
|
||||
|
||||
private fun SmartPrinter.printErrorsObject(diagnosticList: DiagnosticList) {
|
||||
inBracketsWithIndent("object FirErrors") {
|
||||
for (group in diagnosticList.groups) {
|
||||
printDiagnosticGroup(group.name, group.diagnostics)
|
||||
val groups = diagnosticList.diagnostics.groupBy { it.group }
|
||||
for ((group, diagnostics) in groups) {
|
||||
printDiagnosticGroup(group, diagnostics)
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun SmartPrinter.printDiagnosticGroup(
|
||||
group: String,
|
||||
group: String?,
|
||||
diagnostics: List<DiagnosticData>
|
||||
) {
|
||||
println("// $group")
|
||||
println("// ${group ?: "NO GROUP"}")
|
||||
for (it in diagnostics) {
|
||||
printDiagnostic(it)
|
||||
}
|
||||
@@ -109,7 +110,7 @@ object ErrorListDiagnosticListRenderer : DiagnosticListRenderer() {
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun collectImports(diagnosticList: DiagnosticList): Collection<String> = buildSet {
|
||||
diagnosticList.allDiagnostics.forEach { diagnostic ->
|
||||
diagnosticList.diagnostics.forEach { diagnostic ->
|
||||
for (typeArgument in diagnostic.getAllTypeArguments()) {
|
||||
typeArgument.collectClassNamesTo(this)
|
||||
}
|
||||
|
||||
@@ -25,15 +25,15 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
@OptIn(PrivateForInline::class)
|
||||
object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val Miscellaneous by object : DiagnosticGroup("Miscellaneous") {
|
||||
val DIAGNOSTICS_LIST = DiagnosticListBuilder.buildDiagnosticList {
|
||||
group("Miscellaneous") {
|
||||
val SYNTAX by error<FirSourceElement, PsiElement>()
|
||||
val OTHER_ERROR by error<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
val GENERAL_SYNTAX by object : DiagnosticGroup("General syntax") {
|
||||
group("General syntax") {
|
||||
val ILLEGAL_CONST_EXPRESSION by error<FirSourceElement, PsiElement>()
|
||||
val ILLEGAL_UNDERSCORE by error<FirSourceElement, PsiElement>()
|
||||
val EXPRESSION_REQUIRED by error<FirSourceElement, PsiElement>()
|
||||
@@ -44,7 +44,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val DELEGATION_IN_INTERFACE by error<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
||||
group("Unresolved") {
|
||||
val HIDDEN by error<FirSourceElement, PsiElement> {
|
||||
parameter<AbstractFirBasedSymbol<*>>("hidden")
|
||||
}
|
||||
@@ -59,7 +59,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val NO_THIS by error<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
val SUPER by object : DiagnosticGroup("Super") {
|
||||
group("Super") {
|
||||
val SUPER_IS_NOT_AN_EXPRESSION by error<FirSourceElement, PsiElement>()
|
||||
val SUPER_NOT_AVAILABLE by error<FirSourceElement, PsiElement>()
|
||||
val ABSTRACT_SUPER_CALL by error<FirSourceElement, PsiElement>()
|
||||
@@ -68,7 +68,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
}
|
||||
|
||||
val SUPERTYPES by object : DiagnosticGroup("Supertypes") {
|
||||
group("Supertypes") {
|
||||
val TYPE_PARAMETER_AS_SUPERTYPE by error<FirSourceElement, PsiElement>()
|
||||
val ENUM_AS_SUPERTYPE by error<FirSourceElement, PsiElement>()
|
||||
val RECURSION_IN_SUPERTYPES by error<FirSourceElement, PsiElement>()
|
||||
@@ -84,7 +84,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
val CONSTRUCTOR_PROBLEMS by object : DiagnosticGroup("Constructor problems") {
|
||||
group(" Constructor problems") {
|
||||
val CONSTRUCTOR_IN_OBJECT by error<FirSourceElement, KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||
val CONSTRUCTOR_IN_INTERFACE by error<FirSourceElement, KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||
val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by error<FirSourceElement, PsiElement>()
|
||||
@@ -98,7 +98,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val SEALED_CLASS_CONSTRUCTOR_CALL by error<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
val ANNOTATIONS by object : DiagnosticGroup("Annotations") {
|
||||
group("Annotations") {
|
||||
val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error<FirSourceElement, KtExpression>()
|
||||
val ANNOTATION_ARGUMENT_MUST_BE_CONST by error<FirSourceElement, KtExpression>()
|
||||
val ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST by error<FirSourceElement, KtExpression>()
|
||||
@@ -116,7 +116,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val VAR_ANNOTATION_PARAMETER by error<FirSourceElement, KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE)
|
||||
}
|
||||
|
||||
val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") {
|
||||
group("Exposed visibility group") {
|
||||
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||
val EXPOSED_FUNCTION_RETURN_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||
|
||||
@@ -128,7 +128,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val EXPOSED_TYPE_PARAMETER_BOUND by exposedVisibilityError<KtTypeReference>()
|
||||
}
|
||||
|
||||
val MODIFIERS by object : DiagnosticGroup("Modifiers") {
|
||||
group("Modifiers") {
|
||||
val INAPPLICABLE_INFIX_MODIFIER by error<FirSourceElement, PsiElement>()
|
||||
val REPEATED_MODIFIER by error<FirSourceElement, PsiElement> {
|
||||
parameter<KtModifierKeywordToken>("modifier")
|
||||
@@ -148,7 +148,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val REDUNDANT_OPEN_IN_INTERFACE by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.OPEN_MODIFIER)
|
||||
}
|
||||
|
||||
val APPLICABILITY by object : DiagnosticGroup("Applicability") {
|
||||
group("Applicability") {
|
||||
val NONE_APPLICABLE by error<FirSourceElement, PsiElement> {
|
||||
parameter<Collection<AbstractFirBasedSymbol<*>>>("candidates")
|
||||
}
|
||||
@@ -156,12 +156,12 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val INAPPLICABLE_CANDIDATE by error<FirSourceElement, PsiElement> {
|
||||
parameter<AbstractFirBasedSymbol<*>>("candidate")
|
||||
}
|
||||
val INAPPLICABLE_LATEINIT_MODIFIER by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.LATEINIT_MODIFIER) {
|
||||
val INAPPLICABLE_LATEINIT_MODIFIER by error<FirSourceElement, PsiElement> {
|
||||
parameter<String>("reason")
|
||||
}
|
||||
}
|
||||
|
||||
val AMBIGUIRY by object : DiagnosticGroup("Ambiguity") {
|
||||
group("Ambiguity") {
|
||||
val AMBIGUITY by error<FirSourceElement, PsiElement> {
|
||||
parameter<Collection<AbstractFirBasedSymbol<*>>>("candidates")
|
||||
}
|
||||
@@ -170,7 +170,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
}
|
||||
|
||||
val TYPES_AND_TYPE_PARAMETERS by object : DiagnosticGroup("Types & type parameters") {
|
||||
group("Types & type parameters") {
|
||||
val TYPE_MISMATCH by error<FirSourceElement, PsiElement> {
|
||||
parameter<ConeKotlinType>("expectedType")
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
@@ -203,7 +203,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error<FirSourceElement, KtClassOrObject>(PositioningStrategy.DECLARATION_NAME)
|
||||
}
|
||||
|
||||
val OVERRIDES by object : DiagnosticGroup("overrides") {
|
||||
group("overrides") {
|
||||
val NOTHING_TO_OVERRIDE by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.OVERRIDE_MODIFIER) {
|
||||
parameter<FirMemberDeclaration>("declaration")
|
||||
}
|
||||
@@ -242,7 +242,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
}
|
||||
|
||||
val REDECLARATIONS by object : DiagnosticGroup("Redeclarations") {
|
||||
group("Redeclarations") {
|
||||
val MANY_COMPANION_OBJECTS by error<FirSourceElement, PsiElement>()
|
||||
val CONFLICTING_OVERLOADS by error<FirSourceElement, PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||
parameter<Collection<AbstractFirBasedSymbol<*>>>("conflictingOverloads")
|
||||
@@ -253,7 +253,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val ANY_METHOD_IMPLEMENTED_IN_INTERFACE by error<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
val INVALID_LOCAL_DECLARATIONS by object : DiagnosticGroup("Invalid local declarations") {
|
||||
group("Invalid local declarations") {
|
||||
val LOCAL_OBJECT_NOT_ALLOWED by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
|
||||
parameter<Name>("objectName")
|
||||
}
|
||||
@@ -262,7 +262,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
}
|
||||
|
||||
val FUNCTIONS by object : DiagnosticGroup("Functions") {
|
||||
group("Functions") {
|
||||
val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error<FirSourceElement, KtFunction>(PositioningStrategy.MODALITY_MODIFIER) {
|
||||
parameter<FirMemberDeclaration>("function")
|
||||
parameter<FirMemberDeclaration>("containingClass") // TODO use FirClass instead of FirMemberDeclaration
|
||||
@@ -288,7 +288,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val USELESS_VARARG_ON_PARAMETER by warning<FirSourceElement, KtParameter>()
|
||||
}
|
||||
|
||||
val PROPERTIES_ANS_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
|
||||
group("Properties & accessors") {
|
||||
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER) {
|
||||
parameter<FirMemberDeclaration>("property")
|
||||
parameter<FirMemberDeclaration>("containingClass") // TODO use FirClass instead of FirMemberDeclaration
|
||||
@@ -314,15 +314,14 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val EXPECTED_PRIVATE_DECLARATION by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
||||
}
|
||||
|
||||
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
|
||||
group("Multi-platform projects") {
|
||||
val EXPECTED_DECLARATION_WITH_BODY by error<FirSourceElement, KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||
val EXPECTED_PROPERTY_INITIALIZER by error<FirSourceElement, KtExpression>()
|
||||
|
||||
// TODO: need to cover `by` as well as delegate expression
|
||||
val EXPECTED_DELEGATED_PROPERTY by error<FirSourceElement, KtPropertyDelegate>()
|
||||
}
|
||||
|
||||
val DESTRUCTING_DECLARATION by object : DiagnosticGroup("Destructuring declaration") {
|
||||
group("Destructuring declaration") {
|
||||
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error<FirSourceElement, KtDestructuringDeclaration>()
|
||||
val COMPONENT_FUNCTION_MISSING by error<FirSourceElement, PsiElement> {
|
||||
parameter<Name>("missingFunctionName")
|
||||
@@ -340,7 +339,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
// TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ...
|
||||
}
|
||||
|
||||
val CONTROL_FLOW by object : DiagnosticGroup("Control flow diagnostics") {
|
||||
group("Control flow diagnostics") {
|
||||
val UNINITIALIZED_VARIABLE by error<FirSourceElement, PsiElement> {
|
||||
parameter<FirPropertySymbol>("variable")
|
||||
}
|
||||
@@ -355,7 +354,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val WRONG_IMPLIES_CONDITION by warning<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
val NULLABILITY by object : DiagnosticGroup("Nullability") {
|
||||
group("Nullability") {
|
||||
val UNSAFE_CALL by error<FirSourceElement, PsiElement>(PositioningStrategy.DOT_BY_SELECTOR) {
|
||||
parameter<ConeKotlinType>("receiverType")
|
||||
}
|
||||
@@ -375,20 +374,20 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
// TODO: val UNEXPECTED_SAFE_CALL by ...
|
||||
}
|
||||
|
||||
val WHNE_EXPRESSIONS by object : DiagnosticGroup("When expressions") {
|
||||
group("When expressions") {
|
||||
val NO_ELSE_IN_WHEN by error<FirSourceElement, KtWhenExpression>(PositioningStrategy.WHEN_EXPRESSION) {
|
||||
parameter<List<WhenMissingCase>>("missingWhenCases")
|
||||
}
|
||||
val INVALID_IF_AS_EXPRESSION by error<FirSourceElement, KtIfExpression>(PositioningStrategy.IF_EXPRESSION)
|
||||
}
|
||||
|
||||
val FUNCTION_CONTRACTS by object : DiagnosticGroup("Function contracts") {
|
||||
group("Function contracts") {
|
||||
val ERROR_IN_CONTRACT_DESCRIPTION by error<FirSourceElement, KtElement> {
|
||||
parameter<String>("reason")
|
||||
}
|
||||
}
|
||||
|
||||
val EXTENDED_CHECKERS by object : DiagnosticGroup("Extended checkers") {
|
||||
group("Extended checkers") {
|
||||
val REDUNDANT_VISIBILITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
||||
val REDUNDANT_MODALITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER)
|
||||
val REDUNDANT_RETURN_UNIT_TYPE by warning<FirSourceElement, PsiTypeElement>()
|
||||
@@ -408,7 +407,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified P : PsiElement> DiagnosticGroup.exposedVisibilityError(
|
||||
private inline fun <reified P : PsiElement> DiagnosticListBuilder.exposedVisibilityError(
|
||||
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT
|
||||
) = error<FirSourceElement, P>(positioningStrategy) {
|
||||
parameter<FirEffectiveVisibility>("elementVisibility")
|
||||
|
||||
@@ -91,7 +91,7 @@ object FirErrors {
|
||||
val SEALED_SUPERTYPE by error0<FirSourceElement, PsiElement>()
|
||||
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0<FirSourceElement, PsiElement>()
|
||||
|
||||
// Constructor problems
|
||||
// Constructor problems
|
||||
val CONSTRUCTOR_IN_OBJECT by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||
val CONSTRUCTOR_IN_INTERFACE by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||
val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by error0<FirSourceElement, PsiElement>()
|
||||
@@ -119,7 +119,7 @@ object FirErrors {
|
||||
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error0<FirSourceElement, KtTypeReference>()
|
||||
val VAR_ANNOTATION_PARAMETER by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
|
||||
// Exposed visibility
|
||||
// Exposed visibility group
|
||||
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val EXPOSED_FUNCTION_RETURN_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val EXPOSED_RECEIVER_TYPE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
|
||||
@@ -140,7 +140,7 @@ object FirErrors {
|
||||
// Applicability
|
||||
val NONE_APPLICABLE by error1<FirSourceElement, PsiElement, Collection<AbstractFirBasedSymbol<*>>>()
|
||||
val INAPPLICABLE_CANDIDATE by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>()
|
||||
val INAPPLICABLE_LATEINIT_MODIFIER by error1<FirSourceElement, KtModifierListOwner, String>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||
val INAPPLICABLE_LATEINIT_MODIFIER by error1<FirSourceElement, PsiElement, String>()
|
||||
|
||||
// Ambiguity
|
||||
val AMBIGUITY by error1<FirSourceElement, PsiElement, Collection<AbstractFirBasedSymbol<*>>>()
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.analysis.cfa
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
@@ -16,12 +15,9 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph
|
||||
|
||||
class FirControlFlowAnalyzer(
|
||||
session: FirSession,
|
||||
declarationCheckers: DeclarationCheckers = session.checkersComponent.declarationCheckers
|
||||
) {
|
||||
private val cfaCheckers = declarationCheckers.controlFlowAnalyserCheckers
|
||||
private val variableAssignmentCheckers = declarationCheckers.variableAssignmentCfaBasedCheckers
|
||||
class FirControlFlowAnalyzer(session: FirSession) {
|
||||
private val cfaCheckers = session.checkersComponent.declarationCheckers.controlFlowAnalyserCheckers
|
||||
private val variableAssignmentCheckers = session.checkersComponent.declarationCheckers.variableAssignmentCfaBasedCheckers
|
||||
|
||||
// Currently declaration in analyzeXXX is not used, but it may be useful in future
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.typeCheckerContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -317,4 +317,4 @@ val FirFunctionCall.isIterator
|
||||
internal fun throwableClassLikeType(session: FirSession) = session.builtinTypes.throwableType.type
|
||||
|
||||
fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession) =
|
||||
throwableClassLikeType(session).isSupertypeOf(session.typeContext, this.fullyExpandedType(session))
|
||||
throwableClassLikeType(session).isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session))
|
||||
|
||||
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.min
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirOverrideChecker : FirClassChecker() {
|
||||
override fun check(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
object FirOverrideChecker : FirRegularClassChecker() {
|
||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext(
|
||||
errorTypesEqualToAnything = false,
|
||||
stubTypesEqualToAnything = false
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.min
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -62,13 +63,18 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
parameterPairs.mapValues { it.value.coneType }
|
||||
)
|
||||
|
||||
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext(
|
||||
errorTypesEqualToAnything = false,
|
||||
stubTypesEqualToAnything = false
|
||||
)
|
||||
|
||||
parameterPairs.forEach { (proto, actual) ->
|
||||
if (actual.source == null) {
|
||||
// inferred types don't report INAPPLICABLE_CANDIDATE for type aliases!
|
||||
return@forEach
|
||||
}
|
||||
|
||||
if (!satisfiesBounds(proto, actual.coneType, substitutor, context.session.typeContext)) {
|
||||
if (!satisfiesBounds(proto, actual.coneType, substitutor, typeCheckerContext)) {
|
||||
reporter.reportOn(actual.source, proto, actual.coneType, context)
|
||||
return
|
||||
}
|
||||
@@ -76,7 +82,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
// we must analyze nested things like
|
||||
// S<S<K, L>, T<K, L>>()
|
||||
actual.coneType.safeAs<ConeClassLikeType>()?.let {
|
||||
val errorOccurred = analyzeTypeParameters(it, context, reporter, context.session.typeContext, actual.source)
|
||||
val errorOccurred = analyzeTypeParameters(it, context, reporter, typeCheckerContext, actual.source)
|
||||
|
||||
if (errorOccurred) {
|
||||
return
|
||||
@@ -93,14 +99,14 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
// typealias A<G> = B<List<G>>
|
||||
// val a = A<Int>()
|
||||
when (calleeFir) {
|
||||
is FirConstructor -> analyzeConstructorCall(expression, substitutor, context.session.typeContext, reporter, context)
|
||||
is FirConstructor -> analyzeConstructorCall(expression, substitutor, typeCheckerContext, reporter, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun analyzeConstructorCall(
|
||||
functionCall: FirQualifiedAccessExpression,
|
||||
callSiteSubstitutor: ConeSubstitutor,
|
||||
typeSystemContext: ConeTypeContext,
|
||||
typeCheckerContext: AbstractTypeCheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
context: CheckerContext
|
||||
) {
|
||||
@@ -151,7 +157,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
|
||||
constructorsParameterPairs.forEach { (proto, actual) ->
|
||||
// just in case
|
||||
var intersection = typeSystemContext.intersectTypes(
|
||||
var intersection = typeCheckerContext.intersectTypes(
|
||||
proto.fir.bounds.map { it.coneType }
|
||||
).safeAs<ConeKotlinType>() ?: return@forEach
|
||||
|
||||
@@ -161,7 +167,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
// substitute Int for G from
|
||||
// the example above
|
||||
val target = callSiteSubstitutor.substituteOrSelf(actual)
|
||||
val satisfiesBounds = AbstractTypeChecker.isSubtypeOf(typeSystemContext, target, intersection)
|
||||
val satisfiesBounds = AbstractTypeChecker.isSubtypeOf(typeCheckerContext, target, intersection)
|
||||
|
||||
if (!satisfiesBounds) {
|
||||
reporter.reportOn(functionCall.source, proto, actual, context)
|
||||
@@ -181,7 +187,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
type: ConeClassLikeType,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
typeSystemContext: ConeTypeContext,
|
||||
typeCheckerContext: AbstractTypeCheckerContext,
|
||||
reportTarget: FirSourceElement?
|
||||
): Boolean {
|
||||
val prototypeClass = type.lookupTag.toSymbol(context.session)
|
||||
@@ -212,13 +218,13 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
)
|
||||
|
||||
parameterPairs.forEach { (proto, actual) ->
|
||||
if (!satisfiesBounds(proto, actual.type, substitutor, typeSystemContext)) {
|
||||
if (!satisfiesBounds(proto, actual.type, substitutor, typeCheckerContext)) {
|
||||
// should report on the parameter instead!
|
||||
reporter.reportOn(reportTarget, proto, actual, context)
|
||||
return true
|
||||
}
|
||||
|
||||
val errorOccurred = analyzeTypeParameters(actual, context, reporter, typeSystemContext, reportTarget)
|
||||
val errorOccurred = analyzeTypeParameters(actual, context, reporter, typeCheckerContext, reportTarget)
|
||||
|
||||
if (errorOccurred) {
|
||||
return true
|
||||
@@ -236,14 +242,14 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
prototypeSymbol: FirTypeParameterSymbol,
|
||||
target: ConeKotlinType,
|
||||
substitutor: ConeSubstitutor,
|
||||
typeSystemContext: ConeTypeContext
|
||||
typeCheckerContext: AbstractTypeCheckerContext
|
||||
): Boolean {
|
||||
var intersection = typeSystemContext.intersectTypes(
|
||||
var intersection = typeCheckerContext.intersectTypes(
|
||||
prototypeSymbol.fir.bounds.map { it.coneType }
|
||||
).safeAs<ConeKotlinType>() ?: return true
|
||||
|
||||
intersection = substitutor.substituteOrSelf(intersection)
|
||||
return AbstractTypeChecker.isSubtypeOf(typeSystemContext, target, intersection, stubTypesEqualToAnything = false)
|
||||
return AbstractTypeChecker.isSubtypeOf(typeCheckerContext, target, intersection)
|
||||
}
|
||||
|
||||
private fun DiagnosticReporter.reportOn(
|
||||
|
||||
@@ -7,18 +7,13 @@ package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirControlFlowAnalyzer
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
||||
|
||||
class ControlFlowAnalysisDiagnosticComponent(
|
||||
collector: AbstractDiagnosticCollector,
|
||||
declarationCheckers: DeclarationCheckers = collector.session.checkersComponent.declarationCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
private val controlFlowAnalyzer = FirControlFlowAnalyzer(session, declarationCheckers)
|
||||
class ControlFlowAnalysisDiagnosticComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
private val controlFlowAnalyzer = FirControlFlowAnalyzer(session)
|
||||
|
||||
// ------------------------------- Class initializer -------------------------------
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirDeclarationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
@@ -14,9 +13,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
|
||||
class DeclarationCheckersDiagnosticComponent(
|
||||
collector: AbstractDiagnosticCollector,
|
||||
private val checkers: DeclarationCheckers = collector.session.checkersComponent.declarationCheckers,
|
||||
collector: AbstractDiagnosticCollector
|
||||
) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
private val checkers = session.checkersComponent.declarationCheckers
|
||||
|
||||
override fun visitFile(file: FirFile, data: CheckerContext) {
|
||||
checkers.fileCheckers.check(file, data, reporter)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirExpressionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
@@ -14,10 +13,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
|
||||
class ExpressionCheckersDiagnosticComponent(
|
||||
collector: AbstractDiagnosticCollector,
|
||||
private val checkers: ExpressionCheckers = collector.session.checkersComponent.expressionCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
class ExpressionCheckersDiagnosticComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
private val checkers = session.checkersComponent.expressionCheckers
|
||||
|
||||
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: CheckerContext) {
|
||||
checkers.basicExpressionCheckers.check(anonymousFunction, data, reporter)
|
||||
|
||||
@@ -14,12 +14,10 @@ object StandardClassIds {
|
||||
|
||||
val BASE_KOTLIN_PACKAGE = FqName("kotlin")
|
||||
val BASE_REFLECT_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("reflect"))
|
||||
val BASE_COLLECTIONS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("collections"))
|
||||
private fun String.baseId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier(this))
|
||||
private fun ClassId.unsignedId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier("U" + shortClassName.identifier))
|
||||
private fun String.reflectId() = ClassId(BASE_REFLECT_PACKAGE, Name.identifier(this))
|
||||
private fun Name.primitiveArrayId() = ClassId(Array.packageFqName, Name.identifier(identifier + Array.shortClassName.identifier))
|
||||
private fun String.collectionsId() = ClassId(BASE_COLLECTIONS_PACKAGE, Name.identifier(this))
|
||||
|
||||
val Nothing = "Nothing".baseId()
|
||||
val Unit = "Unit".baseId()
|
||||
@@ -87,25 +85,6 @@ object StandardClassIds {
|
||||
return "Function$n".baseId()
|
||||
}
|
||||
|
||||
val Iterator = "Iterator".collectionsId()
|
||||
val Iterable = "Iterable".collectionsId()
|
||||
val Collection = "Collection".collectionsId()
|
||||
val List = "List".collectionsId()
|
||||
val ListIterator = "ListIterator".collectionsId()
|
||||
val Set = "Set".collectionsId()
|
||||
val Map = "Map".collectionsId()
|
||||
val MutableIterator = "MutableIterator".collectionsId()
|
||||
|
||||
val MutableIterable = "MutableIterable".collectionsId()
|
||||
val MutableCollection = "MutableCollection".collectionsId()
|
||||
val MutableList = "MutableList".collectionsId()
|
||||
val MutableListIterator = "MutableListIterator".collectionsId()
|
||||
val MutableSet = "MutableSet".collectionsId()
|
||||
val MutableMap = "MutableMap".collectionsId()
|
||||
|
||||
val MapEntry = Map.createNestedClassId(Name.identifier("Entry"))
|
||||
val MutableMapEntry = MutableMap.createNestedClassId(Name.identifier("MutableEntry"))
|
||||
|
||||
val Suppress = "Suppress".baseId()
|
||||
}
|
||||
|
||||
|
||||
@@ -82,17 +82,6 @@ object CompilerConeAttributes {
|
||||
|
||||
override fun toString(): String = "@UnsafeVariance"
|
||||
}
|
||||
|
||||
val compilerAttributeByClassId: Map<ClassId, ConeAttribute<*>> = mapOf(
|
||||
Exact.ANNOTATION_CLASS_ID to Exact,
|
||||
NoInfer.ANNOTATION_CLASS_ID to NoInfer,
|
||||
EnhancedNullability.ANNOTATION_CLASS_ID to EnhancedNullability,
|
||||
ExtensionFunctionType.ANNOTATION_CLASS_ID to ExtensionFunctionType,
|
||||
FlexibleNullability.ANNOTATION_CLASS_ID to FlexibleNullability,
|
||||
UnsafeVariance.ANNOTATION_CLASS_ID to UnsafeVariance
|
||||
)
|
||||
|
||||
val compilerAttributeByFqName: Map<FqName, ConeAttribute<*>> = compilerAttributeByClassId.mapKeys { it.key.asSingleFqName() }
|
||||
}
|
||||
|
||||
val ConeAttributes.exact: CompilerConeAttributes.Exact? by ConeAttributes.attributeAccessor<CompilerConeAttributes.Exact>()
|
||||
|
||||
@@ -9,12 +9,11 @@ import org.jetbrains.kotlin.fir.utils.AttributeArrayOwner
|
||||
import org.jetbrains.kotlin.fir.utils.Protected
|
||||
import org.jetbrains.kotlin.fir.utils.TypeRegistry
|
||||
import org.jetbrains.kotlin.fir.utils.isEmpty
|
||||
import org.jetbrains.kotlin.types.model.AnnotationMarker
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class ConeAttribute<T : ConeAttribute<T>> : AnnotationMarker {
|
||||
abstract class ConeAttribute<T : ConeAttribute<T>> {
|
||||
abstract fun union(other: @UnsafeVariance T?): T?
|
||||
abstract fun intersect(other: @UnsafeVariance T?): T?
|
||||
abstract fun isSubtypeOf(other: @UnsafeVariance T?): Boolean
|
||||
@@ -70,13 +69,6 @@ class ConeAttributes private constructor(attributes: List<ConeAttribute<*>>) : A
|
||||
return perform(other) { this.intersect(it) }
|
||||
}
|
||||
|
||||
fun remove(attribute: ConeAttribute<*>): ConeAttributes {
|
||||
if (arrayMap.isEmpty()) return this
|
||||
val attributes = arrayMap.filter { it != attribute }
|
||||
if (attributes.size == arrayMap.size) return this
|
||||
return create(attributes)
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<ConeAttribute<*>> {
|
||||
return arrayMap.iterator()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.analysis
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
|
||||
@@ -84,7 +83,7 @@ class FirAnalyzerFacade(
|
||||
|
||||
fun convertToIr(extensions: GeneratorExtensions): Fir2IrResult {
|
||||
if (scopeSession == null) runResolution()
|
||||
val signaturer = JvmIdSignatureDescriptor(JvmManglerDesc())
|
||||
val signaturer = IdSignatureDescriptor(JvmManglerDesc())
|
||||
|
||||
return Fir2IrConverter.createModuleFragment(
|
||||
session, scopeSession!!, firFiles!!,
|
||||
|
||||
@@ -37,7 +37,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
)
|
||||
|
||||
override val classCheckers: Set<FirClassChecker> = setOf(
|
||||
FirOverrideChecker,
|
||||
FirThrowableSubclassChecker,
|
||||
)
|
||||
|
||||
@@ -52,6 +51,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirLocalEntityNotAllowedChecker,
|
||||
FirManyCompanionObjectsChecker,
|
||||
FirMethodOfAnyImplementedInInterfaceChecker,
|
||||
FirOverrideChecker,
|
||||
FirPrimaryConstructorRequiredForDataClassChecker,
|
||||
FirSupertypeInitializedInInterfaceChecker,
|
||||
FirSupertypeInitializedWithoutPrimaryConstructor,
|
||||
|
||||
@@ -30,9 +30,6 @@ import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
|
||||
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersionSettings) {
|
||||
register(FirLanguageSettingsComponent::class, FirLanguageSettingsComponent(languageVersionSettings))
|
||||
register(InferenceComponents::class, InferenceComponents(this))
|
||||
|
||||
register(FirDeclaredMemberScopeProvider::class, FirDeclaredMemberScopeProvider())
|
||||
register(FirCorrespondingSupertypesCache::class, FirCorrespondingSupertypesCache(this))
|
||||
register(FirDefaultParametersResolver::class, FirDefaultParametersResolver())
|
||||
@@ -41,6 +38,8 @@ fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersion
|
||||
register(FirRegisteredPluginAnnotations::class, FirRegisteredPluginAnnotations.create(this))
|
||||
register(FirPredicateBasedProvider::class, FirPredicateBasedProvider.create(this))
|
||||
register(GeneratedClassIndex::class, GeneratedClassIndex.create())
|
||||
register(FirLanguageSettingsComponent::class, FirLanguageSettingsComponent(languageVersionSettings))
|
||||
register(InferenceComponents::class, InferenceComponents(this))
|
||||
}
|
||||
|
||||
@OptIn(SessionConfiguration::class)
|
||||
|
||||
@@ -220,7 +220,7 @@ class FirBuiltinSymbolProvider(session: FirSession, val kotlinScopeProvider: Kot
|
||||
isVararg = false
|
||||
}
|
||||
}
|
||||
dispatchReceiverType = classId.defaultType(this@klass.typeParameters.map { it.symbol })
|
||||
dispatchReceiverType = classId.defaultType(typeParameters.map { it.symbol })
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -51,8 +51,6 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.utils.threadLocal
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
class Fir2IrDeclarationStorage(
|
||||
@@ -62,28 +60,28 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
private val firProvider = session.firProvider
|
||||
|
||||
private val fragmentCache = ConcurrentHashMap<FqName, IrExternalPackageFragment>()
|
||||
private val fragmentCache = mutableMapOf<FqName, IrExternalPackageFragment>()
|
||||
|
||||
private val builtInsFragmentCache = ConcurrentHashMap<FqName, IrExternalPackageFragment>()
|
||||
private val builtInsFragmentCache = mutableMapOf<FqName, IrExternalPackageFragment>()
|
||||
|
||||
private val fileCache = ConcurrentHashMap<FirFile, IrFile>()
|
||||
private val fileCache = mutableMapOf<FirFile, IrFile>()
|
||||
|
||||
private val functionCache = ConcurrentHashMap<FirFunction<*>, IrSimpleFunction>()
|
||||
private val functionCache = mutableMapOf<FirFunction<*>, IrSimpleFunction>()
|
||||
|
||||
private val constructorCache = ConcurrentHashMap<FirConstructor, IrConstructor>()
|
||||
private val constructorCache = mutableMapOf<FirConstructor, IrConstructor>()
|
||||
|
||||
private val initializerCache = ConcurrentHashMap<FirAnonymousInitializer, IrAnonymousInitializer>()
|
||||
private val initializerCache = mutableMapOf<FirAnonymousInitializer, IrAnonymousInitializer>()
|
||||
|
||||
private val propertyCache = ConcurrentHashMap<FirProperty, IrProperty>()
|
||||
private val propertyCache = mutableMapOf<FirProperty, IrProperty>()
|
||||
|
||||
// For pure fields (from Java) only
|
||||
private val fieldToPropertyCache = ConcurrentHashMap<FirField, IrProperty>()
|
||||
private val fieldToPropertyCache = mutableMapOf<FirField, IrProperty>()
|
||||
|
||||
private val delegatedReverseCache = ConcurrentHashMap<IrDeclaration, FirDeclaration>()
|
||||
private val delegatedReverseCache = mutableMapOf<IrDeclaration, FirDeclaration>()
|
||||
|
||||
private val fieldCache = ConcurrentHashMap<FirField, IrField>()
|
||||
private val fieldCache = mutableMapOf<FirField, IrField>()
|
||||
|
||||
private val localStorage by threadLocal { Fir2IrLocalStorage() }
|
||||
private val localStorage = Fir2IrLocalStorage()
|
||||
|
||||
private val delegatedMemberGenerator = DelegatedMemberGenerator(components)
|
||||
|
||||
|
||||
@@ -12,10 +12,7 @@ import org.jetbrains.kotlin.fir.backend.convertWithOffsets
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirFakeArgumentForCallableReference
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolvedCallArgument
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
@@ -32,7 +29,10 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.types.typeOrNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -58,7 +58,7 @@ internal class AdapterGenerator(
|
||||
function: IrFunction
|
||||
): Boolean =
|
||||
needSuspendConversion(type, function) || needCoercionToUnit(type, function) ||
|
||||
needVarargSpread(callableReferenceAccess)
|
||||
needVarargSpread(callableReferenceAccess, type, function)
|
||||
|
||||
/**
|
||||
* For example,
|
||||
@@ -96,11 +96,26 @@ internal class AdapterGenerator(
|
||||
*
|
||||
* At the use site, instead of referenced, we can put the adapter: { a, b -> referenced(a, b) }
|
||||
*/
|
||||
private fun needVarargSpread(callableReferenceAccess: FirCallableReferenceAccess): Boolean {
|
||||
private fun needVarargSpread(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
type: IrSimpleType,
|
||||
function: IrFunction
|
||||
): Boolean {
|
||||
// Unbound callable reference 'A::foo'
|
||||
return (callableReferenceAccess.calleeReference as? FirResolvedCallableReference)?.mappedArguments?.any {
|
||||
it.value is ResolvedCallArgument.VarargArgument || it.value is ResolvedCallArgument.DefaultArgument
|
||||
} == true
|
||||
val shift = if (callableReferenceAccess.explicitReceiver is FirResolvedQualifier) 1 else 0
|
||||
val typeArguments = type.arguments
|
||||
// Drop the return type from type arguments
|
||||
val expectedParameterSize = typeArguments.size - 1 - shift
|
||||
if (expectedParameterSize < function.valueParameters.size) {
|
||||
return false
|
||||
}
|
||||
var hasSpreadCase = false
|
||||
function.valueParameters.forEachIndexed { index, irValueParameter ->
|
||||
if (irValueParameter.isVararg && typeArguments[shift + index] == irValueParameter.varargElementType) {
|
||||
hasSpreadCase = true
|
||||
}
|
||||
}
|
||||
return hasSpreadCase
|
||||
}
|
||||
|
||||
internal fun ConeKotlinType.kFunctionTypeToFunctionType(): IrSimpleType =
|
||||
@@ -112,7 +127,7 @@ internal class AdapterGenerator(
|
||||
adapteeSymbol: IrFunctionSymbol,
|
||||
type: IrSimpleType
|
||||
): IrExpression {
|
||||
val firAdaptee = callableReferenceAccess.toResolvedCallableReference()?.resolvedSymbol?.fir as? FirFunction
|
||||
val firAdaptee = callableReferenceAccess.toResolvedCallableReference()?.resolvedSymbol?.fir as? FirSimpleFunction
|
||||
val adaptee = adapteeSymbol.owner
|
||||
val expectedReturnType = type.arguments.last().typeOrNull
|
||||
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
||||
@@ -123,7 +138,7 @@ internal class AdapterGenerator(
|
||||
callableReferenceAccess, startOffset, endOffset, firAdaptee!!, adaptee, type, boundDispatchReceiver, boundExtensionReceiver
|
||||
)
|
||||
val irCall = createAdapteeCallForCallableReference(
|
||||
callableReferenceAccess, firAdaptee, adapteeSymbol, irAdapterFunction, boundDispatchReceiver, boundExtensionReceiver
|
||||
callableReferenceAccess, adapteeSymbol, irAdapterFunction, boundDispatchReceiver, boundExtensionReceiver
|
||||
)
|
||||
irAdapterFunction.body = irFactory.createBlockBody(startOffset, endOffset) {
|
||||
if (expectedReturnType?.isUnit() == true) {
|
||||
@@ -164,7 +179,7 @@ internal class AdapterGenerator(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
firAdaptee: FirFunction<*>,
|
||||
firAdaptee: FirSimpleFunction,
|
||||
adaptee: IrFunction,
|
||||
type: IrSimpleType,
|
||||
boundDispatchReceiver: IrExpression?,
|
||||
@@ -172,7 +187,6 @@ internal class AdapterGenerator(
|
||||
): IrSimpleFunction {
|
||||
val returnType = type.arguments.last().typeOrNull!!
|
||||
val parameterTypes = type.arguments.dropLast(1).map { it.typeOrNull!! }
|
||||
val firMemberAdaptee = firAdaptee as FirMemberDeclaration
|
||||
return irFactory.createFunction(
|
||||
startOffset, endOffset,
|
||||
IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE,
|
||||
@@ -181,13 +195,13 @@ internal class AdapterGenerator(
|
||||
DescriptorVisibilities.LOCAL,
|
||||
Modality.FINAL,
|
||||
returnType,
|
||||
isInline = firMemberAdaptee.isInline,
|
||||
isExternal = firMemberAdaptee.isExternal,
|
||||
isTailrec = firMemberAdaptee.isTailRec,
|
||||
isSuspend = firMemberAdaptee.isSuspend || type.isSuspendFunction(),
|
||||
isOperator = firMemberAdaptee.isOperator,
|
||||
isInfix = firMemberAdaptee.isInfix,
|
||||
isExpect = firMemberAdaptee.isExpect,
|
||||
isInline = firAdaptee.isInline,
|
||||
isExternal = firAdaptee.isExternal,
|
||||
isTailrec = firAdaptee.isTailRec,
|
||||
isSuspend = firAdaptee.isSuspend || type.isSuspendFunction(),
|
||||
isOperator = firAdaptee.isOperator,
|
||||
isInfix = firAdaptee.isInfix,
|
||||
isExpect = firAdaptee.isExpect,
|
||||
isFakeOverride = false
|
||||
).also { irAdapterFunction ->
|
||||
irAdapterFunction.metadata = FirMetadataSource.Function(firAdaptee)
|
||||
@@ -254,7 +268,6 @@ internal class AdapterGenerator(
|
||||
|
||||
private fun createAdapteeCallForCallableReference(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
firAdaptee: FirFunction<*>,
|
||||
adapteeSymbol: IrFunctionSymbol,
|
||||
adapterFunction: IrFunction,
|
||||
boundDispatchReceiver: IrExpression?,
|
||||
@@ -283,7 +296,6 @@ internal class AdapterGenerator(
|
||||
}
|
||||
|
||||
var adapterParameterIndex = 0
|
||||
var parameterShift = 0
|
||||
if (boundDispatchReceiver != null || boundExtensionReceiver != null) {
|
||||
val receiverValue = IrGetValueImpl(
|
||||
startOffset, endOffset, adapterFunction.extensionReceiverParameter!!.symbol, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE
|
||||
@@ -300,56 +312,50 @@ internal class AdapterGenerator(
|
||||
)
|
||||
if (adapteeFunction.extensionReceiverParameter != null) {
|
||||
irCall.extensionReceiver = adaptedReceiverValue
|
||||
adapterParameterIndex++
|
||||
} else {
|
||||
irCall.dispatchReceiver = adaptedReceiverValue
|
||||
}
|
||||
parameterShift++
|
||||
}
|
||||
|
||||
val mappedArguments = (callableReferenceAccess.calleeReference as? FirResolvedCallableReference)?.mappedArguments
|
||||
|
||||
fun buildIrGetValueArgument(argument: FirExpression): IrGetValue {
|
||||
val parameterIndex = (argument as? FirFakeArgumentForCallableReference)?.index ?: adapterParameterIndex
|
||||
adapterParameterIndex++
|
||||
return adapterFunction.valueParameters[parameterIndex + parameterShift].toIrGetValue(startOffset, endOffset)
|
||||
}
|
||||
|
||||
adapteeFunction.valueParameters.zip(firAdaptee.valueParameters).mapIndexed { index, (valueParameter, firParameter) ->
|
||||
when (val mappedArgument = mappedArguments?.get(firParameter)) {
|
||||
is ResolvedCallArgument.VarargArgument -> {
|
||||
val valueArgument = if (mappedArgument.arguments.isEmpty()) {
|
||||
null
|
||||
adapteeFunction.valueParameters.mapIndexed { index, valueParameter ->
|
||||
when {
|
||||
valueParameter.isVararg -> {
|
||||
if (adapterFunction.valueParameters.size <= index) {
|
||||
irCall.putValueArgument(index, null)
|
||||
} else {
|
||||
val adaptedValueArgument = IrVarargImpl(
|
||||
startOffset, endOffset,
|
||||
valueParameter.type, valueParameter.varargElementType!!,
|
||||
)
|
||||
for (argument in mappedArgument.arguments) {
|
||||
val irValueArgument = buildIrGetValueArgument(argument)
|
||||
adaptedValueArgument.addElement(irValueArgument)
|
||||
val adaptedValueArgument =
|
||||
IrVarargImpl(startOffset, endOffset, valueParameter.type, valueParameter.varargElementType!!)
|
||||
var neitherArrayNorSpread = false
|
||||
while (adapterParameterIndex < adapterFunction.valueParameters.size) {
|
||||
val irValueArgument =
|
||||
adapterFunction.valueParameters[adapterParameterIndex].toIrGetValue(startOffset, endOffset)
|
||||
if (irValueArgument.type == valueParameter.type) {
|
||||
adaptedValueArgument.addElement(IrSpreadElementImpl(startOffset, endOffset, irValueArgument))
|
||||
adapterParameterIndex++
|
||||
break
|
||||
} else if (irValueArgument.type == valueParameter.varargElementType) {
|
||||
adaptedValueArgument.addElement(irValueArgument)
|
||||
adapterParameterIndex++
|
||||
} else {
|
||||
neitherArrayNorSpread = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (neitherArrayNorSpread) {
|
||||
irCall.putValueArgument(index, null)
|
||||
} else {
|
||||
irCall.putValueArgument(index, adaptedValueArgument)
|
||||
}
|
||||
adaptedValueArgument
|
||||
}
|
||||
irCall.putValueArgument(index, valueArgument)
|
||||
}
|
||||
ResolvedCallArgument.DefaultArgument -> {
|
||||
valueParameter.hasDefaultValue() -> {
|
||||
irCall.putValueArgument(index, null)
|
||||
}
|
||||
is ResolvedCallArgument.SimpleArgument -> {
|
||||
val irValueArgument = buildIrGetValueArgument(mappedArgument.callArgument)
|
||||
if (valueParameter.isVararg) {
|
||||
irCall.putValueArgument(
|
||||
index, IrVarargImpl(
|
||||
startOffset, endOffset,
|
||||
valueParameter.type, valueParameter.varargElementType!!,
|
||||
listOf(IrSpreadElementImpl(startOffset, endOffset, irValueArgument))
|
||||
)
|
||||
)
|
||||
} else {
|
||||
irCall.putValueArgument(index, irValueArgument)
|
||||
}
|
||||
}
|
||||
null -> {
|
||||
else -> {
|
||||
irCall.putValueArgument(
|
||||
index, adapterFunction.valueParameters[adapterParameterIndex++].toIrGetValue(startOffset, endOffset)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,16 @@ class CallAndReferenceGenerator(
|
||||
origin
|
||||
)
|
||||
}
|
||||
is IrConstructorSymbol -> {
|
||||
val constructor = symbol.owner
|
||||
val klass = constructor.parent as? IrClass
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type, symbol,
|
||||
typeArgumentsCount = constructor.typeParameters.size + (klass?.typeParameters?.size ?: 0),
|
||||
valueArgumentsCount = constructor.valueParameters.size,
|
||||
reflectionTarget = symbol
|
||||
)
|
||||
}
|
||||
is IrFunctionSymbol -> {
|
||||
assert(type.isFunctionTypeOrSubtype()) {
|
||||
"Callable reference whose symbol refers to a function should be of functional type."
|
||||
@@ -134,12 +144,9 @@ class CallAndReferenceGenerator(
|
||||
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType)
|
||||
}
|
||||
} else {
|
||||
val klass = function.parent as? IrClass
|
||||
val typeArgumentCount = function.typeParameters.size +
|
||||
if (function is IrConstructor) klass?.typeParameters?.size ?: 0 else 0
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type, symbol,
|
||||
typeArgumentsCount = typeArgumentCount,
|
||||
typeArgumentsCount = function.typeParameters.size,
|
||||
valueArgumentsCount = function.valueParameters.size,
|
||||
reflectionTarget = symbol
|
||||
)
|
||||
@@ -636,7 +643,7 @@ class CallAndReferenceGenerator(
|
||||
// If the type of the argument is already an explicitly subtype of the type of the parameter, we don't need SAM conversion.
|
||||
if (argument.typeRef !is FirResolvedTypeRef ||
|
||||
AbstractTypeChecker.isSubtypeOf(
|
||||
session.inferenceComponents.ctx.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true),
|
||||
session.inferenceComponents.ctx,
|
||||
argument.typeRef.coneType,
|
||||
parameter.returnTypeRef.coneType,
|
||||
isFromNullabilityConstraint = true
|
||||
|
||||
@@ -2440,12 +2440,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/callableReference/kt37604.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44483.kt")
|
||||
public void testKt44483() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/kt44483.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nested.kt")
|
||||
public void testNested() throws Exception {
|
||||
@@ -19987,12 +19981,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/samConversionOnFunctionReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("samExtFunWithCapturingLambda.kt")
|
||||
public void testSamExtFunWithCapturingLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/samExtFunWithCapturingLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleFunInterfaceConstructor.kt")
|
||||
public void testSimpleFunInterfaceConstructor() throws Exception {
|
||||
@@ -35387,12 +35375,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/reflection/types/classifiersOfBuiltInTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equalsForClassAndTypeParameterWithSameFqName.kt")
|
||||
public void testEqualsForClassAndTypeParameterWithSameFqName() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/types/equalsForClassAndTypeParameterWithSameFqName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("innerGenericArguments.kt")
|
||||
public void testInnerGenericArguments() throws Exception {
|
||||
@@ -37325,6 +37307,94 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/signatureAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class SignatureAnnotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInSignatureAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/signatureAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultAndNamedCombination.kt")
|
||||
public void testDefaultAndNamedCombination() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultAndNamedCombination.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultBoxTypes.kt")
|
||||
public void testDefaultBoxTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultBoxTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultEnumType.kt")
|
||||
public void testDefaultEnumType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultEnumType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultLongLiteral.kt")
|
||||
public void testDefaultLongLiteral() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultLongLiteral.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultMultipleParams.kt")
|
||||
public void testDefaultMultipleParams() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultMultipleParams.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultNull.kt")
|
||||
public void testDefaultNull() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultNull.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultNullableBoxTypes.kt")
|
||||
public void testDefaultNullableBoxTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultNullableBoxTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultOverrides.kt")
|
||||
public void testDefaultOverrides() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultPrimitiveTypes.kt")
|
||||
public void testDefaultPrimitiveTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultPrimitiveTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultValueInConstructor.kt")
|
||||
public void testDefaultValueInConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultValueInConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultWithJavaBase.kt")
|
||||
public void testDefaultWithJavaBase() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultWithJavaBase.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("defaultWithKotlinBase.kt")
|
||||
public void testDefaultWithKotlinBase() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/defaultWithKotlinBase.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reorderedParameterNames.kt")
|
||||
public void testReorderedParameterNames() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/signatureAnnotations/reorderedParameterNames.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/smap")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@@ -37452,24 +37522,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/smartCasts/kt44804.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44814.kt")
|
||||
public void testKt44814() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/smartCasts/kt44814.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44932.kt")
|
||||
public void testKt44932() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/smartCasts/kt44932.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44942.kt")
|
||||
public void testKt44942() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/smartCasts/kt44942.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaArgumentWithoutType.kt")
|
||||
public void testLambdaArgumentWithoutType() throws Exception {
|
||||
|
||||
@@ -647,18 +647,6 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn
|
||||
runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_3.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt8668_nested.kt")
|
||||
public void testKt8668_nested() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt8668_nested_2.kt")
|
||||
public void testKt8668_nested_2() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/anonymousObject/twoCapturedReceivers/kt8668_nested_2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoDifferentDispatchReceivers.kt")
|
||||
public void testTwoDifferentDispatchReceivers() throws Exception {
|
||||
|
||||
@@ -5080,12 +5080,6 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndyDataClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("concatDynamicUnit.kt")
|
||||
public void testConcatDynamicUnit() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicUnit.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("concatNotDynamic.kt")
|
||||
public void testConcatNotDynamic() throws Exception {
|
||||
@@ -5580,12 +5574,6 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/subjectAny.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenOr.kt")
|
||||
public void testWhenOr() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/whenOr.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("withoutElse.kt")
|
||||
public void testWithoutElse() throws Exception {
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.resolveSupertypesInTheAir
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -242,7 +241,9 @@ private fun ConeClassLikeType.mapToCanonicalNoExpansionString(session: FirSessio
|
||||
} + "[]"
|
||||
}
|
||||
|
||||
with(session.typeContext) {
|
||||
val context = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session = session)
|
||||
|
||||
with(context) {
|
||||
val typeConstructor = typeConstructor()
|
||||
typeConstructor.getPrimitiveType()?.let { return JvmPrimitiveType.get(it).wrapperFqName.asString() }
|
||||
typeConstructor.getPrimitiveArrayType()?.let { return JvmPrimitiveType.get(it).javaKeywordName + "[]" }
|
||||
|
||||
@@ -69,7 +69,6 @@ class JavaSymbolProvider(
|
||||
private val scopeProvider = JavaScopeProvider(::wrapScopeWithJvmMapped, this)
|
||||
|
||||
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
|
||||
private val parentClassTypeParameterStackCache = mutableMapOf<FirRegularClassSymbol, JavaTypeParameterStack>()
|
||||
|
||||
private fun findClass(
|
||||
classId: ClassId,
|
||||
@@ -189,15 +188,12 @@ class JavaSymbolProvider(
|
||||
|
||||
|
||||
if (parentClassSymbol != null) {
|
||||
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol]
|
||||
?: (parentClassSymbol.fir as? FirJavaClass)?.javaTypeParameterStack
|
||||
val parentStack = (parentClassSymbol.fir as? FirJavaClass)?.javaTypeParameterStack
|
||||
if (parentStack != null) {
|
||||
javaTypeParameterStack.addStack(parentStack)
|
||||
}
|
||||
}
|
||||
parentClassTypeParameterStackCache[classSymbol] = javaTypeParameterStack
|
||||
val firJavaClass = createFirJavaClass(javaClass, classSymbol, outerClassId, parentClassSymbol, classId, javaTypeParameterStack)
|
||||
parentClassTypeParameterStackCache.remove(classSymbol)
|
||||
firJavaClass.convertSuperTypes(javaClass, javaTypeParameterStack)
|
||||
firJavaClass.addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||
return firJavaClass
|
||||
|
||||
@@ -393,8 +393,6 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||
)
|
||||
}
|
||||
|
||||
val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol
|
||||
|
||||
val mappedTypeArguments = if (isRaw) {
|
||||
val defaultArgs = (1..classifier.typeParameters.size).map { ConeStarProjection }
|
||||
|
||||
@@ -405,10 +403,14 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||
} else {
|
||||
val position = if (isLowerBound) TypeComponentPosition.FLEXIBLE_LOWER else TypeComponentPosition.FLEXIBLE_UPPER
|
||||
|
||||
val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol
|
||||
classSymbol?.fir?.createRawArguments(defaultArgs, position) ?: defaultArgs
|
||||
}
|
||||
} else {
|
||||
val typeParameters = runIf(!forTypeParameterBounds && !isForSupertypes) { classSymbol?.fir?.typeParameters } ?: emptyList()
|
||||
val typeParameters = runIf(!forTypeParameterBounds && !isForSupertypes) {
|
||||
val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol
|
||||
classSymbol?.fir?.typeParameters
|
||||
} ?: emptyList()
|
||||
|
||||
typeArguments.indices.map { index ->
|
||||
val argument = typeArguments[index]
|
||||
|
||||
@@ -18,6 +18,8 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
@@ -28,9 +30,12 @@ import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import org.jetbrains.kotlin.utils.JavaTypeEnhancementState
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -180,26 +185,27 @@ class FirSignatureEnhancement(
|
||||
enhanceReturnType(firMethod, overriddenMembers, memberContext, predefinedEnhancementInfo)
|
||||
}
|
||||
|
||||
val enhancedValueParameterTypes = mutableListOf<FirResolvedTypeRef>()
|
||||
val newValueParameterInfo = mutableListOf<EnhanceValueParameterResult>()
|
||||
|
||||
for ((index, valueParameter) in firMethod.valueParameters.withIndex()) {
|
||||
if (hasReceiver && index == 0) continue
|
||||
enhancedValueParameterTypes += enhanceValueParameterType(
|
||||
newValueParameterInfo += enhanceValueParameter(
|
||||
firMethod, overriddenMembers, hasReceiver,
|
||||
memberContext, predefinedEnhancementInfo, valueParameter as FirJavaValueParameter,
|
||||
if (hasReceiver) index - 1 else index
|
||||
)
|
||||
}
|
||||
|
||||
val newValueParameters = firMethod.valueParameters.zip(enhancedValueParameterTypes) { valueParameter, enhancedReturnType ->
|
||||
val newValueParameters = firMethod.valueParameters.zip(newValueParameterInfo) { valueParameter, newInfo ->
|
||||
val (newTypeRef, newDefaultValue) = newInfo
|
||||
buildValueParameter {
|
||||
source = valueParameter.source
|
||||
session = this@FirSignatureEnhancement.session
|
||||
origin = FirDeclarationOrigin.Enhancement
|
||||
returnTypeRef = enhancedReturnType
|
||||
returnTypeRef = newTypeRef
|
||||
this.name = valueParameter.name
|
||||
symbol = FirVariableSymbol(this.name)
|
||||
defaultValue = valueParameter.defaultValue
|
||||
defaultValue = valueParameter.defaultValue ?: newDefaultValue
|
||||
isCrossinline = valueParameter.isCrossinline
|
||||
isNoinline = valueParameter.isNoinline
|
||||
isVararg = valueParameter.isVararg
|
||||
@@ -292,7 +298,9 @@ class FirSignatureEnhancement(
|
||||
return signatureParts.type
|
||||
}
|
||||
|
||||
private fun enhanceValueParameterType(
|
||||
private data class EnhanceValueParameterResult(val typeRef: FirResolvedTypeRef, val defaultValue: FirExpression?)
|
||||
|
||||
private fun enhanceValueParameter(
|
||||
ownerFunction: FirFunction<*>,
|
||||
overriddenMembers: List<FirCallableMemberDeclaration<*>>,
|
||||
hasReceiver: Boolean,
|
||||
@@ -300,7 +308,7 @@ class FirSignatureEnhancement(
|
||||
predefinedEnhancementInfo: PredefinedFunctionEnhancementInfo?,
|
||||
ownerParameter: FirJavaValueParameter,
|
||||
index: Int
|
||||
): FirResolvedTypeRef {
|
||||
): EnhanceValueParameterResult {
|
||||
val signatureParts = ownerFunction.partsForValueParameter(
|
||||
typeQualifierResolver,
|
||||
overriddenMembers,
|
||||
@@ -313,7 +321,13 @@ class FirSignatureEnhancement(
|
||||
predefinedEnhancementInfo?.parametersInfo?.getOrNull(index),
|
||||
forAnnotationMember = owner.classKind == ClassKind.ANNOTATION_CLASS
|
||||
)
|
||||
return signatureParts.type
|
||||
val firResolvedTypeRef = signatureParts.type
|
||||
val defaultValueExpression = when (val defaultValue = ownerParameter.getDefaultValueFromAnnotation()) {
|
||||
NullDefaultValue -> buildConstExpression(null, ConstantValueKind.Null, null)
|
||||
is StringDefaultValue -> firResolvedTypeRef.type.lexicalCastFrom(session, defaultValue.value)
|
||||
null -> null
|
||||
}
|
||||
return EnhanceValueParameterResult(firResolvedTypeRef, defaultValueExpression)
|
||||
}
|
||||
|
||||
private fun enhanceReturnType(
|
||||
|
||||
@@ -13,6 +13,11 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
@@ -26,6 +31,11 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.load.java.JavaDefaultQualifiers
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_NULL_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||
@@ -35,6 +45,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import org.jetbrains.kotlin.types.RawType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.extractRadix
|
||||
|
||||
internal class IndexedJavaTypeQualifiers(private val data: Array<JavaTypeQualifiers>) {
|
||||
@@ -306,6 +317,22 @@ internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String):
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirValueParameter.getDefaultValueFromAnnotation(): AnnotationDefaultValue? {
|
||||
annotations.find { it.classId == DEFAULT_VALUE_ID }
|
||||
?.arguments?.firstOrNull()
|
||||
?.safeAs<FirConstExpression<*>>()?.value?.safeAs<String>()
|
||||
?.let { return StringDefaultValue(it) }
|
||||
|
||||
if (annotations.any { it.classId == DEFAULT_NULL_ID }) {
|
||||
return NullDefaultValue
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private val DEFAULT_VALUE_ID = ClassId.topLevel(DEFAULT_VALUE_FQ_NAME)
|
||||
private val DEFAULT_NULL_ID = ClassId.topLevel(DEFAULT_NULL_FQ_NAME)
|
||||
|
||||
internal fun List<FirAnnotationCall>.computeTypeAttributesForJavaType(): ConeAttributes =
|
||||
computeTypeAttributes { classId ->
|
||||
when (classId) {
|
||||
|
||||
@@ -6,19 +6,21 @@
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
|
||||
|
||||
val FirSession.typeContext: ConeInferenceContext
|
||||
get() = inferenceComponents.ctx
|
||||
|
||||
val FirSession.typeCheckerContext: ConeTypeCheckerContext
|
||||
get() = inferenceComponents.ctx
|
||||
|
||||
/**
|
||||
* Returns the list of functions that overridden by given
|
||||
*/
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
|
||||
fun ConeKotlinType.substitutedUnderlyingTypeForInlineClass(session: FirSession, context: ConeTypeContext): ConeKotlinType? {
|
||||
val symbol = (this.fullyExpandedType(session) as? ConeLookupTagBasedType)
|
||||
?.lookupTag
|
||||
?.toSymbol(session) as? FirRegularClassSymbol
|
||||
?: return null
|
||||
symbol.ensureResolved(FirResolvePhase.STATUS, session)
|
||||
val firClass = symbol.fir
|
||||
if (!firClass.status.isInline) return null
|
||||
val constructor = firClass.declarations.singleOrNull { it is FirConstructor && it.isPrimary } as FirConstructor? ?: return null
|
||||
val valueParameter = constructor.valueParameters.singleOrNull() ?: return null
|
||||
val unsubstitutedType = valueParameter.returnTypeRef.coneType
|
||||
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(mapOf(this.typeConstructor(context) to this), context)
|
||||
return substitutor.substituteOrNull(unsubstitutedType)
|
||||
}
|
||||
@@ -104,7 +104,6 @@ abstract class AbstractConeCallConflictResolver(
|
||||
is FirConstructor -> createFlatSignature(call, declaration)
|
||||
is FirVariable<*> -> createFlatSignature(call, declaration)
|
||||
is FirClass<*> -> createFlatSignature(call, declaration)
|
||||
is FirTypeAlias -> createFlatSignature(call, declaration)
|
||||
else -> error("Not supported: $declaration")
|
||||
}
|
||||
}
|
||||
@@ -164,10 +163,10 @@ abstract class AbstractConeCallConflictResolver(
|
||||
?: call.argumentMapping?.map { it.value.argumentType() }.orEmpty())
|
||||
}
|
||||
|
||||
private fun createFlatSignature(call: Candidate, klass: FirClassLikeDeclaration<*>): FlatSignature<Candidate> {
|
||||
private fun createFlatSignature(call: Candidate, klass: FirClass<*>): FlatSignature<Candidate> {
|
||||
return FlatSignature(
|
||||
call,
|
||||
(klass as? FirTypeParameterRefsOwner)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(),
|
||||
(klass as? FirRegularClass)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(),
|
||||
valueParameterTypes = emptyList(),
|
||||
hasExtensionReceiver = false,
|
||||
hasVarargs = false,
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclarati
|
||||
import org.jetbrains.kotlin.fir.returnExpressions
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.typeCheckerContext
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -25,7 +26,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompat
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||
import org.jetbrains.kotlin.types.model.TypeSystemCommonSuperTypesContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
|
||||
fun Candidate.resolveArgumentExpression(
|
||||
@@ -416,10 +416,7 @@ fun FirExpression.isFunctional(
|
||||
val returnTypeCompatible =
|
||||
expectedReturnType is ConeTypeParameterType ||
|
||||
AbstractTypeChecker.isSubtypeOf(
|
||||
session.inferenceComponents.ctx.newBaseTypeCheckerContext(
|
||||
errorTypesEqualToAnything = false,
|
||||
stubTypesEqualToAnything = true
|
||||
),
|
||||
session.inferenceComponents.ctx,
|
||||
invokeSymbol.fir.returnTypeRef.coneType,
|
||||
expectedReturnType,
|
||||
isFromNullabilityConstraint = false
|
||||
@@ -436,10 +433,7 @@ fun FirExpression.isFunctional(
|
||||
val expectedParameterType = expectedParameter!!.lowerBoundIfFlexible()
|
||||
expectedParameterType is ConeTypeParameterType ||
|
||||
AbstractTypeChecker.isSubtypeOf(
|
||||
session.inferenceComponents.ctx.newBaseTypeCheckerContext(
|
||||
errorTypesEqualToAnything = false,
|
||||
stubTypesEqualToAnything = true
|
||||
),
|
||||
session.inferenceComponents.ctx,
|
||||
invokeParameter.returnTypeRef.coneType,
|
||||
expectedParameterType,
|
||||
isFromNullabilityConstraint = false
|
||||
@@ -494,7 +488,7 @@ internal fun captureFromTypeParameterUpperBoundIfNeeded(
|
||||
val simplifiedArgumentType = argumentType.lowerBoundIfFlexible() as? ConeTypeParameterType ?: return argumentType
|
||||
val typeParameter = simplifiedArgumentType.lookupTag.typeParameterSymbol.fir
|
||||
|
||||
val context = session.typeContext
|
||||
val context = session.typeCheckerContext
|
||||
|
||||
val chosenSupertype = typeParameter.bounds.map { it.coneType }
|
||||
.singleOrNull { it.hasSupertypeWithGivenClassId(expectedTypeClassId, context) } ?: return argumentType
|
||||
@@ -507,7 +501,7 @@ internal fun captureFromTypeParameterUpperBoundIfNeeded(
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.hasSupertypeWithGivenClassId(classId: ClassId, context: TypeSystemCommonSuperTypesContext): Boolean {
|
||||
private fun ConeKotlinType.hasSupertypeWithGivenClassId(classId: ClassId, context: ConeTypeCheckerContext): Boolean {
|
||||
return with(context) {
|
||||
anySuperTypeConstructor {
|
||||
it is ConeClassLikeLookupTag && it.classId == classId
|
||||
|
||||
@@ -51,7 +51,8 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
||||
}
|
||||
|
||||
candidate.resultingTypeForCallableReference = resultingType
|
||||
candidate.callableReferenceAdaptation = callableReferenceAdaptation
|
||||
candidate.usesSuspendConversion =
|
||||
callableReferenceAdaptation?.suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION
|
||||
candidate.outerConstraintBuilderEffect = fun ConstraintSystemOperation.() {
|
||||
addOtherSystem(candidate.system.asReadOnlyStorage())
|
||||
|
||||
@@ -132,7 +133,7 @@ internal class CallableReferenceAdaptation(
|
||||
val argumentTypes: Array<ConeKotlinType>,
|
||||
val coercionStrategy: CoercionStrategy,
|
||||
val defaults: Int,
|
||||
val mappedArguments: CallableReferenceMappedArguments,
|
||||
val mappedArguments: Map<FirValueParameter, ResolvedCallArgument>,
|
||||
val suspendConversionStrategy: SuspendConversionStrategy
|
||||
)
|
||||
|
||||
@@ -350,7 +351,7 @@ private fun createFakeArgumentsForReference(
|
||||
}
|
||||
}
|
||||
|
||||
class FirFakeArgumentForCallableReference(
|
||||
private class FirFakeArgumentForCallableReference(
|
||||
val index: Int
|
||||
) : FirExpression() {
|
||||
override val source: FirSourceElement?
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.components.SuspendConversionStrategy
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
@@ -98,13 +97,6 @@ class Candidate(
|
||||
var resultingTypeForCallableReference: ConeKotlinType? = null
|
||||
var outerConstraintBuilderEffect: (ConstraintSystemOperation.() -> Unit)? = null
|
||||
var usesSAM: Boolean = false
|
||||
|
||||
internal var callableReferenceAdaptation: CallableReferenceAdaptation? = null
|
||||
set(value) {
|
||||
field = value
|
||||
usesSuspendConversion = value?.suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION
|
||||
}
|
||||
|
||||
var usesSuspendConversion: Boolean = false
|
||||
|
||||
var argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>? = null
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.LinkedHashMap
|
||||
import kotlin.collections.component1
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
|
||||
sealed class ResolvedCallArgument {
|
||||
@@ -24,6 +23,4 @@ sealed class ResolvedCallArgument {
|
||||
}
|
||||
|
||||
class VarargArgument(override val arguments: List<FirExpression>) : ResolvedCallArgument()
|
||||
}
|
||||
|
||||
typealias CallableReferenceMappedArguments = Map<FirValueParameter, ResolvedCallArgument>
|
||||
}
|
||||
@@ -1136,6 +1136,12 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
lhsExitNode.mergeIncomingFlow()
|
||||
val flow = lhsExitNode.flow
|
||||
val lhsVariable = variableStorage.getOrCreateVariable(flow, elvisExpression.lhs)
|
||||
rhsEnterNode.flow = logicSystem.approveStatementsInsideFlow(
|
||||
flow,
|
||||
lhsVariable eq null,
|
||||
shouldForkFlow = true,
|
||||
shouldRemoveSynthetics = false
|
||||
)
|
||||
lhsIsNotNullNode.flow = logicSystem.approveStatementsInsideFlow(
|
||||
flow,
|
||||
lhsVariable notEq null,
|
||||
@@ -1146,14 +1152,6 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
it.addTypeStatement(lhsVariable typeEq any)
|
||||
}
|
||||
}
|
||||
rhsEnterNode.flow = logicSystem.approveStatementsInsideFlow(
|
||||
flow,
|
||||
lhsVariable eq null,
|
||||
shouldForkFlow = true,
|
||||
shouldRemoveSynthetics = false
|
||||
).also {
|
||||
logicSystem.updateAllReceivers(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun exitElvis(elvisExpression: FirElvisExpression) {
|
||||
|
||||
@@ -143,7 +143,7 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
||||
if (types.any { it.isEmpty() }) return mutableSetOf()
|
||||
val intersectedTypes = types.map {
|
||||
if (it.size > 1) {
|
||||
context.intersectTypes(it.toList())
|
||||
context.intersectTypes(it.toList()) as ConeKotlinType
|
||||
} else {
|
||||
assert(it.size == 1) { "We've already checked each set of types is not empty." }
|
||||
it.single()
|
||||
|
||||
@@ -79,7 +79,6 @@ class ControlFlowGraphBuilder {
|
||||
private val exitsFromCompletedPostponedAnonymousFunctions: MutableList<PostponedLambdaExitNode> = mutableListOf()
|
||||
|
||||
private val whenExitNodes: NodeStorage<FirWhenExpression, WhenExitNode> = NodeStorage()
|
||||
private val whenBranchIndices: Stack<Map<FirWhenBranch, Int>> = stackOf()
|
||||
|
||||
private val binaryAndExitNodes: Stack<BinaryAndExitNode> = stackOf()
|
||||
private val binaryOrExitNodes: Stack<BinaryOrExitNode> = stackOf()
|
||||
@@ -597,7 +596,6 @@ class ControlFlowGraphBuilder {
|
||||
val node = createWhenEnterNode(whenExpression)
|
||||
addNewSimpleNode(node)
|
||||
whenExitNodes.push(createWhenExitNode(whenExpression))
|
||||
whenBranchIndices.push(whenExpression.branches.mapIndexed { index, branch -> branch to index }.toMap())
|
||||
levelCounter++
|
||||
return node
|
||||
}
|
||||
@@ -615,7 +613,6 @@ class ControlFlowGraphBuilder {
|
||||
lastNodes.push(it)
|
||||
addEdge(conditionExitNode, it)
|
||||
}
|
||||
levelCounter += whenBranchIndices.top().getValue(whenBranch)
|
||||
return conditionExitNode to branchEnterNode
|
||||
}
|
||||
|
||||
@@ -625,7 +622,6 @@ class ControlFlowGraphBuilder {
|
||||
popAndAddEdge(node)
|
||||
val whenExitNode = whenExitNodes.top()
|
||||
addEdge(node, whenExitNode, propagateDeadness = false)
|
||||
levelCounter -= whenBranchIndices.top().getValue(whenBranch)
|
||||
return node
|
||||
}
|
||||
|
||||
@@ -644,7 +640,6 @@ class ControlFlowGraphBuilder {
|
||||
lastNodes.push(whenExitNode)
|
||||
dropPostponedLambdasForNonDeterministicCalls()
|
||||
levelCounter--
|
||||
whenBranchIndices.pop()
|
||||
return whenExitNode to syntheticElseBranchNode
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import java.util.*
|
||||
|
||||
class FirControlFlowGraphRenderVisitor(
|
||||
builder: StringBuilder,
|
||||
private val renderLevels: Boolean = false
|
||||
) : FirVisitorVoid() {
|
||||
companion object {
|
||||
private const val EDGE = " -> "
|
||||
@@ -82,13 +81,7 @@ class FirControlFlowGraphRenderVisitor(
|
||||
color = BLUE
|
||||
}
|
||||
val attributes = mutableListOf<String>()
|
||||
val label = buildString {
|
||||
append(node.render().replace("\"", ""))
|
||||
if (renderLevels) {
|
||||
append(" [${node.level}]")
|
||||
}
|
||||
}
|
||||
attributes += "label=\"$label\""
|
||||
attributes += "label=\"${node.render().replace("\"", "")}\""
|
||||
|
||||
fun fillColor(color: String) {
|
||||
attributes += "style=\"filled\""
|
||||
@@ -225,4 +218,4 @@ private fun ControlFlowGraph.forEachSubGraph(block: (ControlFlowGraph) -> Unit)
|
||||
block(subGraph)
|
||||
subGraph.forEachSubGraph(block)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,14 @@ package org.jetbrains.kotlin.fir.resolve.inference
|
||||
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
||||
|
||||
@NoMutableState
|
||||
class InferenceComponents(val session: FirSession) : FirSessionComponent {
|
||||
val ctx: ConeInferenceContext = object : ConeInferenceContext {
|
||||
override val session: FirSession
|
||||
get() = this@InferenceComponents.session
|
||||
}
|
||||
val ctx: ConeTypeCheckerContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session)
|
||||
|
||||
val approximator: AbstractTypeApproximator = object : AbstractTypeApproximator(ctx) {}
|
||||
val trivialConstraintTypeInferenceOracle = TrivialConstraintTypeInferenceOracle.create(ctx)
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
@@ -46,15 +45,16 @@ fun ConeKotlinType.isKMutableProperty(session: FirSession): Boolean {
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.functionClassKind(session: FirSession): FunctionClassKind? {
|
||||
return classId(session)?.toFunctionClassKind()
|
||||
}
|
||||
|
||||
private fun ClassId.toFunctionClassKind(): FunctionClassKind? {
|
||||
return FunctionClassKind.byClassNamePrefix(packageFqName, relativeClassName.asString())
|
||||
val classId = classId(session) ?: return null
|
||||
return FunctionClassKind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString())
|
||||
}
|
||||
|
||||
fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean {
|
||||
return functionClassKind(session) != null
|
||||
val kind = functionClassKind(session) ?: return false
|
||||
return kind == FunctionClassKind.Function ||
|
||||
kind == FunctionClassKind.KFunction ||
|
||||
kind == FunctionClassKind.SuspendFunction ||
|
||||
kind == FunctionClassKind.KSuspendFunction
|
||||
}
|
||||
|
||||
fun ConeKotlinType.isFunctionalType(session: FirSession): Boolean {
|
||||
@@ -62,10 +62,6 @@ fun ConeKotlinType.isFunctionalType(session: FirSession): Boolean {
|
||||
return kind == FunctionClassKind.Function
|
||||
}
|
||||
|
||||
fun ConeClassLikeLookupTag.isBuiltinFunctionalType(): Boolean {
|
||||
return classId.toFunctionClassKind() != null
|
||||
}
|
||||
|
||||
fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
|
||||
val kind = functionClassKind(session) ?: return false
|
||||
return kind == FunctionClassKind.SuspendFunction ||
|
||||
|
||||
@@ -10,10 +10,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
|
||||
abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
|
||||
@@ -166,15 +162,3 @@ data class ConeSubstitutorByMap(val substitution: Map<FirTypeParameterSymbol, Co
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
||||
if (map.isEmpty()) return ConeSubstitutor.Empty
|
||||
return object : AbstractConeSubstitutor(),
|
||||
TypeSubstitutorMarker {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
||||
val new = map[type.typeConstructor(context)] ?: return null
|
||||
return new.approximateIntegerLiteralType().updateNullabilityIfNeeded(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.CallableReferenceAdaptation
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.varargElementType
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
@@ -293,7 +295,6 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
name = calleeReference.name
|
||||
resolvedSymbol = calleeReference.candidateSymbol
|
||||
inferredTypeArguments.addAll(computeTypeArgumentTypes(calleeReference.candidate))
|
||||
mappedArguments = subCandidate.callableReferenceAdaptation?.mappedArguments ?: emptyMap()
|
||||
},
|
||||
).transformDispatchReceiver(StoreReceiver, subCandidate.dispatchReceiverExpression())
|
||||
.transformExtensionReceiver(StoreReceiver, subCandidate.extensionReceiverExpression())
|
||||
|
||||
@@ -989,8 +989,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
if (variable.returnTypeRef is FirImplicitTypeRef) {
|
||||
when {
|
||||
initializer != null -> {
|
||||
val unwrappedInitializer = (initializer as? FirExpressionWithSmartcast)?.originalExpression ?: initializer
|
||||
val expectedType = when (val resultType = unwrappedInitializer.resultType) {
|
||||
val expectedType = when (val resultType = initializer.resultType) {
|
||||
is FirImplicitTypeRef -> buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError)
|
||||
}
|
||||
|
||||
@@ -496,8 +496,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
if (baseType !is ConeClassLikeType) return this
|
||||
val baseFirClass = baseType.lookupTag.toSymbol(session)?.fir ?: return this
|
||||
|
||||
val newArguments = if (AbstractTypeChecker.isSubtypeOfClass(
|
||||
session.typeContext.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true), baseType.lookupTag, type.lookupTag)) {
|
||||
val newArguments = if (AbstractTypeChecker.isSubtypeOfClass(session.typeCheckerContext, baseType.lookupTag, type.lookupTag)) {
|
||||
// If actual type of declaration is more specific than bare type then we should just find
|
||||
// corresponding supertype with proper arguments
|
||||
with(session.typeContext) {
|
||||
|
||||
@@ -13,11 +13,9 @@ import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
private val INVISIBLE_DEFAULT_STAR_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultStarImportingScope>()
|
||||
private val VISIBLE_DEFAULT_STAR_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultStarImportingScope>()
|
||||
private val DEFAULT_SIMPLE_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultSimpleImportingScope>()
|
||||
private val PACKAGE_MEMBER = scopeSessionKey<FqName, FirPackageMemberScope>()
|
||||
private val ALL_IMPORTS = scopeSessionKey<FirFile, ListStorageFirScope>()
|
||||
private object FirDefaultStarImportingScopeKey : ScopeSessionKey<DefaultImportPriority, FirScope>()
|
||||
private object FirDefaultSimpleImportingScopeKey : ScopeSessionKey<DefaultImportPriority, FirScope>()
|
||||
private object FileImportingScopeKey : ScopeSessionKey<FirFile, ListStorageFirScope>()
|
||||
|
||||
private class ListStorageFirScope(val result: List<FirScope>) : FirScope()
|
||||
|
||||
@@ -27,7 +25,7 @@ fun createImportingScopes(
|
||||
scopeSession: ScopeSession,
|
||||
useCaching: Boolean = true
|
||||
): List<FirScope> = if (useCaching) {
|
||||
scopeSession.getOrBuild(file, ALL_IMPORTS) {
|
||||
scopeSession.getOrBuild(file, FileImportingScopeKey) {
|
||||
ListStorageFirScope(doCreateImportingScopes(file, session, scopeSession))
|
||||
}.result
|
||||
} else {
|
||||
@@ -41,26 +39,17 @@ private fun doCreateImportingScopes(
|
||||
): List<FirScope> {
|
||||
return listOf(
|
||||
// from low priority to high priority
|
||||
scopeSession.getOrBuild(DefaultImportPriority.LOW, INVISIBLE_DEFAULT_STAR_IMPORT) {
|
||||
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES, DefaultImportPriority.LOW)
|
||||
scopeSession.getOrBuild(DefaultImportPriority.LOW, FirDefaultStarImportingScopeKey) {
|
||||
FirDefaultStarImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
|
||||
},
|
||||
scopeSession.getOrBuild(DefaultImportPriority.HIGH, INVISIBLE_DEFAULT_STAR_IMPORT) {
|
||||
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES, DefaultImportPriority.HIGH)
|
||||
scopeSession.getOrBuild(DefaultImportPriority.HIGH, FirDefaultStarImportingScopeKey) {
|
||||
FirDefaultStarImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
|
||||
},
|
||||
FirExplicitStarImportingScope(file.imports, session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES),
|
||||
// TODO: invisible classes from current package should go before this point
|
||||
scopeSession.getOrBuild(DefaultImportPriority.LOW, VISIBLE_DEFAULT_STAR_IMPORT) {
|
||||
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.MEMBERS_AND_VISIBLE_CLASSES, DefaultImportPriority.LOW)
|
||||
},
|
||||
scopeSession.getOrBuild(DefaultImportPriority.HIGH, VISIBLE_DEFAULT_STAR_IMPORT) {
|
||||
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.MEMBERS_AND_VISIBLE_CLASSES, DefaultImportPriority.HIGH)
|
||||
},
|
||||
FirExplicitStarImportingScope(file.imports, session, scopeSession, FirImportingScopeFilter.MEMBERS_AND_VISIBLE_CLASSES),
|
||||
|
||||
scopeSession.getOrBuild(DefaultImportPriority.LOW, DEFAULT_SIMPLE_IMPORT) {
|
||||
FirExplicitStarImportingScope(file.imports, session, scopeSession),
|
||||
scopeSession.getOrBuild(DefaultImportPriority.LOW, FirDefaultSimpleImportingScopeKey) {
|
||||
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
|
||||
},
|
||||
scopeSession.getOrBuild(DefaultImportPriority.HIGH, DEFAULT_SIMPLE_IMPORT) {
|
||||
scopeSession.getOrBuild(DefaultImportPriority.HIGH, FirDefaultSimpleImportingScopeKey) {
|
||||
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
|
||||
},
|
||||
scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
|
||||
@@ -71,6 +60,8 @@ private fun doCreateImportingScopes(
|
||||
)
|
||||
}
|
||||
|
||||
private val PACKAGE_MEMBER = scopeSessionKey<FqName, FirPackageMemberScope>()
|
||||
|
||||
fun ConeClassLikeLookupTag.getNestedClassifierScope(session: FirSession, scopeSession: ScopeSession): FirScope? {
|
||||
val klass = toSymbol(session)?.fir as? FirRegularClass ?: return null
|
||||
return klass.scopeProvider.getNestedClassifierScope(klass, session, scopeSession)
|
||||
|
||||
@@ -6,12 +6,9 @@
|
||||
package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
|
||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.moduleVisibilityChecker
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls
|
||||
@@ -20,90 +17,52 @@ import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_THROWS_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.annotations.KOTLIN_NATIVE_THROWS_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.annotations.KOTLIN_THROWS_ANNOTATION_FQ_NAME
|
||||
|
||||
enum class FirImportingScopeFilter {
|
||||
ALL, INVISIBLE_CLASSES, MEMBERS_AND_VISIBLE_CLASSES;
|
||||
|
||||
fun check(symbol: FirClassLikeSymbol<*>, session: FirSession): Boolean {
|
||||
if (this == ALL) return true
|
||||
// TODO: also check DeprecationLevel.HIDDEN and required Kotlin version
|
||||
val fir = symbol.fir as? FirMemberDeclaration ?: return false
|
||||
val isVisible = when (fir.status.visibility) {
|
||||
// When importing from the same module, status may be unknown because the status resolver depends on super types
|
||||
// to determine visibility for functions, so it may not have finished yet. Since we only care about classes,
|
||||
// though, "unknown" will always become public anyway.
|
||||
Visibilities.Unknown -> true
|
||||
Visibilities.Internal ->
|
||||
symbol.fir.session == session || session.moduleVisibilityChecker?.isInFriendModule(fir) == true
|
||||
// All non-`internal` visibilities are either even more restrictive (e.g. `private`) or must not
|
||||
// be checked in imports (e.g. `protected` may be valid in some use sites).
|
||||
else -> !fir.status.visibility.mustCheckInImports()
|
||||
}
|
||||
return isVisible == (this == MEMBERS_AND_VISIBLE_CLASSES)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FirAbstractImportingScope(
|
||||
session: FirSession,
|
||||
protected val scopeSession: ScopeSession,
|
||||
protected val filter: FirImportingScopeFilter,
|
||||
lookupInFir: Boolean
|
||||
) : FirAbstractProviderBasedScope(session, lookupInFir) {
|
||||
private val FirClassLikeSymbol<*>.fullyExpandedSymbol: FirClassSymbol<*>?
|
||||
get() = when (this) {
|
||||
is FirTypeAliasSymbol -> fir.expandedConeType?.lookupTag?.toSymbol(session)?.fullyExpandedSymbol
|
||||
is FirClassSymbol<*> -> this
|
||||
}
|
||||
|
||||
private fun FirClassSymbol<*>.getStaticsScope(): FirScope? =
|
||||
if (fir.classKind == ClassKind.OBJECT) {
|
||||
FirObjectImportedCallableScope(
|
||||
classId, fir.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
|
||||
)
|
||||
private fun getStaticsScope(symbol: FirClassLikeSymbol<*>): FirScope? {
|
||||
if (symbol is FirTypeAliasSymbol) {
|
||||
val expansionSymbol = symbol.fir.expandedConeType?.lookupTag?.toSymbol(session)
|
||||
if (expansionSymbol != null) {
|
||||
return getStaticsScope(expansionSymbol)
|
||||
}
|
||||
} else {
|
||||
fir.scopeProvider.getStaticScope(fir, session, scopeSession)
|
||||
}
|
||||
val firClass = (symbol as FirClassSymbol<*>).fir
|
||||
|
||||
fun getStaticsScope(classId: ClassId): FirScope? =
|
||||
provider.getClassLikeSymbolByFqName(classId)?.fullyExpandedSymbol?.getStaticsScope()
|
||||
|
||||
protected fun findSingleClassifierSymbolByName(name: Name?, imports: List<FirResolvedImport>): FirClassLikeSymbol<*>? {
|
||||
var result: FirClassLikeSymbol<*>? = null
|
||||
for (import in imports) {
|
||||
val importedName = name ?: import.importedName ?: continue
|
||||
val classId = import.resolvedClassId?.createNestedClassId(importedName)
|
||||
?: ClassId.topLevel(import.packageFqName.child(importedName))
|
||||
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: continue
|
||||
if (!filter.check(symbol, session)) continue
|
||||
result = when {
|
||||
result == null || result == symbol -> symbol
|
||||
// Importing multiple versions of the same type is normally an ambiguity, but in the case of `kotlin.Throws`,
|
||||
// it should take precedence over platform-specific variants. This is lifted directly from `LazyImportScope`
|
||||
// from the old backend; most likely `Throws` predates expect-actual, and this is a backwards compatibility hack.
|
||||
// TODO: remove redundant versions of `Throws` from the standard library
|
||||
result.classId.isJvmOrNativeThrows && symbol.classId.isCommonThrows -> symbol
|
||||
result.classId.isCommonThrows && symbol.classId.isJvmOrNativeThrows -> result
|
||||
// TODO: if there is an ambiguity at this scope, further scopes should not be checked.
|
||||
// Doing otherwise causes KT-39073. Also, returning null here instead of an error symbol
|
||||
// or something produces poor quality diagnostics ("unresolved name" rather than "ambiguity").
|
||||
else -> return null
|
||||
return if (firClass.classKind == ClassKind.OBJECT) {
|
||||
FirObjectImportedCallableScope(
|
||||
symbol.classId,
|
||||
firClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
|
||||
)
|
||||
} else {
|
||||
firClass.scopeProvider.getStaticScope(firClass, session, scopeSession)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
protected fun processFunctionsByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||
if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
|
||||
for (import in imports) {
|
||||
val importedName = name ?: import.importedName ?: continue
|
||||
val staticsScope = import.resolvedClassId?.let(::getStaticsScope)
|
||||
if (staticsScope != null) {
|
||||
staticsScope.processFunctionsByName(importedName, processor)
|
||||
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
|
||||
for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, importedName)) {
|
||||
fun getStaticsScope(classId: ClassId): FirScope? {
|
||||
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: return null
|
||||
return getStaticsScope(symbol)
|
||||
}
|
||||
|
||||
protected inline fun processFunctionsByNameWithImport(
|
||||
name: Name,
|
||||
import: FirResolvedImport,
|
||||
crossinline processor: (FirNamedFunctionSymbol) -> Unit
|
||||
) {
|
||||
import.resolvedClassId?.let { classId ->
|
||||
getStaticsScope(classId)?.processFunctionsByName(name) { processor(it) }
|
||||
} ?: run {
|
||||
if (name.isSpecial || name.identifier.isNotEmpty()) {
|
||||
val symbols = provider.getTopLevelFunctionSymbols(import.packageFqName, name)
|
||||
for (symbol in symbols) {
|
||||
symbol.ensureResolvedForCalls(session)
|
||||
processor(symbol)
|
||||
}
|
||||
@@ -111,15 +70,17 @@ abstract class FirAbstractImportingScope(
|
||||
}
|
||||
}
|
||||
|
||||
protected fun processPropertiesByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
|
||||
for (import in imports) {
|
||||
val importedName = name ?: import.importedName ?: continue
|
||||
val staticsScope = import.resolvedClassId?.let(::getStaticsScope)
|
||||
if (staticsScope != null) {
|
||||
staticsScope.processPropertiesByName(importedName, processor)
|
||||
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
|
||||
for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, importedName)) {
|
||||
protected inline fun processPropertiesByNameWithImport(
|
||||
name: Name,
|
||||
import: FirResolvedImport,
|
||||
crossinline processor: (FirVariableSymbol<*>) -> Unit
|
||||
) {
|
||||
import.resolvedClassId?.let { classId ->
|
||||
getStaticsScope(classId)?.processPropertiesByName(name) { processor(it) }
|
||||
} ?: run {
|
||||
if (name.isSpecial || name.identifier.isNotEmpty()) {
|
||||
val symbols = provider.getTopLevelPropertySymbols(import.packageFqName, name)
|
||||
for (symbol in symbols) {
|
||||
symbol.ensureResolvedForCalls(session)
|
||||
processor(symbol)
|
||||
}
|
||||
@@ -127,9 +88,3 @@ abstract class FirAbstractImportingScope(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val ClassId.isJvmOrNativeThrows: Boolean
|
||||
get() = asSingleFqName().let { it == JVM_THROWS_ANNOTATION_FQ_NAME || it == KOTLIN_NATIVE_THROWS_ANNOTATION_FQ_NAME }
|
||||
|
||||
private val ClassId.isCommonThrows: Boolean
|
||||
get() = asSingleFqName() == KOTLIN_THROWS_ANNOTATION_FQ_NAME
|
||||
|
||||
@@ -8,33 +8,47 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
abstract class FirAbstractSimpleImportingScope(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : FirAbstractImportingScope(session, scopeSession, FirImportingScopeFilter.ALL, lookupInFir = true) {
|
||||
) : FirAbstractImportingScope(session, scopeSession, lookupInFir = true) {
|
||||
|
||||
// TODO try to hide this
|
||||
abstract val simpleImports: Map<Name, List<FirResolvedImport>>
|
||||
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
val imports = simpleImports[name] ?: return
|
||||
val symbol = findSingleClassifierSymbolByName(null, imports) ?: return
|
||||
processor(symbol, ConeSubstitutor.Empty)
|
||||
if (imports.isEmpty()) return
|
||||
val provider = session.symbolProvider
|
||||
for (import in imports) {
|
||||
val importedName = import.importedName ?: continue
|
||||
val classId =
|
||||
import.resolvedClassId?.createNestedClassId(importedName)
|
||||
?: ClassId.topLevel(import.packageFqName.child(importedName))
|
||||
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: continue
|
||||
processor(symbol, ConeSubstitutor.Empty)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||
val imports = simpleImports[name] ?: return
|
||||
processFunctionsByName(null, imports, processor)
|
||||
for (import in imports) {
|
||||
processFunctionsByNameWithImport(import.importedName!!, import, processor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
val imports = simpleImports[name] ?: return
|
||||
processPropertiesByName(null, imports, processor)
|
||||
for (import in imports) {
|
||||
processPropertiesByNameWithImport(import.importedName!!, import, processor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,14 +12,14 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
abstract class FirAbstractStarImportingScope(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
filter: FirImportingScopeFilter,
|
||||
lookupInFir: Boolean
|
||||
) : FirAbstractImportingScope(session, scopeSession, filter, lookupInFir) {
|
||||
lookupInFir: Boolean = true
|
||||
) : FirAbstractImportingScope(session, scopeSession, lookupInFir) {
|
||||
|
||||
// TODO try to hide this
|
||||
abstract val starImports: List<FirResolvedImport>
|
||||
@@ -27,20 +27,35 @@ abstract class FirAbstractStarImportingScope(
|
||||
private val absentClassifierNames = mutableSetOf<Name>()
|
||||
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
if ((!name.isSpecial && name.identifier.isEmpty()) || starImports.isEmpty() || name in absentClassifierNames) {
|
||||
if (starImports.isEmpty() || name in absentClassifierNames) {
|
||||
return
|
||||
}
|
||||
val symbol = findSingleClassifierSymbolByName(name, starImports)
|
||||
if (symbol != null) {
|
||||
var empty = true
|
||||
for (import in starImports) {
|
||||
val relativeClassName = import.relativeClassName
|
||||
val classId = when {
|
||||
!name.isSpecial && name.identifier.isEmpty() -> return
|
||||
relativeClassName == null -> ClassId(import.packageFqName, name)
|
||||
else -> ClassId(import.packageFqName, relativeClassName.child(name), false)
|
||||
}
|
||||
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: continue
|
||||
empty = false
|
||||
processor(symbol, ConeSubstitutor.Empty)
|
||||
} else {
|
||||
}
|
||||
if (empty) {
|
||||
absentClassifierNames += name
|
||||
}
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) =
|
||||
processFunctionsByName(name, starImports, processor)
|
||||
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||
for (import in starImports) {
|
||||
processFunctionsByNameWithImport(name, import, processor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) =
|
||||
processPropertiesByName(name, starImports, processor)
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
for (import in starImports) {
|
||||
processPropertiesByNameWithImport(name, import, processor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
@@ -24,10 +23,6 @@ class FirClassUseSiteMemberScope(
|
||||
val seen = mutableSetOf<FirVariableSymbol<*>>()
|
||||
declaredMemberScope.processPropertiesByName(name) l@{
|
||||
if (it.isStatic) return@l
|
||||
if (it is FirPropertySymbol) {
|
||||
val directOverridden = computeDirectOverridden(it.fir)
|
||||
this@FirClassUseSiteMemberScope.directOverriddenProperties[it] = directOverridden
|
||||
}
|
||||
seen += it
|
||||
processor(it)
|
||||
}
|
||||
@@ -36,18 +31,9 @@ class FirClassUseSiteMemberScope(
|
||||
val overriddenBy = it.getOverridden(seen)
|
||||
if (overriddenBy == null) {
|
||||
processor(it)
|
||||
} else if (overriddenBy is FirPropertySymbol && it is FirPropertySymbol) {
|
||||
directOverriddenProperties.getOrPut(overriddenBy) { mutableListOf() }.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeDirectOverridden(property: FirProperty): MutableList<FirPropertySymbol> {
|
||||
val result = mutableListOf<FirPropertySymbol>()
|
||||
superTypesScope.processPropertiesByName(property.name) l@{ superSymbol ->
|
||||
if (superSymbol !is FirPropertySymbol) return@l
|
||||
if (overrideChecker.isOverriddenProperty(property, superSymbol.fir)) {
|
||||
result.add(superSymbol)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,8 @@ import org.jetbrains.kotlin.name.Name
|
||||
class FirDefaultStarImportingScope(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
filter: FirImportingScopeFilter,
|
||||
priority: DefaultImportPriority
|
||||
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = false) {
|
||||
) : FirAbstractStarImportingScope(session, scopeSession, lookupInFir = false) {
|
||||
|
||||
// TODO: put languageVersionSettings into FirSession?
|
||||
override val starImports = run {
|
||||
@@ -39,7 +38,6 @@ class FirDefaultStarImportingScope(
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||
if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
|
||||
if (name.isSpecial || name.identifier.isNotEmpty()) {
|
||||
for (import in starImports) {
|
||||
for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, name)) {
|
||||
@@ -50,7 +48,6 @@ class FirDefaultStarImportingScope(
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
|
||||
if (name.isSpecial || name.identifier.isNotEmpty()) {
|
||||
for (import in starImports) {
|
||||
for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, name)) {
|
||||
|
||||
@@ -13,8 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
class FirExplicitStarImportingScope(
|
||||
imports: List<FirImport>,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
filter: FirImportingScopeFilter
|
||||
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = true) {
|
||||
scopeSession: ScopeSession
|
||||
) : FirAbstractStarImportingScope(session, scopeSession) {
|
||||
override val starImports = imports.filterIsInstance<FirResolvedImport>().filter { it.isAllUnder }
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
@@ -110,8 +109,6 @@ class FirStandardOverrideChecker(session: FirSession) : FirAbstractOverrideCheck
|
||||
}
|
||||
|
||||
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
|
||||
if (Visibilities.isPrivate(baseDeclaration.visibility)) return false
|
||||
|
||||
if (overrideCandidate.valueParameters.size != baseDeclaration.valueParameters.size) return false
|
||||
|
||||
val substitutor = buildTypeParametersSubstitutorIfCompatible(overrideCandidate, baseDeclaration) ?: return false
|
||||
@@ -127,8 +124,6 @@ class FirStandardOverrideChecker(session: FirSession) : FirAbstractOverrideCheck
|
||||
overrideCandidate: FirCallableMemberDeclaration<*>,
|
||||
baseDeclaration: FirProperty
|
||||
): Boolean {
|
||||
if (Visibilities.isPrivate(baseDeclaration.visibility)) return false
|
||||
|
||||
if (overrideCandidate !is FirProperty) return false
|
||||
val substitutor = buildTypeParametersSubstitutorIfCompatible(overrideCandidate, baseDeclaration) ?: return false
|
||||
return isEqualReceiverTypes(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitutor)
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
@@ -34,7 +33,7 @@ class FirTypeIntersectionScope private constructor(
|
||||
private val absentProperties: MutableSet<Name> = mutableSetOf()
|
||||
private val absentClassifiers: MutableSet<Name> = mutableSetOf()
|
||||
|
||||
private val typeCheckerContext = session.typeContext.newBaseTypeCheckerContext(false, false)
|
||||
private val typeContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session)
|
||||
|
||||
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<out FirCallableSymbol<*>>>> =
|
||||
mutableMapOf()
|
||||
@@ -358,7 +357,7 @@ class FirTypeIntersectionScope private constructor(
|
||||
require(bFir is FirProperty) { "b is " + b.javaClass }
|
||||
// TODO: if (!OverridingUtil.isAccessorMoreSpecific(pa.getSetter(), pb.getSetter())) return false
|
||||
return if (aFir.isVar && bFir.isVar) {
|
||||
AbstractTypeChecker.equalTypes(typeCheckerContext as AbstractTypeCheckerContext, aReturnType, bReturnType)
|
||||
AbstractTypeChecker.equalTypes(typeContext as AbstractTypeCheckerContext, aReturnType, bReturnType)
|
||||
} else { // both vals or var vs val: val can't be more specific then var
|
||||
!(!aFir.isVar && bFir.isVar) && isTypeMoreSpecific(aReturnType, bReturnType)
|
||||
}
|
||||
@@ -367,7 +366,7 @@ class FirTypeIntersectionScope private constructor(
|
||||
}
|
||||
|
||||
private fun isTypeMoreSpecific(a: ConeKotlinType, b: ConeKotlinType): Boolean =
|
||||
AbstractTypeChecker.isSubtypeOf(typeCheckerContext as AbstractTypeCheckerContext, a, b)
|
||||
AbstractTypeChecker.isSubtypeOf(typeContext as AbstractTypeCheckerContext, a, b)
|
||||
|
||||
private fun <D : FirCallableSymbol<*>> findMemberWithMaxVisibility(members: Collection<MemberWithBaseScope<D>>): MemberWithBaseScope<D> {
|
||||
assert(members.isNotEmpty())
|
||||
|
||||
@@ -11,7 +11,7 @@ fun ConeKotlinType.createOutArrayType(nullable: Boolean = false): ConeKotlinType
|
||||
return ConeKotlinTypeProjectionOut(this).createArrayType(nullable)
|
||||
}
|
||||
|
||||
fun ConeTypeProjection.createArrayType(nullable: Boolean = false): ConeClassLikeType {
|
||||
fun ConeTypeProjection.createArrayType(nullable: Boolean = false): ConeKotlinType {
|
||||
if (this is ConeKotlinTypeProjection) {
|
||||
val type = type.lowerBoundIfFlexible()
|
||||
if (type is ConeClassLikeType && type.nullability != ConeNullability.NULLABLE) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user