Decrease resolution priority of declarations from kotlin-stdlib-jre7/8
In order to allow "overload resolution ambiguity" when both kotlin-stdlib-jre7/8 and kotlin-stdlib-jdk7/8 are in the dependencies
This commit is contained in:
committed by
Ilya Gorbunov
parent
1592555783
commit
a4f378d04d
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.USE_NEW_INFERENCE
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForTypeAliasObject
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isLowPriorityFromStdlibJre7Or8
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassValueDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasHidesMembersAnnotation
|
||||
@@ -59,7 +60,9 @@ internal abstract class AbstractScopeTowerLevel(
|
||||
diagnostics.add(ErrorDescriptorDiagnostic)
|
||||
}
|
||||
else {
|
||||
if (descriptor.hasLowPriorityInOverloadResolution()) diagnostics.add(LowPriorityDescriptorDiagnostic)
|
||||
if (descriptor.hasLowPriorityInOverloadResolution() || descriptor.isLowPriorityFromStdlibJre7Or8()) {
|
||||
diagnostics.add(LowPriorityDescriptorDiagnostic)
|
||||
}
|
||||
if (dispatchReceiverSmartCastType != null) diagnostics.add(UsedSmartCastForDispatchReceiver(dispatchReceiverSmartCastType))
|
||||
|
||||
if (!USE_NEW_INFERENCE) {
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.util
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.SINCE_KOTLIN_FQ_NAME
|
||||
|
||||
private val kotlin: FqName = KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
||||
private val kotlinText: FqName = KotlinBuiltIns.TEXT_PACKAGE_FQ_NAME
|
||||
private val kotlinCollections: FqName = KotlinBuiltIns.COLLECTIONS_PACKAGE_FQ_NAME
|
||||
private val kotlinStreams: FqName = kotlin.child(Name.identifier("streams"))
|
||||
|
||||
private val use: Name = Name.identifier("use")
|
||||
private val get: Name = Name.identifier("get")
|
||||
private val getOrDefault: Name = Name.identifier("getOrDefault")
|
||||
private val remove: Name = Name.identifier("remove")
|
||||
|
||||
// We treat all declarations in deprecated libraries kotlin-stdlib-jre7 and kotlin-stdlib-jre8 as if they were
|
||||
// annotated with @LowPriorityInOverloadResolution.
|
||||
// This is needed in order to avoid reporting "overload resolution ambiguity" in case when there's both kotlin-stdlib-jreN and
|
||||
// kotlin-stdlib-jdkN in dependencies, to allow smooth migration from the former to the latter. The ambiguity here would be incorrect
|
||||
// because there's really no ambiguity in the bytecode since all declarations in -jdk7/8 have been moved to another JVM package.
|
||||
// We locate declarations in kotlin-stdlib-jre{7,8} by FQ name and @SinceKotlin annotation value, which should be 1.1.
|
||||
fun CallableDescriptor.isLowPriorityFromStdlibJre7Or8(): Boolean {
|
||||
val containingPackage = containingDeclaration as? PackageFragmentDescriptor ?: return false
|
||||
val packageFqName = containingPackage.fqName
|
||||
if (!packageFqName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) return false
|
||||
|
||||
val isFromStdlibJre7Or8 =
|
||||
packageFqName == kotlin && name == use ||
|
||||
packageFqName == kotlinText && name == get ||
|
||||
packageFqName == kotlinCollections && (name == getOrDefault || name == remove) ||
|
||||
packageFqName == kotlinStreams
|
||||
|
||||
if (!isFromStdlibJre7Or8) return false
|
||||
|
||||
val sinceKotlin = annotations.findAnnotation(SINCE_KOTLIN_FQ_NAME) ?: return false
|
||||
val version = sinceKotlin.allValueArguments.values.singleOrNull()?.value as? String ?: return false
|
||||
|
||||
return version == LanguageVersion.KOTLIN_1_1.versionString
|
||||
}
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,13 +23,13 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForTypeAliasObject
|
||||
|
||||
internal val SINCE_KOTLIN_FQ_NAME = FqName("kotlin.SinceKotlin")
|
||||
val SINCE_KOTLIN_FQ_NAME = FqName("kotlin.SinceKotlin")
|
||||
|
||||
/**
|
||||
* @return true if the descriptor is accessible according to [languageVersionSettings], or false otherwise. The [actionIfInaccessible]
|
||||
* callback is called with the version specified in the [SinceKotlin] annotation if the descriptor is inaccessible.
|
||||
*/
|
||||
internal fun DeclarationDescriptor.checkSinceKotlinVersionAccessibility(
|
||||
fun DeclarationDescriptor.checkSinceKotlinVersionAccessibility(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
actionIfInaccessible: ((ApiVersion) -> Unit)? = null
|
||||
): Boolean {
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
OUT:
|
||||
Buildfile: [TestData]/build.xml
|
||||
|
||||
build:
|
||||
[kotlinc] Compiling [[TestData]/main.kt] => [[Temp]/test.jar]
|
||||
|
||||
BUILD SUCCESSFUL
|
||||
Total time: [time]
|
||||
|
||||
Return code: 0
|
||||
@@ -0,0 +1,15 @@
|
||||
<project name="Ant Task Test" default="build">
|
||||
<taskdef resource="org/jetbrains/kotlin/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||
|
||||
<target name="build">
|
||||
<kotlinc src="${test.data}/main.kt" output="${temp}/test.jar" nowarn="true">
|
||||
<classpath>
|
||||
<file file="${kotlin.stdlib.jre7.jar}"/>
|
||||
<file file="${kotlin.stdlib.jre8.jar}"/>
|
||||
<file file="${kotlin.stdlib.jdk7.jar}"/>
|
||||
<file file="${kotlin.stdlib.jdk8.jar}"/>
|
||||
</classpath>
|
||||
<compilerarg line="-jvm-target 1.8"/>
|
||||
</kotlinc>
|
||||
</target>
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
import java.util.stream.Stream
|
||||
import kotlin.streams.*
|
||||
|
||||
// kotlin-stdlib-jdk7
|
||||
|
||||
fun testUse(c: AutoCloseable) = c.use {}
|
||||
|
||||
// kotlin-stdlib-jdk8
|
||||
|
||||
fun testGet(c: MatchGroupCollection) = c.get("")
|
||||
|
||||
fun testGetOrDefault(c: Map<out Number, Any>) = c.getOrDefault(42, "")
|
||||
fun testRemove(c: MutableMap<out Number, Any>) = c.remove(42, "")
|
||||
|
||||
fun testAsSequence(c: Stream<String>) = c.asSequence()
|
||||
@@ -33,6 +33,10 @@ public abstract class AbstractAntTaskTest extends KotlinIntegrationTestBase {
|
||||
"-Dkotlin.lib=" + KotlinIntegrationTestBase.getCompilerLib(),
|
||||
"-Dkotlin.runtime.jar=" + ForTestCompileRuntime.runtimeJarForTests().getAbsolutePath(),
|
||||
"-Dkotlin.reflect.jar=" + ForTestCompileRuntime.reflectJarForTests().getAbsolutePath(),
|
||||
"-Dkotlin.stdlib.jre7.jar=" + new File("dist/kotlinc/lib/kotlin-stdlib-jre7.jar").getAbsolutePath(),
|
||||
"-Dkotlin.stdlib.jre8.jar=" + new File("dist/kotlinc/lib/kotlin-stdlib-jre8.jar").getAbsolutePath(),
|
||||
"-Dkotlin.stdlib.jdk7.jar=" + new File("dist/kotlinc/lib/kotlin-stdlib-jdk7.jar").getAbsolutePath(),
|
||||
"-Dkotlin.stdlib.jdk8.jar=" + new File("dist/kotlinc/lib/kotlin-stdlib-jdk8.jar").getAbsolutePath(),
|
||||
"-Dtest.data=" + testDataDir,
|
||||
"-Dtemp=" + tmpdir,
|
||||
"-f", "build.xml"
|
||||
|
||||
@@ -132,6 +132,12 @@ public class AntTaskTestGenerated extends AbstractAntTaskTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stdlibJre78AndStdlibJdk78")
|
||||
public void testStdlibJre78AndStdlibJdk78() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/integration/ant/jvm/stdlibJre78AndStdlibJdk78/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("suppressWarnings")
|
||||
public void testSuppressWarnings() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/integration/ant/jvm/suppressWarnings/");
|
||||
|
||||
Reference in New Issue
Block a user