Introduce propertyDelegated method in delegates
This commit is contained in:
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
@@ -247,8 +248,16 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
type = boxType(type);
|
||||
}
|
||||
codegen.gen(initializer, type);
|
||||
|
||||
propValue.store(type, codegen.v);
|
||||
|
||||
ResolvedCall<FunctionDescriptor> pdResolvedCall =
|
||||
bindingContext.get(BindingContext.DELEGATED_PROPERTY_PD_RESOLVED_CALL, propertyDescriptor);
|
||||
if (pdResolvedCall != null) {
|
||||
int index = PropertyCodegen.indexOfDelegatedProperty(property);
|
||||
StackValue lastValue = PropertyCodegen.invokeDelegatedPropertyConventionMethod(propertyDescriptor, codegen,
|
||||
state.getTypeMapper(), pdResolvedCall, index, 0);
|
||||
lastValue.put(Type.VOID_TYPE, codegen.v);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldInitializeProperty(@NotNull JetProperty property) {
|
||||
|
||||
@@ -344,7 +344,7 @@ public class PropertyCodegen {
|
||||
functionCodegen.generateMethod(OtherOrigin(accessor != null ? accessor : p, accessorDescriptor), signature, accessorDescriptor, strategy);
|
||||
}
|
||||
|
||||
private static int indexOfDelegatedProperty(@NotNull JetProperty property) {
|
||||
public static int indexOfDelegatedProperty(@NotNull JetProperty property) {
|
||||
PsiElement parent = property.getParent();
|
||||
JetDeclarationContainer container;
|
||||
if (parent instanceof JetClassBody) {
|
||||
@@ -409,6 +409,46 @@ public class PropertyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
public static StackValue invokeDelegatedPropertyConventionMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull JetTypeMapper typeMapper,
|
||||
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall,
|
||||
final int indexInPropertyMetadataArray,
|
||||
int propertyMetadataArgumentIndex
|
||||
) {
|
||||
if (codegen.getContext().getContextKind() != OwnerKind.PACKAGE) {
|
||||
codegen.v.load(0, OBJECT_TYPE);
|
||||
}
|
||||
|
||||
CodegenContext<? extends ClassOrPackageFragmentDescriptor> ownerContext = codegen.getContext().getClassOrPackageParentContext();
|
||||
final Type owner;
|
||||
if (ownerContext instanceof ClassContext) {
|
||||
owner = typeMapper.mapClass(((ClassContext) ownerContext).getContextDescriptor());
|
||||
}
|
||||
else if (ownerContext instanceof PackageContext) {
|
||||
owner = ((PackageContext) ownerContext).getPackagePartType();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown context: " + ownerContext);
|
||||
}
|
||||
|
||||
codegen.tempVariables.put(
|
||||
resolvedCall.getCall().getValueArguments().get(propertyMetadataArgumentIndex).asElement(),
|
||||
new StackValue(PROPERTY_METADATA_TYPE) {
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
v.getstatic(owner.getInternalName(), JvmAbi.PROPERTY_METADATA_ARRAY_NAME, "[" + PROPERTY_METADATA_TYPE);
|
||||
v.iconst(indexInPropertyMetadataArray);
|
||||
StackValue.arrayElement(PROPERTY_METADATA_TYPE).put(type, v);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
StackValue delegatedProperty = codegen.intermediateValueForProperty(propertyDescriptor, true, null);
|
||||
return codegen.invokeFunction(resolvedCall, delegatedProperty);
|
||||
}
|
||||
|
||||
private static class DelegatedPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased<PropertyAccessorDescriptor> {
|
||||
private final int index;
|
||||
|
||||
@@ -426,37 +466,8 @@ public class PropertyCodegen {
|
||||
bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, callableDescriptor);
|
||||
assert resolvedCall != null : "Resolve call should be recorded for delegate call " + signature.toString();
|
||||
|
||||
if (codegen.getContext().getContextKind() != OwnerKind.PACKAGE) {
|
||||
v.load(0, OBJECT_TYPE);
|
||||
}
|
||||
|
||||
CodegenContext<? extends ClassOrPackageFragmentDescriptor> ownerContext = codegen.getContext().getClassOrPackageParentContext();
|
||||
final Type owner;
|
||||
if (ownerContext instanceof ClassContext) {
|
||||
owner = state.getTypeMapper().mapClass(((ClassContext) ownerContext).getContextDescriptor());
|
||||
}
|
||||
else if (ownerContext instanceof PackageContext) {
|
||||
owner = ((PackageContext) ownerContext).getPackagePartType();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown context: " + ownerContext);
|
||||
}
|
||||
|
||||
codegen.tempVariables.put(
|
||||
resolvedCall.getCall().getValueArguments().get(1).asElement(),
|
||||
new StackValue(PROPERTY_METADATA_TYPE) {
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
v.getstatic(owner.getInternalName(), JvmAbi.PROPERTY_METADATA_ARRAY_NAME, "[" + PROPERTY_METADATA_TYPE);
|
||||
v.iconst(index);
|
||||
StackValue.arrayElement(PROPERTY_METADATA_TYPE).put(type, v);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
StackValue delegatedProperty = codegen.intermediateValueForProperty(callableDescriptor.getCorrespondingProperty(), true, null);
|
||||
StackValue lastValue = codegen.invokeFunction(resolvedCall, delegatedProperty);
|
||||
|
||||
StackValue lastValue = invokeDelegatedPropertyConventionMethod(callableDescriptor.getCorrespondingProperty(),
|
||||
codegen, state.getTypeMapper(), resolvedCall, index, 1);
|
||||
Type asmType = signature.getReturnType();
|
||||
lastValue.put(asmType, v);
|
||||
v.areturn(asmType);
|
||||
|
||||
@@ -446,6 +446,7 @@ public interface Errors {
|
||||
DiagnosticFactory2<JetExpression, String, Collection<? extends ResolvedCall<?>>> DELEGATE_SPECIAL_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<JetExpression, String, Collection<? extends ResolvedCall<?>>> DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory3<JetExpression, String, JetType, JetType> DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory2<JetExpression, String, Collection<? extends ResolvedCall<?>>> DELEGATE_PD_METHOD_NONE_APPLICABLE = DiagnosticFactory2.create(WARNING);
|
||||
|
||||
DiagnosticFactory1<JetSimpleNameExpression, JetType> COMPARE_TO_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
|
||||
+1
@@ -285,6 +285,7 @@ public class DefaultErrorMessages {
|
||||
STRING, AMBIGUOUS_CALLS);
|
||||
MAP.put(DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH, "The ''{0}'' function of property delegate is expected to return ''{1}'', but returns ''{2}''",
|
||||
STRING, RENDER_TYPE, RENDER_TYPE);
|
||||
MAP.put(DELEGATE_PD_METHOD_NONE_APPLICABLE, "''{0}'' method may be missing. None of the following functions will be called: {1}", STRING, AMBIGUOUS_CALLS);
|
||||
|
||||
MAP.put(COMPARE_TO_TYPE_MISMATCH, "''compareTo()'' must return kotlin.Int, but returns {0}", RENDER_TYPE);
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ public interface BindingContext {
|
||||
WritableSlice<PropertyAccessorDescriptor, ResolvedCall<FunctionDescriptor>> DELEGATED_PROPERTY_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<PropertyAccessorDescriptor, Call> DELEGATED_PROPERTY_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<PropertyDescriptor, ResolvedCall<FunctionDescriptor>> DELEGATED_PROPERTY_PD_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<JetMultiDeclarationEntry, ResolvedCall<FunctionDescriptor>> COMPONENT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_GET = Slices.createSimpleSlice();
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.containers.Queue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -26,17 +25,13 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.SimpleResolutionContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.util.Box;
|
||||
import org.jetbrains.jet.util.ReenteringLazyValueComputationException;
|
||||
@@ -553,6 +548,9 @@ public class BodyResolver {
|
||||
delegatedPropertyResolver.resolveDelegatedPropertySetMethod(propertyDescriptor, delegateExpression, delegateType,
|
||||
trace, accessorScope);
|
||||
}
|
||||
|
||||
delegatedPropertyResolver.resolveDelegatedPropertyPDMethod(propertyDescriptor, delegateExpression, delegateType,
|
||||
trace, accessorScope);
|
||||
}
|
||||
|
||||
public void resolvePropertyInitializer(
|
||||
|
||||
+52
-4
@@ -61,6 +61,8 @@ public class DelegatedPropertyResolver {
|
||||
@NotNull
|
||||
private CallResolver callResolver;
|
||||
|
||||
private static final String PD_METHOD_NAME = "propertyDelegated";
|
||||
|
||||
@Inject
|
||||
public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
|
||||
this.expressionTypingServices = expressionTypingServices;
|
||||
@@ -115,6 +117,55 @@ public class DelegatedPropertyResolver {
|
||||
resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, trace, scope, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetExpression createExpressionForPropertyMetadata(
|
||||
@NotNull JetPsiFactory psiFactory,
|
||||
@NotNull PropertyDescriptor propertyDescriptor
|
||||
) {
|
||||
return psiFactory.createExpression(KotlinBuiltIns.getInstance().getPropertyMetadataImpl().getName().asString() +
|
||||
"(\"" +
|
||||
propertyDescriptor.getName().asString() +
|
||||
"\")");
|
||||
}
|
||||
|
||||
public void resolveDelegatedPropertyPDMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetExpression delegateExpression,
|
||||
@NotNull JetType delegateType,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope
|
||||
) {
|
||||
TemporaryBindingTrace traceToResolvePDMethod = TemporaryBindingTrace.create(trace, "Trace to resolve propertyDelegated method in delegated property");
|
||||
ExpressionTypingContext context = ExpressionTypingContext.newContext(
|
||||
expressionTypingServices, traceToResolvePDMethod, scope,
|
||||
DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE);
|
||||
|
||||
List<JetExpression> arguments = Lists.newArrayList();
|
||||
JetPsiFactory psiFactory = JetPsiFactory(delegateExpression);
|
||||
arguments.add(createExpressionForPropertyMetadata(psiFactory, propertyDescriptor));
|
||||
Name functionName = Name.identifier(PD_METHOD_NAME);
|
||||
JetReferenceExpression fakeCalleeExpression = psiFactory.createSimpleName(functionName.asString());
|
||||
ExpressionReceiver receiver = new ExpressionReceiver(delegateExpression, delegateType);
|
||||
Call call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT);
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> functionResults =
|
||||
callResolver.resolveCallWithGivenName(context, call, fakeCalleeExpression, functionName);
|
||||
|
||||
if (!functionResults.isSuccess()) {
|
||||
String expectedFunction = renderCall(call, traceToResolvePDMethod.getBindingContext());
|
||||
if (functionResults.isIncomplete() || functionResults.isSingleResult() ||
|
||||
functionResults.getResultCode() == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) {
|
||||
trace.report(DELEGATE_PD_METHOD_NONE_APPLICABLE.on(delegateExpression, expectedFunction, functionResults.getResultingCalls()));
|
||||
} else if (functionResults.isAmbiguity()) {
|
||||
trace.report(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY
|
||||
.on(delegateExpression, expectedFunction, functionResults.getResultingCalls()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
trace.record(DELEGATED_PROPERTY_PD_RESOLVED_CALL, propertyDescriptor, functionResults.getResultingCall());
|
||||
}
|
||||
|
||||
/* Resolve get() or set() methods from delegate */
|
||||
private void resolveDelegatedPropertyConventionMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@@ -179,10 +230,7 @@ public class DelegatedPropertyResolver {
|
||||
JetPsiFactory psiFactory = JetPsiFactory(delegateExpression);
|
||||
arguments.add(psiFactory.createExpression(hasThis ? "this" : "null"));
|
||||
|
||||
arguments.add(psiFactory.createExpression(KotlinBuiltIns.getInstance().getPropertyMetadataImpl().getName().asString() +
|
||||
"(\"" +
|
||||
propertyDescriptor.getName().asString() +
|
||||
"\")"));
|
||||
arguments.add(createExpressionForPropertyMetadata(psiFactory, propertyDescriptor));
|
||||
|
||||
if (!isGet) {
|
||||
JetReferenceExpression fakeArgument = (JetReferenceExpression) createFakeExpressionOfType(expressionTypingServices.getProject(), trace,
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata, s: String = "is OK") { name = "${p.name} $s" }
|
||||
}
|
||||
|
||||
val prop by Delegate()
|
||||
|
||||
fun box(): String {
|
||||
return if (prop == "prop is OK") "OK" else "fail";
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class A {
|
||||
val prop: String by Delegate()
|
||||
|
||||
inner class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if (A().prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
class A {
|
||||
val p = Delegate()
|
||||
val prop by p
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if (A().prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
fun foo() = Delegate()
|
||||
|
||||
class A {
|
||||
val prop by foo()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if (A().prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
val p = Delegate()
|
||||
|
||||
class A {
|
||||
val prop by p
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if (A().prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: A, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
val A.prop by Delegate()
|
||||
|
||||
class A {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if (A().prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: F.A, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
class F {
|
||||
val A.prop by Delegate()
|
||||
|
||||
class A {
|
||||
}
|
||||
|
||||
fun foo(): String {
|
||||
return A().prop
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if (F().foo() == "prop") "OK" else "fail"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
trait A {
|
||||
val prop: String
|
||||
}
|
||||
|
||||
class AImpl: A {
|
||||
override val prop by Delegate()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if(AImpl().prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Delegate {
|
||||
var inner = "OK"
|
||||
fun get(t: Any?, p: PropertyMetadata): String = inner
|
||||
|
||||
private fun propertyDelegated(p: PropertyMetadata) { inner = "fail" }
|
||||
fun propertyDelegated() { inner = "fail" }
|
||||
fun propertyDelegated(a: Int) { inner = "fail" }
|
||||
fun propertyDelegated(a: String) { inner = "fail" }
|
||||
fun propertyDelegated(p: PropertyMetadata, a: Int) { inner = "fail" }
|
||||
fun propertyDelegated<T>(p: PropertyMetadata, s: String = "") { inner = "fail" }
|
||||
}
|
||||
|
||||
val prop by Delegate()
|
||||
|
||||
fun box(): String {
|
||||
return prop
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
}
|
||||
|
||||
fun Delegate.propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
|
||||
class A {
|
||||
val prop by Delegate()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return if (A().prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
class A {
|
||||
private val prop by Delegate()
|
||||
|
||||
fun test(): String {
|
||||
return if (prop == "prop") "OK" else "fail"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return A().test()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
val prop by Delegate()
|
||||
|
||||
fun box(): String {
|
||||
return if (prop == "prop") "OK" else "fail"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class Delegate {
|
||||
var count = 0
|
||||
fun get(t: Any?, p: PropertyMetadata) {}
|
||||
fun propertyDelegated(vararg p: PropertyMetadata) { count++ }
|
||||
}
|
||||
|
||||
val delegate = Delegate()
|
||||
|
||||
val prop1 by delegate
|
||||
val prop2 by delegate
|
||||
|
||||
fun box(): String {
|
||||
return if(delegate.count == 2) "OK" else "fail"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(p: PropertyMetadata) { name = p.name }
|
||||
}
|
||||
|
||||
class A {
|
||||
inner class B {
|
||||
val prop by Delegate()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val p = A().B().prop
|
||||
return if(p == "prop") "OK" else "fail"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class Delegate {
|
||||
var name = ""
|
||||
fun get(t: Any?, p: PropertyMetadata): String = name
|
||||
fun propertyDelegated(vararg p: PropertyMetadata) { name = p[0].name }
|
||||
}
|
||||
|
||||
val prop by Delegate()
|
||||
|
||||
fun box(): String {
|
||||
return if (prop == "prop") "OK" else "fail"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
val a: Int by <!DELEGATE_SPECIAL_FUNCTION_AMBIGUITY!>Delegate()<!>
|
||||
|
||||
class Delegate {
|
||||
fun get(t: Any?, p: PropertyMetadata): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
|
||||
fun propertyDelegated(p: PropertyMetadata) {
|
||||
p.equals(p)
|
||||
}
|
||||
|
||||
fun propertyDelegated(p: PropertyMetadata, s: String = "") {
|
||||
p.equals(s)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
internal val a: kotlin.Int
|
||||
|
||||
internal final class Delegate {
|
||||
public constructor Delegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal final fun propertyDelegated(/*0*/ p: kotlin.PropertyMetadata): kotlin.Unit
|
||||
internal final fun propertyDelegated(/*0*/ p: kotlin.PropertyMetadata, /*1*/ s: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
val a: Int by <!DELEGATE_PD_METHOD_NONE_APPLICABLE!>Delegate()<!>
|
||||
|
||||
class Delegate {
|
||||
fun get(t: Any?, p: PropertyMetadata): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
|
||||
fun propertyDelegated<T>(p: PropertyMetadata) {
|
||||
p.equals(p)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
internal val a: kotlin.Int
|
||||
|
||||
internal final class Delegate {
|
||||
public constructor Delegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal final fun </*0*/ T> propertyDelegated(/*0*/ p: kotlin.PropertyMetadata): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
val a: Int by Delegate()
|
||||
|
||||
class Delegate {
|
||||
fun get(t: Any?, p: PropertyMetadata): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal val a: kotlin.Int
|
||||
|
||||
internal final class Delegate {
|
||||
public constructor Delegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
val a: Int by <!DELEGATE_PD_METHOD_NONE_APPLICABLE!>Delegate()<!>
|
||||
|
||||
class Delegate {
|
||||
fun get(t: Any?, p: PropertyMetadata): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
|
||||
private fun propertyDelegated(p: PropertyMetadata) {
|
||||
p.equals(p)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
internal val a: kotlin.Int
|
||||
|
||||
internal final class Delegate {
|
||||
public constructor Delegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
private final fun propertyDelegated(/*0*/ p: kotlin.PropertyMetadata): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
val a: Int by <!DELEGATE_PD_METHOD_NONE_APPLICABLE!>Delegate()<!>
|
||||
|
||||
class Delegate {
|
||||
fun get(t: Any?, p: PropertyMetadata): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
|
||||
fun propertyDelegated() {}
|
||||
|
||||
fun propertyDelegated(a: Int) {
|
||||
a.equals(a)
|
||||
}
|
||||
|
||||
fun propertyDelegated(a: String) {
|
||||
a.equals(a)
|
||||
}
|
||||
|
||||
fun propertyDelegated(p: PropertyMetadata, a: Int) {
|
||||
p.equals(a)
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package
|
||||
|
||||
internal val a: kotlin.Int
|
||||
|
||||
internal final class Delegate {
|
||||
public constructor Delegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal final fun propertyDelegated(): kotlin.Unit
|
||||
internal final fun propertyDelegated(/*0*/ a: kotlin.Int): kotlin.Unit
|
||||
internal final fun propertyDelegated(/*0*/ p: kotlin.PropertyMetadata, /*1*/ a: kotlin.Int): kotlin.Unit
|
||||
internal final fun propertyDelegated(/*0*/ a: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -2934,6 +2934,36 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyDelegatedAmbiguity.kt")
|
||||
public void testPropertyDelegatedAmbiguity() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/propertyDelegatedAmbiguity.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyDelegatedIncomplete.kt")
|
||||
public void testPropertyDelegatedIncomplete() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/propertyDelegatedIncomplete.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyDelegatedMissing.kt")
|
||||
public void testPropertyDelegatedMissing() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/propertyDelegatedMissing.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyDelegatedPrivate.kt")
|
||||
public void testPropertyDelegatedPrivate() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/propertyDelegatedPrivate.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyDelegatedWrongArguments.kt")
|
||||
public void testPropertyDelegatedWrongArguments() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/propertyDelegatedWrongArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("publicDelegatedProperty.kt")
|
||||
public void testPublicDelegatedProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/publicDelegatedProperty.kt");
|
||||
|
||||
@@ -2276,6 +2276,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/delegatedProperty")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({DelegatedProperty.PropertyDelegatedMethod.class})
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
public static class DelegatedProperty extends AbstractBlackBoxCodegenTest {
|
||||
@TestMetadata("accessTopLevelDelegatedPropertyInClinit.kt")
|
||||
@@ -2456,6 +2457,106 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
public static class PropertyDelegatedMethod extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInPropertyDelegatedMethod() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgs.kt")
|
||||
public void testDefaultArgs() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/defaultArgs.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegateAsInnerClass.kt")
|
||||
public void testDelegateAsInnerClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/delegateAsInnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegateByOtherProperty.kt")
|
||||
public void testDelegateByOtherProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/delegateByOtherProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegateByTopLevelFun.kt")
|
||||
public void testDelegateByTopLevelFun() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/delegateByTopLevelFun.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegateByTopLevelProperty.kt")
|
||||
public void testDelegateByTopLevelProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/delegateByTopLevelProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegateForExtProperty.kt")
|
||||
public void testDelegateForExtProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/delegateForExtProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegateForExtPropertyInClass.kt")
|
||||
public void testDelegateForExtPropertyInClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/delegateForExtPropertyInClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inTrait.kt")
|
||||
public void testInTrait() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/inTrait.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noneApplicable.kt")
|
||||
public void testNoneApplicable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/noneApplicable.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("pdAsExtensionFun.kt")
|
||||
public void testPdAsExtensionFun() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/pdAsExtensionFun.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("privateProperty.kt")
|
||||
public void testPrivateProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/privateProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevel.kt")
|
||||
public void testTopLevel() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/topLevel.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("twoPropsByOneDelegate.kt")
|
||||
public void testTwoPropsByOneDelegate() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/twoPropsByOneDelegate.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valInInnerClass.kt")
|
||||
public void testValInInnerClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/valInInnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/propertyDelegatedMethod/vararg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/elvis")
|
||||
|
||||
@@ -104,6 +104,8 @@ public class IdeErrorMessages {
|
||||
MAP.put(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY, "<html>Overload resolution ambiguity on method ''{0}''. All these functions match. <ul>{1}</ul></html>", STRING, HTML_AMBIGUOUS_CALLS);
|
||||
MAP.put(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, "<html>Property delegate must have a ''{0}'' method. None of the following functions is suitable. <ul>{1}</ul></html>",
|
||||
STRING, HTML_NONE_APPLICABLE_CALLS);
|
||||
MAP.put(DELEGATE_PD_METHOD_NONE_APPLICABLE, "''{0}'' method may be missing. None of the following functions will be called: <ul>{1}</ul></html>",
|
||||
STRING, HTML_NONE_APPLICABLE_CALLS);
|
||||
|
||||
MAP.put(CONFLICTING_JVM_DECLARATIONS, "<html>Platform declaration clash: {0}</html>", HTML_CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||
MAP.put(ACCIDENTAL_OVERRIDE, "<html>Accidental override: {0}</html>", HTML_CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||
|
||||
Reference in New Issue
Block a user