Support :: references to properties in frontend
#KT-1183 In Progress
This commit is contained in:
@@ -21,11 +21,10 @@ import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.types.*
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils
|
||||
import java.util.ArrayList
|
||||
|
||||
private val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
|
||||
|
||||
@@ -40,10 +39,23 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
|
||||
?: ErrorUtils.createErrorClass(KOTLIN_REFLECT_FQ_NAME.child(name).asString())
|
||||
}
|
||||
|
||||
private object ClassLookup {
|
||||
fun get(types: ReflectionTypes, property: PropertyMetadata): ClassDescriptor {
|
||||
return types.find(property.name.capitalize())
|
||||
}
|
||||
}
|
||||
|
||||
public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n")
|
||||
public fun getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n")
|
||||
public fun getKMemberFunction(n: Int): ClassDescriptor = find("KMemberFunction$n")
|
||||
|
||||
public val kTopLevelProperty: ClassDescriptor by ClassLookup
|
||||
public val kMutableTopLevelProperty: ClassDescriptor by ClassLookup
|
||||
public val kMemberProperty: ClassDescriptor by ClassLookup
|
||||
public val kMutableMemberProperty: ClassDescriptor by ClassLookup
|
||||
public val kExtensionProperty: ClassDescriptor by ClassLookup
|
||||
public val kMutableExtensionProperty: ClassDescriptor by ClassLookup
|
||||
|
||||
public fun getKFunctionType(
|
||||
annotations: Annotations,
|
||||
receiverType: JetType?,
|
||||
@@ -51,26 +63,47 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
|
||||
returnType: JetType,
|
||||
extensionFunction: Boolean
|
||||
): JetType {
|
||||
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
|
||||
val classDescriptor = correspondingKFunctionClass(receiverType, extensionFunction, parameterTypes.size)
|
||||
val arity = parameterTypes.size()
|
||||
val classDescriptor =
|
||||
if (extensionFunction) getKExtensionFunction(arity)
|
||||
else if (receiverType != null) getKMemberFunction(arity)
|
||||
else getKFunction(arity)
|
||||
|
||||
return if (ErrorUtils.isError(classDescriptor))
|
||||
classDescriptor.getDefaultType()
|
||||
else
|
||||
JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
|
||||
if (ErrorUtils.isError(classDescriptor)) {
|
||||
return classDescriptor.getDefaultType()
|
||||
}
|
||||
|
||||
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
|
||||
return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
|
||||
}
|
||||
|
||||
private fun correspondingKFunctionClass(
|
||||
public fun getKPropertyType(
|
||||
annotations: Annotations,
|
||||
receiverType: JetType?,
|
||||
extensionFunction: Boolean,
|
||||
numberOfParameters: Int
|
||||
): ClassDescriptor {
|
||||
if (extensionFunction) {
|
||||
return getKExtensionFunction(numberOfParameters)
|
||||
returnType: JetType,
|
||||
extensionProperty: Boolean,
|
||||
mutable: Boolean
|
||||
): JetType {
|
||||
val classDescriptor = if (mutable) when {
|
||||
extensionProperty -> kMutableExtensionProperty
|
||||
receiverType != null -> kMutableMemberProperty
|
||||
else -> kMutableTopLevelProperty
|
||||
}
|
||||
else when {
|
||||
extensionProperty -> kExtensionProperty
|
||||
receiverType != null -> kMemberProperty
|
||||
else -> kTopLevelProperty
|
||||
}
|
||||
|
||||
if (ErrorUtils.isError(classDescriptor)) {
|
||||
return classDescriptor.getDefaultType()
|
||||
}
|
||||
|
||||
val arguments = ArrayList<TypeProjection>(2)
|
||||
if (receiverType != null) {
|
||||
return getKMemberFunction(numberOfParameters)
|
||||
arguments.add(TypeProjectionImpl(receiverType))
|
||||
}
|
||||
return getKFunction(numberOfParameters)
|
||||
arguments.add(TypeProjectionImpl(returnType))
|
||||
return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
|
||||
}
|
||||
}
|
||||
|
||||
+90
-21
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
|
||||
@@ -472,7 +473,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetSimpleNameExpression reference = expression.getCallableReference();
|
||||
|
||||
boolean[] result = new boolean[1];
|
||||
FunctionDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result);
|
||||
CallableDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result);
|
||||
|
||||
if (!result[0]) {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
||||
@@ -481,8 +482,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
|
||||
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
|
||||
if (receiverParameter != null && expectedThisObject != null) {
|
||||
context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, descriptor));
|
||||
if (receiverParameter != null && expectedThisObject != null && descriptor instanceof CallableMemberDescriptor) {
|
||||
context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, (CallableMemberDescriptor) descriptor));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -493,14 +494,37 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
else if (expectedThisObject != null) {
|
||||
receiverType = expectedThisObject.getType();
|
||||
}
|
||||
boolean isExtension = receiverParameter != null;
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
return createFunctionReferenceType(expression, context, (FunctionDescriptor) descriptor, receiverType, isExtension);
|
||||
}
|
||||
else if (descriptor instanceof PropertyDescriptor) {
|
||||
return createPropertyReferenceType(expression, context, (PropertyDescriptor) descriptor, receiverType, isExtension);
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor) {
|
||||
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Callable reference resolved to an unsupported descriptor: " + descriptor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType createFunctionReferenceType(
|
||||
@NotNull JetCallableReferenceExpression expression,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@Nullable JetType receiverType,
|
||||
boolean isExtension
|
||||
) {
|
||||
//noinspection ConstantConditions
|
||||
JetType type = components.reflectionTypes.getKFunctionType(
|
||||
Annotations.EMPTY,
|
||||
receiverType,
|
||||
getValueParametersTypes(descriptor.getValueParameters()),
|
||||
descriptor.getReturnType(),
|
||||
receiverParameter != null
|
||||
isExtension
|
||||
);
|
||||
|
||||
if (type.isError()) {
|
||||
@@ -511,7 +535,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
|
||||
context.scope.getContainingDeclaration(),
|
||||
Annotations.EMPTY,
|
||||
CallableMemberDescriptor.Kind.DECLARATION);
|
||||
CallableMemberDescriptor.Kind.DECLARATION
|
||||
);
|
||||
|
||||
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
|
||||
|
||||
@@ -521,7 +546,32 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FunctionDescriptor resolveCallableReferenceTarget(
|
||||
private JetType createPropertyReferenceType(
|
||||
@NotNull JetCallableReferenceExpression expression,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable JetType receiverType,
|
||||
boolean isExtension
|
||||
) {
|
||||
JetType type = components.reflectionTypes.getKPropertyType(Annotations.EMPTY, receiverType, descriptor.getType(), isExtension,
|
||||
descriptor.isVar());
|
||||
|
||||
if (type.isError()) {
|
||||
context.trace.report(REFLECTION_TYPES_NOT_LOADED.on(expression.getDoubleColonTokenReference()));
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalVariableDescriptor localVariable =
|
||||
new LocalVariableDescriptor(context.scope.getContainingDeclaration(), Annotations.EMPTY, Name.special("<anonymous>"),
|
||||
type, /* mutable = */ false);
|
||||
|
||||
context.trace.record(VARIABLE, expression, localVariable);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CallableDescriptor resolveCallableReferenceTarget(
|
||||
@Nullable JetType lhsType,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@NotNull JetCallableReferenceExpression expression,
|
||||
@@ -542,7 +592,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
ReceiverValue receiver = new TransientReceiver(lhsType);
|
||||
TemporaryTraceAndCache temporaryWithReceiver = TemporaryTraceAndCache.create(
|
||||
context, "trace to resolve callable reference with receiver", reference);
|
||||
FunctionDescriptor descriptor = resolveCallableNotCheckingArguments(
|
||||
CallableDescriptor descriptor = resolveCallableNotCheckingArguments(
|
||||
reference, receiver, context.replaceTraceAndCache(temporaryWithReceiver), result);
|
||||
if (result[0]) {
|
||||
temporaryWithReceiver.commit();
|
||||
@@ -552,7 +602,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetScope staticScope = getStaticNestedClassesScope((ClassDescriptor) classifier);
|
||||
TemporaryTraceAndCache temporaryForStatic = TemporaryTraceAndCache.create(
|
||||
context, "trace to resolve callable reference in static scope", reference);
|
||||
FunctionDescriptor possibleStaticNestedClassConstructor = resolveCallableNotCheckingArguments(reference, NO_RECEIVER,
|
||||
CallableDescriptor possibleStaticNestedClassConstructor = resolveCallableNotCheckingArguments(reference, NO_RECEIVER,
|
||||
context.replaceTraceAndCache(temporaryForStatic).replaceScope(staticScope), result);
|
||||
if (result[0]) {
|
||||
temporaryForStatic.commit();
|
||||
@@ -563,7 +613,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FunctionDescriptor resolveCallableNotCheckingArguments(
|
||||
private CallableDescriptor resolveCallableNotCheckingArguments(
|
||||
@NotNull JetSimpleNameExpression reference,
|
||||
@NotNull ReceiverValue receiver,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@@ -571,22 +621,41 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
) {
|
||||
Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance());
|
||||
|
||||
TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", reference);
|
||||
|
||||
ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE);
|
||||
TemporaryTraceAndCache funTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as function",
|
||||
reference);
|
||||
ResolvedCall<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver()
|
||||
.getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result);
|
||||
if (!result[0]) return null;
|
||||
.getResolvedCallForFunction(call, reference, context.replaceTraceAndCache(funTrace).replaceExpectedType(NO_EXPECTED_TYPE),
|
||||
CheckValueArgumentsMode.DISABLED, result);
|
||||
if (result[0]) {
|
||||
funTrace.commit();
|
||||
|
||||
if (function instanceof VariableAsFunctionResolvedCall) {
|
||||
// TODO: KProperty
|
||||
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
||||
return null;
|
||||
if (function instanceof VariableAsFunctionResolvedCall) {
|
||||
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
|
||||
return null;
|
||||
}
|
||||
|
||||
return function != null ? function.getResultingDescriptor() : null;
|
||||
}
|
||||
|
||||
trace.commit();
|
||||
return function != null ? function.getResultingDescriptor() : null;
|
||||
TemporaryTraceAndCache varTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as variable",
|
||||
reference);
|
||||
OverloadResolutionResults<VariableDescriptor> variableResults =
|
||||
components.expressionTypingServices.getCallResolver().resolveSimpleProperty(
|
||||
BasicCallResolutionContext.create(context.replaceTraceAndCache(varTrace).replaceExpectedType(NO_EXPECTED_TYPE),
|
||||
call, CheckValueArgumentsMode.DISABLED)
|
||||
);
|
||||
if (!variableResults.isNothing()) {
|
||||
ResolvedCall<VariableDescriptor> variable =
|
||||
OverloadResolutionResultsUtil.getResultingCall(variableResults, context.contextDependency);
|
||||
|
||||
varTrace.commit();
|
||||
if (variable != null) {
|
||||
result[0] = true;
|
||||
return variable.getResultingDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
trait Base {
|
||||
val x: Any
|
||||
}
|
||||
|
||||
class A : Base {
|
||||
override val x: String = ""
|
||||
}
|
||||
|
||||
open class B : Base {
|
||||
override val x: Number = 1.0
|
||||
}
|
||||
|
||||
class C : B() {
|
||||
override val x: Int = 42
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val base = Base::x
|
||||
base : KMemberProperty<Base, Any>
|
||||
base.get(A()) : Any
|
||||
<!TYPE_MISMATCH!>base.get(B())<!> : Number
|
||||
<!TYPE_MISMATCH!>base.get(C())<!> : Int
|
||||
|
||||
val a = A::x
|
||||
a : KMemberProperty<A, String>
|
||||
a.get(A()) : String
|
||||
<!TYPE_MISMATCH!>a.get(<!TYPE_MISMATCH!>B()<!>)<!> : Number
|
||||
|
||||
val b = B::x
|
||||
b : KMemberProperty<B, Number>
|
||||
<!TYPE_MISMATCH!>b.get(C())<!> : Int
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
open class Base {
|
||||
val foo: Int = 42
|
||||
}
|
||||
|
||||
open class Derived : Base()
|
||||
|
||||
fun test() {
|
||||
val o = Base::foo
|
||||
o : KMemberProperty<Base, Int>
|
||||
o.get(Derived()) : Int
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class A(var g: A) {
|
||||
val f: Int = 0
|
||||
|
||||
fun test() {
|
||||
::f : KMemberProperty<A, Int>
|
||||
::g : KMutableMemberProperty<A, A>
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class A {
|
||||
fun test() {
|
||||
::foo : KExtensionProperty<A, String>
|
||||
::bar : KMutableExtensionProperty<A, Int>
|
||||
}
|
||||
}
|
||||
|
||||
val A.foo: String get() = ""
|
||||
var A.bar: Int
|
||||
get() = 42
|
||||
set(value) { }
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
val String.countCharacters: Int
|
||||
get() = length
|
||||
|
||||
var Int.meaning: Long
|
||||
get() = 42L
|
||||
set(value) {}
|
||||
|
||||
fun test() {
|
||||
val f = String::countCharacters
|
||||
|
||||
f : KExtensionProperty<String, Int>
|
||||
<!TYPE_MISMATCH!>f<!> : KMutableExtensionProperty<String, Int>
|
||||
f.get("abc") : Int
|
||||
f.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>set<!>("abc", 0)
|
||||
|
||||
val g = Int::meaning
|
||||
|
||||
g : KExtensionProperty<Int, Long>
|
||||
g : KMutableExtensionProperty<Int, Long>
|
||||
g.get(0) : Long
|
||||
g.set(1, 0L)
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
val Any?.meaning: Int
|
||||
get() = 42
|
||||
|
||||
fun test() {
|
||||
val f = Any?::meaning
|
||||
f.get(null) : Int
|
||||
f.get("") : Int
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class A<T>(val t: T) {
|
||||
val foo: T = t
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
val x = A<String>::foo
|
||||
x : KMemberProperty<A<String>, String>
|
||||
x : KMemberProperty<A<String>, Any?>
|
||||
|
||||
val y = A<*>::foo
|
||||
y : KMemberProperty<A<*>, Any?>
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass {
|
||||
public final int publicFinal;
|
||||
public long publicMutable;
|
||||
|
||||
protected final double protectedFinal;
|
||||
protected char protectedMutable;
|
||||
|
||||
private final String privateFinal;
|
||||
private Object privateMutable;
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun test() {
|
||||
JavaClass::publicFinal : KMemberProperty<JavaClass, Int>
|
||||
JavaClass::publicMutable : KMutableMemberProperty<JavaClass, Long>
|
||||
JavaClass::protectedFinal : KMemberProperty<JavaClass, Double>
|
||||
JavaClass::protectedMutable : KMutableMemberProperty<JavaClass, Char>
|
||||
JavaClass::<!INVISIBLE_MEMBER!>privateFinal<!> : KMemberProperty<JavaClass, String?>
|
||||
JavaClass::<!INVISIBLE_MEMBER!>privateMutable<!> : KMutableMemberProperty<JavaClass, Any?>
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass {
|
||||
public static final String publicFinal;
|
||||
public static volatile Object publicMutable;
|
||||
|
||||
protected static final double protectedFinal;
|
||||
protected static char protectedMutable;
|
||||
|
||||
private static final JavaClass privateFinal;
|
||||
private static Throwable privateMutable;
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import JavaClass.*
|
||||
|
||||
fun test() {
|
||||
::publicFinal : KTopLevelProperty<String>
|
||||
::publicMutable : KMutableTopLevelProperty<Any?>
|
||||
::protectedFinal : KProperty<Double>
|
||||
::protectedMutable : KMutableProperty<Char>
|
||||
::<!INVISIBLE_MEMBER!>privateFinal<!> : KProperty<JavaClass?>
|
||||
::<!INVISIBLE_MEMBER!>privateMutable<!> : KMutableProperty<Throwable?>
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
fun test(param: String) {
|
||||
val a = ::<!UNSUPPORTED!>param<!>
|
||||
|
||||
val local = "local"
|
||||
val b = ::<!UNSUPPORTED!>local<!>
|
||||
|
||||
val lambda = { -> }
|
||||
val g = ::<!UNSUPPORTED!>lambda<!>
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
class A {
|
||||
val foo: Unit = Unit.VALUE
|
||||
var bar: String = ""
|
||||
var self: A
|
||||
get() = this
|
||||
set(value) { }
|
||||
}
|
||||
|
||||
fun A.test() {
|
||||
val x = ::foo
|
||||
val y = ::bar
|
||||
val z = ::self
|
||||
|
||||
x : KMemberProperty<A, Unit>
|
||||
y : KMutableMemberProperty<A, String>
|
||||
z : KMutableMemberProperty<A, A>
|
||||
|
||||
y.set(z.get(A()), x.get(A()).toString())
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
class A {
|
||||
val foo: Int = 42
|
||||
var bar: String = ""
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val p = A::foo
|
||||
|
||||
p : KMemberProperty<A, Int>
|
||||
<!TYPE_MISMATCH!>p<!> : KMutableMemberProperty<A, Int>
|
||||
p.get(A()) : Int
|
||||
p.get(<!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||
p.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>set<!>(A(), 239)
|
||||
|
||||
val q = A::bar
|
||||
|
||||
q : KMemberProperty<A, String>
|
||||
q : KMutableMemberProperty<A, String>
|
||||
q.get(A()): String
|
||||
q.set(A(), "q")
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
var x: Int = 42
|
||||
val y: String get() = "y"
|
||||
|
||||
fun testX() {
|
||||
val xx = ::x
|
||||
xx : KMutableTopLevelProperty<Int>
|
||||
xx : KTopLevelProperty<Int>
|
||||
xx : KMutableProperty<Int>
|
||||
xx : KProperty<Int>
|
||||
xx : KCallable<Int>
|
||||
|
||||
xx.name : String
|
||||
xx.get() : Int
|
||||
xx.set(239)
|
||||
}
|
||||
|
||||
fun testY() {
|
||||
val yy = ::y
|
||||
<!TYPE_MISMATCH!>yy<!> : KMutableTopLevelProperty<String>
|
||||
yy : KTopLevelProperty<String>
|
||||
<!TYPE_MISMATCH!>yy<!> : KMutableProperty<String>
|
||||
yy : KProperty<String>
|
||||
yy : KCallable<String>
|
||||
|
||||
yy.name : String
|
||||
yy.get() : String
|
||||
yy.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>set<!>("yy")
|
||||
}
|
||||
+75
-1
@@ -105,7 +105,7 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference")
|
||||
@InnerTestClasses({CallableReference.Function.class})
|
||||
@InnerTestClasses({CallableReference.Function.class, CallableReference.Property.class})
|
||||
public static class CallableReference extends AbstractJetDiagnosticsTestWithStdLib {
|
||||
public void testAllFilesPresentInCallableReference() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/testsWithStdLib/callableReference"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
@@ -359,10 +359,84 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference/property")
|
||||
public static class Property extends AbstractJetDiagnosticsTestWithStdLib {
|
||||
@TestMetadata("abstractPropertyViaSubclasses.kt")
|
||||
public void testAbstractPropertyViaSubclasses() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/abstractPropertyViaSubclasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("accessViaSubclass.kt")
|
||||
public void testAccessViaSubclass() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/accessViaSubclass.kt");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInProperty() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/testsWithStdLib/callableReference/property"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classFromClass.kt")
|
||||
public void testClassFromClass() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/classFromClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFromClass.kt")
|
||||
public void testExtensionFromClass() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFromTopLevel.kt")
|
||||
public void testExtensionFromTopLevel() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromTopLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionPropertyOnNullable.kt")
|
||||
public void testExtensionPropertyOnNullable() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionPropertyOnNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericClass.kt")
|
||||
public void testGenericClass() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/genericClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaInstanceField.kt")
|
||||
public void testJavaInstanceField() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaInstanceField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaStaticFieldViaImport.kt")
|
||||
public void testJavaStaticFieldViaImport() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaStaticFieldViaImport.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVariable.kt")
|
||||
public void testLocalVariable() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/localVariable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberFromExtension.kt")
|
||||
public void testMemberFromExtension() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberFromTopLevel.kt")
|
||||
public void testMemberFromTopLevel() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromTopLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelFromTopLevel.kt")
|
||||
public void testTopLevelFromTopLevel() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/topLevelFromTopLevel.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test innerSuite() {
|
||||
TestSuite suite = new TestSuite("CallableReference");
|
||||
suite.addTestSuite(CallableReference.class);
|
||||
suite.addTestSuite(Function.class);
|
||||
suite.addTestSuite(Property.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 kotlin.reflect
|
||||
|
||||
public trait KCallable<out R> {
|
||||
public val name: String
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 kotlin.reflect
|
||||
|
||||
public trait KExtensionProperty<T, out R> : KProperty<R> {
|
||||
public fun get(receiver: T): R
|
||||
}
|
||||
|
||||
public trait KMutableExtensionProperty<T, R> : KExtensionProperty<T, R>, KMutableProperty<R> {
|
||||
public fun set(receiver: T, value: R)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 kotlin.reflect
|
||||
|
||||
public trait KMemberProperty<T, out R> : KProperty<R> {
|
||||
public fun get(receiver: T): R
|
||||
}
|
||||
|
||||
public trait KMutableMemberProperty<T, R> : KMemberProperty<T, R>, KMutableProperty<R> {
|
||||
public fun set(receiver: T, value: R)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 kotlin.reflect
|
||||
|
||||
public trait KProperty<out R> : KCallable<R>
|
||||
|
||||
public trait KMutableProperty<R> : KProperty<R>
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 kotlin.reflect
|
||||
|
||||
public trait KTopLevelProperty<out R> : KVariable<R>
|
||||
|
||||
public trait KMutableTopLevelProperty<R> : KTopLevelProperty<R>, KMutableVariable<R>
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 kotlin.reflect
|
||||
|
||||
public trait KVariable<out R> : KProperty<R> {
|
||||
public fun get(): R
|
||||
}
|
||||
|
||||
public trait KMutableVariable<R> : KVariable<R>, KMutableProperty<R> {
|
||||
public fun set(value: R)
|
||||
}
|
||||
Reference in New Issue
Block a user