"field": synthetic variable creation in accessors, codegen changed accordingly, a set of tests, relevant code fix (j2k)

This commit is contained in:
Mikhail Glukhikh
2015-09-16 11:12:33 +03:00
parent 6282a16013
commit 9f640b00d9
26 changed files with 315 additions and 8 deletions
@@ -0,0 +1,41 @@
/*
* 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.PropertyAccessorDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetProperty
import org.jetbrains.kotlin.resolve.source.toSourceElement
class SyntheticFieldDescriptor private constructor(
val propertyDescriptor: PropertyDescriptor,
accessorDescriptor: PropertyAccessorDescriptor,
property: JetProperty
): LocalVariableDescriptor(accessorDescriptor, Annotations.EMPTY, SyntheticFieldDescriptor.NAME,
propertyDescriptor.type, propertyDescriptor.isVar, property.toSourceElement()) {
constructor(accessorDescriptor: PropertyAccessorDescriptor,
property: JetProperty): this(accessorDescriptor.correspondingProperty, accessorDescriptor, property)
override fun getDispatchReceiverParameter() = propertyDescriptor.dispatchReceiverParameter
companion object {
val NAME = Name.identifier("field")
}
}
@@ -25,7 +25,11 @@ import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.kotlin.resolve.calls.CallResolver;
@@ -37,6 +41,7 @@ import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
import org.jetbrains.kotlin.resolve.scopes.*;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
@@ -649,6 +654,9 @@ public class BodyResolver {
trace.record(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); // TODO: this trace?
}
}
if (descriptor instanceof SyntheticFieldDescriptor) {
trace.record(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
}
}
}
});
@@ -766,6 +774,16 @@ public class BodyResolver {
trace, innerScope, outerDataFlowInfo, NO_EXPECTED_TYPE, callChecker)
);
// Synthetic "field" creation
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
assert innerScope instanceof WritableScopeStorage : "Expected innerScope as WritableScopeStorage but got " + innerScope;
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) functionDescriptor;
JetProperty property = (JetProperty) function.getParent();
SyntheticFieldDescriptor fieldDescriptor = new SyntheticFieldDescriptor(accessorDescriptor, property);
WritableScopeStorage innerScopeStorage = (WritableScopeStorage) innerScope;
innerScopeStorage.addVariableOrClassDescriptor(fieldDescriptor);
}
DataFlowInfo dataFlowInfo = null;
if (beforeBlockBody != null) {