Use LanguageFeatureSettings instead of custom option for bound callable references
This commit is contained in:
@@ -18,12 +18,13 @@ package org.jetbrains.kotlin.config
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersion.KOTLIN_1_1
|
import org.jetbrains.kotlin.config.LanguageVersion.KOTLIN_1_1
|
||||||
|
|
||||||
|
|
||||||
enum class LanguageFeature(val sinceVersion: LanguageVersion) {
|
enum class LanguageFeature(val sinceVersion: LanguageVersion) {
|
||||||
// Note: names of these entries are also used in diagnostic tests
|
// Note: names of these entries are also used in diagnostic tests
|
||||||
TypeAliases(KOTLIN_1_1),
|
TypeAliases(KOTLIN_1_1),
|
||||||
|
BoundCallableReferences(KOTLIN_1_1),
|
||||||
LocalDelegatedProperties(KOTLIN_1_1),
|
LocalDelegatedProperties(KOTLIN_1_1),
|
||||||
TopLevelSealedInheritance(KOTLIN_1_1);
|
TopLevelSealedInheritance(KOTLIN_1_1),
|
||||||
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
+13
-6
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.types.expressions
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeatureSettings
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
@@ -40,9 +42,6 @@ import org.jetbrains.kotlin.types.TypeUtils
|
|||||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
// TODO: use a language level option
|
|
||||||
val BOUND_REFERENCES_ENABLED by lazy { System.getProperty("kotlin.lang.enable.bound.references") == "true" }
|
|
||||||
|
|
||||||
sealed class DoubleColonLHS(val type: KotlinType) {
|
sealed class DoubleColonLHS(val type: KotlinType) {
|
||||||
class Expression(val typeInfo: KotlinTypeInfo) : DoubleColonLHS(typeInfo.type!!)
|
class Expression(val typeInfo: KotlinTypeInfo) : DoubleColonLHS(typeInfo.type!!)
|
||||||
|
|
||||||
@@ -58,7 +57,8 @@ class DoubleColonExpressionResolver(
|
|||||||
val qualifiedExpressionResolver: QualifiedExpressionResolver,
|
val qualifiedExpressionResolver: QualifiedExpressionResolver,
|
||||||
val dataFlowAnalyzer: DataFlowAnalyzer,
|
val dataFlowAnalyzer: DataFlowAnalyzer,
|
||||||
val reflectionTypes: ReflectionTypes,
|
val reflectionTypes: ReflectionTypes,
|
||||||
val typeResolver: TypeResolver
|
val typeResolver: TypeResolver,
|
||||||
|
val languageFeatureSettings: LanguageFeatureSettings
|
||||||
) {
|
) {
|
||||||
private lateinit var expressionTypingServices: ExpressionTypingServices
|
private lateinit var expressionTypingServices: ExpressionTypingServices
|
||||||
|
|
||||||
@@ -120,13 +120,20 @@ class DoubleColonExpressionResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun shouldTryResolveLHSAsExpression(expression: KtDoubleColonExpression): Boolean {
|
||||||
|
// TODO: improve diagnostic when bound callable references are disabled
|
||||||
|
if (!languageFeatureSettings.supportsFeature(LanguageFeature.BoundCallableReferences)) return false
|
||||||
|
|
||||||
|
val lhs = expression.receiverExpression ?: return false
|
||||||
|
return lhs.canBeConsideredProperExpression() && !expression.hasQuestionMarks /* TODO: test this */
|
||||||
|
}
|
||||||
|
|
||||||
private fun resolveDoubleColonLHS(
|
private fun resolveDoubleColonLHS(
|
||||||
expression: KtExpression, doubleColonExpression: KtDoubleColonExpression, c: ExpressionTypingContext
|
expression: KtExpression, doubleColonExpression: KtDoubleColonExpression, c: ExpressionTypingContext
|
||||||
): DoubleColonLHS? {
|
): DoubleColonLHS? {
|
||||||
// First, try resolving the LHS as expression, if possible
|
// First, try resolving the LHS as expression, if possible
|
||||||
|
|
||||||
if (BOUND_REFERENCES_ENABLED && expression.canBeConsideredProperExpression() &&
|
if (shouldTryResolveLHSAsExpression(doubleColonExpression)) {
|
||||||
!doubleColonExpression.hasQuestionMarks /* TODO: test this */) {
|
|
||||||
val traceForExpr = TemporaryTraceAndCache.create(c, "resolve '::' LHS as expression", expression)
|
val traceForExpr = TemporaryTraceAndCache.create(c, "resolve '::' LHS as expression", expression)
|
||||||
val contextForExpr = c.replaceTraceAndCache(traceForExpr)
|
val contextForExpr = c.replaceTraceAndCache(traceForExpr)
|
||||||
val typeInfo = expressionTypingServices.getTypeInfo(expression, contextForExpr)
|
val typeInfo = expressionTypingServices.getTypeInfo(expression, contextForExpr)
|
||||||
|
|||||||
+1
-1
@@ -15,6 +15,6 @@ data class User(val surname: String)
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
bar<String> {
|
bar<String> {
|
||||||
<!UNUSED_EXPRESSION!>User::surname<!>
|
<!UNUSED_EXPRESSION!><!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>User<!>::<!OVERLOAD_RESOLUTION_AMBIGUITY!>surname<!><!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// !LANGUAGE: -BoundCallableReferences
|
||||||
|
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
val <T : Any> KClass<T>.java: Class<T> get() = null!!
|
||||||
|
|
||||||
|
val <T : Any> KClass<T>.javaObjectType: Class<T>
|
||||||
|
get() {
|
||||||
|
return java.lang.Class::class.java as Class<T>
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val </*0*/ T : kotlin.Any> kotlin.reflect.KClass<T>.java: java.lang.Class<T>
|
||||||
|
public val </*0*/ T : kotlin.Any> kotlin.reflect.KClass<T>.javaObjectType: java.lang.Class<T>
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// !LANGUAGE: -BoundCallableReferences
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
val <T : Any> KClass<T>.java: Class<T> get() = null!!
|
||||||
|
|
||||||
|
val <T : Any> KClass<T>.foo: Any?
|
||||||
|
get() {
|
||||||
|
return java.lang.Integer::hashCode
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val </*0*/ T : kotlin.Any> kotlin.reflect.KClass<T>.foo: kotlin.Any?
|
||||||
|
public val </*0*/ T : kotlin.Any> kotlin.reflect.KClass<T>.java: java.lang.Class<T>
|
||||||
@@ -18383,6 +18383,27 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noTopLevelSealedInheritance.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NoBoundCallableReferences extends AbstractDiagnosticsTest {
|
||||||
|
public void testAllFilesPresentInNoBoundCallableReferences() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifiedJavaClassLiteralInKClassExtension.kt")
|
||||||
|
public void testQualifiedJavaClassLiteralInKClassExtension() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/qualifiedJavaClassLiteralInKClassExtension.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifiedJavaClassReferenceInKClassExtension.kt")
|
||||||
|
public void testQualifiedJavaClassReferenceInKClassExtension() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/qualifiedJavaClassReferenceInKClassExtension.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/substitutions")
|
@TestMetadata("compiler/testData/diagnostics/tests/substitutions")
|
||||||
|
|||||||
Reference in New Issue
Block a user