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.FqName
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name
|
import org.jetbrains.jet.lang.resolve.name.Name
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
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.types.lang.KotlinBuiltIns
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.jet.lang.types.JetType
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.lang.types.JetTypeImpl
|
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils
|
|
||||||
|
|
||||||
private val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
|
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())
|
?: 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 getKFunction(n: Int): ClassDescriptor = find("KFunction$n")
|
||||||
public fun getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n")
|
public fun getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n")
|
||||||
public fun getKMemberFunction(n: Int): ClassDescriptor = find("KMemberFunction$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(
|
public fun getKFunctionType(
|
||||||
annotations: Annotations,
|
annotations: Annotations,
|
||||||
receiverType: JetType?,
|
receiverType: JetType?,
|
||||||
@@ -51,26 +63,47 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
|
|||||||
returnType: JetType,
|
returnType: JetType,
|
||||||
extensionFunction: Boolean
|
extensionFunction: Boolean
|
||||||
): JetType {
|
): JetType {
|
||||||
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
|
val arity = parameterTypes.size()
|
||||||
val classDescriptor = correspondingKFunctionClass(receiverType, extensionFunction, parameterTypes.size)
|
val classDescriptor =
|
||||||
|
if (extensionFunction) getKExtensionFunction(arity)
|
||||||
|
else if (receiverType != null) getKMemberFunction(arity)
|
||||||
|
else getKFunction(arity)
|
||||||
|
|
||||||
return if (ErrorUtils.isError(classDescriptor))
|
if (ErrorUtils.isError(classDescriptor)) {
|
||||||
classDescriptor.getDefaultType()
|
return classDescriptor.getDefaultType()
|
||||||
else
|
}
|
||||||
JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
|
|
||||||
|
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?,
|
receiverType: JetType?,
|
||||||
extensionFunction: Boolean,
|
returnType: JetType,
|
||||||
numberOfParameters: Int
|
extensionProperty: Boolean,
|
||||||
): ClassDescriptor {
|
mutable: Boolean
|
||||||
if (extensionFunction) {
|
): JetType {
|
||||||
return getKExtensionFunction(numberOfParameters)
|
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) {
|
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.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
|
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.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
|
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
|
||||||
@@ -472,7 +473,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
JetSimpleNameExpression reference = expression.getCallableReference();
|
JetSimpleNameExpression reference = expression.getCallableReference();
|
||||||
|
|
||||||
boolean[] result = new boolean[1];
|
boolean[] result = new boolean[1];
|
||||||
FunctionDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result);
|
CallableDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result);
|
||||||
|
|
||||||
if (!result[0]) {
|
if (!result[0]) {
|
||||||
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
||||||
@@ -481,8 +482,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
|
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
|
||||||
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
|
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
|
||||||
if (receiverParameter != null && expectedThisObject != null) {
|
if (receiverParameter != null && expectedThisObject != null && descriptor instanceof CallableMemberDescriptor) {
|
||||||
context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, descriptor));
|
context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, (CallableMemberDescriptor) descriptor));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,14 +494,37 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
else if (expectedThisObject != null) {
|
else if (expectedThisObject != null) {
|
||||||
receiverType = expectedThisObject.getType();
|
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
|
//noinspection ConstantConditions
|
||||||
JetType type = components.reflectionTypes.getKFunctionType(
|
JetType type = components.reflectionTypes.getKFunctionType(
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
receiverType,
|
receiverType,
|
||||||
getValueParametersTypes(descriptor.getValueParameters()),
|
getValueParametersTypes(descriptor.getValueParameters()),
|
||||||
descriptor.getReturnType(),
|
descriptor.getReturnType(),
|
||||||
receiverParameter != null
|
isExtension
|
||||||
);
|
);
|
||||||
|
|
||||||
if (type.isError()) {
|
if (type.isError()) {
|
||||||
@@ -511,7 +535,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
|
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
|
||||||
context.scope.getContainingDeclaration(),
|
context.scope.getContainingDeclaration(),
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
CallableMemberDescriptor.Kind.DECLARATION);
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
|
);
|
||||||
|
|
||||||
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
|
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
|
||||||
|
|
||||||
@@ -521,7 +546,32 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@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,
|
@Nullable JetType lhsType,
|
||||||
@NotNull ExpressionTypingContext context,
|
@NotNull ExpressionTypingContext context,
|
||||||
@NotNull JetCallableReferenceExpression expression,
|
@NotNull JetCallableReferenceExpression expression,
|
||||||
@@ -542,7 +592,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
ReceiverValue receiver = new TransientReceiver(lhsType);
|
ReceiverValue receiver = new TransientReceiver(lhsType);
|
||||||
TemporaryTraceAndCache temporaryWithReceiver = TemporaryTraceAndCache.create(
|
TemporaryTraceAndCache temporaryWithReceiver = TemporaryTraceAndCache.create(
|
||||||
context, "trace to resolve callable reference with receiver", reference);
|
context, "trace to resolve callable reference with receiver", reference);
|
||||||
FunctionDescriptor descriptor = resolveCallableNotCheckingArguments(
|
CallableDescriptor descriptor = resolveCallableNotCheckingArguments(
|
||||||
reference, receiver, context.replaceTraceAndCache(temporaryWithReceiver), result);
|
reference, receiver, context.replaceTraceAndCache(temporaryWithReceiver), result);
|
||||||
if (result[0]) {
|
if (result[0]) {
|
||||||
temporaryWithReceiver.commit();
|
temporaryWithReceiver.commit();
|
||||||
@@ -552,7 +602,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
JetScope staticScope = getStaticNestedClassesScope((ClassDescriptor) classifier);
|
JetScope staticScope = getStaticNestedClassesScope((ClassDescriptor) classifier);
|
||||||
TemporaryTraceAndCache temporaryForStatic = TemporaryTraceAndCache.create(
|
TemporaryTraceAndCache temporaryForStatic = TemporaryTraceAndCache.create(
|
||||||
context, "trace to resolve callable reference in static scope", reference);
|
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);
|
context.replaceTraceAndCache(temporaryForStatic).replaceScope(staticScope), result);
|
||||||
if (result[0]) {
|
if (result[0]) {
|
||||||
temporaryForStatic.commit();
|
temporaryForStatic.commit();
|
||||||
@@ -563,7 +613,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private FunctionDescriptor resolveCallableNotCheckingArguments(
|
private CallableDescriptor resolveCallableNotCheckingArguments(
|
||||||
@NotNull JetSimpleNameExpression reference,
|
@NotNull JetSimpleNameExpression reference,
|
||||||
@NotNull ReceiverValue receiver,
|
@NotNull ReceiverValue receiver,
|
||||||
@NotNull ExpressionTypingContext context,
|
@NotNull ExpressionTypingContext context,
|
||||||
@@ -571,22 +621,41 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
) {
|
) {
|
||||||
Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance());
|
Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance());
|
||||||
|
|
||||||
TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", reference);
|
TemporaryTraceAndCache funTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as function",
|
||||||
|
reference);
|
||||||
ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE);
|
|
||||||
ResolvedCall<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver()
|
ResolvedCall<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver()
|
||||||
.getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result);
|
.getResolvedCallForFunction(call, reference, context.replaceTraceAndCache(funTrace).replaceExpectedType(NO_EXPECTED_TYPE),
|
||||||
if (!result[0]) return null;
|
CheckValueArgumentsMode.DISABLED, result);
|
||||||
|
if (result[0]) {
|
||||||
|
funTrace.commit();
|
||||||
|
|
||||||
if (function instanceof VariableAsFunctionResolvedCall) {
|
if (function instanceof VariableAsFunctionResolvedCall) {
|
||||||
// TODO: KProperty
|
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
|
||||||
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
|
return null;
|
||||||
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
}
|
||||||
return null;
|
|
||||||
|
return function != null ? function.getResultingDescriptor() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace.commit();
|
TemporaryTraceAndCache varTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as variable",
|
||||||
return function != null ? function.getResultingDescriptor() : null;
|
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
|
@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")
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference")
|
||||||
@InnerTestClasses({CallableReference.Function.class})
|
@InnerTestClasses({CallableReference.Function.class, CallableReference.Property.class})
|
||||||
public static class CallableReference extends AbstractJetDiagnosticsTestWithStdLib {
|
public static class CallableReference extends AbstractJetDiagnosticsTestWithStdLib {
|
||||||
public void testAllFilesPresentInCallableReference() throws Exception {
|
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);
|
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() {
|
public static Test innerSuite() {
|
||||||
TestSuite suite = new TestSuite("CallableReference");
|
TestSuite suite = new TestSuite("CallableReference");
|
||||||
suite.addTestSuite(CallableReference.class);
|
suite.addTestSuite(CallableReference.class);
|
||||||
suite.addTestSuite(Function.class);
|
suite.addTestSuite(Function.class);
|
||||||
|
suite.addTestSuite(Property.class);
|
||||||
return suite;
|
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