Resolve expression in property delegate
This commit is contained in:
@@ -95,6 +95,9 @@ public interface BindingContext {
|
||||
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> LOOP_RANGE_HAS_NEXT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> LOOP_RANGE_NEXT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<PropertyAccessorDescriptor, ResolvedCall<FunctionDescriptor>> DELEGATED_PROPERTY_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<PropertyAccessorDescriptor, Call> DELEGATED_PROPERTY_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<JetMultiDeclarationEntry, ResolvedCall<FunctionDescriptor>> COMPONENT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_GET = Slices.createSimpleSlice();
|
||||
|
||||
@@ -30,13 +30,11 @@ import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
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.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.expressions.DelegatedPropertyUtils;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.util.Box;
|
||||
@@ -123,7 +121,6 @@ public class BodyResolver {
|
||||
resolveDelegationSpecifierLists();
|
||||
resolveClassAnnotations();
|
||||
|
||||
resolvePropertyDelegates();
|
||||
resolvePropertyDeclarationBodies();
|
||||
resolveAnonymousInitializers();
|
||||
resolvePrimaryConstructorParameters();
|
||||
@@ -153,27 +150,6 @@ public class BodyResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void resolvePropertyDelegates() {
|
||||
for (Map.Entry<JetProperty, PropertyDescriptor> entry : context.getProperties().entrySet()) {
|
||||
JetProperty jetProperty = entry.getKey();
|
||||
|
||||
JetExpression delegateExpression = jetProperty.getDelegateExpression();
|
||||
if (delegateExpression == null) continue;
|
||||
|
||||
JetPropertyAccessor getter = jetProperty.getGetter();
|
||||
if (getter != null) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(getter));
|
||||
}
|
||||
|
||||
JetPropertyAccessor setter = jetProperty.getSetter();
|
||||
if (setter != null) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter));
|
||||
}
|
||||
|
||||
//todo resolve delegate expression
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveDelegationSpecifierList(JetClassOrObject jetClass, MutableClassDescriptor descriptor) {
|
||||
resolveDelegationSpecifierList(jetClass, descriptor,
|
||||
descriptor.getUnsubstitutedPrimaryConstructor(),
|
||||
@@ -413,6 +389,12 @@ public class BodyResolver {
|
||||
}
|
||||
}
|
||||
|
||||
JetExpression delegateExpression = property.getDelegateExpression();
|
||||
if (delegateExpression != null) {
|
||||
assert initializer == null : "Initializer should be null for delegated property : " + property.getText();
|
||||
resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, classDescriptor.getScopeForMemberResolution());
|
||||
}
|
||||
|
||||
resolvePropertyAccessors(property, propertyDescriptor);
|
||||
processed.add(property);
|
||||
}
|
||||
@@ -433,21 +415,21 @@ public class BodyResolver {
|
||||
resolvePropertyInitializer(property, propertyDescriptor, initializer);
|
||||
}
|
||||
|
||||
JetExpression delegateExpression = property.getDelegateExpression();
|
||||
if (delegateExpression != null) {
|
||||
assert initializer == null : "Initializer should be null for delegated property : " + property.getText();
|
||||
JetScope scope = context.getDeclaringScopes().apply(property);
|
||||
resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, scope);
|
||||
}
|
||||
|
||||
resolvePropertyAccessors(property, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private JetScope makeScopeForPropertyAccessor(@NotNull JetPropertyAccessor accessor, PropertyDescriptor propertyDescriptor) {
|
||||
JetScope declaringScope = context.getDeclaringScopes().apply(accessor);
|
||||
|
||||
JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScope(
|
||||
propertyDescriptor, declaringScope, propertyDescriptor.getTypeParameters(), propertyDescriptor.getReceiverParameter(),
|
||||
trace);
|
||||
WritableScope accessorScope = new WritableScopeImpl(
|
||||
propertyDeclarationInnerScope, declaringScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace), "Accessor scope");
|
||||
accessorScope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||
|
||||
return accessorScope;
|
||||
private JetScope makeScopeForPropertyAccessor(@NotNull JetPropertyAccessor accessor, @NotNull PropertyDescriptor descriptor) {
|
||||
JetScope accessorDeclaringScope = context.getDeclaringScopes().apply(accessor);
|
||||
assert accessorDeclaringScope != null : "Scope for accessor " + accessor.getText() + " should exists";
|
||||
return JetScopeUtils.makeScopeForPropertyAccessor(descriptor, accessorDeclaringScope, descriptorResolver, trace);
|
||||
}
|
||||
|
||||
public void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor) {
|
||||
@@ -485,8 +467,38 @@ public class BodyResolver {
|
||||
});
|
||||
}
|
||||
|
||||
private void resolvePropertyDelegate(
|
||||
@NotNull JetProperty jetProperty,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetExpression delegateExpression,
|
||||
@NotNull JetScope parentScopeForAccessor
|
||||
) {
|
||||
JetPropertyAccessor getter = jetProperty.getGetter();
|
||||
if (getter != null) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(getter));
|
||||
}
|
||||
|
||||
JetPropertyAccessor setter = jetProperty.getSetter();
|
||||
if (setter != null) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter));
|
||||
}
|
||||
|
||||
JetScope scope = makeScopeForPropertyInitializerOrDelegate(jetProperty, propertyDescriptor);
|
||||
JetType delegateType = expressionTypingServices.safeGetType(scope, delegateExpression, NO_EXPECTED_TYPE,
|
||||
DataFlowInfo.EMPTY, trace);
|
||||
|
||||
JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, parentScopeForAccessor, descriptorResolver, trace);
|
||||
DelegatedPropertyUtils.resolveDelegatedPropertyGetMethod(propertyDescriptor, delegateExpression, delegateType,
|
||||
expressionTypingServices, trace, accessorScope);
|
||||
|
||||
if (jetProperty.isVar()) {
|
||||
DelegatedPropertyUtils.resolveDelegatedPropertySetMethod(propertyDescriptor, delegateExpression, delegateType,
|
||||
expressionTypingServices, trace, accessorScope);
|
||||
}
|
||||
}
|
||||
|
||||
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer) {
|
||||
JetScope propertyDeclarationInnerScope = makeScopeForPropertyInitializer(property, propertyDescriptor);
|
||||
JetScope propertyDeclarationInnerScope = makeScopeForPropertyInitializerOrDelegate(property, propertyDescriptor);
|
||||
resolvePropertyInitializer(property, propertyDescriptor, initializer, propertyDeclarationInnerScope);
|
||||
}
|
||||
|
||||
@@ -498,7 +510,7 @@ public class BodyResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetScope makeScopeForPropertyInitializer(@NotNull JetProperty property, @NotNull PropertyDescriptor descriptor) {
|
||||
private JetScope makeScopeForPropertyInitializerOrDelegate(@NotNull JetProperty property, @NotNull PropertyDescriptor descriptor) {
|
||||
JetScope scope = this.context.getDeclaringScopes().apply(property);
|
||||
assert scope != null : "Scope for property " + property.getText() + " should exists";
|
||||
return descriptorResolver.getPropertyDeclarationInnerScopeForInitializer(
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
@@ -38,6 +39,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.expressions.DelegatedPropertyUtils;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
@@ -993,9 +995,17 @@ public class DescriptorResolver {
|
||||
if (propertyTypeRef == null) {
|
||||
final JetExpression initializer = variable.getInitializer();
|
||||
if (initializer == null) {
|
||||
if (hasDelegate) {
|
||||
// todo resolve type from delegate
|
||||
return ErrorUtils.createErrorType("Type from delegate");
|
||||
if (hasDelegate && variableDescriptor instanceof PropertyDescriptor) {
|
||||
final JetExpression propertyDelegateExpression = ((JetProperty) variable).getDelegateExpression();
|
||||
if (propertyDelegateExpression != null) {
|
||||
return DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
|
||||
@Override
|
||||
protected JetType compute() {
|
||||
return resolveDelegatedPropertyType((PropertyDescriptor) variableDescriptor, scope,
|
||||
propertyDelegateExpression, dataFlowInfo, trace);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!notLocal) {
|
||||
trace.report(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.on(variable));
|
||||
@@ -1023,6 +1033,26 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetType resolveDelegatedPropertyType(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetScope scope,
|
||||
@NotNull JetExpression delegateExpression,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
JetType type = expressionTypingServices.safeGetType(scope, delegateExpression, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace);
|
||||
|
||||
JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, scope, this, trace);
|
||||
JetType getterReturnType = DelegatedPropertyUtils
|
||||
.getDelegatedPropertyGetMethodReturnType(propertyDescriptor, delegateExpression, type, expressionTypingServices, trace,
|
||||
accessorScope);
|
||||
if (getterReturnType != null) {
|
||||
return getterReturnType;
|
||||
}
|
||||
return ErrorUtils.createErrorType("Type from delegate");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType transformAnonymousTypeIfNeeded(
|
||||
@NotNull DeclarationDescriptorWithVisibility descriptor,
|
||||
|
||||
@@ -23,7 +23,11 @@ import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -67,4 +71,22 @@ public final class JetScopeUtils {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static JetScope makeScopeForPropertyAccessor(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetScope parentScope,
|
||||
@NotNull DescriptorResolver descriptorResolver,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
JetScope propertyDeclarationInnerScope = descriptorResolver
|
||||
.getPropertyDeclarationInnerScope(propertyDescriptor, parentScope,
|
||||
propertyDescriptor.getTypeParameters(),
|
||||
propertyDescriptor.getReceiverParameter(), trace);
|
||||
WritableScope accessorScope = new WritableScopeImpl(propertyDeclarationInnerScope, parentScope.getContainingDeclaration(),
|
||||
new TraceBasedRedeclarationHandler(trace), "Accessor Scope");
|
||||
accessorScope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||
|
||||
return accessorScope;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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 org.jetbrains.jet.lang.types.expressions;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.types.DeferredType;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.psi.JetPsiFactory.createExpression;
|
||||
import static org.jetbrains.jet.lang.psi.JetPsiFactory.createSimpleName;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.createFakeExpressionOfType;
|
||||
|
||||
public class DelegatedPropertyUtils {
|
||||
|
||||
@Nullable
|
||||
public static JetType getDelegatedPropertyGetMethodReturnType(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetExpression delegateExpression,
|
||||
@NotNull JetType delegateType,
|
||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope
|
||||
) {
|
||||
resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, expressionTypingServices, trace,
|
||||
scope, true);
|
||||
return getDelegateGetMethodReturnType(trace.getBindingContext(), propertyDescriptor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetType getDelegateGetMethodReturnType(@NotNull BindingContext context, @NotNull PropertyDescriptor descriptor) {
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall =
|
||||
context.get(DELEGATED_PROPERTY_RESOLVED_CALL, descriptor.getGetter());
|
||||
return resolvedCall != null ? resolvedCall.getResultingDescriptor().getReturnType() : null;
|
||||
}
|
||||
|
||||
public static void resolveDelegatedPropertyGetMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetExpression delegateExpression,
|
||||
@NotNull JetType delegateType,
|
||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope
|
||||
) {
|
||||
resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, expressionTypingServices, trace,
|
||||
scope, true);
|
||||
JetType returnType = getDelegateGetMethodReturnType(trace.getBindingContext(), propertyDescriptor);
|
||||
JetType propertyType = propertyDescriptor.getType();
|
||||
if (propertyType instanceof DeferredType) {
|
||||
assert ((DeferredType) propertyType).isComputed() : "Property type should be computed when resolving delegate convention method";
|
||||
}
|
||||
|
||||
if (returnType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(returnType, propertyType)) {
|
||||
//todo report error
|
||||
}
|
||||
}
|
||||
|
||||
public static void resolveDelegatedPropertySetMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetExpression delegateExpression,
|
||||
@NotNull JetType delegateType,
|
||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope
|
||||
) {
|
||||
resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, expressionTypingServices, trace,
|
||||
scope, false);
|
||||
}
|
||||
|
||||
/* Resolve get() or set() methods from delegate */
|
||||
private static void resolveDelegatedPropertyConventionMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull JetExpression delegateExpression,
|
||||
@NotNull JetType delegateType,
|
||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope,
|
||||
boolean isGet
|
||||
) {
|
||||
PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
||||
assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText();
|
||||
|
||||
Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor);
|
||||
if (call != null) return;
|
||||
|
||||
ExpressionTypingContext context = ExpressionTypingContext.newContext(
|
||||
expressionTypingServices, trace, scope,
|
||||
DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE, ExpressionPosition.FREE);
|
||||
Project project = context.expressionTypingServices.getProject();
|
||||
|
||||
boolean hasThis = propertyDescriptor.getReceiverParameter() != null || propertyDescriptor.getExpectedThisObject() != null;
|
||||
|
||||
List<JetExpression> arguments = Lists.newArrayList();
|
||||
arguments.add(createExpression(project, hasThis ? "this" : "null"));
|
||||
arguments.add(createExpression(project, "\"" + propertyDescriptor.getName().getName() + "\""));
|
||||
if (!isGet) {
|
||||
JetReferenceExpression fakeArgument = createFakeExpressionOfType(context.expressionTypingServices.getProject(), trace,
|
||||
"fakeArgument" + arguments.size(),
|
||||
propertyDescriptor.getType());
|
||||
arguments.add(fakeArgument);
|
||||
List<ValueParameterDescriptor> valueParameters = accessor.getValueParameters();
|
||||
context.trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0));
|
||||
}
|
||||
|
||||
Name functionName = Name.identifier(isGet ? "get" : "set");
|
||||
JetReferenceExpression fakeCalleeExpression = createSimpleName(project, functionName.getName());
|
||||
|
||||
ExpressionReceiver receiver = new ExpressionReceiver(delegateExpression, delegateType);
|
||||
call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT);
|
||||
context.trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call);
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> functionResults = context.resolveCallWithGivenName(call, fakeCalleeExpression, functionName);
|
||||
|
||||
if (!functionResults.isSuccess()) {
|
||||
//todo report errors
|
||||
return;
|
||||
}
|
||||
|
||||
context.trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, functionResults.getResultingCall());
|
||||
}
|
||||
|
||||
private DelegatedPropertyUtils() {
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
trait A {
|
||||
val prop: Int
|
||||
}
|
||||
|
||||
class AImpl: A {
|
||||
override val prop by Delegate()
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
AImpl().prop
|
||||
}
|
||||
|
||||
class Delegate {
|
||||
fun get(t: Any?, p: String): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class B {
|
||||
val c by Delegate(<!UNRESOLVED_REFERENCE!>ag<!>)
|
||||
}
|
||||
|
||||
class Delegate<T: Any>(val init: T) {
|
||||
fun get(t: Any?, p: String): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
throw Exception()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
val a by <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>a<!>
|
||||
|
||||
val b by Delegate(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>b<!>)
|
||||
|
||||
val c by <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>d<!>
|
||||
val d by <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>c<!>
|
||||
|
||||
class Delegate(i: Int) {
|
||||
fun get(t: Any?, p: String): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
val Int.a by Delegate(<!NO_THIS!>this<!>)
|
||||
|
||||
class A {
|
||||
val Int.a by Delegate(<!TYPE_MISMATCH!>this<!>)
|
||||
}
|
||||
|
||||
class Delegate(i: Int) {
|
||||
fun get(t: Any?, p: String): Int {
|
||||
t.equals(p) // to avoid UNUSED_PARAMETER warning
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
~A~class A {
|
||||
~foo~fun foo() = A()
|
||||
}
|
||||
|
||||
val a: Int by `A`A().`foo`foo()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
~A~class A
|
||||
|
||||
val a: Int by `A`A()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class A
|
||||
|
||||
val a: Int by `foo`foo()
|
||||
|
||||
~foo~fun foo() = A()
|
||||
@@ -0,0 +1,4 @@
|
||||
object ~A~A
|
||||
|
||||
val a: Int by `A`A
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class A
|
||||
|
||||
~b~val b = A()
|
||||
|
||||
val a: Int by `b`b
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
~A~class A {
|
||||
~foo~fun foo() = A()
|
||||
}
|
||||
|
||||
class B {
|
||||
val a: Int by `A`A().`foo`foo()
|
||||
val b: Int by `A`A()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
~A~class A {
|
||||
~foo~fun foo() = A()
|
||||
}
|
||||
|
||||
class B {
|
||||
fun bar() {
|
||||
val a: Int by `A`A().`foo`foo()
|
||||
val b: Int by `A`A()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1913,6 +1913,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/backingField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegatedPropertyOverridedInTrait.kt")
|
||||
public void testDelegatedPropertyOverridedInTrait() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/delegatedPropertyOverridedInTrait.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inTrait.kt")
|
||||
public void testInTrait() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/inTrait.kt");
|
||||
@@ -1923,11 +1928,21 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/localVariable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyDefferedType.kt")
|
||||
public void testPropertyDefferedType() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/propertyDefferedType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("publicDelegatedProperty.kt")
|
||||
public void testPublicDelegatedProperty() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/publicDelegatedProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveType.kt")
|
||||
public void testRecursiveType() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/recursiveType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("redundantGetter.kt")
|
||||
public void testRedundantGetter() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/redundantGetter.kt");
|
||||
@@ -1938,6 +1953,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/redundantSetter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("thisInDelegate.kt")
|
||||
public void testThisInDelegate() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/delegatedProperty/thisInDelegate.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/deparenthesize")
|
||||
|
||||
Reference in New Issue
Block a user