diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/reflect/ReflectionTypes.kt b/compiler/frontend/src/org/jetbrains/jet/lang/reflect/ReflectionTypes.kt index 9a0d57bdd8c..299d3b2c8fa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/reflect/ReflectionTypes.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/reflect/ReflectionTypes.kt @@ -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(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)) } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 976d1b5ab19..59cbb914568 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -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(""), + 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.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 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 variableResults = + components.expressionTypingServices.getCallResolver().resolveSimpleProperty( + BasicCallResolutionContext.create(context.replaceTraceAndCache(varTrace).replaceExpectedType(NO_EXPECTED_TYPE), + call, CheckValueArgumentsMode.DISABLED) + ); + if (!variableResults.isNothing()) { + ResolvedCall variable = + OverloadResolutionResultsUtil.getResultingCall(variableResults, context.contextDependency); + + varTrace.commit(); + if (variable != null) { + result[0] = true; + return variable.getResultingDescriptor(); + } + } + + return null; } @Override diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/abstractPropertyViaSubclasses.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/abstractPropertyViaSubclasses.kt new file mode 100644 index 00000000000..5054f0a717c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/abstractPropertyViaSubclasses.kt @@ -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.get(A()) : Any + base.get(B()) : Number + base.get(C()) : Int + + val a = A::x + a : KMemberProperty + a.get(A()) : String + a.get(B()) : Number + + val b = B::x + b : KMemberProperty + b.get(C()) : Int +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/accessViaSubclass.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/accessViaSubclass.kt new file mode 100644 index 00000000000..d3081f85a95 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/accessViaSubclass.kt @@ -0,0 +1,11 @@ +open class Base { + val foo: Int = 42 +} + +open class Derived : Base() + +fun test() { + val o = Base::foo + o : KMemberProperty + o.get(Derived()) : Int +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/classFromClass.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/classFromClass.kt new file mode 100644 index 00000000000..f99c615756a --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/classFromClass.kt @@ -0,0 +1,8 @@ +class A(var g: A) { + val f: Int = 0 + + fun test() { + ::f : KMemberProperty + ::g : KMutableMemberProperty + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromClass.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromClass.kt new file mode 100644 index 00000000000..581b698c8e4 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromClass.kt @@ -0,0 +1,11 @@ +class A { + fun test() { + ::foo : KExtensionProperty + ::bar : KMutableExtensionProperty + } +} + +val A.foo: String get() = "" +var A.bar: Int + get() = 42 + set(value) { } diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromTopLevel.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromTopLevel.kt new file mode 100644 index 00000000000..dc7c5dd3052 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionFromTopLevel.kt @@ -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 + f : KMutableExtensionProperty + f.get("abc") : Int + f.set("abc", 0) + + val g = Int::meaning + + g : KExtensionProperty + g : KMutableExtensionProperty + g.get(0) : Long + g.set(1, 0L) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionPropertyOnNullable.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionPropertyOnNullable.kt new file mode 100644 index 00000000000..10c3c1de770 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/extensionPropertyOnNullable.kt @@ -0,0 +1,8 @@ +val Any?.meaning: Int + get() = 42 + +fun test() { + val f = Any?::meaning + f.get(null) : Int + f.get("") : Int +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/genericClass.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/genericClass.kt new file mode 100644 index 00000000000..4e89f7155d6 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/genericClass.kt @@ -0,0 +1,12 @@ +class A(val t: T) { + val foo: T = t +} + +fun bar() { + val x = A::foo + x : KMemberProperty, String> + x : KMemberProperty, Any?> + + val y = A<*>::foo + y : KMemberProperty, Any?> +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaInstanceField.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaInstanceField.kt new file mode 100644 index 00000000000..fa2f1f436ec --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaInstanceField.kt @@ -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::publicMutable : KMutableMemberProperty + JavaClass::protectedFinal : KMemberProperty + JavaClass::protectedMutable : KMutableMemberProperty + JavaClass::privateFinal : KMemberProperty + JavaClass::privateMutable : KMutableMemberProperty +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaStaticFieldViaImport.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaStaticFieldViaImport.kt new file mode 100644 index 00000000000..555b296f0c6 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/javaStaticFieldViaImport.kt @@ -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 + ::publicMutable : KMutableTopLevelProperty + ::protectedFinal : KProperty + ::protectedMutable : KMutableProperty + ::privateFinal : KProperty + ::privateMutable : KMutableProperty +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/localVariable.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/localVariable.kt new file mode 100644 index 00000000000..5550b022d63 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/localVariable.kt @@ -0,0 +1,11 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +fun test(param: String) { + val a = ::param + + val local = "local" + val b = ::local + + val lambda = { -> } + val g = ::lambda +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromExtension.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromExtension.kt new file mode 100644 index 00000000000..091e60a2893 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromExtension.kt @@ -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 + y : KMutableMemberProperty + z : KMutableMemberProperty + + y.set(z.get(A()), x.get(A()).toString()) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromTopLevel.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromTopLevel.kt new file mode 100644 index 00000000000..93e5bb0601c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/memberFromTopLevel.kt @@ -0,0 +1,21 @@ +class A { + val foo: Int = 42 + var bar: String = "" +} + +fun test() { + val p = A::foo + + p : KMemberProperty + p : KMutableMemberProperty + p.get(A()) : Int + p.get() + p.set(A(), 239) + + val q = A::bar + + q : KMemberProperty + q : KMutableMemberProperty + q.get(A()): String + q.set(A(), "q") +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/topLevelFromTopLevel.kt b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/topLevelFromTopLevel.kt new file mode 100644 index 00000000000..85ef42b4398 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/callableReference/property/topLevelFromTopLevel.kt @@ -0,0 +1,28 @@ +var x: Int = 42 +val y: String get() = "y" + +fun testX() { + val xx = ::x + xx : KMutableTopLevelProperty + xx : KTopLevelProperty + xx : KMutableProperty + xx : KProperty + xx : KCallable + + xx.name : String + xx.get() : Int + xx.set(239) +} + +fun testY() { + val yy = ::y + yy : KMutableTopLevelProperty + yy : KTopLevelProperty + yy : KMutableProperty + yy : KProperty + yy : KCallable + + yy.name : String + yy.get() : String + yy.set("yy") +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java index ed8963048ac..7bc1d1161ba 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -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; } } diff --git a/core/reflection/src/kotlin/reflect/KCallable.kt b/core/reflection/src/kotlin/reflect/KCallable.kt new file mode 100644 index 00000000000..7c2cea54c38 --- /dev/null +++ b/core/reflection/src/kotlin/reflect/KCallable.kt @@ -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 { + public val name: String +} diff --git a/core/reflection/src/kotlin/reflect/KExtensionProperty.kt b/core/reflection/src/kotlin/reflect/KExtensionProperty.kt new file mode 100644 index 00000000000..a2791873ccb --- /dev/null +++ b/core/reflection/src/kotlin/reflect/KExtensionProperty.kt @@ -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 : KProperty { + public fun get(receiver: T): R +} + +public trait KMutableExtensionProperty : KExtensionProperty, KMutableProperty { + public fun set(receiver: T, value: R) +} diff --git a/core/reflection/src/kotlin/reflect/KMemberProperty.kt b/core/reflection/src/kotlin/reflect/KMemberProperty.kt new file mode 100644 index 00000000000..233a369617f --- /dev/null +++ b/core/reflection/src/kotlin/reflect/KMemberProperty.kt @@ -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 : KProperty { + public fun get(receiver: T): R +} + +public trait KMutableMemberProperty : KMemberProperty, KMutableProperty { + public fun set(receiver: T, value: R) +} diff --git a/core/reflection/src/kotlin/reflect/KProperty.kt b/core/reflection/src/kotlin/reflect/KProperty.kt new file mode 100644 index 00000000000..8253bb0669b --- /dev/null +++ b/core/reflection/src/kotlin/reflect/KProperty.kt @@ -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 : KCallable + +public trait KMutableProperty : KProperty diff --git a/core/reflection/src/kotlin/reflect/KTopLevelProperty.kt b/core/reflection/src/kotlin/reflect/KTopLevelProperty.kt new file mode 100644 index 00000000000..ee1bf17b6b7 --- /dev/null +++ b/core/reflection/src/kotlin/reflect/KTopLevelProperty.kt @@ -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 : KVariable + +public trait KMutableTopLevelProperty : KTopLevelProperty, KMutableVariable diff --git a/core/reflection/src/kotlin/reflect/KVariable.kt b/core/reflection/src/kotlin/reflect/KVariable.kt new file mode 100644 index 00000000000..4c8fcbb4851 --- /dev/null +++ b/core/reflection/src/kotlin/reflect/KVariable.kt @@ -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 : KProperty { + public fun get(): R +} + +public trait KMutableVariable : KVariable, KMutableProperty { + public fun set(value: R) +}