Base support of StackValue.Property inlining
This commit is contained in:
@@ -2264,7 +2264,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
receiver = StackValue.receiverWithoutReceiverArgument(receiver);
|
||||
}
|
||||
|
||||
return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superCallTarget, false, receiver);
|
||||
return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superCallTarget, false, receiver, resolvedCall);
|
||||
}
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
@@ -2411,7 +2411,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@Nullable ClassDescriptor superCallTarget,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
return intermediateValueForProperty(propertyDescriptor, forceField, false, superCallTarget, false, receiver);
|
||||
return intermediateValueForProperty(propertyDescriptor, forceField, false, superCallTarget, false, receiver, null);
|
||||
}
|
||||
|
||||
private CodegenContext getBackingFieldContext(
|
||||
@@ -2434,7 +2434,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
boolean syntheticBackingField,
|
||||
@Nullable ClassDescriptor superCallTarget,
|
||||
boolean skipAccessorsForPrivateFieldInOuterClass,
|
||||
StackValue receiver
|
||||
@NotNull StackValue receiver,
|
||||
@Nullable ResolvedCall resolvedCall
|
||||
) {
|
||||
if (propertyDescriptor instanceof SyntheticJavaPropertyDescriptor) {
|
||||
return intermediateValueForSyntheticExtensionProperty((SyntheticJavaPropertyDescriptor) propertyDescriptor, receiver);
|
||||
@@ -2530,13 +2531,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return StackValue.property(propertyDescriptor, backingFieldOwner,
|
||||
typeMapper.mapType(
|
||||
isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()),
|
||||
isStaticBackingField, fieldName, callableGetter, callableSetter, state, receiver);
|
||||
isStaticBackingField, fieldName, callableGetter, callableSetter, receiver, this, resolvedCall);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue.Property intermediateValueForSyntheticExtensionProperty(
|
||||
@NotNull SyntheticJavaPropertyDescriptor propertyDescriptor,
|
||||
StackValue receiver
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getOriginal().getType());
|
||||
CallableMethod callableGetter =
|
||||
@@ -2544,7 +2545,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor setMethod = propertyDescriptor.getSetMethod();
|
||||
CallableMethod callableSetter =
|
||||
setMethod != null ? typeMapper.mapToCallableMethod(context.accessibleDescriptor(setMethod, null), false) : null;
|
||||
return StackValue.property(propertyDescriptor, null, type, false, null, callableGetter, callableSetter, state, receiver);
|
||||
return StackValue.property(propertyDescriptor, null, type, false, null, callableGetter, callableSetter, receiver, this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2831,8 +2832,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return getOrCreateCallGenerator(descriptor, function, null, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
return getOrCreateCallGenerator(resolvedCall, resolvedCall.getResultingDescriptor());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall, @NotNull CallableDescriptor descriptor) {
|
||||
Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
|
||||
TypeParameterMappings mappings = new TypeParameterMappings();
|
||||
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
|
||||
@@ -2858,8 +2863,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
);
|
||||
}
|
||||
}
|
||||
return getOrCreateCallGenerator(
|
||||
resolvedCall.getResultingDescriptor(), resolvedCall.getCall().getCallElement(), mappings, false);
|
||||
return getOrCreateCallGenerator(descriptor, resolvedCall.getCall().getCallElement(), mappings, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -391,7 +391,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
KtExpression initializer = property.getDelegateExpressionOrInitializer();
|
||||
assert initializer != null : "shouldInitializeProperty must return false if initializer is null";
|
||||
|
||||
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, false, null, true, StackValue.LOCAL_0);
|
||||
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, false, null, true, StackValue.LOCAL_0,
|
||||
null);
|
||||
|
||||
propValue.store(codegen.gen(initializer), codegen.v);
|
||||
}
|
||||
@@ -611,7 +612,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
syntheticBackingField ||
|
||||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
|
||||
StackValue property = codegen.intermediateValueForProperty(
|
||||
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), forceFieldForCompanionProperty, StackValue.none()
|
||||
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(),
|
||||
forceFieldForCompanionProperty, StackValue.none(), null
|
||||
);
|
||||
|
||||
InstructionAdapter iv = codegen.v;
|
||||
|
||||
@@ -271,10 +271,11 @@ public abstract class StackValue {
|
||||
@Nullable String fieldName,
|
||||
@Nullable CallableMethod getter,
|
||||
@Nullable CallableMethod setter,
|
||||
GenerationState state,
|
||||
@NotNull StackValue receiver
|
||||
@NotNull StackValue receiver,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@Nullable ResolvedCall resolvedCall
|
||||
) {
|
||||
return new Property(descriptor, backingFieldOwner, getter, setter, isStaticBackingField, fieldName, type, state, receiver);
|
||||
return new Property(descriptor, backingFieldOwner, getter, setter, isStaticBackingField, fieldName, type, receiver, codegen, resolvedCall);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1170,23 +1171,27 @@ public abstract class StackValue {
|
||||
private final Type backingFieldOwner;
|
||||
|
||||
private final PropertyDescriptor descriptor;
|
||||
private final GenerationState state;
|
||||
|
||||
private final String fieldName;
|
||||
@NotNull private final ExpressionCodegen codegen;
|
||||
@Nullable private final ResolvedCall resolvedCall;
|
||||
|
||||
public Property(
|
||||
@NotNull PropertyDescriptor descriptor, @Nullable Type backingFieldOwner,
|
||||
@Nullable CallableMethod getter, @Nullable CallableMethod setter, boolean isStaticBackingField,
|
||||
@Nullable String fieldName, @NotNull Type type, @NotNull GenerationState state,
|
||||
@NotNull StackValue receiver
|
||||
@Nullable String fieldName, @NotNull Type type,
|
||||
@NotNull StackValue receiver,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@Nullable ResolvedCall resolvedCall
|
||||
) {
|
||||
super(type, isStatic(isStaticBackingField, getter), isStatic(isStaticBackingField, setter), receiver, true);
|
||||
this.backingFieldOwner = backingFieldOwner;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.descriptor = descriptor;
|
||||
this.state = state;
|
||||
this.fieldName = fieldName;
|
||||
this.codegen = codegen;
|
||||
this.resolvedCall = resolvedCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1202,8 +1207,16 @@ public abstract class StackValue {
|
||||
coerceTo(type, v);
|
||||
}
|
||||
else {
|
||||
getter.genInvokeInstruction(v);
|
||||
coerce(getter.getReturnType(), type, v);
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
assert getter != null : "Getter descriptor should be not null for " + descriptor;
|
||||
if (resolvedCall != null && getter.isInline()) {
|
||||
CallGenerator callGenerator = codegen.getOrCreateCallGenerator(resolvedCall, getter);
|
||||
callGenerator.putHiddenParams();
|
||||
callGenerator.genCall(this.getter, resolvedCall, false, codegen);
|
||||
} else {
|
||||
this.getter.genInvokeInstruction(v);
|
||||
}
|
||||
coerce(this.getter.getReturnType(), type, v);
|
||||
|
||||
KotlinType returnType = descriptor.getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
@@ -1245,6 +1258,23 @@ public abstract class StackValue {
|
||||
v.mark(ok);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(@NotNull StackValue rightSide, @NotNull InstructionAdapter v, boolean skipReceiver) {
|
||||
PropertySetterDescriptor setter = descriptor.getSetter();
|
||||
if (resolvedCall != null && setter != null && setter.isInline()) {
|
||||
assert this.setter != null : "Setter descriptor should be not null for " + descriptor;
|
||||
CallGenerator callGenerator = codegen.getOrCreateCallGenerator(resolvedCall, setter);
|
||||
if (!skipReceiver) {
|
||||
putReceiver(v, false);
|
||||
}
|
||||
callGenerator.putHiddenParams();
|
||||
callGenerator.putValueIfNeeded(rightSide.type, rightSide);
|
||||
callGenerator.genCall(this.setter, resolvedCall, false, codegen);
|
||||
} else {
|
||||
super.store(rightSide, v, skipReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
if (setter == null) {
|
||||
|
||||
@@ -115,7 +115,7 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||
}
|
||||
|
||||
public boolean isInlineMethodContext() {
|
||||
return InlineUtil.isInline(getContextDescriptor());
|
||||
return InlineUtil.isInline(getFunctionDescriptor());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -46,7 +46,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
||||
import org.jetbrains.kotlin.types.expressions.LabelResolver;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
@@ -211,8 +211,8 @@ public class InlineCodegen extends CallGenerator {
|
||||
: jvmSignature.getAsmMethod();
|
||||
|
||||
MethodId methodId = new MethodId(DescriptorUtils.getFqNameSafe(functionDescriptor.getContainingDeclaration()), asmMethod);
|
||||
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && !(functionDescriptor instanceof DeserializedSimpleFunctionDescriptor)) {
|
||||
final CallableMemberDescriptor directMember = JvmCodegenUtil.getDirectMember(functionDescriptor);
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && !(directMember instanceof DeserializedCallableMemberDescriptor)) {
|
||||
return doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, codegen, context, callDefault, state, asmMethod);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
state.getInlineCache().getMethodNodeById(), methodId, new Function0<SMAPAndMethodNode>() {
|
||||
@Override
|
||||
public SMAPAndMethodNode invoke() {
|
||||
SMAPAndMethodNode result = doCreateMethodNodeFromCompiled(functionDescriptor, state, asmMethod);
|
||||
SMAPAndMethodNode result = doCreateMethodNodeFromCompiled(directMember, state, asmMethod);
|
||||
if (result == null) {
|
||||
throw new IllegalStateException("Couldn't obtain compiled function body for " + functionDescriptor);
|
||||
}
|
||||
@@ -245,13 +245,13 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
@Nullable
|
||||
private static SMAPAndMethodNode doCreateMethodNodeFromCompiled(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull CallableMemberDescriptor callableDescriptor,
|
||||
@NotNull final GenerationState state,
|
||||
@NotNull Method asmMethod
|
||||
) {
|
||||
KotlinTypeMapper typeMapper = state.getTypeMapper();
|
||||
|
||||
if (isBuiltInArrayIntrinsic(functionDescriptor)) {
|
||||
if (isBuiltInArrayIntrinsic(callableDescriptor)) {
|
||||
ClassId classId = IntrinsicArrayConstructorsKt.getClassId();
|
||||
byte[] bytes = InlineCacheKt.getOrPut(state.getInlineCache().getClassBytes(), classId, new Function0<byte[]>() {
|
||||
@Override
|
||||
@@ -263,10 +263,10 @@ public class InlineCodegen extends CallGenerator {
|
||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId, state);
|
||||
}
|
||||
|
||||
assert functionDescriptor instanceof DeserializedSimpleFunctionDescriptor : "Not a deserialized function: " + functionDescriptor;
|
||||
assert callableDescriptor instanceof DeserializedCallableMemberDescriptor : "Not a deserialized function or proper: " + callableDescriptor;
|
||||
|
||||
KotlinTypeMapper.ContainingClassesInfo containingClasses =
|
||||
typeMapper.getContainingClassesForDeserializedCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor);
|
||||
typeMapper.getContainingClassesForDeserializedCallable((DeserializedCallableMemberDescriptor) callableDescriptor);
|
||||
|
||||
final ClassId containerId = containingClasses.getImplClassId();
|
||||
|
||||
@@ -292,7 +292,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
@NotNull
|
||||
private static SMAPAndMethodNode doCreateMethodNodeFromSource(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull FunctionDescriptor callableDescriptor,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull CodegenContext context,
|
||||
@@ -300,16 +300,16 @@ public class InlineCodegen extends CallGenerator {
|
||||
@NotNull GenerationState state,
|
||||
@NotNull Method asmMethod
|
||||
) {
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(callableDescriptor);
|
||||
|
||||
if (!(element instanceof KtNamedFunction)) {
|
||||
throw new IllegalStateException("Couldn't find declaration for function " + functionDescriptor);
|
||||
if (!(element instanceof KtNamedFunction || element instanceof KtPropertyAccessor)) {
|
||||
throw new IllegalStateException("Couldn't find declaration for function " + callableDescriptor);
|
||||
}
|
||||
KtNamedFunction inliningFunction = (KtNamedFunction) element;
|
||||
KtDeclarationWithBody inliningFunction = (KtDeclarationWithBody) element;
|
||||
|
||||
MethodNode node = new MethodNode(
|
||||
InlineCodegenUtil.API,
|
||||
getMethodAsmFlags(functionDescriptor, context.getContextKind(), state) | (callDefault ? Opcodes.ACC_STATIC : 0),
|
||||
getMethodAsmFlags(callableDescriptor, context.getContextKind(), state) | (callDefault ? Opcodes.ACC_STATIC : 0),
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
null, null
|
||||
@@ -319,23 +319,26 @@ public class InlineCodegen extends CallGenerator {
|
||||
MethodVisitor maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node);
|
||||
CodegenContext parentContext = context.getParentContext();
|
||||
assert parentContext != null : "Context has no parent: " + context;
|
||||
MethodContext methodContext = parentContext.intoFunction(functionDescriptor);
|
||||
MethodContext methodContext = parentContext.intoFunction(callableDescriptor);
|
||||
|
||||
SMAP smap;
|
||||
if (callDefault) {
|
||||
Type implementationOwner = state.getTypeMapper().mapImplementationOwner(functionDescriptor);
|
||||
Type implementationOwner = state.getTypeMapper().mapImplementationOwner(callableDescriptor);
|
||||
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(
|
||||
codegen.getParentCodegen(), inliningFunction, (FieldOwnerContext) methodContext.getParentContext(),
|
||||
implementationOwner.getInternalName()
|
||||
);
|
||||
if (!(element instanceof KtNamedFunction)) {
|
||||
throw new IllegalStateException("Propertiy accessors with default parameters not supported " + callableDescriptor);
|
||||
}
|
||||
FunctionCodegen.generateDefaultImplBody(
|
||||
methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||
inliningFunction, parentCodegen, asmMethod
|
||||
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||
(KtNamedFunction) inliningFunction, parentCodegen, asmMethod
|
||||
);
|
||||
smap = createSMAPWithDefaultMapping(inliningFunction, parentCodegen.getOrCreateSourceMapper().getResultMappings());
|
||||
}
|
||||
else {
|
||||
smap = generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, inliningFunction, jvmSignature, false, codegen);
|
||||
smap = generateMethodBody(maxCalcAdapter, callableDescriptor, methodContext, inliningFunction, jvmSignature, false, codegen);
|
||||
}
|
||||
maxCalcAdapter.visitMaxs(-1, -1);
|
||||
maxCalcAdapter.visitEnd();
|
||||
@@ -343,11 +346,11 @@ public class InlineCodegen extends CallGenerator {
|
||||
return new SMAPAndMethodNode(node, smap);
|
||||
}
|
||||
|
||||
private static boolean isBuiltInArrayIntrinsic(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
if (functionDescriptor instanceof FictitiousArrayConstructor) return true;
|
||||
String name = functionDescriptor.getName().asString();
|
||||
private static boolean isBuiltInArrayIntrinsic(@NotNull CallableMemberDescriptor callableDescriptor) {
|
||||
if (callableDescriptor instanceof FictitiousArrayConstructor) return true;
|
||||
String name = callableDescriptor.getName().asString();
|
||||
return (name.equals("arrayOf") || name.equals("emptyArray")) &&
|
||||
functionDescriptor.getContainingDeclaration() instanceof BuiltInsPackageFragment;
|
||||
callableDescriptor.getContainingDeclaration() instanceof BuiltInsPackageFragment;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
|
||||
fun inlineFunctionsJvmNames(header: KotlinClassHeader): Set<String> {
|
||||
@@ -31,12 +33,14 @@ fun inlineFunctionsJvmNames(header: KotlinClassHeader): Set<String> {
|
||||
return when (header.kind) {
|
||||
KotlinClassHeader.Kind.CLASS -> {
|
||||
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(BitEncoding.decodeBytes(annotationData), strings)
|
||||
inlineFunctionsJvmNames(classProto.functionList, nameResolver, classProto.typeTable)
|
||||
inlineFunctionsJvmNames(classProto.functionList, nameResolver, classProto.typeTable) +
|
||||
inlineAccessorsJvmNames(classProto.propertyList, nameResolver)
|
||||
}
|
||||
KotlinClassHeader.Kind.FILE_FACADE,
|
||||
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
||||
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(BitEncoding.decodeBytes(annotationData), strings)
|
||||
inlineFunctionsJvmNames(packageProto.functionList, nameResolver, packageProto.typeTable)
|
||||
inlineFunctionsJvmNames(packageProto.functionList, nameResolver, packageProto.typeTable) +
|
||||
inlineAccessorsJvmNames(packageProto.propertyList, nameResolver)
|
||||
}
|
||||
else -> emptySet()
|
||||
}
|
||||
@@ -50,3 +54,27 @@ private fun inlineFunctionsJvmNames(functions: List<ProtoBuf.Function>, nameReso
|
||||
}
|
||||
return jvmNames.toSet()
|
||||
}
|
||||
|
||||
private fun inlineAccessorsJvmNames(properties: List<ProtoBuf.Property>, nameResolver: NameResolver): Set<String> {
|
||||
val propertiesWithInlineAccessors = properties.filter { proto ->
|
||||
proto.hasGetterFlags() && Flags.IS_INLINE_ACCESSOR.get(proto.getterFlags) ||
|
||||
proto.hasSetterFlags() && Flags.IS_INLINE_ACCESSOR.get(proto.setterFlags)
|
||||
}
|
||||
val inlineAccessors = arrayListOf<JvmMethodSignature>()
|
||||
propertiesWithInlineAccessors.forEach { proto ->
|
||||
if (proto.hasExtension(JvmProtoBuf.propertySignature)) {
|
||||
val signature = proto.getExtension(JvmProtoBuf.propertySignature)
|
||||
if (proto.hasGetterFlags() && Flags.IS_INLINE_ACCESSOR.get(proto.getterFlags)) {
|
||||
inlineAccessors.add(signature.getter)
|
||||
}
|
||||
|
||||
if (proto.hasSetterFlags() && Flags.IS_INLINE_ACCESSOR.get(proto.setterFlags)) {
|
||||
inlineAccessors.add(signature.setter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inlineAccessors.mapNotNull {
|
||||
nameResolver.getString(it.name) + nameResolver.getString(it.desc)
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
var value: Int = 0
|
||||
|
||||
inline var z: Int
|
||||
get() = ++value
|
||||
set(p: Int) { value = p }
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val v = z
|
||||
if (value != 1) return "fail 1: $value"
|
||||
|
||||
z = v + 2
|
||||
|
||||
if (value != 3) return "fail 2: $value"
|
||||
var p = z
|
||||
|
||||
if (value != 4) return "fail 3: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
var value: Int = 0
|
||||
|
||||
inline var Int.z: Int
|
||||
get() = this + ++value
|
||||
set(p: Int) { value = p + this}
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val v = 11.z
|
||||
if (v != 12) return "fail 1: $v"
|
||||
|
||||
11.z = v + 2
|
||||
|
||||
if (value != 25) return "fail 2: $value"
|
||||
var p = 11.z
|
||||
|
||||
if (p != 37) return "fail 3: $p"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package test
|
||||
|
||||
var value: Int = 0
|
||||
|
||||
inline var z: Int
|
||||
get() = ++value
|
||||
set(p: Int) { value = p }
|
||||
|
||||
fun box(): String {
|
||||
val v = z
|
||||
if (value != 1) return "fail 1: $value"
|
||||
|
||||
z = v + 2
|
||||
|
||||
if (value != 3) return "fail 2: $value"
|
||||
var p = z
|
||||
|
||||
if (value != 4) return "fail 3: $value"
|
||||
|
||||
return "OK1"
|
||||
}
|
||||
|
||||
// 0 SimpleKt.getZ
|
||||
// 0 SimpleKt.setZ
|
||||
@@ -1514,6 +1514,27 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/property")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Property extends AbstractBlackBoxInlineCodegenTest {
|
||||
public void testAllFilesPresentInProperty() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/property"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/property/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleExtension.kt")
|
||||
public void testSimpleExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/property/simpleExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/reified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -1008,6 +1008,21 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/whenMappingOnCallSite.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/inline/property")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Property extends AbstractBytecodeTextTest {
|
||||
public void testAllFilesPresentInProperty() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inline/property"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/property/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/interfaces")
|
||||
|
||||
+21
@@ -1514,6 +1514,27 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/property")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Property extends AbstractCompileKotlinAgainstInlineKotlinTest {
|
||||
public void testAllFilesPresentInProperty() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/property"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/property/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleExtension.kt")
|
||||
public void testSimpleExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/property/simpleExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/reified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user