From a633a33627621860eaa67b2ca024181076c6cf19 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 27 Sep 2019 14:24:11 +0300 Subject: [PATCH] KT-14513 Don't generate delegated property metadata when unused If the delegated property operators involved are inline, and delegated property metadata parameter is not used (which is often the case, e.g., 'lazy'), we can skip those properties in metadata generation. NOT implemented: special case when only 'kProperty.name' is used by the corresponding delegated property operators. Also a sneak fix for KT-34060. --- .../DelegatedPropertiesCodegenHelper.kt | 110 ++++++++++++++++++ .../kotlin/codegen/PropertyCodegen.java | 7 +- .../binding/CodegenAnnotatingVisitor.java | 23 ++-- .../codegen/binding/CodegenBinding.java | 4 + .../kotlin/codegen/inline/InlineCodegen.kt | 31 ++++- .../cfg/ControlFlowInformationProvider.kt | 16 +-- .../kotlin/resolve/BindingContext.java | 2 + .../definedInSources.kt | 65 +++++++++++ .../definedInSourcesWithNonNullParameter.kt | 65 +++++++++++ .../inSeparateModule.kt | 76 ++++++++++++ .../inSeparateModuleWithNonNullParameter.kt | 76 ++++++++++++ .../optimizedDelegatedProperties/lazy.kt | 17 +++ .../mixedArgumentSizes.kt | 59 ++++++++++ .../definedInSources.kt | 55 +++++++++ .../inSeparateModule.kt | 91 +++++++++++++++ .../optimizedDelegatedProperties/lazy.kt | 22 ++++ .../withNonNullMetadataParameter.kt | 53 +++++++++ .../diagnostics/tests/UnusedParameters.kt | 15 ++- .../diagnostics/tests/UnusedParameters.txt | 3 + .../disallowImplInTypeParameter.kt | 2 +- .../checkers/AbstractDiagnosticsTest.kt | 3 - .../codegen/BlackBoxCodegenTestGenerated.java | 43 +++++++ .../codegen/BytecodeTextTestGenerated.java | 33 ++++++ .../LightAnalysisModeTestGenerated.java | 43 +++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 43 +++++++ .../ir/IrBytecodeTextTestGenerated.java | 33 ++++++ .../kotlin/util/OperatorNameConventions.kt | 3 + .../IrJsCodegenBoxTestGenerated.java | 43 +++++++ .../semantics/JsCodegenBoxTestGenerated.java | 43 +++++++ 29 files changed, 1054 insertions(+), 25 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt create mode 100644 compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt create mode 100644 compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt create mode 100644 compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt create mode 100644 compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt create mode 100644 compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt create mode 100644 compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt create mode 100644 compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/definedInSources.kt create mode 100644 compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/inSeparateModule.kt create mode 100644 compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/lazy.kt create mode 100644 compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/withNonNullMetadataParameter.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt new file mode 100644 index 00000000000..11cf6c63aed --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt @@ -0,0 +1,110 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen + +import org.jetbrains.kotlin.codegen.binding.CodegenBinding +import org.jetbrains.kotlin.codegen.inline.InlineCodegen +import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull +import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.FunctionImportedFromObject +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode +import org.jetbrains.org.objectweb.asm.tree.MethodNode +import org.jetbrains.org.objectweb.asm.tree.VarInsnNode + +class DelegatedPropertiesCodegenHelper(private val state: GenerationState) { + + private val bindingContext = state.bindingContext + private val bindingTrace = state.bindingTrace + private val typeMapper = state.typeMapper + + fun isDelegatedPropertyMetadataRequired(descriptor: VariableDescriptorWithAccessors): Boolean { + val provideDelegateResolvedCall = bindingContext[BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, descriptor] + val getValueResolvedCall = descriptor.getter?.let { bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, it] } + val setValueResolvedCall = descriptor.setter?.let { bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, it] } + + return provideDelegateResolvedCall != null && isDelegatedPropertyMetadataRequired(provideDelegateResolvedCall) || + getValueResolvedCall != null && isDelegatedPropertyMetadataRequired(getValueResolvedCall) || + setValueResolvedCall != null && isDelegatedPropertyMetadataRequired(setValueResolvedCall) + } + + private fun isDelegatedPropertyMetadataRequired(operatorCall: ResolvedCall): Boolean { + val calleeDescriptor = operatorCall.resultingDescriptor.getActualCallee().original + + if (!calleeDescriptor.isInline) return true + + val metadataParameter = calleeDescriptor.valueParameters[1] + if (true == bindingContext[BindingContext.UNUSED_DELEGATED_PROPERTY_OPERATOR_PARAMETER, metadataParameter]) { + return false + } + + if (calleeDescriptor !is DescriptorWithContainerSource) return true + + val cachedResult = bindingTrace[CodegenBinding.PROPERTY_METADATA_REQUIRED_FOR_OPERATOR_CALL, calleeDescriptor] + if (cachedResult != null) { + return cachedResult + } + + return isDelegatedPropertyMetadataRequiredForFunctionFromBinaries(calleeDescriptor).also { + bindingTrace.record(CodegenBinding.PROPERTY_METADATA_REQUIRED_FOR_OPERATOR_CALL, calleeDescriptor, it) + } + } + + private fun FunctionDescriptor.getActualCallee(): FunctionDescriptor = + if (this is FunctionImportedFromObject) + callableFromObject + else + this + + private fun isDelegatedPropertyMetadataRequiredForFunctionFromBinaries(calleeDescriptor: FunctionDescriptor): Boolean { + assert(calleeDescriptor is DescriptorWithContainerSource) { + "Function descriptor from binaries expected: $calleeDescriptor" + } + + val metadataParameterIndex = getMetadataParameterIndex(calleeDescriptor) + val methodNode = InlineCodegen.createSpecialInlineMethodNodeFromBinaries(calleeDescriptor, state) + + return isMetadataParameterUsedInCompiledMethodBody(metadataParameterIndex, methodNode) + } + + private fun isMetadataParameterUsedInCompiledMethodBody(metadataParameterIndex: Int, methodNode: MethodNode): Boolean = + methodNode.instructions.toArray().any { insn -> + insn is VarInsnNode && insn.opcode == Opcodes.ALOAD && insn.`var` == metadataParameterIndex && + !isParameterNullCheckArgument(insn) + } + + private fun isParameterNullCheckArgument(insn: AbstractInsnNode): Boolean { + val next1 = insn.next + val next2 = next1.next + return next1 != null && next2 != null && + next1.opcode == Opcodes.LDC && next2.isCheckParameterIsNotNull() + } + + private fun getMetadataParameterIndex(calleeDescriptor: FunctionDescriptor): Int { + assert(calleeDescriptor.valueParameters.size >= 2) { + "Unexpected delegated property operator (should have at least 2 value parameters): $calleeDescriptor" + } + + var index = 0 + + calleeDescriptor.dispatchReceiverParameter?.let { + index += typeMapper.mapType(it.type).size + } + + calleeDescriptor.extensionReceiverParameter?.let { + index += typeMapper.mapType(it.type).size + } + + index += typeMapper.mapType(calleeDescriptor.valueParameters[0].type).size + + return index + } +} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index 51a1a6b5923..ed916230a59 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -49,8 +49,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField; import static org.jetbrains.kotlin.codegen.FunctionCodegen.processInterfaceMethod; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface; -import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES_WITH_METADATA; -import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER; +import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*; import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject; @@ -569,6 +568,10 @@ public class PropertyCodegen { @NotNull VariableDescriptorWithAccessors descriptor, @NotNull BindingContext bindingContext ) { + if (Boolean.TRUE == bindingContext.get(DELEGATED_PROPERTY_WITH_OPTIMIZED_METADATA, descriptor)) { + return StackValue.constant(null, K_PROPERTY_TYPE); + } + Type owner = bindingContext.get(DELEGATED_PROPERTY_METADATA_OWNER, descriptor); assert owner != null : "Delegated property owner not found: " + descriptor; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index cebc54d638a..2ba7191e535 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -88,6 +88,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { private final SwitchCodegenProvider switchCodegenProvider; private final LanguageVersionSettings languageVersionSettings; private final ClassBuilderMode classBuilderMode; + private final DelegatedPropertiesCodegenHelper delegatedPropertiesCodegenHelper; public CodegenAnnotatingVisitor(@NotNull GenerationState state) { this.bindingTrace = state.getBindingTrace(); @@ -97,6 +98,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { this.switchCodegenProvider = new SwitchCodegenProvider(state); this.languageVersionSettings = state.getLanguageVersionSettings(); this.classBuilderMode = state.getClassBuilderMode(); + this.delegatedPropertiesCodegenHelper = new DelegatedPropertiesCodegenHelper(state); } @NotNull @@ -509,15 +511,20 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { ClassDescriptor classDescriptor = recordClassForCallable(delegate, variableDescriptor, Collections.singleton(supertype), name); recordClosure(classDescriptor, name); - Type containerType = getMetadataOwner(property); - List descriptors = bindingTrace.get(DELEGATED_PROPERTIES_WITH_METADATA, containerType); - if (descriptors == null) { - descriptors = new ArrayList<>(1); - bindingTrace.record(DELEGATED_PROPERTIES_WITH_METADATA, containerType, descriptors); - } - descriptors.add(variableDescriptor); + if (delegatedPropertiesCodegenHelper.isDelegatedPropertyMetadataRequired(variableDescriptor)) { + Type containerType = getMetadataOwner(property); + List descriptors = bindingTrace.get(DELEGATED_PROPERTIES_WITH_METADATA, containerType); + if (descriptors == null) { + descriptors = new ArrayList<>(1); + bindingTrace.record(DELEGATED_PROPERTIES_WITH_METADATA, containerType, descriptors); + } + descriptors.add(variableDescriptor); - bindingTrace.record(DELEGATED_PROPERTY_METADATA_OWNER, variableDescriptor, containerType); + bindingTrace.record(DELEGATED_PROPERTY_METADATA_OWNER, variableDescriptor, containerType); + } + else { + bindingTrace.record(DELEGATED_PROPERTY_WITH_OPTIMIZED_METADATA, variableDescriptor); + } } super.visitProperty(property); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java index bc50cc161f0..46d9bc288b7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java @@ -75,6 +75,10 @@ public class CodegenBinding { Slices.createSimpleSlice(); public static final WritableSlice LOCAL_VARIABLE_PROPERTY_METADATA = Slices.createSimpleSlice(); + public static final WritableSlice PROPERTY_METADATA_REQUIRED_FOR_OPERATOR_CALL = + Slices.createSimpleSlice(); + public static final WritableSlice DELEGATED_PROPERTY_WITH_OPTIMIZED_METADATA = + Slices.createSimpleSlice(); public static final WritableSlice CALL_LABEL_FOR_LAMBDA_ARGUMENT = Slices.createSimpleSlice(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 29667d45830..2308c3774ee 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -534,12 +534,41 @@ abstract class InlineCodegen( else mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod) - val methodId = MethodId(methodOwner.internalName, asmMethod) val directMember = getDirectMemberAndCallableFromObject(functionDescriptor) if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DescriptorWithContainerSource) { return sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod) } + return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature) + } + + internal fun createSpecialInlineMethodNodeFromBinaries(functionDescriptor: FunctionDescriptor, state: GenerationState): MethodNode { + val directMember = getDirectMemberAndCallableFromObject(functionDescriptor) + assert(directMember is DescriptorWithContainerSource) { + "Function is not in binaries: $functionDescriptor" + } + assert(directMember is FunctionDescriptor && directMember.isOperator) { + "Operator function expected: $directMember" + } + + val methodOwner = state.typeMapper.mapImplementationOwner(functionDescriptor) + val jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, OwnerKind.IMPLEMENTATION) + + val asmMethod = mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod) + + return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature).node + } + + private fun getCompiledMethodNodeInner( + functionDescriptor: FunctionDescriptor, + directMember: CallableMemberDescriptor, + asmMethod: Method, + methodOwner: Type, + state: GenerationState, + jvmSignature: JvmMethodSignature + ): SMAPAndMethodNode { + val methodId = MethodId(methodOwner.internalName, asmMethod) + val resultInCache = state.inlineCache.methodNodeById.getOrPut(methodId) { val result = doCreateMethodNodeFromCompiled(directMember, state, asmMethod) ?: if (functionDescriptor.isSuspend) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt index bb42f06a0d3..480b75696f5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt @@ -33,8 +33,11 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType -import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext.* +import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.bindingContextUtil.getEnclosingDescriptor import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsResultOfLambda @@ -744,12 +747,11 @@ class ControlFlowInformationProvider private constructor( } } } - if (functionDescriptor.isOverridableOrOverrides - || owner.hasModifier(KtTokens.OVERRIDE_KEYWORD) - || OperatorNameConventions.GET_VALUE == functionName - || OperatorNameConventions.SET_VALUE == functionName - || OperatorNameConventions.PROVIDE_DELEGATE == functionName - ) { + if (functionDescriptor.isOperator && functionName in OperatorNameConventions.DELEGATED_PROPERTY_OPERATORS) { + trace.record(UNUSED_DELEGATED_PROPERTY_OPERATOR_PARAMETER, variableDescriptor, true) + return + } + if (functionDescriptor.isOverridableOrOverrides || owner.hasModifier(KtTokens.OVERRIDE_KEYWORD)) { return } if (anonymous) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index ac5a6eeb7fa..6ea918ff734 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -107,6 +107,8 @@ public interface BindingContext { WritableSlice LEAKING_THIS = Slices.createSimpleSlice(); WritableSlice UNUSED_MAIN_PARAMETER = Slices.createSimpleSlice(); + WritableSlice UNUSED_DELEGATED_PROPERTY_OPERATOR_PARAMETER = Slices.createSimpleSlice(); + /** * A qualifier corresponds to a receiver expression (if any). For 'A.B' qualifier is recorded for 'A'. */ diff --git a/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt new file mode 100644 index 00000000000..073c1676afb --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt @@ -0,0 +1,65 @@ +class Provider(val _value: T) { + inline operator fun provideDelegate(thisRef: Any?, kProperty: Any?) = + Mut(_value) +} + +class Mut(var _value: T) { + + inline operator fun getValue(thisRef: Any?, kProperty: Any?) = _value + + inline operator fun setValue(thisRef: Any?, kProperty: Any?, newValue: T) { + _value = newValue + } +} + +class C { + val delegatedVal by Mut(1) + var delegatedVar by Mut(2) + val delegatedValByProvider by Provider(1) + var delegatedVarByProvider by Provider(2) +} + +val topLevelDelegatedVal by Mut(1) +var topLevelDelegatedVar by Mut(2) +val topLevelDelegatedValByProvider by Provider(1) +var topLevelDelegatedVarByProvider by Provider(2) + +fun box(): String { + val localDelegatedVal by Mut(1) + var localDelegatedVar by Mut(2) + val localDelegatedValByProvider by Provider(1) + var localDelegatedVarByProvider by Provider(2) + + val x = C() + if (x.delegatedVal != 1) throw AssertionError() + if (x.delegatedVar != 2) throw AssertionError() + x.delegatedVar = 3 + if (x.delegatedVar != 3) throw AssertionError() + + if (x.delegatedValByProvider != 1) throw AssertionError() + if (x.delegatedVarByProvider != 2) throw AssertionError() + x.delegatedVarByProvider = 3 + if (x.delegatedVarByProvider != 3) throw AssertionError() + + if (topLevelDelegatedVal != 1) throw AssertionError() + if (topLevelDelegatedVar != 2) throw AssertionError() + topLevelDelegatedVar = 3 + if (topLevelDelegatedVar != 3) throw AssertionError() + + if (topLevelDelegatedValByProvider != 1) throw AssertionError() + if (topLevelDelegatedVarByProvider != 2) throw AssertionError() + topLevelDelegatedVarByProvider = 3 + if (topLevelDelegatedVarByProvider != 3) throw AssertionError() + + if (localDelegatedVal != 1) throw AssertionError() + if (localDelegatedVar != 2) throw AssertionError() + localDelegatedVar = 3 + if (localDelegatedVar != 3) throw AssertionError() + + if (localDelegatedValByProvider != 1) throw AssertionError() + if (localDelegatedVarByProvider != 2) throw AssertionError() + localDelegatedVarByProvider = 3 + if (localDelegatedVarByProvider != 3) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt new file mode 100644 index 00000000000..590afc160bc --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt @@ -0,0 +1,65 @@ +class Provider(val _value: T) { + inline operator fun provideDelegate(thisRef: Any?, kProperty: Any) = + Mut(_value) +} + +class Mut(var _value: T) { + + inline operator fun getValue(thisRef: Any?, kProperty: Any) = _value + + inline operator fun setValue(thisRef: Any?, kProperty: Any, newValue: T) { + _value = newValue + } +} + +class C { + val delegatedVal by Mut(1) + var delegatedVar by Mut(2) + val delegatedValByProvider by Provider(1) + var delegatedVarByProvider by Provider(2) +} + +val topLevelDelegatedVal by Mut(1) +var topLevelDelegatedVar by Mut(2) +val topLevelDelegatedValByProvider by Provider(1) +var topLevelDelegatedVarByProvider by Provider(2) + +fun box(): String { + val localDelegatedVal by Mut(1) + var localDelegatedVar by Mut(2) + val localDelegatedValByProvider by Provider(1) + var localDelegatedVarByProvider by Provider(2) + + val x = C() + if (x.delegatedVal != 1) throw AssertionError() + if (x.delegatedVar != 2) throw AssertionError() + x.delegatedVar = 3 + if (x.delegatedVar != 3) throw AssertionError() + + if (x.delegatedValByProvider != 1) throw AssertionError() + if (x.delegatedVarByProvider != 2) throw AssertionError() + x.delegatedVarByProvider = 3 + if (x.delegatedVarByProvider != 3) throw AssertionError() + + if (topLevelDelegatedVal != 1) throw AssertionError() + if (topLevelDelegatedVar != 2) throw AssertionError() + topLevelDelegatedVar = 3 + if (topLevelDelegatedVar != 3) throw AssertionError() + + if (topLevelDelegatedValByProvider != 1) throw AssertionError() + if (topLevelDelegatedVarByProvider != 2) throw AssertionError() + topLevelDelegatedVarByProvider = 3 + if (topLevelDelegatedVarByProvider != 3) throw AssertionError() + + if (localDelegatedVal != 1) throw AssertionError() + if (localDelegatedVar != 2) throw AssertionError() + localDelegatedVar = 3 + if (localDelegatedVar != 3) throw AssertionError() + + if (localDelegatedValByProvider != 1) throw AssertionError() + if (localDelegatedVarByProvider != 2) throw AssertionError() + localDelegatedVarByProvider = 3 + if (localDelegatedVarByProvider != 3) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt new file mode 100644 index 00000000000..a0e2d564484 --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt @@ -0,0 +1,76 @@ +// MODULE: lib +// FILE: lib.kt +package lib + +class Provider(val _value: T) { + inline operator fun provideDelegate(thisRef: Any?, kProperty: Any?) = + Mut(_value) +} + +class Mut(var _value: T) { + + inline operator fun getValue(thisRef: Any?, kProperty: Any?) = _value + + inline operator fun setValue(thisRef: Any?, kProperty: Any?, newValue: T) { + _value = newValue + } +} + +// MODULE: main(lib)(lib) +// FILE: main.kt +import lib.* + +class C { + val delegatedVal by Mut(1) + var delegatedVar by Mut(2) + + val delegatedValByProvider by Provider(1) + var delegatedVarByProvider by Provider(2) +} + +val topLevelDelegatedVal by Mut(1) +var topLevelDelegatedVar by Mut(2) + +val topLevelDelegatedValByProvider by Provider(1) +var topLevelDelegatedVarByProvider by Provider(2) + +fun box(): String { + val localDelegatedVal by Mut(1) + var localDelegatedVar by Mut(2) + + val localDelegatedValByProvider by Provider(1) + var localDelegatedVarByProvider by Provider(2) + + val x = C() + if (x.delegatedVal != 1) throw AssertionError() + if (x.delegatedVar != 2) throw AssertionError() + x.delegatedVar = 3 + if (x.delegatedVar != 3) throw AssertionError() + + if (x.delegatedValByProvider != 1) throw AssertionError() + if (x.delegatedVarByProvider != 2) throw AssertionError() + x.delegatedVarByProvider = 3 + if (x.delegatedVarByProvider != 3) throw AssertionError() + + if (topLevelDelegatedVal != 1) throw AssertionError() + if (topLevelDelegatedVar != 2) throw AssertionError() + topLevelDelegatedVar = 3 + if (topLevelDelegatedVar != 3) throw AssertionError() + + if (topLevelDelegatedValByProvider != 1) throw AssertionError() + if (topLevelDelegatedVarByProvider != 2) throw AssertionError() + topLevelDelegatedVarByProvider = 3 + if (topLevelDelegatedVarByProvider != 3) throw AssertionError() + + if (localDelegatedVal != 1) throw AssertionError() + if (localDelegatedVar != 2) throw AssertionError() + localDelegatedVar = 3 + if (localDelegatedVar != 3) throw AssertionError() + + if (localDelegatedValByProvider != 1) throw AssertionError() + if (localDelegatedVarByProvider != 2) throw AssertionError() + localDelegatedVarByProvider = 3 + if (localDelegatedVarByProvider != 3) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt new file mode 100644 index 00000000000..b6ee79d4b73 --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt @@ -0,0 +1,76 @@ +// MODULE: lib +// FILE: lib.kt +package lib + +class Provider(val _value: T) { + inline operator fun provideDelegate(thisRef: Any?, kProperty: Any) = + Mut(_value) +} + +class Mut(var _value: T) { + + inline operator fun getValue(thisRef: Any?, kProperty: Any) = _value + + inline operator fun setValue(thisRef: Any?, kProperty: Any, newValue: T) { + _value = newValue + } +} + +// MODULE: main(lib)(lib) +// FILE: main.kt +import lib.* + +class C { + val delegatedVal by Mut(1) + var delegatedVar by Mut(2) + + val delegatedValByProvider by Provider(1) + var delegatedVarByProvider by Provider(2) +} + +val topLevelDelegatedVal by Mut(1) +var topLevelDelegatedVar by Mut(2) + +val topLevelDelegatedValByProvider by Provider(1) +var topLevelDelegatedVarByProvider by Provider(2) + +fun box(): String { + val localDelegatedVal by Mut(1) + var localDelegatedVar by Mut(2) + + val localDelegatedValByProvider by Provider(1) + var localDelegatedVarByProvider by Provider(2) + + val x = C() + if (x.delegatedVal != 1) throw AssertionError() + if (x.delegatedVar != 2) throw AssertionError() + x.delegatedVar = 3 + if (x.delegatedVar != 3) throw AssertionError() + + if (x.delegatedValByProvider != 1) throw AssertionError() + if (x.delegatedVarByProvider != 2) throw AssertionError() + x.delegatedVarByProvider = 3 + if (x.delegatedVarByProvider != 3) throw AssertionError() + + if (topLevelDelegatedVal != 1) throw AssertionError() + if (topLevelDelegatedVar != 2) throw AssertionError() + topLevelDelegatedVar = 3 + if (topLevelDelegatedVar != 3) throw AssertionError() + + if (topLevelDelegatedValByProvider != 1) throw AssertionError() + if (topLevelDelegatedVarByProvider != 2) throw AssertionError() + topLevelDelegatedVarByProvider = 3 + if (topLevelDelegatedVarByProvider != 3) throw AssertionError() + + if (localDelegatedVal != 1) throw AssertionError() + if (localDelegatedVar != 2) throw AssertionError() + localDelegatedVar = 3 + if (localDelegatedVar != 3) throw AssertionError() + + if (localDelegatedValByProvider != 1) throw AssertionError() + if (localDelegatedVarByProvider != 2) throw AssertionError() + localDelegatedVarByProvider = 3 + if (localDelegatedVarByProvider != 3) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt new file mode 100644 index 00000000000..d4e1d498861 --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +val topLevelLazyVal by lazy { 1 } + +class C { + val memberLazyVal by lazy { 2 } +} + +fun box(): String { + val localLazyVal by lazy { 3 } + + if (topLevelLazyVal != 1) throw AssertionError() + if (C().memberLazyVal != 2) throw AssertionError() + if (localLazyVal != 3) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt new file mode 100644 index 00000000000..dad20517a99 --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt @@ -0,0 +1,59 @@ +inline operator fun Double.provideDelegate(thisRef: Any?, kProp: Any?) = this.toLong() + +inline operator fun Long.getValue(thisRef: Any?, kProp: Any?) = this.toInt() + +inline operator fun Long.getValue(thisRef: Long, kProp: Any?) = this.toInt() + thisRef.toInt() + +inline operator fun Long.getValue(thisRef: IntArray, kProp: Any?) = thisRef[this.toInt()] + +inline operator fun Long.setValue(thisRef: IntArray, kProp: Any?, newValue: Int) { + thisRef[this.toInt()] = newValue +} + +val magic1 by 42.0 + +val magic2 by 42L + +var IntArray.firstElement by 0L + +val Long.plus3 by 3L + +class C { + inline operator fun Long.getValue(thisRef: IntArray, kProp: Any?) = thisRef[this.toInt()] * 10 + + inline operator fun Long.setValue(thisRef: IntArray, kProp: Any?, newValue: Int) { + thisRef[this.toInt()] = newValue * 10 + } + + inline operator fun Long.getValue(thisRef: Long, kProp: Any?) = this.toInt() + thisRef.toInt() * 10 + + var IntArray.secondElementX10 by 1L + + val Long.appendDigit1 by 1L + + fun test(intArray: IntArray) { + if (intArray.secondElementX10 != 220) throw AssertionError() + intArray.secondElementX10 = 42 + if (intArray.secondElementX10 != 4200) throw AssertionError() + + if (42L.appendDigit1 != 421) throw AssertionError() + } +} + +fun box(): String { + if (magic1 != 42) throw AssertionError() + if (magic2 != 42) throw AssertionError() + + val intArray = IntArray(9) { (it + 1) * 10 + it + 1 } // [ 11, 22, 33, ..., 99 ] + + if (10L.plus3 != 13) throw AssertionError() + + if (intArray.firstElement != 11) throw AssertionError() + intArray.firstElement = 42 + if (intArray.firstElement != 42) throw AssertionError() + + val x = C() + x.test(intArray) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/definedInSources.kt b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/definedInSources.kt new file mode 100644 index 00000000000..9fd18f214c4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/definedInSources.kt @@ -0,0 +1,55 @@ +// IGNORE_BACKEND: JVM_IR + +class Provider(val _value: T) { + inline operator fun provideDelegate(thisRef: Any?, kProperty: Any?) = + Mut(_value) +} + +class Mut(var _value: T) { + + inline operator fun getValue(thisRef: Any?, kProperty: Any?) = _value + + inline operator fun setValue(thisRef: Any?, kProperty: Any?, newValue: T) { + _value = newValue + } +} + +class C { + val delegatedVal by Mut(1) + var delegatedVar by Mut(2) + + val delegatedValByProvider by Provider(1) + var delegatedVarByProvider by Provider(2) +} + +val topLevelDelegatedVal by Mut(1) +var topLevelDelegatedVar by Mut(2) + +val topLevelDelegatedValByProvider by Provider(1) +var topLevelDelegatedVarByProvider by Provider(2) + +fun box(): String { + val localDelegatedVal by Mut(1) + var localDelegatedVar by Mut(2) + + val localDelegatedValByProvider by Provider(1) + var localDelegatedVarByProvider by Provider(2) + + if (localDelegatedVal != 1) throw AssertionError() + if (localDelegatedVar != 2) throw AssertionError() + localDelegatedVar = 3 + if (localDelegatedVar != 3) throw AssertionError() + + if (localDelegatedValByProvider != 1) throw AssertionError() + if (localDelegatedVarByProvider != 2) throw AssertionError() + localDelegatedVarByProvider = 3 + if (localDelegatedVarByProvider != 3) throw AssertionError() + + return "OK" +} + +// 0 \$\$delegatedProperties +// 0 ANEWARRAY +// 0 kotlin/reflect/KProperty +// 0 kotlin/jvm/internal/PropertyReference0Impl\.\ +// 0 kotlin/jvm/internal/MutablePropertyReference0Impl\.\ \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/inSeparateModule.kt b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/inSeparateModule.kt new file mode 100644 index 00000000000..7e1baf51cff --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/inSeparateModule.kt @@ -0,0 +1,91 @@ +// IGNORE_BACKEND: JVM_IR + +// MODULE: lib +// FILE: lib.kt +package lib + +class Provider(val _value: T) { + inline operator fun provideDelegate(thisRef: Any?, kProperty: Any?) = + Mut(_value) +} + +class Mut(var _value: T) { + + inline operator fun getValue(thisRef: Any?, kProperty: Any?) = _value + + inline operator fun setValue(thisRef: Any?, kProperty: Any?, newValue: T) { + _value = newValue + } +} + +// MODULE: main(lib)(lib) +// FILE: main.kt +import lib.* + +class C { + val delegatedVal by Mut(1) + var delegatedVar by Mut(2) + val delegatedValByProvider by Provider(1) + var delegatedVarByProvider by Provider(2) +} + +val topLevelDelegatedVal by Mut(1) +var topLevelDelegatedVar by Mut(2) +val topLevelDelegatedValByProvider by Provider(1) +var topLevelDelegatedVarByProvider by Provider(2) + +fun box(): String { + val localDelegatedVal by Mut(1) + var localDelegatedVar by Mut(2) + val localDelegatedValByProvider by Provider(1) + var localDelegatedVarByProvider by Provider(1) + + val x = C() + if (x.delegatedVal != 1) throw AssertionError() + if (x.delegatedVar != 2) throw AssertionError() + x.delegatedVar = 3 + if (x.delegatedVar != 3) throw AssertionError() + + if (x.delegatedValByProvider != 1) throw AssertionError() + if (x.delegatedVarByProvider != 2) throw AssertionError() + x.delegatedVarByProvider = 3 + if (x.delegatedVarByProvider != 3) throw AssertionError() + + if (topLevelDelegatedVal != 1) throw AssertionError() + if (topLevelDelegatedVar != 2) throw AssertionError() + topLevelDelegatedVar = 3 + if (topLevelDelegatedVar != 3) throw AssertionError() + + if (topLevelDelegatedValByProvider != 1) throw AssertionError() + if (topLevelDelegatedVarByProvider != 2) throw AssertionError() + topLevelDelegatedVarByProvider = 3 + if (topLevelDelegatedVarByProvider != 3) throw AssertionError() + + if (localDelegatedVal != 1) throw AssertionError() + if (localDelegatedVar != 2) throw AssertionError() + localDelegatedVar = 3 + if (localDelegatedVar != 3) throw AssertionError() + + if (localDelegatedValByProvider != 1) throw AssertionError() + if (localDelegatedVarByProvider != 2) throw AssertionError() + localDelegatedVarByProvider = 3 + if (localDelegatedVarByProvider != 3) throw AssertionError() + + return "OK" +} + +// @MainKt.class: +// 0 \$\$delegatedProperties +// 0 ANEWARRAY +// 0 kotlin/reflect/KProperty +// 0 final static synthetic \[Lkotlin/reflect/KProperty; \$\$delegatedProperties +// 0 kotlin/jvm/internal/PropertyReference0Impl\.\ +// 0 kotlin/jvm/internal/MutablePropertyReference0Impl\.\ + +// @C.class: +// 0 \$\$delegatedProperties +// 0 ANEWARRAY +// 0 kotlin/reflect/KProperty +// 0 final static synthetic \[Lkotlin/reflect/KProperty; \$\$delegatedProperties +// 0 kotlin/jvm/internal/PropertyReference0Impl\.\ +// 0 kotlin/jvm/internal/MutablePropertyReference0Impl\.\ diff --git a/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/lazy.kt b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/lazy.kt new file mode 100644 index 00000000000..06e0b33c9dc --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/lazy.kt @@ -0,0 +1,22 @@ +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME + +val topLevelLazyVal by lazy { 1 } + +class C { + val memberLazyVal by lazy { 2 } +} + +fun box(): String { + val localLazyVal by lazy { 3 } + + if (topLevelLazyVal != 1) throw AssertionError() + if (C().memberLazyVal != 2) throw AssertionError() + if (localLazyVal != 3) throw AssertionError() + + return "OK" +} + +// 0 \$\$delegatedProperties +// 0 kotlin/jvm/internal/PropertyReference0Impl\.\ +// 0 kotlin/jvm/internal/MutablePropertyReference0Impl\.\ \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/withNonNullMetadataParameter.kt b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/withNonNullMetadataParameter.kt new file mode 100644 index 00000000000..674142655cf --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/withNonNullMetadataParameter.kt @@ -0,0 +1,53 @@ +// IGNORE_BACKEND: JVM_IR + +class Provider(val _value: T) { + inline operator fun provideDelegate(thisRef: Any?, kProperty: Any) = + Mut(_value) +} + +class Mut(var _value: T) { + + inline operator fun getValue(thisRef: Any?, kProperty: Any) = _value + + inline operator fun setValue(thisRef: Any?, kProperty: Any, newValue: T) { + _value = newValue + } +} + +class C { + val delegatedVal by Mut(1) + var delegatedVar by Mut(2) + + val delegatedValByProvider by Provider(1) + var delegatedVarByProvider by Provider(2) +} + +val topLevelDelegatedVal by Mut(1) +var topLevelDelegatedVar by Mut(2) + +val topLevelDelegatedValByProvider by Provider(1) +var topLevelDelegatedVarByProvider by Provider(2) + +fun box(): String { + val localDelegatedVal by Mut(1) + var localDelegatedVar by Mut(2) + + val localDelegatedValByProvider by Provider(1) + var localDelegatedVarByProvider by Provider(2) + + if (localDelegatedVal != 1) throw AssertionError() + if (localDelegatedVar != 2) throw AssertionError() + localDelegatedVar = 3 + if (localDelegatedVar != 3) throw AssertionError() + + if (localDelegatedValByProvider != 1) throw AssertionError() + if (localDelegatedVarByProvider != 2) throw AssertionError() + localDelegatedVarByProvider = 3 + if (localDelegatedVarByProvider != 3) throw AssertionError() + + return "OK" +} + +// 0 final static synthetic \[Lkotlin/reflect/KProperty; \$\$delegatedProperties +// 0 kotlin/jvm/internal/PropertyReference0Impl\.\ +// 0 kotlin/jvm/internal/MutablePropertyReference0Impl\.\ \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/UnusedParameters.kt b/compiler/testData/diagnostics/tests/UnusedParameters.kt index 6d9d36d4454..40a91f87c52 100644 --- a/compiler/testData/diagnostics/tests/UnusedParameters.kt +++ b/compiler/testData/diagnostics/tests/UnusedParameters.kt @@ -16,13 +16,22 @@ fun f(a: Int, b: Int, c: Int = b) { a + a } -fun Any.getValue(thisRef: Any?, prop: KProperty<*>): String = ":)" -fun Any.setValue(thisRef: Any?, prop: KProperty<*>, value: String) { +fun Any.getValue(thisRef: Any?, prop: KProperty<*>): String = ":)" +fun Any.setValue(thisRef: Any?, prop: KProperty<*>, value: String) { } -fun Any.provideDelegate(thisRef: Any?, prop: KProperty<*>) { +fun Any.provideDelegate(thisRef: Any?, prop: KProperty<*>) { } +operator fun Int.getValue(thisRef: Any?, prop: KProperty<*>): String = ":)" + +operator fun Int.setValue(thisRef: Any?, prop: KProperty<*>, value: String) { +} + +operator fun Int.provideDelegate(thisRef: Any?, prop: KProperty<*>) { +} + + fun get(p: Any) { } diff --git a/compiler/testData/diagnostics/tests/UnusedParameters.txt b/compiler/testData/diagnostics/tests/UnusedParameters.txt index 422af376f3b..91a8e2f01eb 100644 --- a/compiler/testData/diagnostics/tests/UnusedParameters.txt +++ b/compiler/testData/diagnostics/tests/UnusedParameters.txt @@ -5,8 +5,11 @@ public fun foo(/*0*/ s: kotlin.String): kotlin.Unit public fun get(/*0*/ p: kotlin.Any): kotlin.Unit public fun set(/*0*/ p: kotlin.Any): kotlin.Unit public fun kotlin.Any.getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.String +public operator fun kotlin.Int.getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.String public fun kotlin.Any.provideDelegate(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.Unit +public operator fun kotlin.Int.provideDelegate(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.Unit public fun kotlin.Any.setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.String): kotlin.Unit +public operator fun kotlin.Int.setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.String): kotlin.Unit public final class C { public constructor C(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int, /*2*/ c: kotlin.Int, /*3*/ d: kotlin.Int, /*4*/ e: kotlin.Int = ..., /*5*/ f: kotlin.String) diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/disallowImplInTypeParameter.kt b/compiler/testData/diagnostics/tests/delegatedProperty/disallowImplInTypeParameter.kt index 9b320bd7f82..ec70b1aa791 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/disallowImplInTypeParameter.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/disallowImplInTypeParameter.kt @@ -3,5 +3,5 @@ import kotlin.reflect.KProperty0 val a: Int by A() class A { - fun getValue(t: Any?, p: KProperty0<*>): Int = 1 + fun getValue(t: Any?, p: KProperty0<*>): Int = 1 } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt index 9e622c4b2a0..a5e77c783e9 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt @@ -39,11 +39,8 @@ import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames -import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.isCommon -import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.platform.konan.KonanPlatforms import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index bc1f23ace75..9600473b301 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -9608,6 +9608,49 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptimizedDelegatedProperties extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInOptimizedDelegatedProperties() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("definedInSources.kt") + public void testDefinedInSources() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt"); + } + + @TestMetadata("definedInSourcesWithNonNullParameter.kt") + public void testDefinedInSourcesWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt"); + } + + @TestMetadata("inSeparateModule.kt") + public void testInSeparateModule() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt"); + } + + @TestMetadata("inSeparateModuleWithNonNullParameter.kt") + public void testInSeparateModuleWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt"); + } + + @TestMetadata("lazy.kt") + public void testLazy() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt"); + } + + @TestMetadata("mixedArgumentSizes.kt") + public void testMixedArgumentSizes() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 5ab24da7713..485b6ab3c0a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -3400,6 +3400,39 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { } } + @TestMetadata("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptimizedDelegatedProperties extends AbstractBytecodeTextTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInOptimizedDelegatedProperties() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("definedInSources.kt") + public void testDefinedInSources() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/definedInSources.kt"); + } + + @TestMetadata("inSeparateModule.kt") + public void testInSeparateModule() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/inSeparateModule.kt"); + } + + @TestMetadata("lazy.kt") + public void testLazy() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/lazy.kt"); + } + + @TestMetadata("withNonNullMetadataParameter.kt") + public void testWithNonNullMetadataParameter() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/withNonNullMetadataParameter.kt"); + } + } + @TestMetadata("compiler/testData/codegen/bytecodeText/properties") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index cd41d7f3c6c..6c33a8a5520 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -9608,6 +9608,49 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptimizedDelegatedProperties extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInOptimizedDelegatedProperties() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("definedInSources.kt") + public void testDefinedInSources() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt"); + } + + @TestMetadata("definedInSourcesWithNonNullParameter.kt") + public void testDefinedInSourcesWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt"); + } + + @TestMetadata("inSeparateModule.kt") + public void testInSeparateModule() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt"); + } + + @TestMetadata("inSeparateModuleWithNonNullParameter.kt") + public void testInSeparateModuleWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt"); + } + + @TestMetadata("lazy.kt") + public void testLazy() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt"); + } + + @TestMetadata("mixedArgumentSizes.kt") + public void testMixedArgumentSizes() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 0dec818837b..8d5d3d8b6e6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -8493,6 +8493,49 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptimizedDelegatedProperties extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInOptimizedDelegatedProperties() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + + @TestMetadata("definedInSources.kt") + public void testDefinedInSources() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt"); + } + + @TestMetadata("definedInSourcesWithNonNullParameter.kt") + public void testDefinedInSourcesWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt"); + } + + @TestMetadata("inSeparateModule.kt") + public void testInSeparateModule() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt"); + } + + @TestMetadata("inSeparateModuleWithNonNullParameter.kt") + public void testInSeparateModuleWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt"); + } + + @TestMetadata("lazy.kt") + public void testLazy() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt"); + } + + @TestMetadata("mixedArgumentSizes.kt") + public void testMixedArgumentSizes() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index 77cc3f96811..b4529e45eb4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -3370,6 +3370,39 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { } } + @TestMetadata("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptimizedDelegatedProperties extends AbstractIrBytecodeTextTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInOptimizedDelegatedProperties() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + + @TestMetadata("definedInSources.kt") + public void testDefinedInSources() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/definedInSources.kt"); + } + + @TestMetadata("inSeparateModule.kt") + public void testInSeparateModule() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/inSeparateModule.kt"); + } + + @TestMetadata("lazy.kt") + public void testLazy() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/lazy.kt"); + } + + @TestMetadata("withNonNullMetadataParameter.kt") + public void testWithNonNullMetadataParameter() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/optimizedDelegatedProperties/withNonNullMetadataParameter.kt"); + } + } + @TestMetadata("compiler/testData/codegen/bytecodeText/properties") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt b/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt index f8bc8d171d9..e257951db31 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt @@ -73,4 +73,7 @@ object OperatorNameConventions { @JvmField internal val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, REM_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN) + + @JvmField + val DELEGATED_PROPERTY_OPERATORS = setOf(GET_VALUE, SET_VALUE, PROVIDE_DELEGATE) } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 1d13dab1935..46f217ec046 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -7313,6 +7313,49 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptimizedDelegatedProperties extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInOptimizedDelegatedProperties() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); + } + + @TestMetadata("definedInSources.kt") + public void testDefinedInSources() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt"); + } + + @TestMetadata("definedInSourcesWithNonNullParameter.kt") + public void testDefinedInSourcesWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt"); + } + + @TestMetadata("inSeparateModule.kt") + public void testInSeparateModule() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt"); + } + + @TestMetadata("inSeparateModuleWithNonNullParameter.kt") + public void testInSeparateModuleWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt"); + } + + @TestMetadata("lazy.kt") + public void testLazy() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt"); + } + + @TestMetadata("mixedArgumentSizes.kt") + public void testMixedArgumentSizes() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 1bef4b8218c..64a718efc6b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -8398,6 +8398,49 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptimizedDelegatedProperties extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInOptimizedDelegatedProperties() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("definedInSources.kt") + public void testDefinedInSources() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSources.kt"); + } + + @TestMetadata("definedInSourcesWithNonNullParameter.kt") + public void testDefinedInSourcesWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/definedInSourcesWithNonNullParameter.kt"); + } + + @TestMetadata("inSeparateModule.kt") + public void testInSeparateModule() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModule.kt"); + } + + @TestMetadata("inSeparateModuleWithNonNullParameter.kt") + public void testInSeparateModuleWithNonNullParameter() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/inSeparateModuleWithNonNullParameter.kt"); + } + + @TestMetadata("lazy.kt") + public void testLazy() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/lazy.kt"); + } + + @TestMetadata("mixedArgumentSizes.kt") + public void testMixedArgumentSizes() throws Exception { + runTest("compiler/testData/codegen/box/delegatedProperty/optimizedDelegatedProperties/mixedArgumentSizes.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)