Delegated Properties: Analysis adjustments for local delegated properties support
This commit is contained in:
@@ -1055,6 +1055,9 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
||||
// We do not want to have getDeferredValue(delegate) here, because delegate value will be read anyway later
|
||||
visitAssignment(property, getDeferredValue(null), property)
|
||||
generateInstructions(delegate)
|
||||
if (property.isLocal) {
|
||||
generateInitializer(property, createSyntheticValue(property, MagicKind.FAKE_INITIALIZER));
|
||||
}
|
||||
if (builder.getBoundValue(delegate) != null) {
|
||||
createSyntheticValue(property, MagicKind.VALUE_CONSUMER, delegate)
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.descriptors.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.VariableAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||
|
||||
sealed class LocalVariableAccessorDescriptor(
|
||||
override val correspondingVariable: LocalVariableDescriptor,
|
||||
isGetter: Boolean
|
||||
) : SimpleFunctionDescriptorImpl(
|
||||
correspondingVariable.containingDeclaration,
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
Name.special((if (isGetter) "<get-" else "<set-") + correspondingVariable.name + ">"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
), VariableAccessorDescriptor {
|
||||
class Getter(correspondingVariable: LocalVariableDescriptor) : LocalVariableAccessorDescriptor(correspondingVariable, true)
|
||||
class Setter(correspondingVariable: LocalVariableDescriptor) : LocalVariableAccessorDescriptor(correspondingVariable, false)
|
||||
|
||||
init {
|
||||
val valueParameters =
|
||||
if (isGetter) emptyList() else createValueParameter(Name.identifier("value"), correspondingVariable.type).singletonList()
|
||||
initialize(null, null, emptyList(), valueParameters, correspondingVariable.type, null, Visibilities.LOCAL)
|
||||
}
|
||||
|
||||
private fun createValueParameter(name: Name, type: KotlinType): ValueParameterDescriptorImpl {
|
||||
return ValueParameterDescriptorImpl(this, null, 0, Annotations.EMPTY, name, type, false, false, false, null, SourceElement.NO_SOURCE)
|
||||
}
|
||||
}
|
||||
+30
-1
@@ -24,16 +24,33 @@ import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
|
||||
public class LocalVariableDescriptor extends VariableDescriptorWithInitializerImpl {
|
||||
public class LocalVariableDescriptor extends VariableDescriptorWithInitializerImpl implements VariableDescriptorWithAccessors {
|
||||
private final boolean withAccessors;
|
||||
private VariableAccessorDescriptor getter;
|
||||
private VariableAccessorDescriptor setter;
|
||||
|
||||
public LocalVariableDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull Annotations annotations,
|
||||
@NotNull Name name,
|
||||
@Nullable KotlinType type,
|
||||
boolean mutable,
|
||||
boolean withAccessors,
|
||||
@NotNull SourceElement source
|
||||
) {
|
||||
super(containingDeclaration, annotations, name, type, mutable, source);
|
||||
this.withAccessors = withAccessors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOutType(KotlinType outType) {
|
||||
super.setOutType(outType);
|
||||
if (withAccessors) {
|
||||
this.getter = new LocalVariableAccessorDescriptor.Getter(this);
|
||||
if (isVar()) {
|
||||
this.setter = new LocalVariableAccessorDescriptor.Setter(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -53,4 +70,16 @@ public class LocalVariableDescriptor extends VariableDescriptorWithInitializerIm
|
||||
public Visibility getVisibility() {
|
||||
return Visibilities.LOCAL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VariableAccessorDescriptor getGetter() {
|
||||
return getter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VariableAccessorDescriptor getSetter() {
|
||||
return setter;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ class SyntheticFieldDescriptor private constructor(
|
||||
accessorDescriptor: PropertyAccessorDescriptor,
|
||||
property: KtProperty
|
||||
): LocalVariableDescriptor(accessorDescriptor, Annotations.EMPTY, SyntheticFieldDescriptor.NAME,
|
||||
propertyDescriptor.type, propertyDescriptor.isVar, property.toSourceElement()) {
|
||||
propertyDescriptor.type, propertyDescriptor.isVar, false, property.toSourceElement()) {
|
||||
|
||||
constructor(accessorDescriptor: PropertyAccessorDescriptor,
|
||||
property: KtProperty): this(accessorDescriptor.correspondingProperty, accessorDescriptor, property)
|
||||
|
||||
@@ -385,7 +385,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtPropertyDelegate> ABSTRACT_DELEGATED_PROPERTY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtPropertyAccessor> ACCESSOR_FOR_DELEGATED_PROPERTY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtPropertyDelegate> DELEGATED_PROPERTY_IN_INTERFACE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtPropertyDelegate> LOCAL_VARIABLE_WITH_DELEGATE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtPropertyDelegate> SCRIPT_TOP_LEVEL_LOCAL_VARIABLE_WITH_DELEGATE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtProperty> PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(ABSTRACT_DELEGATED_PROPERTY, "Delegated property cannot be abstract");
|
||||
MAP.put(ACCESSOR_FOR_DELEGATED_PROPERTY, "Delegated property cannot have accessors with non-default implementations");
|
||||
MAP.put(DELEGATED_PROPERTY_IN_INTERFACE, "Delegated properties are not allowed in interfaces");
|
||||
MAP.put(LOCAL_VARIABLE_WITH_DELEGATE, "Local variables are not allowed to have delegates");
|
||||
MAP.put(SCRIPT_TOP_LEVEL_LOCAL_VARIABLE_WITH_DELEGATE, "Top-level local variables in scripts are not allowed to have delegates");
|
||||
|
||||
MAP.put(INAPPLICABLE_LATEINIT_MODIFIER, "''lateinit'' modifier {0}", STRING);
|
||||
|
||||
|
||||
@@ -123,10 +123,10 @@ public interface BindingContext {
|
||||
WritableSlice<KtExpression, ResolvedCall<FunctionDescriptor>> LOOP_RANGE_HAS_NEXT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<KtExpression, 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<VariableAccessorDescriptor, ResolvedCall<FunctionDescriptor>> DELEGATED_PROPERTY_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<VariableAccessorDescriptor, Call> DELEGATED_PROPERTY_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<PropertyDescriptor, ResolvedCall<FunctionDescriptor>> DELEGATED_PROPERTY_PD_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<VariableDescriptorWithAccessors, ResolvedCall<FunctionDescriptor>> DELEGATED_PROPERTY_PD_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<KtDestructuringDeclarationEntry, ResolvedCall<FunctionDescriptor>> COMPONENT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
|
||||
@@ -696,34 +696,12 @@ public class BodyResolver {
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull LexicalScope propertyHeaderScope
|
||||
) {
|
||||
KtPropertyAccessor getter = property.getGetter();
|
||||
if (getter != null && getter.hasBody()) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(getter));
|
||||
}
|
||||
|
||||
KtPropertyAccessor setter = property.getSetter();
|
||||
if (setter != null && setter.hasBody()) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter));
|
||||
}
|
||||
|
||||
LexicalScope delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(propertyHeaderScope, propertyDescriptor);
|
||||
|
||||
LexicalScope initializerScope = ScopeUtils.makeScopeForPropertyInitializer(propertyHeaderScope, propertyDescriptor);
|
||||
|
||||
KotlinType delegateType = delegatedPropertyResolver.resolveDelegateExpression(
|
||||
delegateExpression, property, propertyDescriptor, initializerScope, trace,
|
||||
outerDataFlowInfo);
|
||||
|
||||
delegatedPropertyResolver.resolveDelegatedPropertyGetMethod(propertyDescriptor, delegateExpression, delegateType,
|
||||
trace, delegateFunctionsScope);
|
||||
|
||||
if (property.isVar()) {
|
||||
delegatedPropertyResolver.resolveDelegatedPropertySetMethod(propertyDescriptor, delegateExpression, delegateType,
|
||||
trace, delegateFunctionsScope);
|
||||
}
|
||||
|
||||
delegatedPropertyResolver.resolveDelegatedPropertyPDMethod(propertyDescriptor, delegateExpression, delegateType,
|
||||
trace, delegateFunctionsScope);
|
||||
delegatedPropertyResolver.resolvePropertyDelegate(outerDataFlowInfo,
|
||||
property,
|
||||
propertyDescriptor,
|
||||
delegateExpression,
|
||||
propertyHeaderScope,
|
||||
trace);
|
||||
}
|
||||
|
||||
private void resolvePropertyInitializer(
|
||||
|
||||
@@ -400,6 +400,14 @@ class DeclarationsChecker(
|
||||
exposedChecker.checkProperty(property, propertyDescriptor)
|
||||
checkPropertyTypeParametersAreUsedInReceiverType(propertyDescriptor)
|
||||
checkImplicitCallableType(property, propertyDescriptor)
|
||||
checkDelegatedPropertyInScript(property)
|
||||
}
|
||||
|
||||
private fun checkDelegatedPropertyInScript(property: KtProperty) {
|
||||
val delegate = property.delegate
|
||||
if (delegate != null && KtPsiUtil.isScriptDeclaration(property)) {
|
||||
trace.report(SCRIPT_TOP_LEVEL_LOCAL_VARIABLE_WITH_DELEGATE.on(delegate))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkPropertyTypeParametersAreUsedInReceiverType(descriptor: PropertyDescriptor) {
|
||||
|
||||
@@ -85,48 +85,93 @@ public class DelegatedPropertyResolver {
|
||||
this.expressionTypingServices = expressionTypingServices;
|
||||
}
|
||||
|
||||
public void resolvePropertyDelegate(
|
||||
@NotNull DataFlowInfo outerDataFlowInfo,
|
||||
@NotNull KtProperty property,
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull LexicalScope propertyHeaderScope,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
KtPropertyAccessor getter = property.getGetter();
|
||||
if (getter != null && getter.hasBody()) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(getter));
|
||||
}
|
||||
|
||||
KtPropertyAccessor setter = property.getSetter();
|
||||
if (setter != null && setter.hasBody()) {
|
||||
trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter));
|
||||
}
|
||||
|
||||
LexicalScope delegateFunctionsScope;
|
||||
LexicalScope initializerScope;
|
||||
|
||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
|
||||
delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(propertyHeaderScope, propertyDescriptor);
|
||||
initializerScope = ScopeUtils.makeScopeForPropertyInitializer(propertyHeaderScope, propertyDescriptor);
|
||||
}
|
||||
else {
|
||||
delegateFunctionsScope = initializerScope = propertyHeaderScope;
|
||||
}
|
||||
|
||||
KotlinType delegateType = resolveDelegateExpression(delegateExpression,
|
||||
property,
|
||||
variableDescriptor,
|
||||
initializerScope,
|
||||
trace,
|
||||
outerDataFlowInfo);
|
||||
|
||||
resolveDelegatedPropertyGetMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope);
|
||||
if (property.isVar()) {
|
||||
resolveDelegatedPropertySetMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope);
|
||||
}
|
||||
|
||||
resolveDelegatedPropertyPDMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public KotlinType getDelegatedPropertyGetMethodReturnType(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull KotlinType delegateType,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull LexicalScope delegateFunctionsScope
|
||||
) {
|
||||
resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, true);
|
||||
resolveDelegatedPropertyConventionMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, true);
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall =
|
||||
trace.getBindingContext().get(DELEGATED_PROPERTY_RESOLVED_CALL, propertyDescriptor.getGetter());
|
||||
trace.getBindingContext().get(DELEGATED_PROPERTY_RESOLVED_CALL, variableDescriptor.getGetter());
|
||||
return resolvedCall != null ? resolvedCall.getResultingDescriptor().getReturnType() : null;
|
||||
}
|
||||
|
||||
public void resolveDelegatedPropertyGetMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull KotlinType delegateType,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull LexicalScope delegateFunctionsScope
|
||||
) {
|
||||
KotlinType returnType = getDelegatedPropertyGetMethodReturnType(
|
||||
propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope);
|
||||
KotlinType propertyType = propertyDescriptor.getType();
|
||||
variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope);
|
||||
KotlinType propertyType = variableDescriptor.getType();
|
||||
|
||||
/* Do not check return type of get() method of delegate for properties with DeferredType because property type is taken from it */
|
||||
if (!(propertyType instanceof DeferredType) && returnType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(returnType, propertyType)) {
|
||||
Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, propertyDescriptor.getGetter());
|
||||
assert call != null : "Call should exists for " + propertyDescriptor.getGetter();
|
||||
Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, variableDescriptor.getGetter());
|
||||
assert call != null : "Call should exists for " + variableDescriptor.getGetter();
|
||||
trace.report(DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH
|
||||
.on(delegateExpression, renderCall(call, trace.getBindingContext()), propertyDescriptor.getType(), returnType));
|
||||
.on(delegateExpression, renderCall(call, trace.getBindingContext()), variableDescriptor.getType(), returnType));
|
||||
}
|
||||
}
|
||||
|
||||
public void resolveDelegatedPropertySetMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull KotlinType delegateType,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull LexicalScope delegateFunctionsScope
|
||||
) {
|
||||
resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, false);
|
||||
resolveDelegatedPropertyConventionMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -135,7 +180,7 @@ public class DelegatedPropertyResolver {
|
||||
}
|
||||
|
||||
public void resolveDelegatedPropertyPDMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull KotlinType delegateType,
|
||||
@NotNull BindingTrace trace,
|
||||
@@ -168,19 +213,19 @@ public class DelegatedPropertyResolver {
|
||||
return;
|
||||
}
|
||||
|
||||
trace.record(DELEGATED_PROPERTY_PD_RESOLVED_CALL, propertyDescriptor, functionResults.getResultingCall());
|
||||
trace.record(DELEGATED_PROPERTY_PD_RESOLVED_CALL, variableDescriptor, functionResults.getResultingCall());
|
||||
}
|
||||
|
||||
/* Resolve getValue() or setValue() methods from delegate */
|
||||
private void resolveDelegatedPropertyConventionMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull VariableDescriptorWithAccessors propertyDescriptor,
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull KotlinType delegateType,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull LexicalScope delegateFunctionsScope,
|
||||
boolean isGet
|
||||
) {
|
||||
PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
||||
VariableAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
||||
assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText();
|
||||
|
||||
if (trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor) != null) return;
|
||||
@@ -229,7 +274,7 @@ public class DelegatedPropertyResolver {
|
||||
|
||||
/* Resolve getValue() or setValue() methods from delegate */
|
||||
public OverloadResolutionResults<FunctionDescriptor> getDelegatedPropertyConventionMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull VariableDescriptorWithAccessors propertyDescriptor,
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull KotlinType delegateType,
|
||||
@NotNull BindingTrace trace,
|
||||
@@ -237,7 +282,7 @@ public class DelegatedPropertyResolver {
|
||||
boolean isGet,
|
||||
boolean isComplete
|
||||
) {
|
||||
PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
||||
VariableAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
||||
assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText();
|
||||
|
||||
KotlinType expectedType = isComplete && isGet && !(propertyDescriptor.getType() instanceof DeferredType)
|
||||
@@ -326,7 +371,7 @@ public class DelegatedPropertyResolver {
|
||||
public KotlinType resolveDelegateExpression(
|
||||
@NotNull KtExpression delegateExpression,
|
||||
@NotNull KtProperty property,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull LexicalScope scopeForDelegate,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull DataFlowInfo dataFlowInfo
|
||||
@@ -334,7 +379,7 @@ public class DelegatedPropertyResolver {
|
||||
TemporaryBindingTrace traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property");
|
||||
KtExpression calleeExpression = CallUtilKt.getCalleeExpressionIfAny(delegateExpression);
|
||||
ConstraintSystemCompleter completer = createConstraintSystemCompleter(
|
||||
property, propertyDescriptor, delegateExpression, scopeForDelegate, trace);
|
||||
property, variableDescriptor, delegateExpression, scopeForDelegate, trace);
|
||||
if (calleeExpression != null) {
|
||||
traceToResolveDelegatedProperty.record(CONSTRAINT_SYSTEM_COMPLETER, calleeExpression, completer);
|
||||
}
|
||||
@@ -352,13 +397,13 @@ public class DelegatedPropertyResolver {
|
||||
@NotNull
|
||||
private ConstraintSystemCompleter createConstraintSystemCompleter(
|
||||
@NotNull KtProperty property,
|
||||
@NotNull final PropertyDescriptor propertyDescriptor,
|
||||
@NotNull final VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull final KtExpression delegateExpression,
|
||||
@NotNull LexicalScope scopeForDelegate,
|
||||
@NotNull final BindingTrace trace
|
||||
) {
|
||||
final LexicalScope delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(scopeForDelegate, propertyDescriptor);
|
||||
final KotlinType expectedType = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
final LexicalScope delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(scopeForDelegate, variableDescriptor);
|
||||
final KotlinType expectedType = property.getTypeReference() != null ? variableDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
return new ConstraintSystemCompleter() {
|
||||
@Override
|
||||
public void completeConstraintSystem(
|
||||
@@ -375,7 +420,7 @@ public class DelegatedPropertyResolver {
|
||||
TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods");
|
||||
OverloadResolutionResults<FunctionDescriptor>
|
||||
getMethodResults = getDelegatedPropertyConventionMethod(
|
||||
propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope,
|
||||
variableDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope,
|
||||
true, false
|
||||
);
|
||||
|
||||
@@ -390,16 +435,16 @@ public class DelegatedPropertyResolver {
|
||||
}
|
||||
addConstraintForThisValue(constraintSystem, typeVariableSubstitutor, descriptor);
|
||||
}
|
||||
if (!propertyDescriptor.isVar()) return;
|
||||
if (!variableDescriptor.isVar()) return;
|
||||
|
||||
// For the case: 'val v by d' (no declared type).
|
||||
// When we add a constraint for 'set' method for delegated expression 'd' we use a type of the declared variable 'v'.
|
||||
// But if the type isn't known yet, the constraint shouldn't be added (we try to infer the type of 'v' here as well).
|
||||
if (propertyDescriptor.getReturnType() instanceof DeferredType) return;
|
||||
if (variableDescriptor.getReturnType() instanceof DeferredType) return;
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor>
|
||||
setMethodResults = getDelegatedPropertyConventionMethod(
|
||||
propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope,
|
||||
variableDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope,
|
||||
false, false
|
||||
);
|
||||
|
||||
@@ -432,8 +477,8 @@ public class DelegatedPropertyResolver {
|
||||
TypeSubstitutor typeVariableSubstitutor,
|
||||
FunctionDescriptor resultingDescriptor
|
||||
) {
|
||||
ReceiverParameterDescriptor extensionReceiver = propertyDescriptor.getExtensionReceiverParameter();
|
||||
ReceiverParameterDescriptor dispatchReceiver = propertyDescriptor.getDispatchReceiverParameter();
|
||||
ReceiverParameterDescriptor extensionReceiver = variableDescriptor.getExtensionReceiverParameter();
|
||||
ReceiverParameterDescriptor dispatchReceiver = variableDescriptor.getDispatchReceiverParameter();
|
||||
KotlinType typeOfThis =
|
||||
extensionReceiver != null ? extensionReceiver.getType() :
|
||||
dispatchReceiver != null ? dispatchReceiver.getType() :
|
||||
|
||||
@@ -655,6 +655,7 @@ public class DescriptorResolver {
|
||||
KtPsiUtil.safeName(parameter.getName()),
|
||||
type,
|
||||
false,
|
||||
false,
|
||||
KotlinSourceElementKt.toSourceElement(parameter)
|
||||
);
|
||||
trace.record(BindingContext.VALUE_PARAMETER, parameter, variableDescriptor);
|
||||
|
||||
@@ -35,12 +35,12 @@ import org.jetbrains.kotlin.types.expressions.*
|
||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
|
||||
|
||||
class LocalVariableResolver(
|
||||
private val expressionTypingServices: ExpressionTypingServices,
|
||||
private val modifiersChecker: ModifiersChecker,
|
||||
private val identifierChecker: IdentifierChecker,
|
||||
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
||||
private val annotationResolver: AnnotationResolver,
|
||||
private val variableTypeResolver: VariableTypeResolver
|
||||
private val variableTypeResolver: VariableTypeResolver,
|
||||
private val delegatedPropertyResolver: DelegatedPropertyResolver
|
||||
) {
|
||||
|
||||
fun process(
|
||||
@@ -65,13 +65,18 @@ class LocalVariableResolver(
|
||||
context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter))
|
||||
}
|
||||
|
||||
val propertyDescriptor = resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.trace)
|
||||
|
||||
val delegateExpression = property.delegateExpression
|
||||
if (delegateExpression != null) {
|
||||
expressionTypingServices.getTypeInfo(delegateExpression, context)
|
||||
context.trace.report(LOCAL_VARIABLE_WITH_DELEGATE.on(property.delegate!!))
|
||||
if (delegateExpression != null && propertyDescriptor is VariableDescriptorWithAccessors) {
|
||||
delegatedPropertyResolver.resolvePropertyDelegate(typingContext.dataFlowInfo,
|
||||
property,
|
||||
propertyDescriptor,
|
||||
delegateExpression,
|
||||
typingContext.scope,
|
||||
typingContext.trace);
|
||||
}
|
||||
|
||||
val propertyDescriptor = resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.trace)
|
||||
val initializer = property.initializer
|
||||
var typeInfo: KotlinTypeInfo
|
||||
if (initializer != null) {
|
||||
@@ -167,12 +172,14 @@ class LocalVariableResolver(
|
||||
type: KotlinType?,
|
||||
trace: BindingTrace
|
||||
): LocalVariableDescriptor {
|
||||
val hasDelegate = variable is KtProperty && variable.hasDelegate();
|
||||
val variableDescriptor = LocalVariableDescriptor(
|
||||
scope.ownerDescriptor,
|
||||
annotationResolver.resolveAnnotationsWithArguments(scope, variable.modifierList, trace),
|
||||
KtPsiUtil.safeName(variable.name),
|
||||
type,
|
||||
variable.isVar,
|
||||
hasDelegate,
|
||||
variable.toSourceElement()
|
||||
)
|
||||
trace.record(BindingContext.VARIABLE, variable, variableDescriptor)
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ private fun bindFunctionReference(expression: KtCallableReferenceExpression, typ
|
||||
|
||||
private fun bindPropertyReference(expression: KtCallableReferenceExpression, referenceType: KotlinType, context: ResolutionContext<*>) {
|
||||
val localVariable = LocalVariableDescriptor(context.scope.ownerDescriptor, Annotations.EMPTY, Name.special("<anonymous>"),
|
||||
referenceType, /* mutable = */ false, expression.toSourceElement())
|
||||
referenceType, /* mutable = */ false, false, expression.toSourceElement())
|
||||
|
||||
context.trace.record(BindingContext.VARIABLE, expression, localVariable)
|
||||
}
|
||||
|
||||
+6
-1
@@ -60,7 +60,7 @@ public class ExpressionTypingComponents {
|
||||
/*package*/ DeclarationsCheckerBuilder declarationsCheckerBuilder;
|
||||
/*package*/ LocalVariableResolver localVariableResolver;
|
||||
/*package*/ LookupTracker lookupTracker;
|
||||
|
||||
/*package*/ DelegatedPropertyResolver delegatedPropertyResolver;
|
||||
|
||||
@Inject
|
||||
public void setGlobalContext(@NotNull GlobalContext globalContext) {
|
||||
@@ -201,4 +201,9 @@ public class ExpressionTypingComponents {
|
||||
public void setLookupTracker(@NotNull LookupTracker lookupTracker) {
|
||||
this.lookupTracker = lookupTracker;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setDelegatedPropertyResolver(DelegatedPropertyResolver delegatedPropertyResolver) {
|
||||
this.delegatedPropertyResolver = delegatedPropertyResolver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,7 @@ import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.utils.Printer;
|
||||
|
||||
public final class ScopeUtils {
|
||||
@@ -69,10 +66,10 @@ public final class ScopeUtils {
|
||||
@NotNull
|
||||
public static LexicalScope makeScopeForDelegateConventionFunctions(
|
||||
@NotNull LexicalScope parent,
|
||||
@NotNull PropertyDescriptor propertyDescriptor
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor
|
||||
) {
|
||||
// todo: very strange scope!
|
||||
return new LexicalScopeImpl(parent, propertyDescriptor, true, propertyDescriptor.getExtensionReceiverParameter(),
|
||||
return new LexicalScopeImpl(parent, variableDescriptor, true, variableDescriptor.getExtensionReceiverParameter(),
|
||||
LexicalScopeKind.PROPERTY_DELEGATE_METHOD
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
== Delegate ==
|
||||
class Delegate {
|
||||
operator fun getValue(t: Any?, p: KProperty<*>): Int = 1
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== getValue ==
|
||||
operator fun getValue(t: Any?, p: KProperty<*>): Int = 1
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
v(t: Any?)
|
||||
magic[FAKE_INITIALIZER](t: Any?) -> <v0>
|
||||
w(t|<v0>)
|
||||
v(p: KProperty<*>)
|
||||
magic[FAKE_INITIALIZER](p: KProperty<*>) -> <v1>
|
||||
w(p|<v1>)
|
||||
r(1) -> <v2>
|
||||
ret(*|<v2>) L1
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== foo ==
|
||||
fun foo(): Int {
|
||||
val prop: Int by Delegate()
|
||||
return prop
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
2 mark({ val prop: Int by Delegate() return prop })
|
||||
v(val prop: Int by Delegate())
|
||||
magic[UNRECOGNIZED_WRITE_RHS](val prop: Int by Delegate()) -> <v0>
|
||||
w(prop|<v0>)
|
||||
mark(Delegate())
|
||||
call(Delegate(), <init>) -> <v1>
|
||||
magic[FAKE_INITIALIZER](val prop: Int by Delegate()) -> <v2>
|
||||
w(prop|<v2>)
|
||||
magic[VALUE_CONSUMER](val prop: Int by Delegate()|<v1>) -> <v3>
|
||||
r(prop) -> <v4>
|
||||
ret(*|<v4>) L1
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
@@ -0,0 +1,10 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Delegate {
|
||||
operator fun getValue(t: Any?, p: KProperty<*>): Int = 1
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
val prop: Int by Delegate()
|
||||
return prop
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
== Delegate ==
|
||||
class Delegate {
|
||||
operator fun getValue(t: Any?, p: KProperty<*>): Int = 1
|
||||
}
|
||||
---------------------
|
||||
=====================
|
||||
== getValue ==
|
||||
operator fun getValue(t: Any?, p: KProperty<*>): Int = 1
|
||||
---------------------
|
||||
<v0>: * NEW: magic[FAKE_INITIALIZER](t: Any?) -> <v0>
|
||||
<v1>: {<: KProperty<*>} NEW: magic[FAKE_INITIALIZER](p: KProperty<*>) -> <v1>
|
||||
1 <v2>: Int NEW: r(1) -> <v2>
|
||||
=====================
|
||||
== foo ==
|
||||
fun foo(): Int {
|
||||
val prop: Int by Delegate()
|
||||
return prop
|
||||
}
|
||||
---------------------
|
||||
<v0>: Int NEW: magic[UNRECOGNIZED_WRITE_RHS](val prop: Int by Delegate()) -> <v0>
|
||||
<v2>: Int NEW: magic[FAKE_INITIALIZER](val prop: Int by Delegate()) -> <v2>
|
||||
<v3>: * NEW: magic[VALUE_CONSUMER](val prop: Int by Delegate()|<v1>) -> <v3>
|
||||
Delegate() <v1>: * NEW: call(Delegate(), <init>) -> <v1>
|
||||
prop <v4>: Int NEW: r(prop) -> <v4>
|
||||
return prop !<v5>: *
|
||||
{ val prop: Int by Delegate() return prop } !<v5>: * COPY
|
||||
=====================
|
||||
@@ -3,13 +3,13 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Local {
|
||||
fun foo() {
|
||||
val a: Int <!LOCAL_VARIABLE_WITH_DELEGATE!>by Delegate()<!>
|
||||
}
|
||||
fun foo() {
|
||||
val a: Int by Delegate()
|
||||
}
|
||||
}
|
||||
|
||||
class Delegate {
|
||||
fun getValue(t: Any?, p: KProperty<*>): Int {
|
||||
return 1
|
||||
}
|
||||
operator fun getValue(t: Any?, p: KProperty<*>): Int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package
|
||||
public final class Delegate {
|
||||
public constructor Delegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun getValue(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.reflect.KProperty<*>): kotlin.Int
|
||||
public final operator fun getValue(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.reflect.KProperty<*>): 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,20 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Delegate {
|
||||
operator fun getValue(t: Any?, p: KProperty<*>): Int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
val a: Int <!SCRIPT_TOP_LEVEL_LOCAL_VARIABLE_WITH_DELEGATE!>by Delegate()<!>
|
||||
|
||||
class Foo {
|
||||
val a: Int by Delegate()
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val a: Int by Delegate()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package
|
||||
|
||||
public final class TopLevelVariable {
|
||||
public constructor TopLevelVariable(/*0*/ args: kotlin.Array<kotlin.String>)
|
||||
public final val a: kotlin.Int
|
||||
public final val args: kotlin.Array<kotlin.String>
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public final class Delegate {
|
||||
public constructor Delegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun getValue(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.reflect.KProperty<*>): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Foo {
|
||||
public constructor Foo()
|
||||
public final val a: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
@@ -474,6 +474,12 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localDelegatedVal.kt")
|
||||
public void testLocalDelegatedVal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localDelegatedVal.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localFunction.kt")
|
||||
public void testLocalFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localFunction.kt");
|
||||
|
||||
@@ -476,6 +476,12 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localDelegatedVal.kt")
|
||||
public void testLocalDelegatedVal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localDelegatedVal.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localFunction.kt")
|
||||
public void testLocalFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localFunction.kt");
|
||||
|
||||
@@ -19641,6 +19641,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/script/SimpleScript.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelVariable.kts")
|
||||
public void testTopLevelVariable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/script/topLevelVariable.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/diagnostics")
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface PropertyAccessorDescriptor extends FunctionDescriptor {
|
||||
public interface PropertyAccessorDescriptor extends VariableAccessorDescriptor {
|
||||
boolean isDefault();
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -23,10 +23,12 @@ import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface PropertyDescriptor extends VariableDescriptor, CallableMemberDescriptor {
|
||||
public interface PropertyDescriptor extends VariableDescriptorWithAccessors, CallableMemberDescriptor {
|
||||
@Override
|
||||
@Nullable
|
||||
PropertyGetterDescriptor getGetter();
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
PropertySetterDescriptor getSetter();
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.descriptors
|
||||
|
||||
public interface VariableAccessorDescriptor : FunctionDescriptor {
|
||||
val correspondingVariable: VariableDescriptorWithAccessors
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.descriptors
|
||||
|
||||
public interface VariableDescriptorWithAccessors : VariableDescriptor {
|
||||
public val getter: VariableAccessorDescriptor?
|
||||
public val setter: VariableAccessorDescriptor?
|
||||
}
|
||||
+6
@@ -132,6 +132,12 @@ public abstract class PropertyAccessorDescriptorImpl extends DeclarationDescript
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VariableDescriptorWithAccessors getCorrespondingVariable() {
|
||||
return correspondingProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PropertyDescriptor getCorrespondingProperty() {
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// "Create property 'foo'" "true"
|
||||
// ERROR: Local variables are not allowed to have delegates
|
||||
// ERROR: Property must be initialized
|
||||
|
||||
fun test() {
|
||||
|
||||
Vendored
-1
@@ -1,7 +1,6 @@
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
// "Create property 'foo'" "true"
|
||||
// ERROR: Local variables are not allowed to have delegates
|
||||
// ERROR: Property must be initialized
|
||||
|
||||
val foo: ReadOnlyProperty<Nothing?, Int>
|
||||
|
||||
Reference in New Issue
Block a user